@rpgm-tools/neo-angband-core 0.10.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 (1183) hide show
  1. package/LICENSE.md +43 -0
  2. package/README.md +80 -0
  3. package/dist/agent/act.d.ts +22 -0
  4. package/dist/agent/act.d.ts.map +1 -0
  5. package/dist/agent/act.js +88 -0
  6. package/dist/agent/act.js.map +1 -0
  7. package/dist/agent/controller.d.ts +34 -0
  8. package/dist/agent/controller.d.ts.map +1 -0
  9. package/dist/agent/controller.js +90 -0
  10. package/dist/agent/controller.js.map +1 -0
  11. package/dist/agent/events.d.ts +27 -0
  12. package/dist/agent/events.d.ts.map +1 -0
  13. package/dist/agent/events.js +31 -0
  14. package/dist/agent/events.js.map +1 -0
  15. package/dist/agent/index.d.ts +17 -0
  16. package/dist/agent/index.d.ts.map +1 -0
  17. package/dist/agent/index.js +15 -0
  18. package/dist/agent/index.js.map +1 -0
  19. package/dist/agent/perceive.d.ts +21 -0
  20. package/dist/agent/perceive.d.ts.map +1 -0
  21. package/dist/agent/perceive.js +386 -0
  22. package/dist/agent/perceive.js.map +1 -0
  23. package/dist/agent/types.d.ts +436 -0
  24. package/dist/agent/types.d.ts.map +1 -0
  25. package/dist/agent/types.js +63 -0
  26. package/dist/agent/types.js.map +1 -0
  27. package/dist/bitflag.d.ts +199 -0
  28. package/dist/bitflag.d.ts.map +1 -0
  29. package/dist/bitflag.js +478 -0
  30. package/dist/bitflag.js.map +1 -0
  31. package/dist/cmd.d.ts +164 -0
  32. package/dist/cmd.d.ts.map +1 -0
  33. package/dist/cmd.js +350 -0
  34. package/dist/cmd.js.map +1 -0
  35. package/dist/color.d.ts +104 -0
  36. package/dist/color.d.ts.map +1 -0
  37. package/dist/color.js +240 -0
  38. package/dist/color.js.map +1 -0
  39. package/dist/combat/brand-slay.d.ts +119 -0
  40. package/dist/combat/brand-slay.d.ts.map +1 -0
  41. package/dist/combat/brand-slay.js +264 -0
  42. package/dist/combat/brand-slay.js.map +1 -0
  43. package/dist/combat/hit.d.ts +198 -0
  44. package/dist/combat/hit.d.ts.map +1 -0
  45. package/dist/combat/hit.js +310 -0
  46. package/dist/combat/hit.js.map +1 -0
  47. package/dist/combat/index.d.ts +15 -0
  48. package/dist/combat/index.d.ts.map +1 -0
  49. package/dist/combat/index.js +15 -0
  50. package/dist/combat/index.js.map +1 -0
  51. package/dist/combat/melee.d.ts +261 -0
  52. package/dist/combat/melee.d.ts.map +1 -0
  53. package/dist/combat/melee.js +402 -0
  54. package/dist/combat/melee.js.map +1 -0
  55. package/dist/combat/mon-melee.d.ts +233 -0
  56. package/dist/combat/mon-melee.d.ts.map +1 -0
  57. package/dist/combat/mon-melee.js +883 -0
  58. package/dist/combat/mon-melee.js.map +1 -0
  59. package/dist/combat/ranged.d.ts +89 -0
  60. package/dist/combat/ranged.d.ts.map +1 -0
  61. package/dist/combat/ranged.js +253 -0
  62. package/dist/combat/ranged.js.map +1 -0
  63. package/dist/constants.d.ts +134 -0
  64. package/dist/constants.d.ts.map +1 -0
  65. package/dist/constants.js +171 -0
  66. package/dist/constants.js.map +1 -0
  67. package/dist/dice.d.ts +91 -0
  68. package/dist/dice.d.ts.map +1 -0
  69. package/dist/dice.js +424 -0
  70. package/dist/dice.js.map +1 -0
  71. package/dist/effects/effect-choice.d.ts +15 -0
  72. package/dist/effects/effect-choice.d.ts.map +1 -0
  73. package/dist/effects/effect-choice.js +18 -0
  74. package/dist/effects/effect-choice.js.map +1 -0
  75. package/dist/effects/effect-info.d.ts +124 -0
  76. package/dist/effects/effect-info.d.ts.map +1 -0
  77. package/dist/effects/effect-info.js +706 -0
  78. package/dist/effects/effect-info.js.map +1 -0
  79. package/dist/effects/effect.d.ts +165 -0
  80. package/dist/effects/effect.d.ts.map +1 -0
  81. package/dist/effects/effect.js +452 -0
  82. package/dist/effects/effect.js.map +1 -0
  83. package/dist/effects/handlers.d.ts +70 -0
  84. package/dist/effects/handlers.d.ts.map +1 -0
  85. package/dist/effects/handlers.js +394 -0
  86. package/dist/effects/handlers.js.map +1 -0
  87. package/dist/effects/interpreter.d.ts +291 -0
  88. package/dist/effects/interpreter.d.ts.map +1 -0
  89. package/dist/effects/interpreter.js +325 -0
  90. package/dist/effects/interpreter.js.map +1 -0
  91. package/dist/events.d.ts +188 -0
  92. package/dist/events.d.ts.map +1 -0
  93. package/dist/events.js +138 -0
  94. package/dist/events.js.map +1 -0
  95. package/dist/expression.d.ts +83 -0
  96. package/dist/expression.d.ts.map +1 -0
  97. package/dist/expression.js +333 -0
  98. package/dist/expression.js.map +1 -0
  99. package/dist/game/cave-cmd.d.ts +195 -0
  100. package/dist/game/cave-cmd.d.ts.map +1 -0
  101. package/dist/game/cave-cmd.js +968 -0
  102. package/dist/game/cave-cmd.js.map +1 -0
  103. package/dist/game/char-sheet.d.ts +189 -0
  104. package/dist/game/char-sheet.d.ts.map +1 -0
  105. package/dist/game/char-sheet.js +381 -0
  106. package/dist/game/char-sheet.js.map +1 -0
  107. package/dist/game/chest.d.ts +94 -0
  108. package/dist/game/chest.d.ts.map +1 -0
  109. package/dist/game/chest.js +267 -0
  110. package/dist/game/chest.js.map +1 -0
  111. package/dist/game/context.d.ts +970 -0
  112. package/dist/game/context.d.ts.map +1 -0
  113. package/dist/game/context.js +353 -0
  114. package/dist/game/context.js.map +1 -0
  115. package/dist/game/curse-tick.d.ts +35 -0
  116. package/dist/game/curse-tick.d.ts.map +1 -0
  117. package/dist/game/curse-tick.js +100 -0
  118. package/dist/game/curse-tick.js.map +1 -0
  119. package/dist/game/describe.d.ts +20 -0
  120. package/dist/game/describe.d.ts.map +1 -0
  121. package/dist/game/describe.js +45 -0
  122. package/dist/game/describe.js.map +1 -0
  123. package/dist/game/display.d.ts +196 -0
  124. package/dist/game/display.d.ts.map +1 -0
  125. package/dist/game/display.js +684 -0
  126. package/dist/game/display.js.map +1 -0
  127. package/dist/game/dump-level.d.ts +37 -0
  128. package/dist/game/dump-level.d.ts.map +1 -0
  129. package/dist/game/dump-level.js +110 -0
  130. package/dist/game/dump-level.js.map +1 -0
  131. package/dist/game/effect-attack.d.ts +36 -0
  132. package/dist/game/effect-attack.d.ts.map +1 -0
  133. package/dist/game/effect-attack.js +694 -0
  134. package/dist/game/effect-attack.js.map +1 -0
  135. package/dist/game/effect-detect.d.ts +34 -0
  136. package/dist/game/effect-detect.d.ts.map +1 -0
  137. package/dist/game/effect-detect.js +456 -0
  138. package/dist/game/effect-detect.js.map +1 -0
  139. package/dist/game/effect-env.d.ts +77 -0
  140. package/dist/game/effect-env.d.ts.map +1 -0
  141. package/dist/game/effect-env.js +166 -0
  142. package/dist/game/effect-env.js.map +1 -0
  143. package/dist/game/effect-game-env.d.ts +76 -0
  144. package/dist/game/effect-game-env.d.ts.map +1 -0
  145. package/dist/game/effect-game-env.js +23 -0
  146. package/dist/game/effect-game-env.js.map +1 -0
  147. package/dist/game/effect-general.d.ts +98 -0
  148. package/dist/game/effect-general.d.ts.map +1 -0
  149. package/dist/game/effect-general.js +914 -0
  150. package/dist/game/effect-general.js.map +1 -0
  151. package/dist/game/effect-item.d.ts +124 -0
  152. package/dist/game/effect-item.d.ts.map +1 -0
  153. package/dist/game/effect-item.js +789 -0
  154. package/dist/game/effect-item.js.map +1 -0
  155. package/dist/game/effect-melee.d.ts +43 -0
  156. package/dist/game/effect-melee.d.ts.map +1 -0
  157. package/dist/game/effect-melee.js +477 -0
  158. package/dist/game/effect-melee.js.map +1 -0
  159. package/dist/game/effect-mon-origin.d.ts +67 -0
  160. package/dist/game/effect-mon-origin.d.ts.map +1 -0
  161. package/dist/game/effect-mon-origin.js +164 -0
  162. package/dist/game/effect-mon-origin.js.map +1 -0
  163. package/dist/game/effect-monster.d.ts +29 -0
  164. package/dist/game/effect-monster.d.ts.map +1 -0
  165. package/dist/game/effect-monster.js +281 -0
  166. package/dist/game/effect-monster.js.map +1 -0
  167. package/dist/game/effect-summon.d.ts +37 -0
  168. package/dist/game/effect-summon.d.ts.map +1 -0
  169. package/dist/game/effect-summon.js +113 -0
  170. package/dist/game/effect-summon.js.map +1 -0
  171. package/dist/game/effect-teleport.d.ts +130 -0
  172. package/dist/game/effect-teleport.d.ts.map +1 -0
  173. package/dist/game/effect-teleport.js +529 -0
  174. package/dist/game/effect-teleport.js.map +1 -0
  175. package/dist/game/effect-terrain.d.ts +91 -0
  176. package/dist/game/effect-terrain.d.ts.map +1 -0
  177. package/dist/game/effect-terrain.js +812 -0
  178. package/dist/game/effect-terrain.js.map +1 -0
  179. package/dist/game/energy.d.ts +45 -0
  180. package/dist/game/energy.d.ts.map +1 -0
  181. package/dist/game/energy.js +51 -0
  182. package/dist/game/energy.js.map +1 -0
  183. package/dist/game/equip-cmp.d.ts +138 -0
  184. package/dist/game/equip-cmp.d.ts.map +1 -0
  185. package/dist/game/equip-cmp.js +363 -0
  186. package/dist/game/equip-cmp.js.map +1 -0
  187. package/dist/game/floor.d.ts +182 -0
  188. package/dist/game/floor.d.ts.map +1 -0
  189. package/dist/game/floor.js +435 -0
  190. package/dist/game/floor.js.map +1 -0
  191. package/dist/game/gear.d.ts +408 -0
  192. package/dist/game/gear.d.ts.map +1 -0
  193. package/dist/game/gear.js +1037 -0
  194. package/dist/game/gear.js.map +1 -0
  195. package/dist/game/harness.d.ts +61 -0
  196. package/dist/game/harness.d.ts.map +1 -0
  197. package/dist/game/harness.js +198 -0
  198. package/dist/game/harness.js.map +1 -0
  199. package/dist/game/history.d.ts +49 -0
  200. package/dist/game/history.d.ts.map +1 -0
  201. package/dist/game/history.js +55 -0
  202. package/dist/game/history.js.map +1 -0
  203. package/dist/game/ignore-cmd.d.ts +42 -0
  204. package/dist/game/ignore-cmd.d.ts.map +1 -0
  205. package/dist/game/ignore-cmd.js +59 -0
  206. package/dist/game/ignore-cmd.js.map +1 -0
  207. package/dist/game/inscription-confirm.d.ts +80 -0
  208. package/dist/game/inscription-confirm.d.ts.map +1 -0
  209. package/dist/game/inscription-confirm.js +95 -0
  210. package/dist/game/inscription-confirm.js.map +1 -0
  211. package/dist/game/known.d.ts +297 -0
  212. package/dist/game/known.d.ts.map +1 -0
  213. package/dist/game/known.js +849 -0
  214. package/dist/game/known.js.map +1 -0
  215. package/dist/game/loop.d.ts +139 -0
  216. package/dist/game/loop.d.ts.map +1 -0
  217. package/dist/game/loop.js +631 -0
  218. package/dist/game/loop.js.map +1 -0
  219. package/dist/game/lore-color.d.ts +25 -0
  220. package/dist/game/lore-color.d.ts.map +1 -0
  221. package/dist/game/lore-color.js +95 -0
  222. package/dist/game/lore-color.js.map +1 -0
  223. package/dist/game/mon-cast.d.ts +150 -0
  224. package/dist/game/mon-cast.d.ts.map +1 -0
  225. package/dist/game/mon-cast.js +301 -0
  226. package/dist/game/mon-cast.js.map +1 -0
  227. package/dist/game/mon-cmd.d.ts +51 -0
  228. package/dist/game/mon-cmd.d.ts.map +1 -0
  229. package/dist/game/mon-cmd.js +670 -0
  230. package/dist/game/mon-cmd.js.map +1 -0
  231. package/dist/game/mon-death.d.ts +143 -0
  232. package/dist/game/mon-death.d.ts.map +1 -0
  233. package/dist/game/mon-death.js +328 -0
  234. package/dist/game/mon-death.js.map +1 -0
  235. package/dist/game/mon-group.d.ts +81 -0
  236. package/dist/game/mon-group.d.ts.map +1 -0
  237. package/dist/game/mon-group.js +323 -0
  238. package/dist/game/mon-group.js.map +1 -0
  239. package/dist/game/mon-list.d.ts +85 -0
  240. package/dist/game/mon-list.d.ts.map +1 -0
  241. package/dist/game/mon-list.js +154 -0
  242. package/dist/game/mon-list.js.map +1 -0
  243. package/dist/game/mon-message.d.ts +100 -0
  244. package/dist/game/mon-message.d.ts.map +1 -0
  245. package/dist/game/mon-message.js +336 -0
  246. package/dist/game/mon-message.js.map +1 -0
  247. package/dist/game/mon-place.d.ts +226 -0
  248. package/dist/game/mon-place.d.ts.map +1 -0
  249. package/dist/game/mon-place.js +642 -0
  250. package/dist/game/mon-place.js.map +1 -0
  251. package/dist/game/mon-ranged.d.ts +87 -0
  252. package/dist/game/mon-ranged.d.ts.map +1 -0
  253. package/dist/game/mon-ranged.js +353 -0
  254. package/dist/game/mon-ranged.js.map +1 -0
  255. package/dist/game/mon-shape.d.ts +43 -0
  256. package/dist/game/mon-shape.d.ts.map +1 -0
  257. package/dist/game/mon-shape.js +115 -0
  258. package/dist/game/mon-shape.js.map +1 -0
  259. package/dist/game/mon-side.d.ts +63 -0
  260. package/dist/game/mon-side.d.ts.map +1 -0
  261. package/dist/game/mon-side.js +403 -0
  262. package/dist/game/mon-side.js.map +1 -0
  263. package/dist/game/monster-turn.d.ts +195 -0
  264. package/dist/game/monster-turn.d.ts.map +1 -0
  265. package/dist/game/monster-turn.js +1560 -0
  266. package/dist/game/monster-turn.js.map +1 -0
  267. package/dist/game/obj-cmd.d.ts +453 -0
  268. package/dist/game/obj-cmd.d.ts.map +1 -0
  269. package/dist/game/obj-cmd.js +1530 -0
  270. package/dist/game/obj-cmd.js.map +1 -0
  271. package/dist/game/obj-list.d.ts +92 -0
  272. package/dist/game/obj-list.d.ts.map +1 -0
  273. package/dist/game/obj-list.js +251 -0
  274. package/dist/game/obj-list.js.map +1 -0
  275. package/dist/game/object-inspect.d.ts +37 -0
  276. package/dist/game/object-inspect.d.ts.map +1 -0
  277. package/dist/game/object-inspect.js +106 -0
  278. package/dist/game/object-inspect.js.map +1 -0
  279. package/dist/game/pickup.d.ts +126 -0
  280. package/dist/game/pickup.d.ts.map +1 -0
  281. package/dist/game/pickup.js +367 -0
  282. package/dist/game/pickup.js.map +1 -0
  283. package/dist/game/player-path.d.ts +133 -0
  284. package/dist/game/player-path.d.ts.map +1 -0
  285. package/dist/game/player-path.js +1268 -0
  286. package/dist/game/player-path.js.map +1 -0
  287. package/dist/game/player-side.d.ts +59 -0
  288. package/dist/game/player-side.d.ts.map +1 -0
  289. package/dist/game/player-side.js +506 -0
  290. package/dist/game/player-side.js.map +1 -0
  291. package/dist/game/player-turn.d.ts +161 -0
  292. package/dist/game/player-turn.d.ts.map +1 -0
  293. package/dist/game/player-turn.js +739 -0
  294. package/dist/game/player-turn.js.map +1 -0
  295. package/dist/game/project-cast.d.ts +268 -0
  296. package/dist/game/project-cast.d.ts.map +1 -0
  297. package/dist/game/project-cast.js +496 -0
  298. package/dist/game/project-cast.js.map +1 -0
  299. package/dist/game/project-feat.d.ts +47 -0
  300. package/dist/game/project-feat.d.ts.map +1 -0
  301. package/dist/game/project-feat.js +350 -0
  302. package/dist/game/project-feat.js.map +1 -0
  303. package/dist/game/project-monster.d.ts +106 -0
  304. package/dist/game/project-monster.d.ts.map +1 -0
  305. package/dist/game/project-monster.js +272 -0
  306. package/dist/game/project-monster.js.map +1 -0
  307. package/dist/game/project-obj.d.ts +60 -0
  308. package/dist/game/project-obj.d.ts.map +1 -0
  309. package/dist/game/project-obj.js +245 -0
  310. package/dist/game/project-obj.js.map +1 -0
  311. package/dist/game/project-player.d.ts +120 -0
  312. package/dist/game/project-player.d.ts.map +1 -0
  313. package/dist/game/project-player.js +108 -0
  314. package/dist/game/project-player.js.map +1 -0
  315. package/dist/game/quest.d.ts +101 -0
  316. package/dist/game/quest.d.ts.map +1 -0
  317. package/dist/game/quest.js +192 -0
  318. package/dist/game/quest.js.map +1 -0
  319. package/dist/game/ranged-cmd.d.ts +32 -0
  320. package/dist/game/ranged-cmd.d.ts.map +1 -0
  321. package/dist/game/ranged-cmd.js +372 -0
  322. package/dist/game/ranged-cmd.js.map +1 -0
  323. package/dist/game/scheduler.d.ts +47 -0
  324. package/dist/game/scheduler.d.ts.map +1 -0
  325. package/dist/game/scheduler.js +141 -0
  326. package/dist/game/scheduler.js.map +1 -0
  327. package/dist/game/spell-cmd.d.ts +104 -0
  328. package/dist/game/spell-cmd.d.ts.map +1 -0
  329. package/dist/game/spell-cmd.js +320 -0
  330. package/dist/game/spell-cmd.js.map +1 -0
  331. package/dist/game/spoil.d.ts +28 -0
  332. package/dist/game/spoil.d.ts.map +1 -0
  333. package/dist/game/spoil.js +435 -0
  334. package/dist/game/spoil.js.map +1 -0
  335. package/dist/game/steal.d.ts +35 -0
  336. package/dist/game/steal.d.ts.map +1 -0
  337. package/dist/game/steal.js +145 -0
  338. package/dist/game/steal.js.map +1 -0
  339. package/dist/game/take-hit-hooks.d.ts +52 -0
  340. package/dist/game/take-hit-hooks.d.ts.map +1 -0
  341. package/dist/game/take-hit-hooks.js +127 -0
  342. package/dist/game/take-hit-hooks.js.map +1 -0
  343. package/dist/game/target-loop.d.ts +119 -0
  344. package/dist/game/target-loop.d.ts.map +1 -0
  345. package/dist/game/target-loop.js +408 -0
  346. package/dist/game/target-loop.js.map +1 -0
  347. package/dist/game/target.d.ts +133 -0
  348. package/dist/game/target.d.ts.map +1 -0
  349. package/dist/game/target.js +353 -0
  350. package/dist/game/target.js.map +1 -0
  351. package/dist/game/thrust.d.ts +37 -0
  352. package/dist/game/thrust.d.ts.map +1 -0
  353. package/dist/game/thrust.js +155 -0
  354. package/dist/game/thrust.js.map +1 -0
  355. package/dist/game/trap.d.ts +218 -0
  356. package/dist/game/trap.d.ts.map +1 -0
  357. package/dist/game/trap.js +618 -0
  358. package/dist/game/trap.js.map +1 -0
  359. package/dist/game/ui-entry.d.ts +282 -0
  360. package/dist/game/ui-entry.d.ts.map +1 -0
  361. package/dist/game/ui-entry.js +1838 -0
  362. package/dist/game/ui-entry.js.map +1 -0
  363. package/dist/game/wizard.d.ts +654 -0
  364. package/dist/game/wizard.d.ts.map +1 -0
  365. package/dist/game/wizard.js +1323 -0
  366. package/dist/game/wizard.js.map +1 -0
  367. package/dist/game/world.d.ts +183 -0
  368. package/dist/game/world.d.ts.map +1 -0
  369. package/dist/game/world.js +685 -0
  370. package/dist/game/world.js.map +1 -0
  371. package/dist/gen/cave.d.ts +247 -0
  372. package/dist/gen/cave.d.ts.map +1 -0
  373. package/dist/gen/cave.js +2406 -0
  374. package/dist/gen/cave.js.map +1 -0
  375. package/dist/gen/gen-monster.d.ts +151 -0
  376. package/dist/gen/gen-monster.d.ts.map +1 -0
  377. package/dist/gen/gen-monster.js +473 -0
  378. package/dist/gen/gen-monster.js.map +1 -0
  379. package/dist/gen/generate.d.ts +240 -0
  380. package/dist/gen/generate.d.ts.map +1 -0
  381. package/dist/gen/generate.js +358 -0
  382. package/dist/gen/generate.js.map +1 -0
  383. package/dist/gen/room.d.ts +160 -0
  384. package/dist/gen/room.d.ts.map +1 -0
  385. package/dist/gen/room.js +1910 -0
  386. package/dist/gen/room.js.map +1 -0
  387. package/dist/gen/util.d.ts +466 -0
  388. package/dist/gen/util.d.ts.map +1 -0
  389. package/dist/gen/util.js +1553 -0
  390. package/dist/gen/util.js.map +1 -0
  391. package/dist/generated/dun-profiles.d.ts +44 -0
  392. package/dist/generated/dun-profiles.d.ts.map +1 -0
  393. package/dist/generated/dun-profiles.js +28 -0
  394. package/dist/generated/dun-profiles.js.map +1 -0
  395. package/dist/generated/effects.d.ts +1021 -0
  396. package/dist/generated/effects.d.ts.map +1 -0
  397. package/dist/generated/effects.js +239 -0
  398. package/dist/generated/effects.js.map +1 -0
  399. package/dist/generated/elements.d.ts +83 -0
  400. package/dist/generated/elements.d.ts.map +1 -0
  401. package/dist/generated/elements.js +60 -0
  402. package/dist/generated/elements.js.map +1 -0
  403. package/dist/generated/equip-slots.d.ts +104 -0
  404. package/dist/generated/equip-slots.d.ts.map +1 -0
  405. package/dist/generated/equip-slots.js +34 -0
  406. package/dist/generated/equip-slots.js.map +1 -0
  407. package/dist/generated/history-types.d.ts +52 -0
  408. package/dist/generated/history-types.d.ts.map +1 -0
  409. package/dist/generated/history-types.js +32 -0
  410. package/dist/generated/history-types.js.map +1 -0
  411. package/dist/generated/ignore-types.d.ts +116 -0
  412. package/dist/generated/ignore-types.d.ts.map +1 -0
  413. package/dist/generated/ignore-types.js +64 -0
  414. package/dist/generated/ignore-types.js.map +1 -0
  415. package/dist/generated/index.d.ts +32 -0
  416. package/dist/generated/index.d.ts.map +1 -0
  417. package/dist/generated/index.js +33 -0
  418. package/dist/generated/index.js.map +1 -0
  419. package/dist/generated/kind-flags.d.ts +72 -0
  420. package/dist/generated/kind-flags.d.ts.map +1 -0
  421. package/dist/generated/kind-flags.js +42 -0
  422. package/dist/generated/kind-flags.js.map +1 -0
  423. package/dist/generated/message.d.ts +624 -0
  424. package/dist/generated/message.d.ts.map +1 -0
  425. package/dist/generated/message.js +318 -0
  426. package/dist/generated/message.js.map +1 -0
  427. package/dist/generated/mon-message.d.ts +386 -0
  428. package/dist/generated/mon-message.d.ts.map +1 -0
  429. package/dist/generated/mon-message.js +136 -0
  430. package/dist/generated/mon-message.js.map +1 -0
  431. package/dist/generated/mon-race-flags.d.ts +433 -0
  432. package/dist/generated/mon-race-flags.d.ts.map +1 -0
  433. package/dist/generated/mon-race-flags.js +180 -0
  434. package/dist/generated/mon-race-flags.js.map +1 -0
  435. package/dist/generated/mon-spells.d.ts +380 -0
  436. package/dist/generated/mon-spells.d.ts.map +1 -0
  437. package/dist/generated/mon-spells.js +196 -0
  438. package/dist/generated/mon-spells.js.map +1 -0
  439. package/dist/generated/mon-temp-flags.d.ts +52 -0
  440. package/dist/generated/mon-temp-flags.d.ts.map +1 -0
  441. package/dist/generated/mon-temp-flags.js +32 -0
  442. package/dist/generated/mon-temp-flags.js.map +1 -0
  443. package/dist/generated/mon-timed.d.ts +118 -0
  444. package/dist/generated/mon-timed.d.ts.map +1 -0
  445. package/dist/generated/mon-timed.js +32 -0
  446. package/dist/generated/mon-timed.js.map +1 -0
  447. package/dist/generated/object-flags.d.ts +169 -0
  448. package/dist/generated/object-flags.d.ts.map +1 -0
  449. package/dist/generated/object-flags.js +93 -0
  450. package/dist/generated/object-flags.js.map +1 -0
  451. package/dist/generated/object-modifiers.d.ts +50 -0
  452. package/dist/generated/object-modifiers.d.ts.map +1 -0
  453. package/dist/generated/object-modifiers.js +41 -0
  454. package/dist/generated/object-modifiers.js.map +1 -0
  455. package/dist/generated/options.d.ts +284 -0
  456. package/dist/generated/options.d.ts.map +1 -0
  457. package/dist/generated/options.js +102 -0
  458. package/dist/generated/options.js.map +1 -0
  459. package/dist/generated/origins.d.ts +138 -0
  460. package/dist/generated/origins.d.ts.map +1 -0
  461. package/dist/generated/origins.js +62 -0
  462. package/dist/generated/origins.js.map +1 -0
  463. package/dist/generated/parser-errors.d.ts +264 -0
  464. package/dist/generated/parser-errors.d.ts.map +1 -0
  465. package/dist/generated/parser-errors.js +138 -0
  466. package/dist/generated/parser-errors.js.map +1 -0
  467. package/dist/generated/player-flags.d.ts +62 -0
  468. package/dist/generated/player-flags.d.ts.map +1 -0
  469. package/dist/generated/player-flags.js +46 -0
  470. package/dist/generated/player-flags.js.map +1 -0
  471. package/dist/generated/player-timed.d.ts +273 -0
  472. package/dist/generated/player-timed.d.ts.map +1 -0
  473. package/dist/generated/player-timed.js +116 -0
  474. package/dist/generated/player-timed.js.map +1 -0
  475. package/dist/generated/projections.d.ts +130 -0
  476. package/dist/generated/projections.d.ts.map +1 -0
  477. package/dist/generated/projections.js +101 -0
  478. package/dist/generated/projections.js.map +1 -0
  479. package/dist/generated/randart-properties.d.ts +388 -0
  480. package/dist/generated/randart-properties.d.ts.map +1 -0
  481. package/dist/generated/randart-properties.js +200 -0
  482. package/dist/generated/randart-properties.js.map +1 -0
  483. package/dist/generated/room-flags.d.ts +21 -0
  484. package/dist/generated/room-flags.d.ts.map +1 -0
  485. package/dist/generated/room-flags.js +19 -0
  486. package/dist/generated/room-flags.js.map +1 -0
  487. package/dist/generated/rooms.d.ts +122 -0
  488. package/dist/generated/rooms.d.ts.map +1 -0
  489. package/dist/generated/rooms.js +48 -0
  490. package/dist/generated/rooms.js.map +1 -0
  491. package/dist/generated/square-flags.d.ts +96 -0
  492. package/dist/generated/square-flags.d.ts.map +1 -0
  493. package/dist/generated/square-flags.js +54 -0
  494. package/dist/generated/square-flags.js.map +1 -0
  495. package/dist/generated/stats.d.ts +23 -0
  496. package/dist/generated/stats.d.ts.map +1 -0
  497. package/dist/generated/stats.js +20 -0
  498. package/dist/generated/stats.js.map +1 -0
  499. package/dist/generated/terrain-flags.d.ts +136 -0
  500. package/dist/generated/terrain-flags.d.ts.map +1 -0
  501. package/dist/generated/terrain-flags.js +74 -0
  502. package/dist/generated/terrain-flags.js.map +1 -0
  503. package/dist/generated/terrain.d.ts +83 -0
  504. package/dist/generated/terrain.d.ts.map +1 -0
  505. package/dist/generated/terrain.js +60 -0
  506. package/dist/generated/terrain.js.map +1 -0
  507. package/dist/generated/trap-flags.d.ts +68 -0
  508. package/dist/generated/trap-flags.d.ts.map +1 -0
  509. package/dist/generated/trap-flags.js +40 -0
  510. package/dist/generated/trap-flags.js.map +1 -0
  511. package/dist/generated/tvals.d.ts +152 -0
  512. package/dist/generated/tvals.d.ts.map +1 -0
  513. package/dist/generated/tvals.js +82 -0
  514. package/dist/generated/tvals.js.map +1 -0
  515. package/dist/generated/ui-entry-renderers.d.ts +62 -0
  516. package/dist/generated/ui-entry-renderers.d.ts.map +1 -0
  517. package/dist/generated/ui-entry-renderers.js +22 -0
  518. package/dist/generated/ui-entry-renderers.js.map +1 -0
  519. package/dist/guard.d.ts +43 -0
  520. package/dist/guard.d.ts.map +1 -0
  521. package/dist/guard.js +65 -0
  522. package/dist/guard.js.map +1 -0
  523. package/dist/host/args.d.ts +129 -0
  524. package/dist/host/args.d.ts.map +1 -0
  525. package/dist/host/args.js +251 -0
  526. package/dist/host/args.js.map +1 -0
  527. package/dist/host/bridge.d.ts +61 -0
  528. package/dist/host/bridge.d.ts.map +1 -0
  529. package/dist/host/bridge.js +176 -0
  530. package/dist/host/bridge.js.map +1 -0
  531. package/dist/host/index.d.ts +18 -0
  532. package/dist/host/index.d.ts.map +1 -0
  533. package/dist/host/index.js +18 -0
  534. package/dist/host/index.js.map +1 -0
  535. package/dist/host/io.d.ts +169 -0
  536. package/dist/host/io.d.ts.map +1 -0
  537. package/dist/host/io.js +137 -0
  538. package/dist/host/io.js.map +1 -0
  539. package/dist/host/memory.d.ts +56 -0
  540. package/dist/host/memory.d.ts.map +1 -0
  541. package/dist/host/memory.js +105 -0
  542. package/dist/host/memory.js.map +1 -0
  543. package/dist/host/raw.d.ts +114 -0
  544. package/dist/host/raw.d.ts.map +1 -0
  545. package/dist/host/raw.js +107 -0
  546. package/dist/host/raw.js.map +1 -0
  547. package/dist/index.d.ts +180 -0
  548. package/dist/index.d.ts.map +1 -0
  549. package/dist/index.js +222 -0
  550. package/dist/index.js.map +1 -0
  551. package/dist/loc.d.ts +63 -0
  552. package/dist/loc.d.ts.map +1 -0
  553. package/dist/loc.js +128 -0
  554. package/dist/loc.js.map +1 -0
  555. package/dist/mod/hooks.d.ts +204 -0
  556. package/dist/mod/hooks.d.ts.map +1 -0
  557. package/dist/mod/hooks.js +161 -0
  558. package/dist/mod/hooks.js.map +1 -0
  559. package/dist/mod/ids.d.ts +160 -0
  560. package/dist/mod/ids.d.ts.map +1 -0
  561. package/dist/mod/ids.js +343 -0
  562. package/dist/mod/ids.js.map +1 -0
  563. package/dist/mod/registry-host.d.ts +156 -0
  564. package/dist/mod/registry-host.d.ts.map +1 -0
  565. package/dist/mod/registry-host.js +142 -0
  566. package/dist/mod/registry-host.js.map +1 -0
  567. package/dist/mod/save-blocks.d.ts +201 -0
  568. package/dist/mod/save-blocks.d.ts.map +1 -0
  569. package/dist/mod/save-blocks.js +640 -0
  570. package/dist/mod/save-blocks.js.map +1 -0
  571. package/dist/mod/vocabulary.d.ts +104 -0
  572. package/dist/mod/vocabulary.d.ts.map +1 -0
  573. package/dist/mod/vocabulary.js +0 -0
  574. package/dist/mod/vocabulary.js.map +1 -0
  575. package/dist/mon/bind.d.ts +266 -0
  576. package/dist/mon/bind.d.ts.map +1 -0
  577. package/dist/mon/bind.js +610 -0
  578. package/dist/mon/bind.js.map +1 -0
  579. package/dist/mon/desc.d.ts +72 -0
  580. package/dist/mon/desc.d.ts.map +1 -0
  581. package/dist/mon/desc.js +237 -0
  582. package/dist/mon/desc.js.map +1 -0
  583. package/dist/mon/knowledge-groups.d.ts +61 -0
  584. package/dist/mon/knowledge-groups.d.ts.map +1 -0
  585. package/dist/mon/knowledge-groups.js +121 -0
  586. package/dist/mon/knowledge-groups.js.map +1 -0
  587. package/dist/mon/lore-describe.d.ts +216 -0
  588. package/dist/mon/lore-describe.d.ts.map +1 -0
  589. package/dist/mon/lore-describe.js +1105 -0
  590. package/dist/mon/lore-describe.js.map +1 -0
  591. package/dist/mon/lore.d.ts +117 -0
  592. package/dist/mon/lore.d.ts.map +1 -0
  593. package/dist/mon/lore.js +221 -0
  594. package/dist/mon/lore.js.map +1 -0
  595. package/dist/mon/make.d.ts +147 -0
  596. package/dist/mon/make.d.ts.map +1 -0
  597. package/dist/mon/make.js +353 -0
  598. package/dist/mon/make.js.map +1 -0
  599. package/dist/mon/monster.d.ts +94 -0
  600. package/dist/mon/monster.d.ts.map +1 -0
  601. package/dist/mon/monster.js +90 -0
  602. package/dist/mon/monster.js.map +1 -0
  603. package/dist/mon/predicate.d.ts +87 -0
  604. package/dist/mon/predicate.d.ts.map +1 -0
  605. package/dist/mon/predicate.js +190 -0
  606. package/dist/mon/predicate.js.map +1 -0
  607. package/dist/mon/project-mon.d.ts +129 -0
  608. package/dist/mon/project-mon.d.ts.map +1 -0
  609. package/dist/mon/project-mon.js +652 -0
  610. package/dist/mon/project-mon.js.map +1 -0
  611. package/dist/mon/spell.d.ts +155 -0
  612. package/dist/mon/spell.d.ts.map +1 -0
  613. package/dist/mon/spell.js +355 -0
  614. package/dist/mon/spell.js.map +1 -0
  615. package/dist/mon/steal.d.ts +112 -0
  616. package/dist/mon/steal.d.ts.map +1 -0
  617. package/dist/mon/steal.js +163 -0
  618. package/dist/mon/steal.js.map +1 -0
  619. package/dist/mon/summon.d.ts +62 -0
  620. package/dist/mon/summon.d.ts.map +1 -0
  621. package/dist/mon/summon.js +111 -0
  622. package/dist/mon/summon.js.map +1 -0
  623. package/dist/mon/take-hit.d.ts +75 -0
  624. package/dist/mon/take-hit.d.ts.map +1 -0
  625. package/dist/mon/take-hit.js +122 -0
  626. package/dist/mon/take-hit.js.map +1 -0
  627. package/dist/mon/timed.d.ts +74 -0
  628. package/dist/mon/timed.d.ts.map +1 -0
  629. package/dist/mon/timed.js +219 -0
  630. package/dist/mon/timed.js.map +1 -0
  631. package/dist/mon/types.d.ts +252 -0
  632. package/dist/mon/types.d.ts.map +1 -0
  633. package/dist/mon/types.js +46 -0
  634. package/dist/mon/types.js.map +1 -0
  635. package/dist/msg.d.ts +71 -0
  636. package/dist/msg.d.ts.map +1 -0
  637. package/dist/msg.js +126 -0
  638. package/dist/msg.js.map +1 -0
  639. package/dist/obj/artifact-fake.d.ts +39 -0
  640. package/dist/obj/artifact-fake.d.ts.map +1 -0
  641. package/dist/obj/artifact-fake.js +52 -0
  642. package/dist/obj/artifact-fake.js.map +1 -0
  643. package/dist/obj/artifact-known.d.ts +50 -0
  644. package/dist/obj/artifact-known.d.ts.map +1 -0
  645. package/dist/obj/artifact-known.js +55 -0
  646. package/dist/obj/artifact-known.js.map +1 -0
  647. package/dist/obj/bind.d.ts +219 -0
  648. package/dist/obj/bind.d.ts.map +1 -0
  649. package/dist/obj/bind.js +1239 -0
  650. package/dist/obj/bind.js.map +1 -0
  651. package/dist/obj/chest.d.ts +91 -0
  652. package/dist/obj/chest.d.ts.map +1 -0
  653. package/dist/obj/chest.js +220 -0
  654. package/dist/obj/chest.js.map +1 -0
  655. package/dist/obj/desc.d.ts +79 -0
  656. package/dist/obj/desc.d.ts.map +1 -0
  657. package/dist/obj/desc.js +602 -0
  658. package/dist/obj/desc.js.map +1 -0
  659. package/dist/obj/effects-info.d.ts +78 -0
  660. package/dist/obj/effects-info.d.ts.map +1 -0
  661. package/dist/obj/effects-info.js +240 -0
  662. package/dist/obj/effects-info.js.map +1 -0
  663. package/dist/obj/flavor.d.ts +68 -0
  664. package/dist/obj/flavor.d.ts.map +1 -0
  665. package/dist/obj/flavor.js +201 -0
  666. package/dist/obj/flavor.js.map +1 -0
  667. package/dist/obj/ignore.d.ts +143 -0
  668. package/dist/obj/ignore.d.ts.map +1 -0
  669. package/dist/obj/ignore.js +345 -0
  670. package/dist/obj/ignore.js.map +1 -0
  671. package/dist/obj/knowledge.d.ts +520 -0
  672. package/dist/obj/knowledge.d.ts.map +1 -0
  673. package/dist/obj/knowledge.js +1364 -0
  674. package/dist/obj/knowledge.js.map +1 -0
  675. package/dist/obj/known-object.d.ts +293 -0
  676. package/dist/obj/known-object.d.ts.map +1 -0
  677. package/dist/obj/known-object.js +532 -0
  678. package/dist/obj/known-object.js.map +1 -0
  679. package/dist/obj/make.d.ts +292 -0
  680. package/dist/obj/make.d.ts.map +1 -0
  681. package/dist/obj/make.js +1055 -0
  682. package/dist/obj/make.js.map +1 -0
  683. package/dist/obj/object-info.d.ts +188 -0
  684. package/dist/obj/object-info.d.ts.map +1 -0
  685. package/dist/obj/object-info.js +1407 -0
  686. package/dist/obj/object-info.js.map +1 -0
  687. package/dist/obj/object.d.ts +335 -0
  688. package/dist/obj/object.d.ts.map +1 -0
  689. package/dist/obj/object.js +1051 -0
  690. package/dist/obj/object.js.map +1 -0
  691. package/dist/obj/power.d.ts +65 -0
  692. package/dist/obj/power.d.ts.map +1 -0
  693. package/dist/obj/power.js +580 -0
  694. package/dist/obj/power.js.map +1 -0
  695. package/dist/obj/randart-build.d.ts +223 -0
  696. package/dist/obj/randart-build.d.ts.map +1 -0
  697. package/dist/obj/randart-build.js +1444 -0
  698. package/dist/obj/randart-build.js.map +1 -0
  699. package/dist/obj/randart-data.d.ts +179 -0
  700. package/dist/obj/randart-data.d.ts.map +1 -0
  701. package/dist/obj/randart-data.js +1153 -0
  702. package/dist/obj/randart-data.js.map +1 -0
  703. package/dist/obj/randart.d.ts +128 -0
  704. package/dist/obj/randart.d.ts.map +1 -0
  705. package/dist/obj/randart.js +458 -0
  706. package/dist/obj/randart.js.map +1 -0
  707. package/dist/obj/randname.d.ts +33 -0
  708. package/dist/obj/randname.d.ts.map +1 -0
  709. package/dist/obj/randname.js +116 -0
  710. package/dist/obj/randname.js.map +1 -0
  711. package/dist/obj/recharge.d.ts +28 -0
  712. package/dist/obj/recharge.d.ts.map +1 -0
  713. package/dist/obj/recharge.js +52 -0
  714. package/dist/obj/recharge.js.map +1 -0
  715. package/dist/obj/types.d.ts +584 -0
  716. package/dist/obj/types.d.ts.map +1 -0
  717. package/dist/obj/types.js +104 -0
  718. package/dist/obj/types.js.map +1 -0
  719. package/dist/obj/value.d.ts +64 -0
  720. package/dist/obj/value.d.ts.map +1 -0
  721. package/dist/obj/value.js +176 -0
  722. package/dist/obj/value.js.map +1 -0
  723. package/dist/player/abilities.d.ts +57 -0
  724. package/dist/player/abilities.d.ts.map +1 -0
  725. package/dist/player/abilities.js +118 -0
  726. package/dist/player/abilities.js.map +1 -0
  727. package/dist/player/best-digger.d.ts +42 -0
  728. package/dist/player/best-digger.d.ts.map +1 -0
  729. package/dist/player/best-digger.js +89 -0
  730. package/dist/player/best-digger.js.map +1 -0
  731. package/dist/player/bind.d.ts +270 -0
  732. package/dist/player/bind.d.ts.map +1 -0
  733. package/dist/player/bind.js +698 -0
  734. package/dist/player/bind.js.map +1 -0
  735. package/dist/player/birth.d.ts +258 -0
  736. package/dist/player/birth.d.ts.map +1 -0
  737. package/dist/player/birth.js +639 -0
  738. package/dist/player/birth.js.map +1 -0
  739. package/dist/player/calcs.d.ts +403 -0
  740. package/dist/player/calcs.d.ts.map +1 -0
  741. package/dist/player/calcs.js +1189 -0
  742. package/dist/player/calcs.js.map +1 -0
  743. package/dist/player/combat-regen.d.ts +14 -0
  744. package/dist/player/combat-regen.d.ts.map +1 -0
  745. package/dist/player/combat-regen.js +29 -0
  746. package/dist/player/combat-regen.js.map +1 -0
  747. package/dist/player/exp.d.ts +96 -0
  748. package/dist/player/exp.d.ts.map +1 -0
  749. package/dist/player/exp.js +229 -0
  750. package/dist/player/exp.js.map +1 -0
  751. package/dist/player/history.d.ts +91 -0
  752. package/dist/player/history.d.ts.map +1 -0
  753. package/dist/player/history.js +145 -0
  754. package/dist/player/history.js.map +1 -0
  755. package/dist/player/options.d.ts +123 -0
  756. package/dist/player/options.d.ts.map +1 -0
  757. package/dist/player/options.js +199 -0
  758. package/dist/player/options.js.map +1 -0
  759. package/dist/player/player.d.ts +242 -0
  760. package/dist/player/player.d.ts.map +1 -0
  761. package/dist/player/player.js +119 -0
  762. package/dist/player/player.js.map +1 -0
  763. package/dist/player/shape-lore.d.ts +56 -0
  764. package/dist/player/shape-lore.d.ts.map +1 -0
  765. package/dist/player/shape-lore.js +221 -0
  766. package/dist/player/shape-lore.js.map +1 -0
  767. package/dist/player/spell.d.ts +146 -0
  768. package/dist/player/spell.d.ts.map +1 -0
  769. package/dist/player/spell.js +519 -0
  770. package/dist/player/spell.js.map +1 -0
  771. package/dist/player/take-hit.d.ts +87 -0
  772. package/dist/player/take-hit.d.ts.map +1 -0
  773. package/dist/player/take-hit.js +99 -0
  774. package/dist/player/take-hit.js.map +1 -0
  775. package/dist/player/timed.d.ts +205 -0
  776. package/dist/player/timed.d.ts.map +1 -0
  777. package/dist/player/timed.js +310 -0
  778. package/dist/player/timed.js.map +1 -0
  779. package/dist/player/types.d.ts +390 -0
  780. package/dist/player/types.d.ts.map +1 -0
  781. package/dist/player/types.js +51 -0
  782. package/dist/player/types.js.map +1 -0
  783. package/dist/rational.d.ts +99 -0
  784. package/dist/rational.d.ts.map +1 -0
  785. package/dist/rational.js +345 -0
  786. package/dist/rational.js.map +1 -0
  787. package/dist/rng.d.ts +168 -0
  788. package/dist/rng.d.ts.map +1 -0
  789. package/dist/rng.js +404 -0
  790. package/dist/rng.js.map +1 -0
  791. package/dist/save/buffer.d.ts +120 -0
  792. package/dist/save/buffer.d.ts.map +1 -0
  793. package/dist/save/buffer.js +238 -0
  794. package/dist/save/buffer.js.map +1 -0
  795. package/dist/save/compress.d.ts +79 -0
  796. package/dist/save/compress.d.ts.map +1 -0
  797. package/dist/save/compress.js +97 -0
  798. package/dist/save/compress.js.map +1 -0
  799. package/dist/save/description.d.ts +61 -0
  800. package/dist/save/description.d.ts.map +1 -0
  801. package/dist/save/description.js +51 -0
  802. package/dist/save/description.js.map +1 -0
  803. package/dist/save/integrity.d.ts +59 -0
  804. package/dist/save/integrity.d.ts.map +1 -0
  805. package/dist/save/integrity.js +103 -0
  806. package/dist/save/integrity.js.map +1 -0
  807. package/dist/score/display.d.ts +40 -0
  808. package/dist/score/display.d.ts.map +1 -0
  809. package/dist/score/display.js +86 -0
  810. package/dist/score/display.js.map +1 -0
  811. package/dist/score/score.d.ts +166 -0
  812. package/dist/score/score.d.ts.map +1 -0
  813. package/dist/score/score.js +244 -0
  814. package/dist/score/score.js.map +1 -0
  815. package/dist/score/types.d.ts +98 -0
  816. package/dist/score/types.d.ts.map +1 -0
  817. package/dist/score/types.js +27 -0
  818. package/dist/score/types.js.map +1 -0
  819. package/dist/session/boot.d.ts +207 -0
  820. package/dist/session/boot.d.ts.map +1 -0
  821. package/dist/session/boot.js +151 -0
  822. package/dist/session/boot.js.map +1 -0
  823. package/dist/session/game.d.ts +257 -0
  824. package/dist/session/game.d.ts.map +1 -0
  825. package/dist/session/game.js +2880 -0
  826. package/dist/session/game.js.map +1 -0
  827. package/dist/session/save.d.ts +847 -0
  828. package/dist/session/save.d.ts.map +1 -0
  829. package/dist/session/save.js +1306 -0
  830. package/dist/session/save.js.map +1 -0
  831. package/dist/sound/engine.d.ts +146 -0
  832. package/dist/sound/engine.d.ts.map +1 -0
  833. package/dist/sound/engine.js +332 -0
  834. package/dist/sound/engine.js.map +1 -0
  835. package/dist/sound/index.d.ts +13 -0
  836. package/dist/sound/index.d.ts.map +1 -0
  837. package/dist/sound/index.js +13 -0
  838. package/dist/sound/index.js.map +1 -0
  839. package/dist/sound/sound-prefs-data.d.ts +10 -0
  840. package/dist/sound/sound-prefs-data.d.ts.map +1 -0
  841. package/dist/sound/sound-prefs-data.js +165 -0
  842. package/dist/sound/sound-prefs-data.js.map +1 -0
  843. package/dist/sound/types.d.ts +64 -0
  844. package/dist/sound/types.d.ts.map +1 -0
  845. package/dist/sound/types.js +23 -0
  846. package/dist/sound/types.js.map +1 -0
  847. package/dist/store/bind.d.ts +43 -0
  848. package/dist/store/bind.d.ts.map +1 -0
  849. package/dist/store/bind.js +130 -0
  850. package/dist/store/bind.js.map +1 -0
  851. package/dist/store/price.d.ts +27 -0
  852. package/dist/store/price.d.ts.map +1 -0
  853. package/dist/store/price.js +81 -0
  854. package/dist/store/price.js.map +1 -0
  855. package/dist/store/store-cmd.d.ts +51 -0
  856. package/dist/store/store-cmd.d.ts.map +1 -0
  857. package/dist/store/store-cmd.js +73 -0
  858. package/dist/store/store-cmd.js.map +1 -0
  859. package/dist/store/store.d.ts +156 -0
  860. package/dist/store/store.d.ts.map +1 -0
  861. package/dist/store/store.js +616 -0
  862. package/dist/store/store.js.map +1 -0
  863. package/dist/store/transact.d.ts +198 -0
  864. package/dist/store/transact.d.ts.map +1 -0
  865. package/dist/store/transact.js +383 -0
  866. package/dist/store/transact.js.map +1 -0
  867. package/dist/store/types.d.ts +101 -0
  868. package/dist/store/types.d.ts.map +1 -0
  869. package/dist/store/types.js +14 -0
  870. package/dist/store/types.js.map +1 -0
  871. package/dist/version.d.ts +25 -0
  872. package/dist/version.d.ts.map +1 -0
  873. package/dist/version.js +25 -0
  874. package/dist/version.js.map +1 -0
  875. package/dist/visuals/engine.d.ts +223 -0
  876. package/dist/visuals/engine.d.ts.map +1 -0
  877. package/dist/visuals/engine.js +357 -0
  878. package/dist/visuals/engine.js.map +1 -0
  879. package/dist/visuals/glyph-table.d.ts +112 -0
  880. package/dist/visuals/glyph-table.d.ts.map +1 -0
  881. package/dist/visuals/glyph-table.js +156 -0
  882. package/dist/visuals/glyph-table.js.map +1 -0
  883. package/dist/visuals/grafmode-data.d.ts +4 -0
  884. package/dist/visuals/grafmode-data.d.ts.map +1 -0
  885. package/dist/visuals/grafmode-data.js +88 -0
  886. package/dist/visuals/grafmode-data.js.map +1 -0
  887. package/dist/visuals/grafmode.d.ts +83 -0
  888. package/dist/visuals/grafmode.d.ts.map +1 -0
  889. package/dist/visuals/grafmode.js +82 -0
  890. package/dist/visuals/grafmode.js.map +1 -0
  891. package/dist/visuals/index.d.ts +19 -0
  892. package/dist/visuals/index.d.ts.map +1 -0
  893. package/dist/visuals/index.js +19 -0
  894. package/dist/visuals/index.js.map +1 -0
  895. package/dist/visuals/map-text.d.ts +79 -0
  896. package/dist/visuals/map-text.d.ts.map +1 -0
  897. package/dist/visuals/map-text.js +122 -0
  898. package/dist/visuals/map-text.js.map +1 -0
  899. package/dist/visuals/pref-expr.d.ts +56 -0
  900. package/dist/visuals/pref-expr.d.ts.map +1 -0
  901. package/dist/visuals/pref-expr.js +173 -0
  902. package/dist/visuals/pref-expr.js.map +1 -0
  903. package/dist/visuals/prefs.d.ts +280 -0
  904. package/dist/visuals/prefs.d.ts.map +1 -0
  905. package/dist/visuals/prefs.js +835 -0
  906. package/dist/visuals/prefs.js.map +1 -0
  907. package/dist/visuals/tile-prefs.d.ts +132 -0
  908. package/dist/visuals/tile-prefs.d.ts.map +1 -0
  909. package/dist/visuals/tile-prefs.js +105 -0
  910. package/dist/visuals/tile-prefs.js.map +1 -0
  911. package/dist/world/chunk.d.ts +195 -0
  912. package/dist/world/chunk.d.ts.map +1 -0
  913. package/dist/world/chunk.js +422 -0
  914. package/dist/world/chunk.js.map +1 -0
  915. package/dist/world/feature.d.ts +86 -0
  916. package/dist/world/feature.d.ts.map +1 -0
  917. package/dist/world/feature.js +153 -0
  918. package/dist/world/feature.js.map +1 -0
  919. package/dist/world/flow.d.ts +33 -0
  920. package/dist/world/flow.d.ts.map +1 -0
  921. package/dist/world/flow.js +115 -0
  922. package/dist/world/flow.js.map +1 -0
  923. package/dist/world/project.d.ts +176 -0
  924. package/dist/world/project.d.ts.map +1 -0
  925. package/dist/world/project.js +543 -0
  926. package/dist/world/project.js.map +1 -0
  927. package/dist/world/projection.d.ts +100 -0
  928. package/dist/world/projection.d.ts.map +1 -0
  929. package/dist/world/projection.js +152 -0
  930. package/dist/world/projection.js.map +1 -0
  931. package/dist/world/scatter.d.ts +25 -0
  932. package/dist/world/scatter.d.ts.map +1 -0
  933. package/dist/world/scatter.js +54 -0
  934. package/dist/world/scatter.js.map +1 -0
  935. package/dist/world/trap.d.ts +84 -0
  936. package/dist/world/trap.d.ts.map +1 -0
  937. package/dist/world/trap.js +106 -0
  938. package/dist/world/trap.js.map +1 -0
  939. package/dist/world/view.d.ts +60 -0
  940. package/dist/world/view.d.ts.map +1 -0
  941. package/dist/world/view.js +436 -0
  942. package/dist/world/view.js.map +1 -0
  943. package/dist/z-queue.d.ts +133 -0
  944. package/dist/z-queue.d.ts.map +1 -0
  945. package/dist/z-queue.js +283 -0
  946. package/dist/z-queue.js.map +1 -0
  947. package/package.json +75 -0
  948. package/src/agent/act.ts +114 -0
  949. package/src/agent/controller.ts +109 -0
  950. package/src/agent/events.ts +47 -0
  951. package/src/agent/index.ts +36 -0
  952. package/src/agent/perceive.ts +440 -0
  953. package/src/agent/types.ts +464 -0
  954. package/src/bitflag.ts +536 -0
  955. package/src/cmd.ts +547 -0
  956. package/src/color.ts +267 -0
  957. package/src/combat/brand-slay.ts +360 -0
  958. package/src/combat/hit.ts +471 -0
  959. package/src/combat/index.ts +15 -0
  960. package/src/combat/melee.ts +728 -0
  961. package/src/combat/mon-melee.ts +1153 -0
  962. package/src/combat/ranged.ts +397 -0
  963. package/src/constants.ts +324 -0
  964. package/src/dice.ts +467 -0
  965. package/src/effects/effect-choice.ts +32 -0
  966. package/src/effects/effect-info.ts +859 -0
  967. package/src/effects/effect.ts +560 -0
  968. package/src/effects/handlers.ts +452 -0
  969. package/src/effects/interpreter.ts +603 -0
  970. package/src/events.ts +317 -0
  971. package/src/expression.ts +360 -0
  972. package/src/game/cave-cmd.ts +1147 -0
  973. package/src/game/char-sheet.ts +557 -0
  974. package/src/game/chest.ts +348 -0
  975. package/src/game/context.ts +1218 -0
  976. package/src/game/curse-tick.ts +130 -0
  977. package/src/game/describe.ts +62 -0
  978. package/src/game/display.ts +838 -0
  979. package/src/game/dump-level.ts +114 -0
  980. package/src/game/effect-attack.ts +746 -0
  981. package/src/game/effect-detect.ts +542 -0
  982. package/src/game/effect-env.ts +252 -0
  983. package/src/game/effect-game-env.ts +86 -0
  984. package/src/game/effect-general.ts +1122 -0
  985. package/src/game/effect-item.ts +999 -0
  986. package/src/game/effect-melee.ts +557 -0
  987. package/src/game/effect-mon-origin.ts +196 -0
  988. package/src/game/effect-monster.ts +310 -0
  989. package/src/game/effect-summon.ts +161 -0
  990. package/src/game/effect-teleport.ts +645 -0
  991. package/src/game/effect-terrain.ts +881 -0
  992. package/src/game/energy.ts +61 -0
  993. package/src/game/equip-cmp.ts +476 -0
  994. package/src/game/floor.ts +524 -0
  995. package/src/game/gear.ts +1352 -0
  996. package/src/game/harness.ts +270 -0
  997. package/src/game/history.ts +78 -0
  998. package/src/game/ignore-cmd.ts +68 -0
  999. package/src/game/inscription-confirm.ts +115 -0
  1000. package/src/game/known.ts +960 -0
  1001. package/src/game/loop.ts +671 -0
  1002. package/src/game/lore-color.ts +108 -0
  1003. package/src/game/mon-cast.ts +409 -0
  1004. package/src/game/mon-cmd.ts +767 -0
  1005. package/src/game/mon-death.ts +459 -0
  1006. package/src/game/mon-group.ts +368 -0
  1007. package/src/game/mon-list.ts +213 -0
  1008. package/src/game/mon-message.ts +359 -0
  1009. package/src/game/mon-place.ts +1012 -0
  1010. package/src/game/mon-ranged.ts +405 -0
  1011. package/src/game/mon-shape.ts +161 -0
  1012. package/src/game/mon-side.ts +511 -0
  1013. package/src/game/monster-turn.ts +1750 -0
  1014. package/src/game/obj-cmd.ts +1970 -0
  1015. package/src/game/obj-list.ts +302 -0
  1016. package/src/game/object-inspect.ts +162 -0
  1017. package/src/game/pickup.ts +483 -0
  1018. package/src/game/player-path.ts +1434 -0
  1019. package/src/game/player-side.ts +555 -0
  1020. package/src/game/player-turn.ts +852 -0
  1021. package/src/game/project-cast.ts +766 -0
  1022. package/src/game/project-feat.ts +386 -0
  1023. package/src/game/project-monster.ts +407 -0
  1024. package/src/game/project-obj.ts +298 -0
  1025. package/src/game/project-player.ts +236 -0
  1026. package/src/game/quest.ts +248 -0
  1027. package/src/game/ranged-cmd.ts +417 -0
  1028. package/src/game/scheduler.ts +150 -0
  1029. package/src/game/spell-cmd.ts +404 -0
  1030. package/src/game/spoil.ts +562 -0
  1031. package/src/game/steal.ts +169 -0
  1032. package/src/game/take-hit-hooks.ts +152 -0
  1033. package/src/game/target-loop.ts +501 -0
  1034. package/src/game/target.ts +424 -0
  1035. package/src/game/thrust.ts +174 -0
  1036. package/src/game/trap.ts +791 -0
  1037. package/src/game/ui-entry.ts +2075 -0
  1038. package/src/game/wizard.ts +1760 -0
  1039. package/src/game/world.ts +786 -0
  1040. package/src/gen/cave.ts +2858 -0
  1041. package/src/gen/gen-monster.ts +592 -0
  1042. package/src/gen/generate.ts +523 -0
  1043. package/src/gen/room.ts +2213 -0
  1044. package/src/gen/util.ts +1958 -0
  1045. package/src/generated/dun-profiles.ts +30 -0
  1046. package/src/generated/effects.ts +241 -0
  1047. package/src/generated/elements.ts +62 -0
  1048. package/src/generated/equip-slots.ts +36 -0
  1049. package/src/generated/history-types.ts +34 -0
  1050. package/src/generated/ignore-types.ts +66 -0
  1051. package/src/generated/index.ts +33 -0
  1052. package/src/generated/kind-flags.ts +44 -0
  1053. package/src/generated/message.ts +320 -0
  1054. package/src/generated/mon-message.ts +138 -0
  1055. package/src/generated/mon-race-flags.ts +182 -0
  1056. package/src/generated/mon-spells.ts +198 -0
  1057. package/src/generated/mon-temp-flags.ts +34 -0
  1058. package/src/generated/mon-timed.ts +34 -0
  1059. package/src/generated/object-flags.ts +95 -0
  1060. package/src/generated/object-modifiers.ts +43 -0
  1061. package/src/generated/options.ts +104 -0
  1062. package/src/generated/origins.ts +64 -0
  1063. package/src/generated/parser-errors.ts +140 -0
  1064. package/src/generated/player-flags.ts +48 -0
  1065. package/src/generated/player-timed.ts +118 -0
  1066. package/src/generated/projections.ts +103 -0
  1067. package/src/generated/randart-properties.ts +202 -0
  1068. package/src/generated/room-flags.ts +21 -0
  1069. package/src/generated/rooms.ts +50 -0
  1070. package/src/generated/square-flags.ts +56 -0
  1071. package/src/generated/stats.ts +22 -0
  1072. package/src/generated/terrain-flags.ts +76 -0
  1073. package/src/generated/terrain.ts +62 -0
  1074. package/src/generated/trap-flags.ts +42 -0
  1075. package/src/generated/tvals.ts +84 -0
  1076. package/src/generated/ui-entry-renderers.ts +24 -0
  1077. package/src/guard.ts +70 -0
  1078. package/src/host/args.ts +334 -0
  1079. package/src/host/bridge.ts +193 -0
  1080. package/src/host/index.ts +18 -0
  1081. package/src/host/io.ts +239 -0
  1082. package/src/host/memory.ts +134 -0
  1083. package/src/host/raw.ts +190 -0
  1084. package/src/index.ts +250 -0
  1085. package/src/loc.ts +157 -0
  1086. package/src/mod/hooks.ts +278 -0
  1087. package/src/mod/ids.ts +390 -0
  1088. package/src/mod/registry-host.ts +258 -0
  1089. package/src/mod/save-blocks.ts +787 -0
  1090. package/src/mod/vocabulary.ts +0 -0
  1091. package/src/mon/bind.ts +899 -0
  1092. package/src/mon/desc.ts +212 -0
  1093. package/src/mon/knowledge-groups.ts +164 -0
  1094. package/src/mon/lore-describe.ts +1414 -0
  1095. package/src/mon/lore.ts +306 -0
  1096. package/src/mon/make.ts +422 -0
  1097. package/src/mon/monster.ts +161 -0
  1098. package/src/mon/predicate.ts +220 -0
  1099. package/src/mon/project-mon.ts +855 -0
  1100. package/src/mon/spell.ts +418 -0
  1101. package/src/mon/steal.ts +246 -0
  1102. package/src/mon/summon.ts +145 -0
  1103. package/src/mon/take-hit.ts +195 -0
  1104. package/src/mon/timed.ts +300 -0
  1105. package/src/mon/types.ts +286 -0
  1106. package/src/msg.ts +146 -0
  1107. package/src/obj/artifact-fake.ts +63 -0
  1108. package/src/obj/artifact-known.ts +69 -0
  1109. package/src/obj/bind.ts +1345 -0
  1110. package/src/obj/chest.ts +249 -0
  1111. package/src/obj/desc.ts +699 -0
  1112. package/src/obj/effects-info.ts +349 -0
  1113. package/src/obj/flavor.ts +256 -0
  1114. package/src/obj/ignore.ts +387 -0
  1115. package/src/obj/knowledge.ts +1577 -0
  1116. package/src/obj/known-object.ts +718 -0
  1117. package/src/obj/make.ts +1367 -0
  1118. package/src/obj/object-info.ts +1737 -0
  1119. package/src/obj/object.ts +1296 -0
  1120. package/src/obj/power.ts +674 -0
  1121. package/src/obj/randart-build.ts +1705 -0
  1122. package/src/obj/randart-data.ts +1344 -0
  1123. package/src/obj/randart.ts +552 -0
  1124. package/src/obj/randname.ts +128 -0
  1125. package/src/obj/recharge.ts +62 -0
  1126. package/src/obj/types.ts +559 -0
  1127. package/src/obj/value.ts +215 -0
  1128. package/src/player/abilities.ts +142 -0
  1129. package/src/player/best-digger.ts +118 -0
  1130. package/src/player/bind.ts +1021 -0
  1131. package/src/player/birth.ts +794 -0
  1132. package/src/player/calcs.ts +1522 -0
  1133. package/src/player/combat-regen.ts +33 -0
  1134. package/src/player/exp.ts +275 -0
  1135. package/src/player/history.ts +211 -0
  1136. package/src/player/options.ts +244 -0
  1137. package/src/player/player.ts +356 -0
  1138. package/src/player/shape-lore.ts +250 -0
  1139. package/src/player/spell.ts +627 -0
  1140. package/src/player/take-hit.ts +173 -0
  1141. package/src/player/timed.ts +482 -0
  1142. package/src/player/types.ts +415 -0
  1143. package/src/rational.ts +388 -0
  1144. package/src/rng.ts +476 -0
  1145. package/src/save/buffer.ts +287 -0
  1146. package/src/save/compress.ts +132 -0
  1147. package/src/save/description.ts +70 -0
  1148. package/src/save/integrity.ts +133 -0
  1149. package/src/score/display.ts +125 -0
  1150. package/src/score/score.ts +341 -0
  1151. package/src/score/types.ts +104 -0
  1152. package/src/session/boot.ts +338 -0
  1153. package/src/session/game.ts +3712 -0
  1154. package/src/session/save.ts +2074 -0
  1155. package/src/sound/engine.ts +375 -0
  1156. package/src/sound/index.ts +13 -0
  1157. package/src/sound/sound-prefs-data.ts +173 -0
  1158. package/src/sound/types.ts +68 -0
  1159. package/src/store/bind.ts +145 -0
  1160. package/src/store/price.ts +97 -0
  1161. package/src/store/store-cmd.ts +73 -0
  1162. package/src/store/store.ts +723 -0
  1163. package/src/store/transact.ts +644 -0
  1164. package/src/store/types.ts +110 -0
  1165. package/src/version.ts +26 -0
  1166. package/src/visuals/engine.ts +444 -0
  1167. package/src/visuals/glyph-table.ts +191 -0
  1168. package/src/visuals/grafmode-data.ts +90 -0
  1169. package/src/visuals/grafmode.ts +123 -0
  1170. package/src/visuals/index.ts +19 -0
  1171. package/src/visuals/map-text.ts +152 -0
  1172. package/src/visuals/pref-expr.ts +182 -0
  1173. package/src/visuals/prefs.ts +981 -0
  1174. package/src/visuals/tile-prefs.ts +183 -0
  1175. package/src/world/chunk.ts +531 -0
  1176. package/src/world/feature.ts +215 -0
  1177. package/src/world/flow.ts +128 -0
  1178. package/src/world/project.ts +687 -0
  1179. package/src/world/projection.ts +228 -0
  1180. package/src/world/scatter.ts +72 -0
  1181. package/src/world/trap.ts +155 -0
  1182. package/src/world/view.ts +513 -0
  1183. package/src/z-queue.ts +300 -0
@@ -0,0 +1,2075 @@
1
+ /**
2
+ * The DATA half of the second character screen's resist / ability / sustain /
3
+ * modifier grid, ported from Angband 4.2.6:
4
+ * - reference/src/ui-entry.c (the config engine + value compute)
5
+ * - reference/src/ui-entry-combiner.c (the 9 value combiners)
6
+ * - reference/src/ui-entry-renderers.c (value -> symbol + palette-index)
7
+ * - reference/src/ui-player.c (display_resistance_panel /
8
+ * display_player_sust_info assembly + configure_char_sheet layout)
9
+ *
10
+ * The upstream files split naturally into an engine (build a table of ui_entry
11
+ * records from ui_entry.txt / ui_entry_base.txt, bind object/player properties
12
+ * to them via the bindui directive, then for a given object or player combine
13
+ * the bound property values) and a renderer (turn a per-column (val, auxval)
14
+ * pair into a cell symbol + a palette-index colour, and colour the row label by
15
+ * the combined value). This module ports both halves as DATA: characterGrid()
16
+ * returns, per panel, an ordered list of rows; each row is a 6-char label, its
17
+ * colour, and one {symbol, color} cell per equipment slot then the player.
18
+ *
19
+ * The DRAW half stays with the shell: the Term_putch / Term_putstr row/col
20
+ * placement, region_erase, the screen-size priority culling of
21
+ * configure_char_sheet's "fit in 24 rows" clamp beyond what the row cap
22
+ * reproduces, the equippy header row and the "abcdefgimnop@" column header.
23
+ *
24
+ * Seams the port does not carry on GameState arrive through UiEntryDeps; each
25
+ * has a documented default and is listed in parity/ledger/ui-entry.yaml. The
26
+ * per-object known twin (obj->known) and player_flags_timed() are not ported,
27
+ * so the timed player-flag / timed element contributions default to "no timed
28
+ * effect" - faithful for a character with no active buffs.
29
+ */
30
+
31
+ import { BASIC_COLORS, COLOR_TABLE, colorCharToAttr } from "../color.js";
32
+ import { FlagSet } from "../bitflag.js";
33
+ import { OF } from "../generated/object-flags.js";
34
+ import { PF } from "../generated/player-flags.js";
35
+ import { TMD } from "../generated/player-timed.js";
36
+ import { OBJ_MOD } from "../generated/object-modifiers.js";
37
+ import { STAT } from "../generated/stats.js";
38
+ import { ELEM, ELEMENT_ENTRIES } from "../generated/elements.js";
39
+ import {
40
+ UI_ENTRY_RENDERER,
41
+ UI_ENTRY_RENDERER_ENTRIES,
42
+ } from "../generated/ui-entry-renderers.js";
43
+ import { EL_INFO_IGNORE, OF_SIZE } from "../obj/types.js";
44
+ import { SKILL } from "../player/types.js";
45
+ import { playerFlags } from "../player/calcs.js";
46
+ import { objectFullyKnown, objectKnownShadow } from "../obj/known-object.js";
47
+ import { gearGet } from "./gear.js";
48
+ import { knownDescOf } from "./describe.js";
49
+ import type { Player } from "../player/player.js";
50
+ import type { GameObject } from "../obj/object.js";
51
+ import type { GameState } from "./context.js";
52
+
53
+ /* ------------------------------------------------------------------ */
54
+ /* Special values (ui-entry-combiner.h) */
55
+ /* ------------------------------------------------------------------ */
56
+
57
+ const INT_MAX = 2147483647;
58
+ const INT_MIN = -2147483648;
59
+
60
+ /** ui-entry-combiner.h: real value unknown to the player. */
61
+ export const UI_ENTRY_UNKNOWN_VALUE = INT_MAX;
62
+ /** ui-entry-combiner.h: value is to be treated as not present. */
63
+ export const UI_ENTRY_VALUE_NOT_PRESENT = INT_MAX - 1;
64
+ /** ui-entry-combiner.h: resist + vulnerability but not immunity, same element. */
65
+ export const UI_ENTRY_RESIST0_RES_VUL = INT_MAX - 2;
66
+
67
+ /* Sign handling (ui-entry-renderers.c enum). */
68
+ const UI_ENTRY_NO_SIGN = 0;
69
+ const UI_ENTRY_ALWAYS_SIGN = 1;
70
+ const UI_ENTRY_NEGATIVE_SIGN = 2;
71
+
72
+ /* Object property types (obj/types.ts OBJ_PROPERTY). */
73
+ const OP_STAT = 1;
74
+ const OP_MOD = 2;
75
+ const OP_FLAG = 3;
76
+ const OP_IGNORE = 4;
77
+ const OP_RESIST = 5;
78
+ const OP_VULN = 6;
79
+ const OP_IMM = 7;
80
+
81
+ /* Entry flag bit (ui-entry.c ENTRY_FLAG_TIMED_AUX). */
82
+ const ENTRY_FLAG_TIMED_AUX = 1;
83
+
84
+ /* ------------------------------------------------------------------ */
85
+ /* Combiners (ui-entry-combiner.c) */
86
+ /* ------------------------------------------------------------------ */
87
+
88
+ interface CombinerState {
89
+ work: number[] | null;
90
+ accum: number;
91
+ accumAux: number;
92
+ }
93
+
94
+ interface CombinerFuncs {
95
+ init: (v: number, a: number, st: CombinerState) => void;
96
+ accum: (v: number, a: number, st: CombinerState) => void;
97
+ finish: (st: CombinerState) => void;
98
+ vec: (vals: number[], auxs: number[]) => { accum: number; accumAux: number };
99
+ }
100
+
101
+ function simpleInit(v: number, a: number, st: CombinerState): void {
102
+ st.work = null;
103
+ st.accum = v;
104
+ st.accumAux = a;
105
+ }
106
+
107
+ function dummyAccum(): void {
108
+ /* Do nothing. */
109
+ }
110
+
111
+ function dummyFinish(): void {
112
+ /* Do nothing. */
113
+ }
114
+
115
+ /* ADD */
116
+ function addHelp(x: number, accum: number): number {
117
+ if (x === UI_ENTRY_VALUE_NOT_PRESENT) return accum;
118
+ if (x === UI_ENTRY_UNKNOWN_VALUE) {
119
+ return accum === UI_ENTRY_VALUE_NOT_PRESENT ? UI_ENTRY_UNKNOWN_VALUE : accum;
120
+ }
121
+ if (accum === UI_ENTRY_UNKNOWN_VALUE || accum === UI_ENTRY_VALUE_NOT_PRESENT) {
122
+ return x;
123
+ }
124
+ if (x > 0) {
125
+ return accum <= INT_MAX - 2 - x ? accum + x : INT_MAX - 2;
126
+ }
127
+ if (x < 0) {
128
+ return accum >= INT_MIN - x ? accum + x : INT_MIN;
129
+ }
130
+ return accum;
131
+ }
132
+
133
+ const ADD: CombinerFuncs = {
134
+ init: simpleInit,
135
+ accum(v, a, st) {
136
+ st.accum = addHelp(v, st.accum);
137
+ st.accumAux = addHelp(a, st.accumAux);
138
+ },
139
+ finish: dummyFinish,
140
+ vec(vals, auxs) {
141
+ let accum = vals.length > 0 ? vals[0]! : UI_ENTRY_VALUE_NOT_PRESENT;
142
+ for (let i = 1; i < vals.length; i++) accum = addHelp(vals[i]!, accum);
143
+ let accumAux = auxs.length > 0 ? auxs[0]! : UI_ENTRY_VALUE_NOT_PRESENT;
144
+ for (let i = 1; i < auxs.length; i++) accumAux = addHelp(auxs[i]!, accumAux);
145
+ return { accum, accumAux };
146
+ },
147
+ };
148
+
149
+ /* BITWISE_OR */
150
+ function bitwiseOrHelp(x: number, accum: number): number {
151
+ if (x === UI_ENTRY_VALUE_NOT_PRESENT) return accum;
152
+ if (x === UI_ENTRY_UNKNOWN_VALUE) {
153
+ return accum === UI_ENTRY_VALUE_NOT_PRESENT ? UI_ENTRY_UNKNOWN_VALUE : accum;
154
+ }
155
+ if (accum === UI_ENTRY_UNKNOWN_VALUE || accum === UI_ENTRY_VALUE_NOT_PRESENT) {
156
+ return x;
157
+ }
158
+ return accum | x;
159
+ }
160
+
161
+ const BITWISE_OR: CombinerFuncs = {
162
+ init: simpleInit,
163
+ accum(v, a, st) {
164
+ st.accum = bitwiseOrHelp(v, st.accum);
165
+ st.accumAux = bitwiseOrHelp(a, st.accumAux);
166
+ },
167
+ finish: dummyFinish,
168
+ vec(vals, auxs) {
169
+ let accum = vals.length > 0 ? vals[0]! : UI_ENTRY_VALUE_NOT_PRESENT;
170
+ for (let i = 1; i < vals.length; i++) accum = bitwiseOrHelp(vals[i]!, accum);
171
+ let accumAux = auxs.length > 0 ? auxs[0]! : UI_ENTRY_VALUE_NOT_PRESENT;
172
+ for (let i = 1; i < auxs.length; i++) accumAux = bitwiseOrHelp(auxs[i]!, accumAux);
173
+ return { accum, accumAux };
174
+ },
175
+ };
176
+
177
+ /* FIRST */
178
+ const FIRST: CombinerFuncs = {
179
+ init: simpleInit,
180
+ accum: dummyAccum,
181
+ finish: dummyFinish,
182
+ vec(vals, auxs) {
183
+ if (vals.length > 0) return { accum: vals[0]!, accumAux: auxs[0]! };
184
+ return { accum: UI_ENTRY_VALUE_NOT_PRESENT, accumAux: UI_ENTRY_VALUE_NOT_PRESENT };
185
+ },
186
+ };
187
+
188
+ /* LARGEST */
189
+ function largestHelp(x: number, accum: number): number {
190
+ if (x === UI_ENTRY_VALUE_NOT_PRESENT) return accum;
191
+ if (x === UI_ENTRY_UNKNOWN_VALUE) {
192
+ return accum === UI_ENTRY_VALUE_NOT_PRESENT ? UI_ENTRY_UNKNOWN_VALUE : accum;
193
+ }
194
+ if (
195
+ accum === UI_ENTRY_UNKNOWN_VALUE ||
196
+ accum === UI_ENTRY_VALUE_NOT_PRESENT ||
197
+ accum < x
198
+ ) {
199
+ return x;
200
+ }
201
+ return accum;
202
+ }
203
+
204
+ const LARGEST: CombinerFuncs = {
205
+ init: simpleInit,
206
+ accum(v, a, st) {
207
+ st.accum = largestHelp(v, st.accum);
208
+ st.accumAux = largestHelp(a, st.accumAux);
209
+ },
210
+ finish: dummyFinish,
211
+ vec(vals, auxs) {
212
+ let accum = vals.length > 0 ? vals[0]! : UI_ENTRY_VALUE_NOT_PRESENT;
213
+ for (let i = 1; i < vals.length; i++) accum = largestHelp(vals[i]!, accum);
214
+ let accumAux = auxs.length > 0 ? auxs[0]! : UI_ENTRY_VALUE_NOT_PRESENT;
215
+ for (let i = 1; i < auxs.length; i++) accumAux = largestHelp(auxs[i]!, accumAux);
216
+ return { accum, accumAux };
217
+ },
218
+ };
219
+
220
+ /* LAST */
221
+ const LAST: CombinerFuncs = {
222
+ init: simpleInit,
223
+ accum(v, a, st) {
224
+ st.accum = v;
225
+ st.accumAux = a;
226
+ },
227
+ finish: dummyFinish,
228
+ vec(vals, auxs) {
229
+ if (vals.length > 0) {
230
+ return { accum: vals[vals.length - 1]!, accumAux: auxs[auxs.length - 1]! };
231
+ }
232
+ return { accum: UI_ENTRY_VALUE_NOT_PRESENT, accumAux: UI_ENTRY_VALUE_NOT_PRESENT };
233
+ },
234
+ };
235
+
236
+ /* LOGICAL_OR */
237
+ function logicalInit(v: number, a: number, st: CombinerState): void {
238
+ st.work = null;
239
+ st.accum =
240
+ v === UI_ENTRY_UNKNOWN_VALUE || v === UI_ENTRY_VALUE_NOT_PRESENT ? v : v !== 0 ? 1 : 0;
241
+ st.accumAux =
242
+ a === UI_ENTRY_UNKNOWN_VALUE || a === UI_ENTRY_VALUE_NOT_PRESENT ? a : a !== 0 ? 1 : 0;
243
+ }
244
+
245
+ function logicalOrHelp(x: number, accum: number): number {
246
+ if (x === UI_ENTRY_VALUE_NOT_PRESENT) return accum;
247
+ if (x === UI_ENTRY_UNKNOWN_VALUE) {
248
+ return accum === UI_ENTRY_VALUE_NOT_PRESENT ? UI_ENTRY_UNKNOWN_VALUE : accum;
249
+ }
250
+ if (accum === UI_ENTRY_UNKNOWN_VALUE || accum === UI_ENTRY_VALUE_NOT_PRESENT) {
251
+ return x !== 0 ? 1 : 0;
252
+ }
253
+ return accum || x !== 0 ? 1 : 0;
254
+ }
255
+
256
+ const LOGICAL_OR: CombinerFuncs = {
257
+ init: logicalInit,
258
+ accum(v, a, st) {
259
+ st.accum = logicalOrHelp(v, st.accum);
260
+ st.accumAux = logicalOrHelp(a, st.accumAux);
261
+ },
262
+ finish: dummyFinish,
263
+ vec(vals, auxs) {
264
+ let accum = UI_ENTRY_VALUE_NOT_PRESENT;
265
+ for (let i = 0; i < vals.length; i++) accum = logicalOrHelp(vals[i]!, accum);
266
+ let accumAux = UI_ENTRY_VALUE_NOT_PRESENT;
267
+ for (let i = 0; i < auxs.length; i++) accumAux = logicalOrHelp(auxs[i]!, accumAux);
268
+ return { accum, accumAux };
269
+ },
270
+ };
271
+
272
+ /* LOGICAL_OR_WITH_CANCEL */
273
+ function locInit(v: number, a: number, st: CombinerState): void {
274
+ st.work = null;
275
+ st.accum =
276
+ v === UI_ENTRY_UNKNOWN_VALUE || v === UI_ENTRY_VALUE_NOT_PRESENT
277
+ ? v
278
+ : v > 0
279
+ ? 1
280
+ : v < 0
281
+ ? 2
282
+ : 0;
283
+ st.accumAux =
284
+ a === UI_ENTRY_UNKNOWN_VALUE || a === UI_ENTRY_VALUE_NOT_PRESENT
285
+ ? a
286
+ : a > 0
287
+ ? 1
288
+ : a < 0
289
+ ? 2
290
+ : 0;
291
+ }
292
+
293
+ function locHelp(x: number, accum: number): number {
294
+ if (x === UI_ENTRY_VALUE_NOT_PRESENT) return accum;
295
+ if (x === UI_ENTRY_UNKNOWN_VALUE) {
296
+ return accum === UI_ENTRY_VALUE_NOT_PRESENT ? UI_ENTRY_UNKNOWN_VALUE : accum;
297
+ }
298
+ if (accum === UI_ENTRY_UNKNOWN_VALUE || accum === UI_ENTRY_VALUE_NOT_PRESENT) {
299
+ return x > 0 ? 1 : x < 0 ? 2 : 0;
300
+ }
301
+ if (x > 0) return accum | 1;
302
+ if (x < 0) return accum | 2;
303
+ return accum;
304
+ }
305
+
306
+ function locResolve(v: number): number {
307
+ if (v !== UI_ENTRY_UNKNOWN_VALUE && v !== UI_ENTRY_VALUE_NOT_PRESENT) {
308
+ if ((v & 2) !== 0) return -1;
309
+ }
310
+ return v;
311
+ }
312
+
313
+ const LOGICAL_OR_WITH_CANCEL: CombinerFuncs = {
314
+ init: locInit,
315
+ accum(v, a, st) {
316
+ st.accum = locHelp(v, st.accum);
317
+ st.accumAux = locHelp(a, st.accumAux);
318
+ },
319
+ finish(st) {
320
+ st.accum = locResolve(st.accum);
321
+ st.accumAux = locResolve(st.accumAux);
322
+ },
323
+ vec(vals, auxs) {
324
+ let accum = UI_ENTRY_VALUE_NOT_PRESENT;
325
+ for (let i = 0; i < vals.length; i++) accum = locHelp(vals[i]!, accum);
326
+ accum = locResolve(accum);
327
+ let accumAux = UI_ENTRY_VALUE_NOT_PRESENT;
328
+ for (let i = 0; i < auxs.length; i++) accumAux = locHelp(auxs[i]!, accumAux);
329
+ accumAux = locResolve(accumAux);
330
+ return { accum, accumAux };
331
+ },
332
+ };
333
+
334
+ /* RESIST_0 (uses work[0]=most negative for val, work[1]=most negative for aux) */
335
+ function resist0Seed(x: number): { pos: number; neg: number } {
336
+ if (x === UI_ENTRY_UNKNOWN_VALUE || x === UI_ENTRY_VALUE_NOT_PRESENT) {
337
+ return { pos: x, neg: x };
338
+ }
339
+ if (x === UI_ENTRY_RESIST0_RES_VUL) return { pos: 1, neg: -1 };
340
+ if (x > 0) return { pos: x, neg: 0 };
341
+ return { pos: 0, neg: x };
342
+ }
343
+
344
+ function resist0Help(x: number, pos: number, neg: number): { pos: number; neg: number } {
345
+ if (x === UI_ENTRY_VALUE_NOT_PRESENT) return { pos, neg };
346
+ if (x === UI_ENTRY_UNKNOWN_VALUE) {
347
+ if (pos === UI_ENTRY_VALUE_NOT_PRESENT) {
348
+ return { pos: UI_ENTRY_UNKNOWN_VALUE, neg: UI_ENTRY_UNKNOWN_VALUE };
349
+ }
350
+ return { pos, neg };
351
+ }
352
+ if (x === UI_ENTRY_RESIST0_RES_VUL) {
353
+ if (pos === UI_ENTRY_UNKNOWN_VALUE || pos === UI_ENTRY_VALUE_NOT_PRESENT) {
354
+ return { pos: 1, neg: -1 };
355
+ }
356
+ return { pos: pos < 1 ? 1 : pos, neg: neg > -1 ? -1 : neg };
357
+ }
358
+ if (x > 0) {
359
+ if (pos === UI_ENTRY_UNKNOWN_VALUE || pos === UI_ENTRY_VALUE_NOT_PRESENT) {
360
+ return { pos: x, neg: 0 };
361
+ }
362
+ return { pos: pos < x ? x : pos, neg };
363
+ }
364
+ if (neg === UI_ENTRY_UNKNOWN_VALUE || neg === UI_ENTRY_VALUE_NOT_PRESENT) {
365
+ return { pos: 0, neg: x };
366
+ }
367
+ return { pos, neg: neg > x ? x : neg };
368
+ }
369
+
370
+ function resist0Finish(pos: number, neg: number): number {
371
+ if (neg < 0 && neg !== UI_ENTRY_UNKNOWN_VALUE && neg !== UI_ENTRY_VALUE_NOT_PRESENT) {
372
+ /* A vulnerability cancels a resist but not an immunity. */
373
+ if (pos < 3 && pos !== UI_ENTRY_UNKNOWN_VALUE && pos !== UI_ENTRY_VALUE_NOT_PRESENT) {
374
+ return pos === 0 ? -1 : UI_ENTRY_RESIST0_RES_VUL;
375
+ }
376
+ }
377
+ return pos;
378
+ }
379
+
380
+ const RESIST_0: CombinerFuncs = {
381
+ init(v, a, st) {
382
+ const sv = resist0Seed(v);
383
+ const sa = resist0Seed(a);
384
+ st.work = [sv.neg, sa.neg];
385
+ st.accum = sv.pos;
386
+ st.accumAux = sa.pos;
387
+ },
388
+ accum(v, a, st) {
389
+ const work = st.work as number[];
390
+ const rv = resist0Help(v, st.accum, work[0]!);
391
+ st.accum = rv.pos;
392
+ work[0] = rv.neg;
393
+ const ra = resist0Help(a, st.accumAux, work[1]!);
394
+ st.accumAux = ra.pos;
395
+ work[1] = ra.neg;
396
+ },
397
+ finish(st) {
398
+ const work = st.work as number[];
399
+ st.accum = resist0Finish(st.accum, work[0]!);
400
+ st.accumAux = resist0Finish(st.accumAux, work[1]!);
401
+ st.work = null;
402
+ },
403
+ vec(vals, auxs) {
404
+ let accum = UI_ENTRY_VALUE_NOT_PRESENT;
405
+ let neg = UI_ENTRY_VALUE_NOT_PRESENT;
406
+ for (let i = 0; i < vals.length; i++) {
407
+ const r = resist0Help(vals[i]!, accum, neg);
408
+ accum = r.pos;
409
+ neg = r.neg;
410
+ }
411
+ accum = resist0Finish(accum, neg);
412
+ let accumAux = UI_ENTRY_VALUE_NOT_PRESENT;
413
+ let negA = UI_ENTRY_VALUE_NOT_PRESENT;
414
+ for (let i = 0; i < auxs.length; i++) {
415
+ const r = resist0Help(auxs[i]!, accumAux, negA);
416
+ accumAux = r.pos;
417
+ negA = r.neg;
418
+ }
419
+ accumAux = resist0Finish(accumAux, negA);
420
+ return { accum, accumAux };
421
+ },
422
+ };
423
+
424
+ /* SMALLEST */
425
+ function smallestHelp(x: number, accum: number): number {
426
+ if (x === UI_ENTRY_VALUE_NOT_PRESENT) return accum;
427
+ if (x === UI_ENTRY_UNKNOWN_VALUE) {
428
+ return accum === UI_ENTRY_VALUE_NOT_PRESENT ? UI_ENTRY_UNKNOWN_VALUE : accum;
429
+ }
430
+ if (
431
+ accum === UI_ENTRY_UNKNOWN_VALUE ||
432
+ accum === UI_ENTRY_VALUE_NOT_PRESENT ||
433
+ accum > x
434
+ ) {
435
+ return x;
436
+ }
437
+ return accum;
438
+ }
439
+
440
+ const SMALLEST: CombinerFuncs = {
441
+ init: simpleInit,
442
+ accum(v, a, st) {
443
+ st.accum = smallestHelp(v, st.accum);
444
+ st.accumAux = smallestHelp(a, st.accumAux);
445
+ },
446
+ finish: dummyFinish,
447
+ vec(vals, auxs) {
448
+ let accum = vals.length > 0 ? vals[0]! : UI_ENTRY_VALUE_NOT_PRESENT;
449
+ for (let i = 1; i < vals.length; i++) accum = smallestHelp(vals[i]!, accum);
450
+ let accumAux = auxs.length > 0 ? auxs[0]! : UI_ENTRY_VALUE_NOT_PRESENT;
451
+ for (let i = 1; i < auxs.length; i++) accumAux = smallestHelp(auxs[i]!, accumAux);
452
+ return { accum, accumAux };
453
+ },
454
+ };
455
+
456
+ /** combiners[], sorted alphabetically by name (ui-entry-combiner.c L83). */
457
+ const COMBINERS: ReadonlyArray<{ name: string; funcs: CombinerFuncs }> = [
458
+ { name: "ADD", funcs: ADD },
459
+ { name: "BITWISE_OR", funcs: BITWISE_OR },
460
+ { name: "FIRST", funcs: FIRST },
461
+ { name: "LARGEST", funcs: LARGEST },
462
+ { name: "LAST", funcs: LAST },
463
+ { name: "LOGICAL_OR", funcs: LOGICAL_OR },
464
+ { name: "LOGICAL_OR_WITH_CANCEL", funcs: LOGICAL_OR_WITH_CANCEL },
465
+ { name: "RESIST_0", funcs: RESIST_0 },
466
+ { name: "SMALLEST", funcs: SMALLEST },
467
+ ];
468
+
469
+ /** ui_entry_combiner_lookup: 1-based index, 0 if unknown. */
470
+ export function combinerLookup(name: string): number {
471
+ for (let i = 0; i < COMBINERS.length; i++) {
472
+ if (COMBINERS[i]!.name === name) return i + 1;
473
+ }
474
+ return 0;
475
+ }
476
+
477
+ function combinerFuncs(index: number): CombinerFuncs {
478
+ const c = COMBINERS[index - 1];
479
+ if (!c) throw new Error(`bad combiner index ${index}`);
480
+ return c.funcs;
481
+ }
482
+
483
+ /** Run a combiner over parallel arrays (its vec_func); exported for tests. */
484
+ export function combineValues(
485
+ combinerName: string,
486
+ vals: number[],
487
+ auxs: number[],
488
+ ): { accum: number; accumAux: number } {
489
+ const idx = combinerLookup(combinerName);
490
+ if (idx === 0) throw new Error(`unknown combiner ${combinerName}`);
491
+ return combinerFuncs(idx).vec(vals, auxs);
492
+ }
493
+
494
+ /* ------------------------------------------------------------------ */
495
+ /* Raw pack record shapes (input to buildUiEntryConfig) */
496
+ /* ------------------------------------------------------------------ */
497
+
498
+ type Json = Record<string, unknown>;
499
+
500
+ interface UiEntryRecord extends Json {
501
+ name: string;
502
+ }
503
+
504
+ /** The pack JSON needed to build the config. */
505
+ export interface UiEntryPackRecords {
506
+ uiEntry: UiEntryRecord[];
507
+ uiEntryBase: UiEntryRecord[];
508
+ uiEntryRenderer: Json[];
509
+ objectProperty: Json[];
510
+ playerProperty: Json[];
511
+ }
512
+
513
+ /* ------------------------------------------------------------------ */
514
+ /* Renderer table (ui-entry-renderers.c) */
515
+ /* ------------------------------------------------------------------ */
516
+
517
+ interface RendererInfo {
518
+ name: string;
519
+ backendIndex: number; // 0..5 into UI_ENTRY_RENDERER_ENTRIES
520
+ combinerIndex: number;
521
+ colors: number[]; // COLOUR_* per palette slot
522
+ labelColors: number[];
523
+ symbols: string; // one code unit per palette slot
524
+ ndigit: number;
525
+ sign: number;
526
+ combinedRendererIndex: number; // 1-based, 0 if none
527
+ }
528
+
529
+ function signNameToInt(name: string): number {
530
+ if (name === "NO_SIGN") return UI_ENTRY_NO_SIGN;
531
+ if (name === "ALWAYS_SIGN") return UI_ENTRY_ALWAYS_SIGN;
532
+ if (name === "NEGATIVE_SIGN") return UI_ENTRY_NEGATIVE_SIGN;
533
+ return UI_ENTRY_NO_SIGN;
534
+ }
535
+
536
+ function colorsFromChars(chars: string): number[] {
537
+ const out: number[] = [];
538
+ for (let i = 0; i < chars.length; i++) {
539
+ const a = colorCharToAttr(chars[i]!);
540
+ out.push(a >= 0 ? a : 1 /* COLOUR_WHITE */);
541
+ }
542
+ return out;
543
+ }
544
+
545
+ /** augment_colors: extend attr[] with the default palette tail if shorter. */
546
+ function augmentColors(defaults: string, attr: number[]): number[] {
547
+ if (attr.length < defaults.length) {
548
+ const tail = colorsFromChars(defaults.slice(attr.length));
549
+ return attr.concat(tail);
550
+ }
551
+ return attr;
552
+ }
553
+
554
+ /** augment_symbols: extend symbols with the default tail if shorter. */
555
+ function augmentSymbols(defaults: string, sym: string): string {
556
+ return sym.length < defaults.length ? sym + defaults.slice(sym.length) : sym;
557
+ }
558
+
559
+ function buildRenderers(records: Json[]): RendererInfo[] {
560
+ const out: RendererInfo[] = [];
561
+ const byName = new Map<string, number>();
562
+ /* First pass: create renderer_info, resolving the backend. */
563
+ for (const rec of records) {
564
+ const name = String(rec["name"]);
565
+ const code = String(rec["code"]);
566
+ const backendIndex = (UI_ENTRY_RENDERER as Record<string, number>)[code] ?? -1;
567
+ const backend = backendIndex >= 0 ? UI_ENTRY_RENDERER_ENTRIES[backendIndex]! : null;
568
+
569
+ let colors = rec["colors"] !== undefined ? colorsFromChars(String(rec["colors"])) : [];
570
+ let labelColors =
571
+ rec["labelcolors"] !== undefined ? colorsFromChars(String(rec["labelcolors"])) : [];
572
+ let symbols = rec["symbols"] !== undefined ? String(rec["symbols"]) : "";
573
+
574
+ /* finish_parse: default combiner + augment with backend defaults. */
575
+ let combinerIndex = rec["combine"] !== undefined ? combinerLookup(String(rec["combine"])) : 0;
576
+ if (backend) {
577
+ if (combinerIndex === 0) combinerIndex = combinerLookup(backend.defaultCombinerName);
578
+ colors = augmentColors(backend.defaultColors, colors);
579
+ labelColors = augmentColors(backend.defaultLabelColors, labelColors);
580
+ symbols = augmentSymbols(backend.defaultSymbols, symbols);
581
+ }
582
+ const ndigit =
583
+ rec["ndigit"] !== undefined ? Number(rec["ndigit"]) : (backend?.defaultNDigit ?? 1);
584
+ const sign =
585
+ rec["sign"] !== undefined
586
+ ? signNameToInt(String(rec["sign"]))
587
+ : signNameToInt(backend?.defaultSign ?? "NO_SIGN");
588
+
589
+ byName.set(name, out.length + 1);
590
+ out.push({
591
+ name,
592
+ backendIndex,
593
+ combinerIndex,
594
+ colors,
595
+ labelColors,
596
+ symbols,
597
+ ndigit,
598
+ sign,
599
+ combinedRendererIndex: 0,
600
+ });
601
+ }
602
+ /* Second pass: resolve combined-renderer links. */
603
+ for (let i = 0; i < records.length; i++) {
604
+ const cr = records[i]!["combined-renderer"];
605
+ if (cr !== undefined) {
606
+ out[i]!.combinedRendererIndex = byName.get(String(cr)) ?? 0;
607
+ }
608
+ }
609
+ return out;
610
+ }
611
+
612
+ /** ui_entry_renderer_lookup: 1-based renderer index, 0 if unknown. */
613
+ function rendererLookup(renderers: RendererInfo[], name: string): number {
614
+ for (let i = 0; i < renderers.length; i++) {
615
+ if (renderers[i]!.name === name) return i + 1;
616
+ }
617
+ return 0;
618
+ }
619
+
620
+ /* ------------------------------------------------------------------ */
621
+ /* Concrete ui_entry table (ui-entry.c) */
622
+ /* ------------------------------------------------------------------ */
623
+
624
+ const MAX_SHORTENED = 10;
625
+
626
+ interface CategoryRef {
627
+ name: string;
628
+ priority: number;
629
+ }
630
+
631
+ interface BoundObjProp {
632
+ type: number;
633
+ index: number;
634
+ value: number;
635
+ haveValue: boolean;
636
+ isaux: boolean;
637
+ }
638
+
639
+ interface BoundPlayerAbility {
640
+ abilityType: string; // "player" | "object" | "element"
641
+ index: number;
642
+ value: number;
643
+ haveValue: boolean;
644
+ isaux: boolean;
645
+ }
646
+
647
+ interface UiEntry {
648
+ name: string;
649
+ categories: CategoryRef[]; // sorted by name
650
+ objProps: BoundObjProp[];
651
+ pAbilities: BoundPlayerAbility[];
652
+ label: string;
653
+ nlabel: number;
654
+ shortened: string[]; // index 0..9 -> length 1..10
655
+ nshortened: number[];
656
+ rendererIndex: number;
657
+ combinerIndex: number;
658
+ defaultPriority: number;
659
+ paramIndex: number;
660
+ flags: number;
661
+ templateOnly: boolean;
662
+ }
663
+
664
+ export interface UiEntryConfig {
665
+ entries: UiEntry[]; // sorted by name (ui_entry_search order)
666
+ renderers: RendererInfo[];
667
+ }
668
+
669
+ /** Priority scheme index: 0=default, 1=index, 2=negative_index. */
670
+ function priorityScheme(name: string): number {
671
+ if (name === "index") return 1;
672
+ if (name === "negative_index") return 2;
673
+ return 0;
674
+ }
675
+ function applyPriorityScheme(scheme: number, i: number): number {
676
+ if (scheme === 1) return i;
677
+ if (scheme === 2) return -i;
678
+ return 0;
679
+ }
680
+
681
+ /** Parameter kind: 0=none, 1=element, 2=stat. */
682
+ function parameterKind(name: string | undefined): number {
683
+ if (name === "element") return 1;
684
+ if (name === "stat") return 2;
685
+ return 0;
686
+ }
687
+ function paramCount(kind: number): number {
688
+ if (kind === 1) return ELEMENT_ENTRIES.length;
689
+ if (kind === 2) return 5; /* STAT_MAX */
690
+ return 1;
691
+ }
692
+ function paramName(kind: number, i: number): string {
693
+ if (kind === 1) return ELEMENT_ENTRIES[i]!.name;
694
+ if (kind === 2) return ["STR", "INT", "WIS", "DEX", "CON"][i]!;
695
+ return "";
696
+ }
697
+
698
+ /** fill_out_shortened (ui-entry.c L1756): fill every shortened slot. */
699
+ function fillOutShortened(entry: UiEntry): void {
700
+ for (let i = 0; i < MAX_SHORTENED; i++) {
701
+ if (entry.nshortened[i] !== 0) continue;
702
+ let n: number;
703
+ let src: string;
704
+ let j = i + 1;
705
+ for (;;) {
706
+ if (j >= MAX_SHORTENED) {
707
+ n = entry.nlabel;
708
+ src = entry.label;
709
+ break;
710
+ }
711
+ if (entry.nshortened[j] !== 0) {
712
+ n = entry.nshortened[j]!;
713
+ src = entry.shortened[j]!;
714
+ break;
715
+ }
716
+ j++;
717
+ }
718
+ const take = n < i + 1 ? n : i + 1;
719
+ entry.nshortened[i] = take;
720
+ entry.shortened[i] = src.slice(0, take);
721
+ }
722
+ }
723
+
724
+ /**
725
+ * get_ui_entry_label (ui-entry.c L337): the visible (length-1)-char label,
726
+ * padded left or right. The final null slot is the caller's business.
727
+ */
728
+ function getUiEntryLabel(entry: UiEntry, length: number, padLeft: boolean): string {
729
+ if (length <= 1) return "";
730
+ let src: string;
731
+ let n: number;
732
+ if (length <= MAX_SHORTENED + 1) {
733
+ src = entry.shortened[length - 2]!;
734
+ n = entry.nshortened[length - 2]!;
735
+ } else {
736
+ src = entry.label;
737
+ n = entry.nlabel;
738
+ }
739
+ const content = length - 1;
740
+ if (n < content) {
741
+ const pad = " ".repeat(content - n);
742
+ return padLeft ? pad + src.slice(0, n) : src.slice(0, n) + pad;
743
+ }
744
+ return src.slice(0, content);
745
+ }
746
+
747
+ function blankEntry(name: string): UiEntry {
748
+ return {
749
+ name,
750
+ categories: [],
751
+ objProps: [],
752
+ pAbilities: [],
753
+ label: "",
754
+ nlabel: 0,
755
+ shortened: new Array<string>(MAX_SHORTENED).fill(""),
756
+ nshortened: new Array<number>(MAX_SHORTENED).fill(0),
757
+ rendererIndex: 0,
758
+ combinerIndex: 0,
759
+ defaultPriority: 0,
760
+ paramIndex: -1,
761
+ flags: 0,
762
+ templateOnly: false,
763
+ };
764
+ }
765
+
766
+ /** search_categories on a UiEntry: insert if absent (kept sorted by name). */
767
+ function addCategory(entry: UiEntry, name: string, priority: number): void {
768
+ let lo = 0;
769
+ let hi = entry.categories.length;
770
+ while (lo < hi) {
771
+ const mid = (lo + hi) >> 1;
772
+ const cmp = entry.categories[mid]!.name < name ? -1 : entry.categories[mid]!.name > name ? 1 : 0;
773
+ if (cmp === 0) return; /* already present */
774
+ if (cmp < 0) lo = mid + 1;
775
+ else hi = mid;
776
+ }
777
+ entry.categories.splice(lo, 0, { name, priority });
778
+ }
779
+
780
+ function categoryPriority(entry: UiEntry, name: string): number | null {
781
+ for (const c of entry.categories) {
782
+ if (c.name === name) return c.priority;
783
+ }
784
+ return null;
785
+ }
786
+
787
+ /**
788
+ * Build the ui_entry table from ui_entry_base.txt (templates) then
789
+ * ui_entry.txt, mirroring run_parse_ui_entry / hatch_embryo. Records are keyed
790
+ * by name; a record whose name already exists edits that entry, otherwise a new
791
+ * one is created (and, if it carries a parameter, expanded per element/stat).
792
+ */
793
+ function buildEntries(
794
+ baseRecords: UiEntryRecord[],
795
+ entryRecords: UiEntryRecord[],
796
+ renderers: RendererInfo[],
797
+ ): Map<string, UiEntry> {
798
+ const table = new Map<string, UiEntry>();
799
+
800
+ const strField = (rec: Json, key: string): string | undefined =>
801
+ rec[key] !== undefined ? String(rec[key]) : undefined;
802
+ const arrField = (rec: Json, key: string): string[] => {
803
+ const v = rec[key];
804
+ if (v === undefined) return [];
805
+ return Array.isArray(v) ? v.map(String) : [String(v)];
806
+ };
807
+
808
+ const hatch = (rec: UiEntryRecord, templateOnlyDefault: boolean): void => {
809
+ const name = rec.name;
810
+ const existing = table.get(name);
811
+
812
+ if (existing) {
813
+ /* Edit an existing entry. */
814
+ applyRecordToEntry(rec, existing, renderers, strField, arrField, -1, 0);
815
+ return;
816
+ }
817
+
818
+ const kind = parameterKind(strField(rec, "parameter"));
819
+ /* Determine the priority scheme source for a fresh (possibly generic) entry. */
820
+ const priorityStr = strField(rec, "priority");
821
+ const psource = priorityStr !== undefined ? priorityScheme(priorityStr) : 0;
822
+
823
+ if (kind === 0) {
824
+ const entry = blankEntry(name);
825
+ entry.templateOnly = templateOnlyDefault;
826
+ applyRecordToEntry(rec, entry, renderers, strField, arrField, -1, 0);
827
+ table.set(name, entry);
828
+ return;
829
+ }
830
+
831
+ /* Generic entry: expand into one concrete entry per parameter value. */
832
+ const n = paramCount(kind);
833
+ for (let i = 0; i < n; i++) {
834
+ const pname = paramName(kind, i);
835
+ const entry = blankEntry(`${name}<${pname}>`);
836
+ entry.templateOnly = templateOnlyDefault;
837
+ entry.paramIndex = i;
838
+ applyRecordToEntry(rec, entry, renderers, strField, arrField, i, psource);
839
+ /* Default label is the parameter name unless one was set. */
840
+ if (entry.nlabel === 0) {
841
+ entry.label = pname;
842
+ entry.nlabel = pname.length;
843
+ }
844
+ table.set(entry.name, entry);
845
+ }
846
+ };
847
+
848
+ for (const rec of baseRecords) hatch(rec, false);
849
+ /* After the base file, all entries so far become templates-only. */
850
+ for (const e of table.values()) e.templateOnly = true;
851
+ for (const rec of entryRecords) hatch(rec, false);
852
+
853
+ /* finish_parse: default labels from name, fill shortened, fill priorities. */
854
+ for (const entry of table.values()) {
855
+ if (entry.nlabel === 0) {
856
+ entry.label = entry.name;
857
+ entry.nlabel = entry.name.length;
858
+ }
859
+ fillOutShortened(entry);
860
+ /*
861
+ * finish_parse (ui-entry.c L2389): categories with no explicit per-category
862
+ * priority inherit the entry's final default priority. The shipped data
863
+ * never sets a per-category priority (priority always precedes any category
864
+ * line, so it sets the default), so every category takes defaultPriority -
865
+ * which is what makes the priority line seen after a template's categories
866
+ * still order the row correctly.
867
+ */
868
+ for (const c of entry.categories) {
869
+ c.priority = entry.defaultPriority;
870
+ }
871
+ }
872
+
873
+ return table;
874
+ }
875
+
876
+ /**
877
+ * Apply one parsed record's fields to an entry, resolving template, renderer,
878
+ * combiner, labels, categories, priority and flags. paramIdx/psource drive the
879
+ * generic priority scheme (negative_index etc.) for expanded entries.
880
+ */
881
+ function applyRecordToEntry(
882
+ rec: UiEntryRecord,
883
+ entry: UiEntry,
884
+ renderers: RendererInfo[],
885
+ strField: (rec: Json, key: string) => string | undefined,
886
+ arrField: (rec: Json, key: string) => string[],
887
+ paramIdx: number,
888
+ psource: number,
889
+ ): void {
890
+ /* Template first: copy simple fields and merge its categories. */
891
+ const template = strField(rec, "template");
892
+ if (template !== undefined) {
893
+ const t = TEMPLATE_LOOKUP.get(template);
894
+ if (t) {
895
+ entry.rendererIndex = t.rendererIndex;
896
+ entry.combinerIndex = t.combinerIndex;
897
+ entry.defaultPriority = t.defaultPriority;
898
+ entry.flags = t.flags & ~0; /* TEMPLATE_ONLY is not a data flag here */
899
+ for (const c of t.categories) addCategory(entry, c.name, entry.defaultPriority);
900
+ }
901
+ }
902
+
903
+ const renderer = strField(rec, "renderer");
904
+ if (renderer !== undefined) entry.rendererIndex = rendererLookup(renderers, renderer);
905
+ const combine = strField(rec, "combine");
906
+ if (combine !== undefined) entry.combinerIndex = combinerLookup(combine);
907
+
908
+ const label = strField(rec, "label");
909
+ if (label !== undefined) {
910
+ entry.label = label;
911
+ entry.nlabel = label.length;
912
+ }
913
+ for (let k = 1; k <= MAX_SHORTENED; k++) {
914
+ const s = strField(rec, `label${k}`);
915
+ if (s !== undefined) {
916
+ const take = s.length < k ? s.length : k;
917
+ entry.shortened[k - 1] = s.slice(0, take);
918
+ entry.nshortened[k - 1] = take;
919
+ }
920
+ }
921
+
922
+ /* Priority (before any category in the shipped data -> default priority). */
923
+ const priorityStr = strField(rec, "priority");
924
+ if (priorityStr !== undefined) {
925
+ const scheme = priorityScheme(priorityStr);
926
+ if (scheme !== 0) {
927
+ entry.defaultPriority = applyPriorityScheme(scheme, paramIdx >= 0 ? paramIdx : entry.paramIndex >= 0 ? entry.paramIndex : 0);
928
+ } else {
929
+ const v = parseInt(priorityStr, 10);
930
+ if (!Number.isNaN(v)) entry.defaultPriority = v;
931
+ }
932
+ } else if (psource !== 0 && paramIdx >= 0) {
933
+ entry.defaultPriority = applyPriorityScheme(psource, paramIdx);
934
+ }
935
+
936
+ /* Categories: added with the (now-resolved) default priority. */
937
+ for (const cat of arrField(rec, "category")) {
938
+ addCategory(entry, cat, entry.defaultPriority);
939
+ }
940
+
941
+ /* Flags. */
942
+ for (const fl of arrField(rec, "flags")) {
943
+ for (const tok of fl.split(/[\s|]+/)) {
944
+ if (tok === "TIMED_AS_AUX") entry.flags |= ENTRY_FLAG_TIMED_AUX;
945
+ }
946
+ }
947
+ }
948
+
949
+ /** Lookup used by applyRecordToEntry for template resolution. */
950
+ let TEMPLATE_LOOKUP: Map<string, UiEntry> = new Map();
951
+
952
+ /* ------------------------------------------------------------------ */
953
+ /* Binding object / player properties to entries (the bindui directive) */
954
+ /* ------------------------------------------------------------------ */
955
+
956
+ function objPropType(typeStr: string): number {
957
+ switch (typeStr) {
958
+ case "stat":
959
+ return OP_STAT;
960
+ case "mod":
961
+ return OP_MOD;
962
+ case "flag":
963
+ return OP_FLAG;
964
+ case "ignore":
965
+ return OP_IGNORE;
966
+ case "resistance":
967
+ return OP_RESIST;
968
+ case "vulnerability":
969
+ return OP_VULN;
970
+ case "immunity":
971
+ return OP_IMM;
972
+ default:
973
+ return 0;
974
+ }
975
+ }
976
+
977
+ /** Resolve an object property's code to its index within its type. */
978
+ function objPropIndex(typeStr: string, code: string): number {
979
+ switch (typeStr) {
980
+ case "stat":
981
+ return (STAT as Record<string, number>)[code] ?? -1;
982
+ case "mod":
983
+ return (OBJ_MOD as Record<string, number>)[code] ?? -1;
984
+ case "flag":
985
+ return (OF as Record<string, number>)[code] ?? -1;
986
+ case "ignore":
987
+ case "resistance":
988
+ case "vulnerability":
989
+ case "immunity":
990
+ return (ELEM as Record<string, number>)[code] ?? -1;
991
+ default:
992
+ return -1;
993
+ }
994
+ }
995
+
996
+ function bindObjectProperties(table: Map<string, UiEntry>, records: Json[]): void {
997
+ for (const rec of records) {
998
+ const bindui = rec["bindui"] as Json | undefined;
999
+ if (!bindui) continue;
1000
+ const uiName = String(bindui["ui"]);
1001
+ const entry = table.get(uiName);
1002
+ if (!entry) continue;
1003
+ const typeStr = String(rec["type"]);
1004
+ const code = String(rec["code"]);
1005
+ const type = objPropType(typeStr);
1006
+ const index = objPropIndex(typeStr, code);
1007
+ if (type === 0 || index < 0) continue;
1008
+ const haveValue = bindui["uival"] !== undefined;
1009
+ const value = haveValue ? Number(bindui["uival"]) : 0;
1010
+ const isaux = Number(bindui["aux"]) !== 0;
1011
+ entry.objProps.push({ type, index, value, haveValue, isaux });
1012
+ }
1013
+ }
1014
+
1015
+ function bindPlayerProperties(table: Map<string, UiEntry>, records: Json[]): void {
1016
+ const elementCount = ELEMENT_ENTRIES.length;
1017
+ for (const rec of records) {
1018
+ const bindui = rec["bindui"] as Json | undefined;
1019
+ if (!bindui) continue;
1020
+ const abilityType = String(rec["type"]);
1021
+ const uiName = String(bindui["ui"]);
1022
+ const uival = bindui["uival"] !== undefined ? String(bindui["uival"]) : "";
1023
+ const isspecial = uival === "special";
1024
+ const haveValue = !isspecial;
1025
+ const value = isspecial ? 0 : parseInt(uival, 10) || 0;
1026
+ const isaux = Number(bindui["aux"]) !== 0;
1027
+
1028
+ if (abilityType === "element") {
1029
+ /* finish_parse_player_prop (init.c L1362): one ability per element,
1030
+ excluding the last, bound to "<ui><ELEM>". */
1031
+ for (let i = 0; i < elementCount - 1; i++) {
1032
+ const name = `${uiName}<${ELEMENT_ENTRIES[i]!.name}>`;
1033
+ const entry = table.get(name);
1034
+ if (!entry) continue;
1035
+ entry.pAbilities.push({ abilityType: "element", index: i, value, haveValue, isaux });
1036
+ }
1037
+ } else {
1038
+ const entry = table.get(uiName);
1039
+ if (!entry) continue;
1040
+ const code = rec["code"] !== undefined ? String(rec["code"]) : "";
1041
+ let index = -1;
1042
+ if (abilityType === "player") index = (PF as Record<string, number>)[code] ?? -1;
1043
+ else if (abilityType === "object") index = (OF as Record<string, number>)[code] ?? -1;
1044
+ if (index < 0) continue;
1045
+ entry.pAbilities.push({ abilityType, index, value, haveValue, isaux });
1046
+ }
1047
+ }
1048
+ }
1049
+
1050
+ /**
1051
+ * One config per pack-records object, so every screen shares the SAME renderer
1052
+ * table. Upstream's renderers are file-scope globals that
1053
+ * ui_entry_renderer_customize mutates in place; if each caller rebuilt its own
1054
+ * copy, an `entry-renderer:` pref line would change one screen and not the next.
1055
+ */
1056
+ const UI_ENTRY_CONFIG_CACHE = new WeakMap<UiEntryPackRecords, UiEntryConfig>();
1057
+
1058
+ /**
1059
+ * Build the whole ui_entry config from the compiled pack records, memoised on
1060
+ * the records object (see UI_ENTRY_CONFIG_CACHE).
1061
+ */
1062
+ export function buildUiEntryConfig(packs: UiEntryPackRecords): UiEntryConfig {
1063
+ const hit = UI_ENTRY_CONFIG_CACHE.get(packs);
1064
+ if (hit) return hit;
1065
+ const built = buildUiEntryConfigUncached(packs);
1066
+ UI_ENTRY_CONFIG_CACHE.set(packs, built);
1067
+ return built;
1068
+ }
1069
+
1070
+ function buildUiEntryConfigUncached(packs: UiEntryPackRecords): UiEntryConfig {
1071
+ const renderers = buildRenderers(packs.uiEntryRenderer);
1072
+
1073
+ /* The base file's entries become the template pool. */
1074
+ TEMPLATE_LOOKUP = new Map();
1075
+ const baseTable = buildEntries(packs.uiEntryBase, [], renderers);
1076
+ TEMPLATE_LOOKUP = baseTable;
1077
+
1078
+ /* Now build the full table: base entries (templates) plus ui_entry.txt. */
1079
+ const table = buildEntries(packs.uiEntryBase, packs.uiEntry, renderers);
1080
+ TEMPLATE_LOOKUP = table;
1081
+
1082
+ bindObjectProperties(table, packs.objectProperty);
1083
+ bindPlayerProperties(table, packs.playerProperty);
1084
+
1085
+ const entries = [...table.values()].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
1086
+ return { entries, renderers };
1087
+ }
1088
+
1089
+ /* ------------------------------------------------------------------ */
1090
+ /* Iterator (initialize_ui_entry_iterator + cmp_desc_prio) */
1091
+ /* ------------------------------------------------------------------ */
1092
+
1093
+ /** Entries with both categories, ordered by descending sortcategory priority. */
1094
+ function iterateEntries(
1095
+ config: UiEntryConfig,
1096
+ cat0: string,
1097
+ cat1: string,
1098
+ sortCategory: string,
1099
+ ): UiEntry[] {
1100
+ const selected = config.entries.filter(
1101
+ (e) =>
1102
+ !e.templateOnly &&
1103
+ categoryPriority(e, cat0) !== null &&
1104
+ categoryPriority(e, cat1) !== null,
1105
+ );
1106
+ selected.sort((left, right) => {
1107
+ const lp = categoryPriority(left, sortCategory);
1108
+ const rp = categoryPriority(right, sortCategory);
1109
+ if (lp !== null && rp !== null) {
1110
+ if (lp > rp) return -1;
1111
+ if (lp < rp) return 1;
1112
+ return left.name < right.name ? -1 : left.name > right.name ? 1 : 0;
1113
+ }
1114
+ if (lp !== null) return -1;
1115
+ if (rp !== null) return 1;
1116
+ return left.name < right.name ? -1 : left.name > right.name ? 1 : 0;
1117
+ });
1118
+ return selected;
1119
+ }
1120
+
1121
+ /* ------------------------------------------------------------------ */
1122
+ /* is_ui_entry_for_known_rune (ui-entry.c L591) */
1123
+ /* ------------------------------------------------------------------ */
1124
+
1125
+ export function isUiEntryForKnownRune(entry: UiEntry, p: Player): boolean {
1126
+ const objKnown = p.objKnown;
1127
+ for (const op of entry.objProps) {
1128
+ const ind = op.index;
1129
+ switch (op.type) {
1130
+ case OP_STAT:
1131
+ case OP_MOD:
1132
+ if ((objKnown.modifiers[ind] ?? 0) === 0) return false;
1133
+ break;
1134
+ case OP_FLAG:
1135
+ if (!objKnown.flags.has(ind)) return false;
1136
+ break;
1137
+ case OP_IGNORE:
1138
+ case OP_RESIST:
1139
+ case OP_VULN:
1140
+ case OP_IMM:
1141
+ if ((objKnown.elInfo[ind]?.resLevel ?? 0) === 0) return false;
1142
+ break;
1143
+ default:
1144
+ return false;
1145
+ }
1146
+ }
1147
+ for (const pa of entry.pAbilities) {
1148
+ const ind = pa.index;
1149
+ if (pa.abilityType === "player") {
1150
+ continue;
1151
+ } else if (pa.abilityType === "object") {
1152
+ if (!objKnown.flags.has(ind)) return false;
1153
+ } else if (pa.abilityType === "element") {
1154
+ if ((objKnown.elInfo[ind]?.resLevel ?? 0) === 0) return false;
1155
+ } else {
1156
+ return false;
1157
+ }
1158
+ }
1159
+ return true;
1160
+ }
1161
+
1162
+ /* ------------------------------------------------------------------ */
1163
+ /* Timed helpers (ui-entry.c) */
1164
+ /* ------------------------------------------------------------------ */
1165
+
1166
+ /** get_timed_modifier_effect (ui-entry.c L1370): fully self-contained. */
1167
+ function getTimedModifierEffect(p: Player, ind: number): number {
1168
+ switch (ind) {
1169
+ case OBJ_MOD.BLOWS:
1170
+ return p.timed[TMD.BLOODLUST] ? Math.trunc(p.timed[TMD.BLOODLUST]! / 20) : 0;
1171
+ case OBJ_MOD.INFRA:
1172
+ return p.timed[TMD.SINFRA] ? 5 : 0;
1173
+ case OBJ_MOD.SPEED: {
1174
+ let result = p.timed[TMD.FAST] || p.timed[TMD.SPRINT] ? 10 : 0;
1175
+ if (p.timed[TMD.STONESKIN]) result -= 5;
1176
+ if (p.timed[TMD.SLOW]) result -= 10;
1177
+ if (p.timed[TMD.TERROR]) result += 10;
1178
+ return result;
1179
+ }
1180
+ case OBJ_MOD.STEALTH:
1181
+ return p.timed[TMD.STEALTH] ? 10 : 0;
1182
+ default:
1183
+ return 0;
1184
+ }
1185
+ }
1186
+
1187
+ /** modifier_to_skill (ui-entry.c L1317): only TUNNEL -> digging/20 is live. */
1188
+ function modifierToSkill(modind: number): { skill: number; num: number; den: number } {
1189
+ if (modind === OBJ_MOD.TUNNEL) return { skill: SKILL.DIGGING, num: 1, den: 20 };
1190
+ return { skill: -1, num: 1, den: 1 };
1191
+ }
1192
+
1193
+ /* ------------------------------------------------------------------ */
1194
+ /* compute_ui_entry_values_for_object (ui-entry.c L708) */
1195
+ /* ------------------------------------------------------------------ */
1196
+
1197
+ /**
1198
+ * The per-object combined (val, auxval). obj may be null (NOT_PRESENT). p is
1199
+ * used to gate knowledge via p.objKnown. The upstream separate curse-object
1200
+ * iteration is deferred (see the ledger); this reads the object's own
1201
+ * flags/modifiers/el_info, which already fold in merged curse data in the port.
1202
+ *
1203
+ * `fullyKnown` is object_fully_known(obj) (obj-knowledge.c L754), which is the
1204
+ * FIRST route out of both object_flag_is_known (L776) and
1205
+ * object_element_is_known (L799) - upstream calls those two helpers here rather
1206
+ * than reading p->obj_k directly. It is true for gear with no unknown runes,
1207
+ * which for ordinary equipment (a plain torch, soft leather armour, a mundane
1208
+ * weapon) means no runes at all, so every flag and element reads as KNOWN and
1209
+ * the grid prints '.'. Callers that cannot synthesise obj->known leave it false,
1210
+ * the pre-existing p->obj_k-only behaviour. The MOD/STAT case takes no such
1211
+ * route in upstream either (L764: raw p->obj_k->modifiers), and does not here.
1212
+ */
1213
+ export function computeObjectValues(
1214
+ entry: UiEntry,
1215
+ obj: GameObject | null,
1216
+ p: Player,
1217
+ fullyKnown = false,
1218
+ ): { val: number; auxval: number } {
1219
+ if (!obj || entry.objProps.length === 0) {
1220
+ return { val: UI_ENTRY_VALUE_NOT_PRESENT, auxval: UI_ENTRY_VALUE_NOT_PRESENT };
1221
+ }
1222
+ const combiner = combinerFuncs(entry.combinerIndex);
1223
+ const st: CombinerState = { work: null, accum: 0, accumAux: 0 };
1224
+ let first = true;
1225
+ let anyAux = false;
1226
+ let allAux = true;
1227
+
1228
+ for (const op of entry.objProps) {
1229
+ const ind = op.index;
1230
+ let v = 0;
1231
+ let a = 0;
1232
+
1233
+ if (op.isaux) {
1234
+ if (entry.flags & ENTRY_FLAG_TIMED_AUX) continue;
1235
+ anyAux = true;
1236
+ } else {
1237
+ allAux = false;
1238
+ }
1239
+
1240
+ switch (op.type) {
1241
+ case OP_STAT:
1242
+ case OP_MOD:
1243
+ if ((p.objKnown.modifiers[ind] ?? 0) !== 0 || (obj.modifiers[ind] ?? 0) === 0) {
1244
+ v = obj.modifiers[ind] ?? 0;
1245
+ if (v && op.haveValue) v = op.value;
1246
+ } else {
1247
+ v = UI_ENTRY_UNKNOWN_VALUE;
1248
+ a = UI_ENTRY_UNKNOWN_VALUE;
1249
+ }
1250
+ break;
1251
+ case OP_FLAG:
1252
+ /* object_flag_is_known (obj-knowledge.c L773-787). */
1253
+ if (fullyKnown || p.objKnown.flags.has(ind)) {
1254
+ v = obj.flags.has(ind) ? 1 : 0;
1255
+ if (v && op.haveValue) v = op.value;
1256
+ } else {
1257
+ v = UI_ENTRY_UNKNOWN_VALUE;
1258
+ a = UI_ENTRY_UNKNOWN_VALUE;
1259
+ }
1260
+ break;
1261
+ case OP_IGNORE:
1262
+ /* object_element_is_known (obj-knowledge.c L795-809). */
1263
+ if (fullyKnown || (p.objKnown.elInfo[ind]?.resLevel ?? 0) !== 0) {
1264
+ v = ((obj.elInfo[ind]?.flags ?? 0) & EL_INFO_IGNORE) !== 0 ? 1 : 0;
1265
+ if (v && op.haveValue) v = op.value;
1266
+ } else {
1267
+ v = UI_ENTRY_UNKNOWN_VALUE;
1268
+ a = UI_ENTRY_UNKNOWN_VALUE;
1269
+ }
1270
+ break;
1271
+ case OP_RESIST:
1272
+ case OP_VULN:
1273
+ case OP_IMM:
1274
+ /* object_element_is_known (obj-knowledge.c L795-809). */
1275
+ if (fullyKnown || (p.objKnown.elInfo[ind]?.resLevel ?? 0) !== 0) {
1276
+ v = obj.elInfo[ind]?.resLevel ?? 0;
1277
+ if (v && op.haveValue) v = op.value;
1278
+ } else {
1279
+ v = UI_ENTRY_UNKNOWN_VALUE;
1280
+ a = UI_ENTRY_UNKNOWN_VALUE;
1281
+ }
1282
+ break;
1283
+ default:
1284
+ v = 0;
1285
+ break;
1286
+ }
1287
+
1288
+ if (v) {
1289
+ if (op.isaux) {
1290
+ const t = a;
1291
+ a = v;
1292
+ v = t;
1293
+ }
1294
+ if (first) {
1295
+ combiner.init(v, a, st);
1296
+ first = false;
1297
+ } else {
1298
+ combiner.accum(v, a, st);
1299
+ }
1300
+ }
1301
+ }
1302
+
1303
+ if (!first) combiner.finish(st);
1304
+ return {
1305
+ val: allAux ? 0 : st.accum,
1306
+ auxval: anyAux ? st.accumAux : 0,
1307
+ };
1308
+ }
1309
+
1310
+ /* ------------------------------------------------------------------ */
1311
+ /* compute_ui_entry_values_for_player (ui-entry.c L910) */
1312
+ /* ------------------------------------------------------------------ */
1313
+
1314
+ /** UiEntryDeps: seams the port does not carry; each defaults per the ledger. */
1315
+ export interface UiEntryDeps {
1316
+ /**
1317
+ * player_flags_timed(p) (compute L928): the OF flags contributed by active
1318
+ * timed effects. Default: empty (no timed OF-flag dups are ported), except
1319
+ * OF_TRAP_IMMUNE which is added here from p->timed[TMD_TRAPSAFE] directly.
1320
+ */
1321
+ timedObjectFlags?: FlagSet;
1322
+ /**
1323
+ * get_timed_element_effect(p, elem) (compute L1064): 1 if a timed effect
1324
+ * grants a temporary resist to elem. Default () => 0 (temp_resist is not on
1325
+ * the ported timed registry).
1326
+ */
1327
+ timedElementEffect?: (elem: number) => number;
1328
+ /**
1329
+ * player_has(p, PF_*) (compute L945): whether the player has an intrinsic
1330
+ * ability flag. Default reads p.pflags if present, else false.
1331
+ */
1332
+ playerHas?: (flag: number) => boolean;
1333
+ }
1334
+
1335
+ interface ResolvedUiDeps {
1336
+ timedObjectFlags: FlagSet;
1337
+ timedElementEffect: (elem: number) => number;
1338
+ playerHas: (flag: number) => boolean;
1339
+ }
1340
+
1341
+ export function resolveUiDeps(p: Player, deps: UiEntryDeps): ResolvedUiDeps {
1342
+ const timed = deps.timedObjectFlags ?? new FlagSet(OF_SIZE);
1343
+ if (p.timed[TMD.TRAPSAFE]) timed.on(OF.TRAP_IMMUNE);
1344
+ const pflags = (p as unknown as { pflags?: FlagSet }).pflags;
1345
+ return {
1346
+ timedObjectFlags: timed,
1347
+ timedElementEffect: deps.timedElementEffect ?? (() => 0),
1348
+ playerHas: deps.playerHas ?? ((flag: number) => (pflags ? pflags.has(flag) : false)),
1349
+ };
1350
+ }
1351
+
1352
+ export function computePlayerValues(
1353
+ entry: UiEntry,
1354
+ p: Player,
1355
+ deps: ResolvedUiDeps,
1356
+ cache: { untimed: FlagSet },
1357
+ ): { val: number; auxval: number } {
1358
+ const combiner = combinerFuncs(entry.combinerIndex);
1359
+ const st: CombinerState = { work: null, accum: 0, accumAux: 0 };
1360
+ let first = true;
1361
+ const timedAux = (entry.flags & ENTRY_FLAG_TIMED_AUX) !== 0;
1362
+
1363
+ /* init_func for the first contribution, accum_func for the rest (the caller
1364
+ order matches the C, where the shape/skill/infra adds are never first). */
1365
+ const push = (v0: number, a0: number, isaux: boolean): void => {
1366
+ let v = v0;
1367
+ let a = a0;
1368
+ if (isaux) {
1369
+ const t = v;
1370
+ v = a;
1371
+ a = t;
1372
+ }
1373
+ if (first) {
1374
+ combiner.init(v, a, st);
1375
+ first = false;
1376
+ } else {
1377
+ combiner.accum(v, a, st);
1378
+ }
1379
+ };
1380
+
1381
+ for (const pa of entry.pAbilities) {
1382
+ const ind = pa.index;
1383
+ if (timedAux && pa.isaux) continue;
1384
+
1385
+ if (pa.abilityType === "player") {
1386
+ if (!deps.playerHas(ind)) continue;
1387
+ if (pa.haveValue) {
1388
+ push(pa.value, UI_ENTRY_VALUE_NOT_PRESENT, pa.isaux);
1389
+ } else {
1390
+ /* Special-case abilities that bound no value (uival "special"). */
1391
+ if (ind === PF.FAST_SHOT) {
1392
+ /* Needs the equipped launcher + KF_SHOOTS_ARROWS; deferred -> 0. */
1393
+ push(0, 0, pa.isaux);
1394
+ } else if (ind === PF.BRAVERY_30) {
1395
+ push(p.lev >= 30 ? 1 : 0, 0, pa.isaux);
1396
+ }
1397
+ }
1398
+ } else if (pa.abilityType === "object") {
1399
+ let v = cache.untimed.has(ind) ? 1 : 0;
1400
+ let a = timedAux ? (deps.timedObjectFlags.has(ind) ? 1 : 0) : 0;
1401
+ push(v, a, pa.isaux);
1402
+ /* Shape contribution. */
1403
+ const shape = p.shape;
1404
+ if (shape) {
1405
+ v = shape.flags.has(ind) ? 1 : 0;
1406
+ a = 0;
1407
+ if (v && p.objKnown.flags.has(ind)) {
1408
+ push(v, a, pa.isaux);
1409
+ }
1410
+ }
1411
+ } else if (pa.abilityType === "element") {
1412
+ let v = p.race.elInfo[ind]?.resLevel ?? 0;
1413
+ let a = timedAux ? deps.timedElementEffect(ind) : 0;
1414
+ push(v, a, pa.isaux);
1415
+ const shape = p.shape;
1416
+ if (shape) {
1417
+ v = shape.elInfo[ind]?.resLevel ?? 0;
1418
+ a = 0;
1419
+ if (v !== 0 && (p.objKnown.elInfo[ind]?.resLevel ?? 0)) {
1420
+ push(v, a, pa.isaux);
1421
+ }
1422
+ }
1423
+ }
1424
+ }
1425
+
1426
+ /* Stats / modifiers aren't in the ability list; add intrinsic values. */
1427
+ for (const op of entry.objProps) {
1428
+ const ind = op.index;
1429
+ if (op.isaux && timedAux) continue;
1430
+ if (op.type === OP_STAT || op.type === OP_MOD) {
1431
+ const shape = p.shape;
1432
+ let v = shape ? (shape.modifiers[ind] ?? 0) : 0;
1433
+ let a = timedAux ? getTimedModifierEffect(p, ind) : 0;
1434
+ push(v, a, op.isaux);
1435
+ const conv = modifierToSkill(ind);
1436
+ if (conv.skill >= 0) {
1437
+ v = Math.trunc(((p.race.skills[conv.skill] ?? 0) * conv.num) / conv.den);
1438
+ a = 0;
1439
+ push(v, a, op.isaux);
1440
+ }
1441
+ if (ind === OBJ_MOD.INFRA) {
1442
+ v = p.race.infravision;
1443
+ a = 0;
1444
+ push(v, a, op.isaux);
1445
+ }
1446
+ }
1447
+ }
1448
+
1449
+ if (first) {
1450
+ return { val: UI_ENTRY_VALUE_NOT_PRESENT, auxval: UI_ENTRY_VALUE_NOT_PRESENT };
1451
+ }
1452
+ combiner.finish(st);
1453
+ return { val: st.accum, auxval: st.accumAux };
1454
+ }
1455
+
1456
+ /* ------------------------------------------------------------------ */
1457
+ /* Renderer apply DATA (ui-entry-renderers.c) */
1458
+ /* ------------------------------------------------------------------ */
1459
+
1460
+ /** One rendered cell: a symbol and its COLOUR_* index. */
1461
+ export interface UiEntryCell {
1462
+ symbol: string;
1463
+ color: number;
1464
+ }
1465
+
1466
+ /** convert_vanilla_res_level (ui-entry-renderers.c L549). */
1467
+ function convertVanillaResLevel(i: number): number {
1468
+ if (i === UI_ENTRY_UNKNOWN_VALUE) return 4;
1469
+ if (i === UI_ENTRY_VALUE_NOT_PRESENT) return 5;
1470
+ if (i === UI_ENTRY_RESIST0_RES_VUL) return 6;
1471
+ if (i >= 3) return 3;
1472
+ if (i >= 1) return 1;
1473
+ if (i <= -1) return 2;
1474
+ return 0;
1475
+ }
1476
+
1477
+ const COMBINED_EFFECT_TBL: number[][] = [
1478
+ [2, 6, 9, 11, 2, 2, 18],
1479
+ [3, 7, 10, 12, 3, 3, 19],
1480
+ [4, 8, 4, 13, 4, 4, 20],
1481
+ [5, 5, 5, 5, 5, 5, 5],
1482
+ [0, 0, 0, 0, 0, 0, 0],
1483
+ [1, 1, 1, 1, 1, 1, 1],
1484
+ [14, 15, 16, 17, 14, 14, 21],
1485
+ ];
1486
+
1487
+ const COMBINED_LABEL_TBL: number[][] = [
1488
+ [1, 5, 8, 10, 1, 1, 1],
1489
+ [2, 6, 9, 11, 2, 2, 2],
1490
+ [3, 7, 3, 12, 3, 3, 3],
1491
+ [4, 4, 4, 4, 4, 4, 4],
1492
+ [1, 5, 8, 10, 1, 1, 1],
1493
+ [1, 5, 8, 10, 1, 1, 1],
1494
+ [1, 5, 8, 10, 1, 1, 1],
1495
+ ];
1496
+
1497
+ /**
1498
+ * format_int (ui-entry-renderers.c L462): render an integer into nbuf chars
1499
+ * using zero/overflow symbols, optional +1, optional sign. Returns the string.
1500
+ */
1501
+ function formatInt(
1502
+ i: number,
1503
+ addOne: boolean,
1504
+ zero: string,
1505
+ overflow: string,
1506
+ nonneg: boolean,
1507
+ useSign: boolean,
1508
+ nbuf: number,
1509
+ ): string {
1510
+ const digits = "0123456789+- ";
1511
+ const buf = new Array<string>(nbuf).fill("");
1512
+ let j = nbuf - 1;
1513
+ let quot: number;
1514
+ let rem: number;
1515
+
1516
+ if (i === 0 && !addOne) {
1517
+ quot = 0;
1518
+ rem = 0;
1519
+ buf[j] = zero;
1520
+ } else {
1521
+ quot = Math.trunc(i / 10);
1522
+ rem = i % 10;
1523
+ if (addOne) {
1524
+ rem++;
1525
+ if (rem === 10) {
1526
+ rem = 0;
1527
+ quot++;
1528
+ }
1529
+ }
1530
+ buf[j] = digits[rem]!;
1531
+ }
1532
+ j--;
1533
+
1534
+ while (quot > 0 && j >= 0) {
1535
+ rem = quot % 10;
1536
+ quot = Math.trunc(quot / 10);
1537
+ buf[j] = digits[rem]!;
1538
+ j--;
1539
+ }
1540
+
1541
+ if (quot > 0 || (useSign && j === -1)) {
1542
+ if (useSign) {
1543
+ buf[0] = nonneg ? digits[10]! : digits[11]!;
1544
+ j = 1;
1545
+ } else {
1546
+ j = 0;
1547
+ }
1548
+ while (j < nbuf) {
1549
+ buf[j] = overflow;
1550
+ j++;
1551
+ }
1552
+ } else {
1553
+ if (useSign && (i !== 0 || addOne || zero === digits[0])) {
1554
+ buf[j] = nonneg ? digits[10]! : digits[11]!;
1555
+ j--;
1556
+ }
1557
+ while (j >= 0) {
1558
+ buf[j] = digits[12]!;
1559
+ j--;
1560
+ }
1561
+ }
1562
+ return buf.join("");
1563
+ }
1564
+
1565
+ /** Details controlling a render (the char screen always uses these values). */
1566
+ interface RenderDetails {
1567
+ knownRune: boolean;
1568
+ alternateColorFirst: boolean;
1569
+ }
1570
+
1571
+ /** The rendered output of one entry row: cells plus the label colour. */
1572
+ export interface RenderedRow {
1573
+ cells: UiEntryCell[];
1574
+ labelColor: number;
1575
+ labelColorIndex: number;
1576
+ }
1577
+
1578
+ /**
1579
+ * ui_entry_renderer_apply (ui-entry-renderers.c L309), DATA half: for each
1580
+ * (val, aux) pair produce a cell {symbol, color}, and colour the label by the
1581
+ * combined value. The Term drawing (positions, combined cell) is the shell's.
1582
+ */
1583
+ export function applyRenderer(
1584
+ renderer: RendererInfo,
1585
+ vals: number[],
1586
+ auxvals: number[],
1587
+ details: RenderDetails,
1588
+ ): RenderedRow {
1589
+ const backend = renderer.backendIndex;
1590
+ const cells: UiEntryCell[] = [];
1591
+ const combiner = combinerFuncs(renderer.combinerIndex);
1592
+
1593
+ const cellColor = (paletteIndex: number, offset: number): number =>
1594
+ renderer.colors[paletteIndex + offset] ?? 1;
1595
+ const sym = (paletteIndex: number): string => renderer.symbols[paletteIndex] ?? " ";
1596
+
1597
+ if (backend === UI_ENTRY_RENDERER.COMPACT_RESIST_RENDERER_WITH_COMBINED_AUX) {
1598
+ let colorOffset = details.alternateColorFirst ? 22 : 0;
1599
+ for (let i = 0; i < vals.length; i++) {
1600
+ const untimed = convertVanillaResLevel(vals[i]!);
1601
+ const timed = convertVanillaResLevel(auxvals[i]!);
1602
+ const pi = COMBINED_EFFECT_TBL[untimed]![timed]!;
1603
+ cells.push({ symbol: sym(pi), color: cellColor(pi, colorOffset) });
1604
+ colorOffset ^= 22;
1605
+ }
1606
+ const { accum: vc, accumAux: ac } = combiner.vec(vals, auxvals);
1607
+ let labelPI = 0;
1608
+ if (details.knownRune) {
1609
+ labelPI = COMBINED_LABEL_TBL[convertVanillaResLevel(vc)]![convertVanillaResLevel(ac)]!;
1610
+ }
1611
+ return {
1612
+ cells,
1613
+ labelColorIndex: labelPI,
1614
+ labelColor: renderer.labelColors[labelPI] ?? 1,
1615
+ };
1616
+ }
1617
+
1618
+ if (backend === UI_ENTRY_RENDERER.COMPACT_FLAG_RENDERER_WITH_COMBINED_AUX) {
1619
+ let colorOffset = details.alternateColorFirst ? 5 : 0;
1620
+ for (let i = 0; i < vals.length; i++) {
1621
+ let pi = 2;
1622
+ if (vals[i] === UI_ENTRY_UNKNOWN_VALUE) pi = 0;
1623
+ else if (vals[i] === UI_ENTRY_VALUE_NOT_PRESENT) pi = 1;
1624
+ else if (vals[i]) pi = 3;
1625
+ const av = auxvals[i]!;
1626
+ if (av && av !== UI_ENTRY_UNKNOWN_VALUE && av !== UI_ENTRY_VALUE_NOT_PRESENT) {
1627
+ if (vals[i] === 0) pi = 4;
1628
+ }
1629
+ cells.push({ symbol: sym(pi), color: cellColor(pi, colorOffset) });
1630
+ colorOffset ^= 5;
1631
+ }
1632
+ const { accum: vc, accumAux: ac } = combiner.vec(vals, auxvals);
1633
+ let labelPI = 1;
1634
+ if (!details.knownRune) labelPI = 0;
1635
+ else if (vc && vc !== UI_ENTRY_UNKNOWN_VALUE && vc !== UI_ENTRY_VALUE_NOT_PRESENT) labelPI = 2;
1636
+ else if (ac && ac !== UI_ENTRY_UNKNOWN_VALUE && ac !== UI_ENTRY_VALUE_NOT_PRESENT) labelPI = 3;
1637
+ return { cells, labelColorIndex: labelPI, labelColor: renderer.labelColors[labelPI] ?? 1 };
1638
+ }
1639
+
1640
+ if (backend === UI_ENTRY_RENDERER.COMPACT_FLAG_WITH_CANCEL_RENDERER_WITH_COMBINED_AUX) {
1641
+ let colorOffset = details.alternateColorFirst ? 11 : 0;
1642
+ for (let i = 0; i < vals.length; i++) {
1643
+ const v = vals[i]!;
1644
+ const av = auxvals[i]!;
1645
+ let pi: number;
1646
+ if (v === UI_ENTRY_UNKNOWN_VALUE || av === UI_ENTRY_UNKNOWN_VALUE) pi = 0;
1647
+ else if (v === UI_ENTRY_VALUE_NOT_PRESENT && av === UI_ENTRY_VALUE_NOT_PRESENT) pi = 1;
1648
+ else if (av === UI_ENTRY_VALUE_NOT_PRESENT || av === 0) {
1649
+ if (v === UI_ENTRY_VALUE_NOT_PRESENT || v === 0) pi = 2;
1650
+ else if (v > 0) pi = 3;
1651
+ else pi = 4;
1652
+ } else if (av > 0) {
1653
+ if (v === UI_ENTRY_VALUE_NOT_PRESENT || v === 0) pi = 5;
1654
+ else if (v > 0) pi = 6;
1655
+ else pi = 7;
1656
+ } else {
1657
+ if (v === UI_ENTRY_VALUE_NOT_PRESENT || v === 0) pi = 8;
1658
+ else if (v > 0) pi = 9;
1659
+ else pi = 10;
1660
+ }
1661
+ cells.push({ symbol: sym(pi), color: cellColor(pi, colorOffset) });
1662
+ colorOffset ^= 11;
1663
+ }
1664
+ const { accum: vc, accumAux: ac } = combiner.vec(vals, auxvals);
1665
+ let labelPI: number;
1666
+ if (!details.knownRune) labelPI = 0;
1667
+ else if (vc === UI_ENTRY_VALUE_NOT_PRESENT || vc === UI_ENTRY_UNKNOWN_VALUE || vc === 0) {
1668
+ if (ac === UI_ENTRY_VALUE_NOT_PRESENT || ac === UI_ENTRY_UNKNOWN_VALUE || ac === 0) labelPI = 4;
1669
+ else if (ac > 0) labelPI = 6;
1670
+ else labelPI = 2;
1671
+ } else if (vc > 0) {
1672
+ if (ac === UI_ENTRY_VALUE_NOT_PRESENT || ac === UI_ENTRY_UNKNOWN_VALUE || ac >= 0) labelPI = 5;
1673
+ else labelPI = 3;
1674
+ } else labelPI = 1;
1675
+ return { cells, labelColorIndex: labelPI, labelColor: renderer.labelColors[labelPI] ?? 1 };
1676
+ }
1677
+
1678
+ if (backend === UI_ENTRY_RENDERER.NUMERIC_AS_SIGN_RENDERER_WITH_COMBINED_AUX) {
1679
+ let colorOffset = details.alternateColorFirst ? 7 : 0;
1680
+ for (let i = 0; i < vals.length; i++) {
1681
+ const cst: CombinerState = { work: null, accum: 0, accumAux: 0 };
1682
+ combiner.init(vals[i]!, 0, cst);
1683
+ combiner.accum(auxvals[i]!, 0, cst);
1684
+ combiner.finish(cst);
1685
+ let pi: number;
1686
+ if (vals[i] === UI_ENTRY_UNKNOWN_VALUE || (vals[i] === 0 && auxvals[i] === UI_ENTRY_UNKNOWN_VALUE)) {
1687
+ pi = 0;
1688
+ } else if (cst.accum === UI_ENTRY_VALUE_NOT_PRESENT) {
1689
+ pi = 1;
1690
+ } else {
1691
+ pi =
1692
+ (cst.accum > 0 ? 5 : cst.accum < 0 ? 8 : 2) +
1693
+ (auxvals[i]! > 0 ? 1 : auxvals[i]! < 0 ? 2 : 0);
1694
+ }
1695
+ cells.push({ symbol: sym(pi), color: cellColor(pi, colorOffset) });
1696
+ colorOffset ^= 11;
1697
+ }
1698
+ const { accum: vc, accumAux: ac } = combiner.vec(vals, auxvals);
1699
+ let labelPI: number;
1700
+ if (!details.knownRune) labelPI = 0;
1701
+ else {
1702
+ const cst: CombinerState = { work: null, accum: 0, accumAux: 0 };
1703
+ combiner.init(vc, 0, cst);
1704
+ combiner.accum(ac, 0, cst);
1705
+ combiner.finish(cst);
1706
+ if (cst.accum === UI_ENTRY_UNKNOWN_VALUE || cst.accum === UI_ENTRY_VALUE_NOT_PRESENT) labelPI = 1;
1707
+ else labelPI = (cst.accum > 0 ? 4 : cst.accum < 0 ? 7 : 1) + (ac > 0 ? 1 : ac < 0 ? 2 : 0);
1708
+ }
1709
+ return { cells, labelColorIndex: labelPI, labelColor: renderer.labelColors[labelPI] ?? 1 };
1710
+ }
1711
+
1712
+ if (backend === UI_ENTRY_RENDERER.NUMERIC_RENDERER_WITH_COMBINED_AUX) {
1713
+ const nbuf = renderer.ndigit + (renderer.sign === UI_ENTRY_NO_SIGN ? 0 : 1);
1714
+ let colorOffset = details.alternateColorFirst ? 11 : 0;
1715
+ for (let i = 0; i < vals.length; i++) {
1716
+ const cst: CombinerState = { work: null, accum: 0, accumAux: 0 };
1717
+ combiner.init(vals[i]!, 0, cst);
1718
+ combiner.accum(auxvals[i]!, 0, cst);
1719
+ combiner.finish(cst);
1720
+ let pi: number;
1721
+ let text: string;
1722
+ if (vals[i] === UI_ENTRY_UNKNOWN_VALUE || (vals[i] === 0 && auxvals[i] === UI_ENTRY_UNKNOWN_VALUE)) {
1723
+ pi = 0;
1724
+ text = formatInt(0, false, sym(0), sym(0), true, renderer.sign === UI_ENTRY_ALWAYS_SIGN, nbuf);
1725
+ } else if (cst.accum === UI_ENTRY_VALUE_NOT_PRESENT) {
1726
+ pi = 1;
1727
+ text = formatInt(0, false, sym(1), sym(1), true, renderer.sign === UI_ENTRY_ALWAYS_SIGN, nbuf);
1728
+ } else if (cst.accum === 0) {
1729
+ pi = auxvals[i]! > 0 ? 3 : auxvals[i]! < 0 ? 4 : 2;
1730
+ text = formatInt(0, false, sym(pi), sym(pi), true, renderer.sign === UI_ENTRY_ALWAYS_SIGN, nbuf);
1731
+ } else if (cst.accum > 0) {
1732
+ pi = auxvals[i]! > 0 ? 6 : auxvals[i]! < 0 ? 7 : 5;
1733
+ text = formatInt(cst.accum, false, sym(2), sym(5), true, renderer.sign === UI_ENTRY_ALWAYS_SIGN, nbuf);
1734
+ } else {
1735
+ pi = auxvals[i]! > 0 ? 9 : auxvals[i]! < 0 ? 10 : 8;
1736
+ let vv: number;
1737
+ let o: boolean;
1738
+ if (vals[i] === INT_MIN) {
1739
+ vv = -(INT_MIN + 1);
1740
+ o = true;
1741
+ } else {
1742
+ vv = -vals[i]!;
1743
+ o = false;
1744
+ }
1745
+ text = formatInt(vv, o, sym(2), sym(6), false, renderer.sign !== UI_ENTRY_NO_SIGN, nbuf);
1746
+ }
1747
+ cells.push({ symbol: text, color: cellColor(pi, colorOffset) });
1748
+ colorOffset ^= 11;
1749
+ }
1750
+ const { accum: vc, accumAux: ac } = combiner.vec(vals, auxvals);
1751
+ let labelPI: number;
1752
+ if (!details.knownRune) labelPI = 0;
1753
+ else {
1754
+ const cst: CombinerState = { work: null, accum: 0, accumAux: 0 };
1755
+ combiner.init(vc, 0, cst);
1756
+ combiner.accum(ac, 0, cst);
1757
+ combiner.finish(cst);
1758
+ if (cst.accum === UI_ENTRY_UNKNOWN_VALUE || cst.accum === UI_ENTRY_VALUE_NOT_PRESENT) labelPI = 1;
1759
+ else labelPI = (cst.accum > 0 ? 4 : cst.accum < 0 ? 7 : 1) + (ac > 0 ? 1 : ac < 0 ? 2 : 0);
1760
+ }
1761
+ return { cells, labelColorIndex: labelPI, labelColor: renderer.labelColors[labelPI] ?? 1 };
1762
+ }
1763
+
1764
+ if (backend === UI_ENTRY_RENDERER.NUMERIC_RENDERER_WITH_BOOL_AUX) {
1765
+ const nbuf = renderer.ndigit + (renderer.sign === UI_ENTRY_NO_SIGN ? 0 : 1);
1766
+ let colorOffset = details.alternateColorFirst ? 8 : 0;
1767
+ for (let i = 0; i < vals.length; i++) {
1768
+ const v = vals[i]!;
1769
+ const av = auxvals[i]!;
1770
+ const auxOn = av !== 0 && av !== UI_ENTRY_UNKNOWN_VALUE && av !== UI_ENTRY_VALUE_NOT_PRESENT;
1771
+ let pi: number;
1772
+ let text: string;
1773
+ if (v === UI_ENTRY_UNKNOWN_VALUE || (v === 0 && av === UI_ENTRY_UNKNOWN_VALUE)) {
1774
+ pi = 0;
1775
+ text = formatInt(0, false, sym(0), sym(0), true, renderer.sign === UI_ENTRY_ALWAYS_SIGN, nbuf);
1776
+ } else if (v === UI_ENTRY_VALUE_NOT_PRESENT) {
1777
+ pi = 1;
1778
+ text = formatInt(0, false, sym(1), sym(1), true, renderer.sign === UI_ENTRY_ALWAYS_SIGN, nbuf);
1779
+ } else if (v > 0) {
1780
+ pi = auxOn ? 5 : 4;
1781
+ text = formatInt(v, false, sym(2), sym(4), true, renderer.sign === UI_ENTRY_ALWAYS_SIGN, nbuf);
1782
+ } else if (v < 0) {
1783
+ pi = auxOn ? 7 : 6;
1784
+ let vv: number;
1785
+ let o: boolean;
1786
+ if (v === INT_MIN) {
1787
+ vv = -(INT_MIN + 1);
1788
+ o = true;
1789
+ } else {
1790
+ vv = -v;
1791
+ o = false;
1792
+ }
1793
+ text = formatInt(vv, o, sym(2), sym(5), false, renderer.sign !== UI_ENTRY_NO_SIGN, nbuf);
1794
+ } else {
1795
+ const zerosym = auxOn ? 3 : 2;
1796
+ pi = auxOn ? 3 : 2;
1797
+ text = formatInt(0, false, sym(zerosym), sym(4), true, renderer.sign === UI_ENTRY_ALWAYS_SIGN, nbuf);
1798
+ }
1799
+ cells.push({ symbol: text, color: cellColor(pi, colorOffset) });
1800
+ colorOffset ^= 8;
1801
+ }
1802
+ const { accum: vc, accumAux: ac } = combiner.vec(vals, auxvals);
1803
+ const acbool = ac !== 0 && ac !== UI_ENTRY_UNKNOWN_VALUE && ac !== UI_ENTRY_VALUE_NOT_PRESENT;
1804
+ let labelPI: number;
1805
+ if (!details.knownRune) labelPI = 0;
1806
+ else if (vc === 0 || vc === UI_ENTRY_UNKNOWN_VALUE || vc === UI_ENTRY_VALUE_NOT_PRESENT)
1807
+ labelPI = acbool ? 6 : 5;
1808
+ else if (vc > 0) labelPI = acbool ? 2 : 1;
1809
+ else labelPI = acbool ? 4 : 3;
1810
+ return { cells, labelColorIndex: labelPI, labelColor: renderer.labelColors[labelPI] ?? 1 };
1811
+ }
1812
+
1813
+ return { cells, labelColorIndex: 0, labelColor: 1 };
1814
+ }
1815
+
1816
+ /* ------------------------------------------------------------------ */
1817
+ /* Grid assembly (ui-player.c) */
1818
+ /* ------------------------------------------------------------------ */
1819
+
1820
+ /** One row of a character-screen grid panel. */
1821
+ export interface UiGridRow {
1822
+ /** The concrete ui_entry name (e.g. "resist_ui_compact_0<ACID>"). */
1823
+ name: string;
1824
+ /** The 6-char label with trailing ':' (resist panels), or "" (stat panel). */
1825
+ label: string;
1826
+ /** COLOUR_* of the label (coloured by the combined value). */
1827
+ labelColor: number;
1828
+ /** One cell per equipment slot then the player column. */
1829
+ cells: UiEntryCell[];
1830
+ }
1831
+
1832
+ /** One panel: its category key and ordered rows. */
1833
+ export interface UiGridPanel {
1834
+ key: string;
1835
+ rows: UiGridRow[];
1836
+ }
1837
+
1838
+ const STAT_MAX = 5;
1839
+ /** configure_char_sheet region_categories (ui-player.c L187). */
1840
+ const REGION_CATEGORIES = ["resistances", "abilities", "hindrances", "modifiers"] as const;
1841
+
1842
+ function slotObject(state: GameState, slot: number): GameObject | null {
1843
+ const handle = state.actor.player.equipment[slot] ?? 0;
1844
+ return gearGet(state.gear, handle);
1845
+ }
1846
+
1847
+ /**
1848
+ * The label for a resist-panel row: get_ui_entry_label(entry, 6, pad_left) with
1849
+ * the null slot overwritten by ':' (configure_char_sheet L252-253).
1850
+ */
1851
+ function resistRowLabel(entry: UiEntry): string {
1852
+ return `${getUiEntryLabel(entry, 6, true)}:`;
1853
+ }
1854
+
1855
+ /**
1856
+ * characterGrid: the ui-entry grid of the second character screen. Returns the
1857
+ * four resist/ability/hindrance/modifier panels (display_player_flag_info ->
1858
+ * display_resistance_panel) and the stat-modifier panel (display_player_sust_
1859
+ * info). Row ordering matches the priority-sorted ui_entry iterator; each row
1860
+ * has its equipment-slot cells then the player cell, and the combined-coloured
1861
+ * label. The Term draw half (positions, headers, equippy row) is the shell's.
1862
+ */
1863
+ export function characterGrid(
1864
+ state: GameState,
1865
+ config: UiEntryConfig,
1866
+ deps: UiEntryDeps = {},
1867
+ ): { resistPanels: UiGridPanel[]; statModPanel: UiGridPanel } {
1868
+ const p = state.actor.player;
1869
+ const bodyCount = p.body.count;
1870
+ const rd = resolveUiDeps(p, deps);
1871
+ const untimedCache = { untimed: playerFlags(p) };
1872
+
1873
+ const equipment: (GameObject | null)[] = [];
1874
+ for (let i = 0; i < bodyCount; i++) equipment.push(slotObject(state, i));
1875
+
1876
+ /* obj->known, synthesised ONCE per equipped object - upstream caches exactly
1877
+ * this per object across the whole grid (cached_object_data, ui-entry.c
1878
+ * L726-733). object_flag_is_known and object_element_is_known both take
1879
+ * object_fully_known as their first route out (obj-knowledge.c L776, L799),
1880
+ * and mundane gear carries no runes at all, so it IS fully known: a plain
1881
+ * torch, soft leather armour or a mundane weapon must print '.' down every
1882
+ * row. Reading p->obj_k alone (what this did) printed '?' for all of them. */
1883
+ const knownDesc = knownDescOf(state);
1884
+ const objFullyKnown: boolean[] = equipment.map((o) =>
1885
+ o ? objectFullyKnown(o, objectKnownShadow(o, p, state.runeEnv, knownDesc), p, state.runeEnv) : false,
1886
+ );
1887
+
1888
+ const renderRow = (
1889
+ entry: UiEntry,
1890
+ forcePlayerValZero: boolean,
1891
+ withLabel: boolean,
1892
+ ): UiGridRow => {
1893
+ const vals: number[] = [];
1894
+ const auxs: number[] = [];
1895
+ for (let j = 0; j < bodyCount; j++) {
1896
+ const r = computeObjectValues(entry, equipment[j]!, p, objFullyKnown[j] ?? false);
1897
+ vals.push(r.val);
1898
+ auxs.push(r.auxval);
1899
+ }
1900
+ const pr = computePlayerValues(entry, p, rd, untimedCache);
1901
+ vals.push(forcePlayerValZero ? 0 : pr.val);
1902
+ auxs.push(pr.auxval);
1903
+
1904
+ const renderer = config.renderers[entry.rendererIndex - 1];
1905
+ const knownRune = withLabel ? isUiEntryForKnownRune(entry, p) : true;
1906
+ const rendered = renderer
1907
+ ? applyRenderer(renderer, vals, auxs, { knownRune, alternateColorFirst: false })
1908
+ : { cells: [], labelColor: 1, labelColorIndex: 0 };
1909
+ return {
1910
+ name: entry.name,
1911
+ label: withLabel ? resistRowLabel(entry) : "",
1912
+ labelColor: rendered.labelColor,
1913
+ cells: rendered.cells,
1914
+ };
1915
+ };
1916
+
1917
+ /* Four resist regions (display_resistance_panel per region). */
1918
+ const region0Row = 2 + STAT_MAX;
1919
+ const resistPanels: UiGridPanel[] = [];
1920
+ for (const cat of REGION_CATEGORIES) {
1921
+ const iter = iterateEntries(config, "CHAR_SCREEN1", cat, cat);
1922
+ /* configure_char_sheet row cap: fit in 24 rows, one blank before prompt. */
1923
+ let n = iter.length;
1924
+ if (n + 2 + region0Row > 22) n = 20 - region0Row;
1925
+ const rows: UiGridRow[] = [];
1926
+ for (let i = 0; i < n; i++) rows.push(renderRow(iter[i]!, false, true));
1927
+ resistPanels.push({ key: cat, rows });
1928
+ }
1929
+
1930
+ /* Stat-modifier panel (display_player_sust_info): stat_mod entries, player
1931
+ column shows only the sustain (val forced to 0), no label drawn. */
1932
+ const statIter = iterateEntries(config, "CHAR_SCREEN1", "stat_modifiers", "stat_modifiers");
1933
+ const nStat = statIter.length > STAT_MAX ? STAT_MAX : statIter.length;
1934
+ const statRows: UiGridRow[] = [];
1935
+ for (let i = 0; i < nStat; i++) statRows.push(renderRow(statIter[i]!, true, false));
1936
+
1937
+ return { resistPanels, statModPanel: { key: "stat_modifiers", rows: statRows } };
1938
+ }
1939
+
1940
+ /* ------------------------------------------------------------------ */
1941
+ /* Equip-cmp support (ui-equip-cmp.c initialize_summary / */
1942
+ /* compute_player_and_equipment_values): shared plumbing the */
1943
+ /* equip-cmp.ts model needs but that lives on the private UiEntry / */
1944
+ /* RendererInfo shapes, so it is exposed here rather than duplicated. */
1945
+ /* ------------------------------------------------------------------ */
1946
+
1947
+ /** initialize_summary's five property categories (L2394), each intersected
1948
+ * with category "EQUIPCMP_SCREEN" (the equip-cmp screen's own category tag,
1949
+ * distinct from the character screen's "CHAR_SCREEN1"). */
1950
+ const EQUIPCMP_CATEGORIES = [...REGION_CATEGORIES, "stat_modifiers"] as const;
1951
+
1952
+ /** One equip-cmp property category and its ordered (priority-sorted) entries. */
1953
+ export interface EquipCmpCategory {
1954
+ key: (typeof EQUIPCMP_CATEGORIES)[number];
1955
+ entries: UiEntry[];
1956
+ }
1957
+
1958
+ /**
1959
+ * The equip-cmp screen's property columns (initialize_summary L2434-2469):
1960
+ * the same five categories as the character screen's resist/ability/
1961
+ * hindrance/modifier/stat-modifier panels, but scoped to "EQUIPCMP_SCREEN"
1962
+ * instead of "CHAR_SCREEN1".
1963
+ */
1964
+ export function equipCmpCategories(config: UiEntryConfig): EquipCmpCategory[] {
1965
+ return EQUIPCMP_CATEGORIES.map((cat) => ({
1966
+ key: cat,
1967
+ entries: iterateEntries(config, "EQUIPCMP_SCREEN", cat, cat),
1968
+ }));
1969
+ }
1970
+
1971
+ /** get_ui_entry_label(entry, nproplab + 1, true) with nproplab hardwired to 2
1972
+ * (ui-equip-cmp.c initialize_summary L2421): the equip-cmp column header. */
1973
+ export function equipCmpColumnLabel(entry: UiEntry): string {
1974
+ return getUiEntryLabel(entry, 3, true);
1975
+ }
1976
+
1977
+ /**
1978
+ * get_ui_entry_label(entry, 4, false) - the three-character label the easy
1979
+ * filter matches a 3-character code against (ui-equip-cmp.c:1345). Only the
1980
+ * stat modifiers have distinct 3-char labels; the comparison is exact over all
1981
+ * three characters, pad included, exactly as the C compares wce[0..2].
1982
+ */
1983
+ export function equipCmpFilterLabel3(entry: UiEntry): string {
1984
+ return getUiEntryLabel(entry, 4, false);
1985
+ }
1986
+
1987
+ /**
1988
+ * compute_player_and_equipment_values's per-property accumulation (ui-equip-
1989
+ * cmp.c L2279), condensed to the vectorized form combineValues already uses:
1990
+ * combine the player's own value with every equipped item's value for one
1991
+ * property entry into the equip-cmp "@" row's single combined (val, auxval).
1992
+ * Uses the entry's own (already-resolved) combinerIndex rather than looking
1993
+ * it up via the renderer - computePlayerValues does the same (L1323).
1994
+ */
1995
+ export function combineEntryValues(
1996
+ entry: UiEntry,
1997
+ vals: number[],
1998
+ auxs: number[],
1999
+ ): { accum: number; accumAux: number } {
2000
+ return combinerFuncs(entry.combinerIndex).vec(vals, auxs);
2001
+ }
2002
+
2003
+ /* ------------------------------------------------------------------ */
2004
+ /* Renderer palette accessors (ui-entry-renderers.c L188-432) */
2005
+ /* ------------------------------------------------------------------ */
2006
+
2007
+ /**
2008
+ * convert_attrs_to_chars (ui-entry-renderers.c L1327-1351): the palette as the
2009
+ * colour-index characters a pref file writes. An attr outside the basic range
2010
+ * is written as 'w', not skipped.
2011
+ */
2012
+ function attrsToChars(attrs: readonly number[]): string {
2013
+ let out = "";
2014
+ for (const a of attrs) {
2015
+ out += a >= 0 && a < BASIC_COLORS ? (COLOR_TABLE[a]?.char ?? "w") : "w";
2016
+ }
2017
+ return out;
2018
+ }
2019
+
2020
+ /**
2021
+ * One `entry-renderer:` line's four fields, as dump_ui_entry_renderers reads
2022
+ * them through ui_entry_renderer_get_name / _get_colors / _get_label_colors /
2023
+ * _get_symbols over [ui_entry_renderer_get_min_index(),
2024
+ * ui_entry_renderer_get_index_limit()) - which is 1-based, so index 0 of the
2025
+ * port's array is renderer 1.
2026
+ */
2027
+ export interface UiEntryRendererRow {
2028
+ name: string;
2029
+ colors: string;
2030
+ labelColors: string;
2031
+ symbols: string;
2032
+ }
2033
+
2034
+ /** The rows dump_ui_entry_renderers writes, in renderer-index order. */
2035
+ export function uiEntryRendererRows(config: UiEntryConfig): UiEntryRendererRow[] {
2036
+ return config.renderers.map((r) => ({
2037
+ name: r.name,
2038
+ colors: attrsToChars(r.colors),
2039
+ labelColors: attrsToChars(r.labelColors),
2040
+ symbols: r.symbols,
2041
+ }));
2042
+ }
2043
+
2044
+ /**
2045
+ * ui_entry_renderer_customize (ui-entry-renderers.c L331-370): overwrite a
2046
+ * renderer's palettes from the colour-index / symbol strings a pref file
2047
+ * carries. Each string is truncated to the palette length it is replacing (the
2048
+ * C's `length < ncolors ? length : ncolors`), so a short string leaves the tail
2049
+ * as the gamedata built it. A null argument leaves that palette alone - which
2050
+ * is what the `*` field in an `entry-renderer:` line means.
2051
+ *
2052
+ * Returns false when the name is not a configured renderer (the C's nonzero
2053
+ * return, which parse_prefs_entry_renderer turns into INVALID_VALUE).
2054
+ */
2055
+ export function uiEntryRendererCustomize(
2056
+ config: UiEntryConfig,
2057
+ name: string,
2058
+ colors: string | null,
2059
+ labelColors: string | null,
2060
+ symbols: string | null,
2061
+ ): boolean {
2062
+ const r = config.renderers.find((x) => x.name === name);
2063
+ if (!r) return false;
2064
+ const overlay = (dst: number[], src: string): void => {
2065
+ const n = Math.min(src.length, dst.length);
2066
+ for (let i = 0; i < n; i++) dst[i] = colorCharToAttr(src[i]!);
2067
+ };
2068
+ if (colors !== null) overlay(r.colors, colors);
2069
+ if (labelColors !== null) overlay(r.labelColors, labelColors);
2070
+ if (symbols !== null) {
2071
+ const n = Math.min(symbols.length, r.symbols.length);
2072
+ r.symbols = symbols.slice(0, n) + r.symbols.slice(n);
2073
+ }
2074
+ return true;
2075
+ }