@datamoc/mw_games 0.1.1

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 (425) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +327 -0
  3. package/dist/actors/Advancement.d.ts +73 -0
  4. package/dist/actors/Advancement.d.ts.map +1 -0
  5. package/dist/actors/Advancement.js +98 -0
  6. package/dist/actors/Advancement.js.map +1 -0
  7. package/dist/actors/Affix.d.ts +44 -0
  8. package/dist/actors/Affix.d.ts.map +1 -0
  9. package/dist/actors/Affix.js +35 -0
  10. package/dist/actors/Affix.js.map +1 -0
  11. package/dist/actors/Appearances.d.ts +36 -0
  12. package/dist/actors/Appearances.d.ts.map +1 -0
  13. package/dist/actors/Appearances.js +50 -0
  14. package/dist/actors/Appearances.js.map +1 -0
  15. package/dist/actors/Charges.d.ts +31 -0
  16. package/dist/actors/Charges.d.ts.map +1 -0
  17. package/dist/actors/Charges.js +35 -0
  18. package/dist/actors/Charges.js.map +1 -0
  19. package/dist/actors/Equipment.d.ts +40 -0
  20. package/dist/actors/Equipment.d.ts.map +1 -0
  21. package/dist/actors/Equipment.js +57 -0
  22. package/dist/actors/Equipment.js.map +1 -0
  23. package/dist/actors/Inventory.d.ts +50 -0
  24. package/dist/actors/Inventory.d.ts.map +1 -0
  25. package/dist/actors/Inventory.js +56 -0
  26. package/dist/actors/Inventory.js.map +1 -0
  27. package/dist/actors/ItemState.d.ts +21 -0
  28. package/dist/actors/ItemState.d.ts.map +1 -0
  29. package/dist/actors/ItemState.js +34 -0
  30. package/dist/actors/ItemState.js.map +1 -0
  31. package/dist/actors/Loot.d.ts +24 -0
  32. package/dist/actors/Loot.d.ts.map +1 -0
  33. package/dist/actors/Loot.js +14 -0
  34. package/dist/actors/Loot.js.map +1 -0
  35. package/dist/actors/Progression.d.ts +30 -0
  36. package/dist/actors/Progression.d.ts.map +1 -0
  37. package/dist/actors/Progression.js +39 -0
  38. package/dist/actors/Progression.js.map +1 -0
  39. package/dist/actors/Resource.d.ts +23 -0
  40. package/dist/actors/Resource.d.ts.map +1 -0
  41. package/dist/actors/Resource.js +28 -0
  42. package/dist/actors/Resource.js.map +1 -0
  43. package/dist/actors/Scaling.d.ts +22 -0
  44. package/dist/actors/Scaling.d.ts.map +1 -0
  45. package/dist/actors/Scaling.js +9 -0
  46. package/dist/actors/Scaling.js.map +1 -0
  47. package/dist/actors/Shop.d.ts +25 -0
  48. package/dist/actors/Shop.d.ts.map +1 -0
  49. package/dist/actors/Shop.js +33 -0
  50. package/dist/actors/Shop.js.map +1 -0
  51. package/dist/actors/SkillPoints.d.ts +45 -0
  52. package/dist/actors/SkillPoints.d.ts.map +1 -0
  53. package/dist/actors/SkillPoints.js +58 -0
  54. package/dist/actors/SkillPoints.js.map +1 -0
  55. package/dist/actors/StatBlock.d.ts +52 -0
  56. package/dist/actors/StatBlock.d.ts.map +1 -0
  57. package/dist/actors/StatBlock.js +80 -0
  58. package/dist/actors/StatBlock.js.map +1 -0
  59. package/dist/actors/StatusEffect.d.ts +38 -0
  60. package/dist/actors/StatusEffect.d.ts.map +1 -0
  61. package/dist/actors/StatusEffect.js +28 -0
  62. package/dist/actors/StatusEffect.js.map +1 -0
  63. package/dist/actors/craft.d.ts +26 -0
  64. package/dist/actors/craft.d.ts.map +1 -0
  65. package/dist/actors/craft.js +34 -0
  66. package/dist/actors/craft.js.map +1 -0
  67. package/dist/actors/index.d.ts +33 -0
  68. package/dist/actors/index.d.ts.map +1 -0
  69. package/dist/actors/index.js +18 -0
  70. package/dist/actors/index.js.map +1 -0
  71. package/dist/actors/skillCheck.d.ts +13 -0
  72. package/dist/actors/skillCheck.d.ts.map +1 -0
  73. package/dist/actors/skillCheck.js +16 -0
  74. package/dist/actors/skillCheck.js.map +1 -0
  75. package/dist/assets/index.d.ts +37 -0
  76. package/dist/assets/index.d.ts.map +1 -0
  77. package/dist/assets/index.js +62 -0
  78. package/dist/assets/index.js.map +1 -0
  79. package/dist/audio/Music.d.ts +22 -0
  80. package/dist/audio/Music.d.ts.map +1 -0
  81. package/dist/audio/Music.js +67 -0
  82. package/dist/audio/Music.js.map +1 -0
  83. package/dist/audio/Playable.d.ts +16 -0
  84. package/dist/audio/Playable.d.ts.map +1 -0
  85. package/dist/audio/Playable.js +6 -0
  86. package/dist/audio/Playable.js.map +1 -0
  87. package/dist/audio/Sound.d.ts +23 -0
  88. package/dist/audio/Sound.d.ts.map +1 -0
  89. package/dist/audio/Sound.js +30 -0
  90. package/dist/audio/Sound.js.map +1 -0
  91. package/dist/audio/index.d.ts +7 -0
  92. package/dist/audio/index.d.ts.map +1 -0
  93. package/dist/audio/index.js +4 -0
  94. package/dist/audio/index.js.map +1 -0
  95. package/dist/battle/BattleAI.d.ts +24 -0
  96. package/dist/battle/BattleAI.d.ts.map +1 -0
  97. package/dist/battle/BattleAI.js +47 -0
  98. package/dist/battle/BattleAI.js.map +1 -0
  99. package/dist/battle/Evolution.d.ts +22 -0
  100. package/dist/battle/Evolution.d.ts.map +1 -0
  101. package/dist/battle/Evolution.js +25 -0
  102. package/dist/battle/Evolution.js.map +1 -0
  103. package/dist/battle/Field.d.ts +25 -0
  104. package/dist/battle/Field.d.ts.map +1 -0
  105. package/dist/battle/Field.js +31 -0
  106. package/dist/battle/Field.js.map +1 -0
  107. package/dist/battle/Hooks.d.ts +29 -0
  108. package/dist/battle/Hooks.d.ts.map +1 -0
  109. package/dist/battle/Hooks.js +20 -0
  110. package/dist/battle/Hooks.js.map +1 -0
  111. package/dist/battle/Move.d.ts +32 -0
  112. package/dist/battle/Move.d.ts.map +1 -0
  113. package/dist/battle/Move.js +10 -0
  114. package/dist/battle/Move.js.map +1 -0
  115. package/dist/battle/Party.d.ts +21 -0
  116. package/dist/battle/Party.d.ts.map +1 -0
  117. package/dist/battle/Party.js +49 -0
  118. package/dist/battle/Party.js.map +1 -0
  119. package/dist/battle/Species.d.ts +40 -0
  120. package/dist/battle/Species.d.ts.map +1 -0
  121. package/dist/battle/Species.js +31 -0
  122. package/dist/battle/Species.js.map +1 -0
  123. package/dist/battle/StatStages.d.ts +38 -0
  124. package/dist/battle/StatStages.d.ts.map +1 -0
  125. package/dist/battle/StatStages.js +50 -0
  126. package/dist/battle/StatStages.js.map +1 -0
  127. package/dist/battle/TypeMatrix.d.ts +14 -0
  128. package/dist/battle/TypeMatrix.d.ts.map +1 -0
  129. package/dist/battle/TypeMatrix.js +24 -0
  130. package/dist/battle/TypeMatrix.js.map +1 -0
  131. package/dist/battle/index.d.ts +16 -0
  132. package/dist/battle/index.d.ts.map +1 -0
  133. package/dist/battle/index.js +10 -0
  134. package/dist/battle/index.js.map +1 -0
  135. package/dist/board/Classics.d.ts +123 -0
  136. package/dist/board/Classics.d.ts.map +1 -0
  137. package/dist/board/Classics.js +260 -0
  138. package/dist/board/Classics.js.map +1 -0
  139. package/dist/board/Engine.d.ts +23 -0
  140. package/dist/board/Engine.d.ts.map +1 -0
  141. package/dist/board/Engine.js +87 -0
  142. package/dist/board/Engine.js.map +1 -0
  143. package/dist/board/Tactics.d.ts +46 -0
  144. package/dist/board/Tactics.d.ts.map +1 -0
  145. package/dist/board/Tactics.js +108 -0
  146. package/dist/board/Tactics.js.map +1 -0
  147. package/dist/board/chess.d.ts +67 -0
  148. package/dist/board/chess.d.ts.map +1 -0
  149. package/dist/board/chess.js +439 -0
  150. package/dist/board/chess.js.map +1 -0
  151. package/dist/board/index.d.ts +9 -0
  152. package/dist/board/index.d.ts.map +1 -0
  153. package/dist/board/index.js +5 -0
  154. package/dist/board/index.js.map +1 -0
  155. package/dist/core/Achievements.d.ts +53 -0
  156. package/dist/core/Achievements.d.ts.map +1 -0
  157. package/dist/core/Achievements.js +80 -0
  158. package/dist/core/Achievements.js.map +1 -0
  159. package/dist/core/Collection.d.ts +46 -0
  160. package/dist/core/Collection.d.ts.map +1 -0
  161. package/dist/core/Collection.js +61 -0
  162. package/dist/core/Collection.js.map +1 -0
  163. package/dist/core/Game.d.ts +115 -0
  164. package/dist/core/Game.d.ts.map +1 -0
  165. package/dist/core/Game.js +236 -0
  166. package/dist/core/Game.js.map +1 -0
  167. package/dist/core/Hex.d.ts +45 -0
  168. package/dist/core/Hex.d.ts.map +1 -0
  169. package/dist/core/Hex.js +120 -0
  170. package/dist/core/Hex.js.map +1 -0
  171. package/dist/core/Input.d.ts +41 -0
  172. package/dist/core/Input.d.ts.map +1 -0
  173. package/dist/core/Input.js +132 -0
  174. package/dist/core/Input.js.map +1 -0
  175. package/dist/core/Log.d.ts +39 -0
  176. package/dist/core/Log.d.ts.map +1 -0
  177. package/dist/core/Log.js +50 -0
  178. package/dist/core/Log.js.map +1 -0
  179. package/dist/core/Random.d.ts +64 -0
  180. package/dist/core/Random.d.ts.map +1 -0
  181. package/dist/core/Random.js +178 -0
  182. package/dist/core/Random.js.map +1 -0
  183. package/dist/core/Replay.d.ts +71 -0
  184. package/dist/core/Replay.d.ts.map +1 -0
  185. package/dist/core/Replay.js +102 -0
  186. package/dist/core/Replay.js.map +1 -0
  187. package/dist/core/Save.d.ts +52 -0
  188. package/dist/core/Save.d.ts.map +1 -0
  189. package/dist/core/Save.js +81 -0
  190. package/dist/core/Save.js.map +1 -0
  191. package/dist/core/Scene.d.ts +40 -0
  192. package/dist/core/Scene.d.ts.map +1 -0
  193. package/dist/core/Scene.js +56 -0
  194. package/dist/core/Scene.js.map +1 -0
  195. package/dist/core/SceneStack.d.ts +37 -0
  196. package/dist/core/SceneStack.d.ts.map +1 -0
  197. package/dist/core/SceneStack.js +67 -0
  198. package/dist/core/SceneStack.js.map +1 -0
  199. package/dist/core/Signal.d.ts +24 -0
  200. package/dist/core/Signal.d.ts.map +1 -0
  201. package/dist/core/Signal.js +41 -0
  202. package/dist/core/Signal.js.map +1 -0
  203. package/dist/core/index.d.ts +23 -0
  204. package/dist/core/index.d.ts.map +1 -0
  205. package/dist/core/index.js +14 -0
  206. package/dist/core/index.js.map +1 -0
  207. package/dist/i18n/index.d.ts +51 -0
  208. package/dist/i18n/index.d.ts.map +1 -0
  209. package/dist/i18n/index.js +74 -0
  210. package/dist/i18n/index.js.map +1 -0
  211. package/dist/index.d.ts +22 -0
  212. package/dist/index.d.ts.map +1 -0
  213. package/dist/index.js +22 -0
  214. package/dist/index.js.map +1 -0
  215. package/dist/mw_games.global.js +993 -0
  216. package/dist/render/ActorAnimator.d.ts +60 -0
  217. package/dist/render/ActorAnimator.d.ts.map +1 -0
  218. package/dist/render/ActorAnimator.js +76 -0
  219. package/dist/render/ActorAnimator.js.map +1 -0
  220. package/dist/render/AnimatedSprite.d.ts +57 -0
  221. package/dist/render/AnimatedSprite.d.ts.map +1 -0
  222. package/dist/render/AnimatedSprite.js +105 -0
  223. package/dist/render/AnimatedSprite.js.map +1 -0
  224. package/dist/render/Autotile.d.ts +42 -0
  225. package/dist/render/Autotile.d.ts.map +1 -0
  226. package/dist/render/Autotile.js +117 -0
  227. package/dist/render/Autotile.js.map +1 -0
  228. package/dist/render/Camera.d.ts +88 -0
  229. package/dist/render/Camera.d.ts.map +1 -0
  230. package/dist/render/Camera.js +145 -0
  231. package/dist/render/Camera.js.map +1 -0
  232. package/dist/render/ColorTransformBatcher.d.ts +57 -0
  233. package/dist/render/ColorTransformBatcher.d.ts.map +1 -0
  234. package/dist/render/ColorTransformBatcher.js +212 -0
  235. package/dist/render/ColorTransformBatcher.js.map +1 -0
  236. package/dist/render/LayeredSprite.d.ts +27 -0
  237. package/dist/render/LayeredSprite.d.ts.map +1 -0
  238. package/dist/render/LayeredSprite.js +53 -0
  239. package/dist/render/LayeredSprite.js.map +1 -0
  240. package/dist/render/Projectile.d.ts +37 -0
  241. package/dist/render/Projectile.d.ts.map +1 -0
  242. package/dist/render/Projectile.js +50 -0
  243. package/dist/render/Projectile.js.map +1 -0
  244. package/dist/render/SpriteSheet.d.ts +38 -0
  245. package/dist/render/SpriteSheet.d.ts.map +1 -0
  246. package/dist/render/SpriteSheet.js +79 -0
  247. package/dist/render/SpriteSheet.js.map +1 -0
  248. package/dist/render/TileMap.d.ts +188 -0
  249. package/dist/render/TileMap.d.ts.map +1 -0
  250. package/dist/render/TileMap.js +488 -0
  251. package/dist/render/TileMap.js.map +1 -0
  252. package/dist/render/TintedSprite.d.ts +47 -0
  253. package/dist/render/TintedSprite.d.ts.map +1 -0
  254. package/dist/render/TintedSprite.js +173 -0
  255. package/dist/render/TintedSprite.js.map +1 -0
  256. package/dist/render/index.d.ts +18 -0
  257. package/dist/render/index.d.ts.map +1 -0
  258. package/dist/render/index.js +11 -0
  259. package/dist/render/index.js.map +1 -0
  260. package/dist/roguelike/Blob.d.ts +46 -0
  261. package/dist/roguelike/Blob.d.ts.map +1 -0
  262. package/dist/roguelike/Blob.js +98 -0
  263. package/dist/roguelike/Blob.js.map +1 -0
  264. package/dist/roguelike/Boss.d.ts +67 -0
  265. package/dist/roguelike/Boss.d.ts.map +1 -0
  266. package/dist/roguelike/Boss.js +114 -0
  267. package/dist/roguelike/Boss.js.map +1 -0
  268. package/dist/roguelike/Combat.d.ts +23 -0
  269. package/dist/roguelike/Combat.d.ts.map +1 -0
  270. package/dist/roguelike/Combat.js +27 -0
  271. package/dist/roguelike/Combat.js.map +1 -0
  272. package/dist/roguelike/Doors.d.ts +60 -0
  273. package/dist/roguelike/Doors.d.ts.map +1 -0
  274. package/dist/roguelike/Doors.js +102 -0
  275. package/dist/roguelike/Doors.js.map +1 -0
  276. package/dist/roguelike/Elevation.d.ts +26 -0
  277. package/dist/roguelike/Elevation.d.ts.map +1 -0
  278. package/dist/roguelike/Elevation.js +37 -0
  279. package/dist/roguelike/Elevation.js.map +1 -0
  280. package/dist/roguelike/FieldOfView.d.ts +72 -0
  281. package/dist/roguelike/FieldOfView.d.ts.map +1 -0
  282. package/dist/roguelike/FieldOfView.js +134 -0
  283. package/dist/roguelike/FieldOfView.js.map +1 -0
  284. package/dist/roguelike/Level.d.ts +96 -0
  285. package/dist/roguelike/Level.d.ts.map +1 -0
  286. package/dist/roguelike/Level.js +137 -0
  287. package/dist/roguelike/Level.js.map +1 -0
  288. package/dist/roguelike/MonsterAI.d.ts +40 -0
  289. package/dist/roguelike/MonsterAI.d.ts.map +1 -0
  290. package/dist/roguelike/MonsterAI.js +69 -0
  291. package/dist/roguelike/MonsterAI.js.map +1 -0
  292. package/dist/roguelike/Pathfinder.d.ts +82 -0
  293. package/dist/roguelike/Pathfinder.d.ts.map +1 -0
  294. package/dist/roguelike/Pathfinder.js +192 -0
  295. package/dist/roguelike/Pathfinder.js.map +1 -0
  296. package/dist/roguelike/Scheduler.d.ts +45 -0
  297. package/dist/roguelike/Scheduler.d.ts.map +1 -0
  298. package/dist/roguelike/Scheduler.js +82 -0
  299. package/dist/roguelike/Scheduler.js.map +1 -0
  300. package/dist/roguelike/Secrets.d.ts +44 -0
  301. package/dist/roguelike/Secrets.d.ts.map +1 -0
  302. package/dist/roguelike/Secrets.js +64 -0
  303. package/dist/roguelike/Secrets.js.map +1 -0
  304. package/dist/roguelike/Targeting.d.ts +66 -0
  305. package/dist/roguelike/Targeting.d.ts.map +1 -0
  306. package/dist/roguelike/Targeting.js +150 -0
  307. package/dist/roguelike/Targeting.js.map +1 -0
  308. package/dist/roguelike/generate.d.ts +44 -0
  309. package/dist/roguelike/generate.d.ts.map +1 -0
  310. package/dist/roguelike/generate.js +88 -0
  311. package/dist/roguelike/generate.js.map +1 -0
  312. package/dist/roguelike/index.d.ts +23 -0
  313. package/dist/roguelike/index.d.ts.map +1 -0
  314. package/dist/roguelike/index.js +15 -0
  315. package/dist/roguelike/index.js.map +1 -0
  316. package/dist/rpg/Event.d.ts +33 -0
  317. package/dist/rpg/Event.d.ts.map +1 -0
  318. package/dist/rpg/Event.js +19 -0
  319. package/dist/rpg/Event.js.map +1 -0
  320. package/dist/rpg/EventRunner.d.ts +72 -0
  321. package/dist/rpg/EventRunner.d.ts.map +1 -0
  322. package/dist/rpg/EventRunner.js +76 -0
  323. package/dist/rpg/EventRunner.js.map +1 -0
  324. package/dist/rpg/GameState.d.ts +22 -0
  325. package/dist/rpg/GameState.d.ts.map +1 -0
  326. package/dist/rpg/GameState.js +35 -0
  327. package/dist/rpg/GameState.js.map +1 -0
  328. package/dist/rpg/GridMover.d.ts +51 -0
  329. package/dist/rpg/GridMover.d.ts.map +1 -0
  330. package/dist/rpg/GridMover.js +91 -0
  331. package/dist/rpg/GridMover.js.map +1 -0
  332. package/dist/rpg/Quest.d.ts +67 -0
  333. package/dist/rpg/Quest.d.ts.map +1 -0
  334. package/dist/rpg/Quest.js +92 -0
  335. package/dist/rpg/Quest.js.map +1 -0
  336. package/dist/rpg/TiledMap.d.ts +107 -0
  337. package/dist/rpg/TiledMap.d.ts.map +1 -0
  338. package/dist/rpg/TiledMap.js +123 -0
  339. package/dist/rpg/TiledMap.js.map +1 -0
  340. package/dist/rpg/automap.d.ts +40 -0
  341. package/dist/rpg/automap.d.ts.map +1 -0
  342. package/dist/rpg/automap.js +81 -0
  343. package/dist/rpg/automap.js.map +1 -0
  344. package/dist/rpg/index.d.ts +14 -0
  345. package/dist/rpg/index.d.ts.map +1 -0
  346. package/dist/rpg/index.js +8 -0
  347. package/dist/rpg/index.js.map +1 -0
  348. package/dist/stage/DialogueStage.d.ts +75 -0
  349. package/dist/stage/DialogueStage.d.ts.map +1 -0
  350. package/dist/stage/DialogueStage.js +207 -0
  351. package/dist/stage/DialogueStage.js.map +1 -0
  352. package/dist/stage/index.d.ts +7 -0
  353. package/dist/stage/index.d.ts.map +1 -0
  354. package/dist/stage/index.js +4 -0
  355. package/dist/stage/index.js.map +1 -0
  356. package/dist/stage/script.d.ts +111 -0
  357. package/dist/stage/script.d.ts.map +1 -0
  358. package/dist/stage/script.js +133 -0
  359. package/dist/stage/script.js.map +1 -0
  360. package/dist/stage/twee.d.ts +42 -0
  361. package/dist/stage/twee.d.ts.map +1 -0
  362. package/dist/stage/twee.js +169 -0
  363. package/dist/stage/twee.js.map +1 -0
  364. package/dist/ui/IconGrid.d.ts +110 -0
  365. package/dist/ui/IconGrid.d.ts.map +1 -0
  366. package/dist/ui/IconGrid.js +284 -0
  367. package/dist/ui/IconGrid.js.map +1 -0
  368. package/dist/ui/Label.d.ts +26 -0
  369. package/dist/ui/Label.d.ts.map +1 -0
  370. package/dist/ui/Label.js +41 -0
  371. package/dist/ui/Label.js.map +1 -0
  372. package/dist/ui/ListView.d.ts +67 -0
  373. package/dist/ui/ListView.d.ts.map +1 -0
  374. package/dist/ui/ListView.js +167 -0
  375. package/dist/ui/ListView.js.map +1 -0
  376. package/dist/ui/MessageBox.d.ts +66 -0
  377. package/dist/ui/MessageBox.d.ts.map +1 -0
  378. package/dist/ui/MessageBox.js +161 -0
  379. package/dist/ui/MessageBox.js.map +1 -0
  380. package/dist/ui/NinePatch.d.ts +34 -0
  381. package/dist/ui/NinePatch.d.ts.map +1 -0
  382. package/dist/ui/NinePatch.js +45 -0
  383. package/dist/ui/NinePatch.js.map +1 -0
  384. package/dist/ui/VerticalLabel.d.ts +46 -0
  385. package/dist/ui/VerticalLabel.d.ts.map +1 -0
  386. package/dist/ui/VerticalLabel.js +81 -0
  387. package/dist/ui/VerticalLabel.js.map +1 -0
  388. package/dist/ui/Window.d.ts +71 -0
  389. package/dist/ui/Window.d.ts.map +1 -0
  390. package/dist/ui/Window.js +126 -0
  391. package/dist/ui/Window.js.map +1 -0
  392. package/dist/ui/WindowStack.d.ts +40 -0
  393. package/dist/ui/WindowStack.d.ts.map +1 -0
  394. package/dist/ui/WindowStack.js +106 -0
  395. package/dist/ui/WindowStack.js.map +1 -0
  396. package/dist/ui/index.d.ts +18 -0
  397. package/dist/ui/index.d.ts.map +1 -0
  398. package/dist/ui/index.js +10 -0
  399. package/dist/ui/index.js.map +1 -0
  400. package/dist/ui/theme.d.ts +50 -0
  401. package/dist/ui/theme.d.ts.map +1 -0
  402. package/dist/ui/theme.js +36 -0
  403. package/dist/ui/theme.js.map +1 -0
  404. package/dist/world/Encounters.d.ts +20 -0
  405. package/dist/world/Encounters.d.ts.map +1 -0
  406. package/dist/world/Encounters.js +9 -0
  407. package/dist/world/Encounters.js.map +1 -0
  408. package/dist/world/Overworld.d.ts +25 -0
  409. package/dist/world/Overworld.d.ts.map +1 -0
  410. package/dist/world/Overworld.js +26 -0
  411. package/dist/world/Overworld.js.map +1 -0
  412. package/dist/world/TurnClock.d.ts +25 -0
  413. package/dist/world/TurnClock.d.ts.map +1 -0
  414. package/dist/world/TurnClock.js +33 -0
  415. package/dist/world/TurnClock.js.map +1 -0
  416. package/dist/world/World.d.ts +50 -0
  417. package/dist/world/World.d.ts.map +1 -0
  418. package/dist/world/World.js +77 -0
  419. package/dist/world/World.js.map +1 -0
  420. package/dist/world/index.d.ts +8 -0
  421. package/dist/world/index.d.ts.map +1 -0
  422. package/dist/world/index.js +5 -0
  423. package/dist/world/index.js.map +1 -0
  424. package/package.json +76 -0
  425. package/tools/compile-resources.mjs +129 -0
@@ -0,0 +1,50 @@
1
+ import * as Random from '../core/Random.js';
2
+ /**
3
+ * Deals each kind a distinct label from a shuffled copy of the pool - pure, so a game
4
+ * that wants the shuffle scoped (one seed per run, say) wraps it in `Random.withSeed`.
5
+ */
6
+ export function assignAppearances(table) {
7
+ if (table.labels.length < table.kinds.length) {
8
+ throw new Error(`not enough appearances: ${table.kinds.length} kinds but only ${table.labels.length} labels`);
9
+ }
10
+ const pool = [...table.labels];
11
+ for (let i = pool.length - 1; i > 0; i--) {
12
+ const j = Random.int(0, i + 1);
13
+ [pool[i], pool[j]] = [pool[i], pool[j]];
14
+ }
15
+ const out = new Map();
16
+ table.kinds.forEach((kind, index) => out.set(kind, pool[index]));
17
+ return out;
18
+ }
19
+ export class Appearances {
20
+ constructor(tables) {
21
+ this.assigned = new Map();
22
+ this.tables = tables;
23
+ }
24
+ /** the look `kind` wears this run in `category`, drawing the shuffle on first ask */
25
+ appearanceOf(category, kind) {
26
+ let categoryMap = this.assigned.get(category);
27
+ if (!categoryMap) {
28
+ const table = this.tables[category];
29
+ if (!table)
30
+ throw new Error(`no such appearance category: "${category}"`);
31
+ categoryMap = assignAppearances(table);
32
+ this.assigned.set(category, categoryMap);
33
+ }
34
+ const label = categoryMap.get(kind);
35
+ if (label === undefined)
36
+ throw new Error(`"${kind}" is not in appearance category "${category}"`);
37
+ return label;
38
+ }
39
+ toJSON() {
40
+ return { assigned: [...this.assigned].map(([category, map]) => [category, [...map]]) };
41
+ }
42
+ /** rebuilds appearances from save data - the tables themselves are supplied fresh, the same as `QuestLog` definitions */
43
+ static fromJSON(tables, data) {
44
+ const appearances = new Appearances(tables);
45
+ for (const [category, entries] of data.assigned)
46
+ appearances.assigned.set(category, new Map(entries));
47
+ return appearances;
48
+ }
49
+ }
50
+ //# sourceMappingURL=Appearances.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Appearances.js","sourceRoot":"","sources":["../../src/actors/Appearances.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAqB5C;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAsB;IACvD,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CACd,2BAA2B,KAAK,CAAC,KAAK,CAAC,MAAM,mBAAmB,KAAK,CAAC,MAAM,CAAC,MAAM,SAAS,CAC5F,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjE,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,MAAM,OAAO,WAAW;IAIvB,YAAY,MAAuC;QAF3C,aAAQ,GAAG,IAAI,GAAG,EAA+B,CAAC;QAGzD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAED,qFAAqF;IACrF,YAAY,CAAC,QAAgB,EAAE,IAAY;QAC1C,IAAI,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACpC,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,QAAQ,GAAG,CAAC,CAAC;YAC1E,WAAW,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;YACvC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAC1C,CAAC;QACD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,oCAAoC,QAAQ,GAAG,CAAC,CAAC;QAClG,OAAO,KAAK,CAAC;IACd,CAAC;IAED,MAAM;QACL,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACxF,CAAC;IAED,yHAAyH;IACzH,MAAM,CAAC,QAAQ,CACd,MAAuC,EACvC,IAAkD;QAElD,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;QAC5C,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ;YAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QACtG,OAAO,WAAW,CAAC;IACpB,CAAC;CACD"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * A resource that refills on its own as turns pass - a wand's limited charges regenerating
3
+ * one every few turns - distinct from a straight spendable pool (mana spent per cast,
4
+ * restored only by an explicit event, which a `StatBlock` stat already covers on its own).
5
+ * What that alone cannot express is "this refills automatically over time," so `Charges`
6
+ * carries its own regeneration progress instead of leaning on `TurnClock` for it - a charge
7
+ * either has or does not have enough banked turns to regenerate, which is exactly the kind
8
+ * of running total a class holds more naturally than a callback would.
9
+ */
10
+ export interface ChargesOptions {
11
+ /** the most this can ever hold */
12
+ max: number;
13
+ /** starting amount; defaults to `max` (a fresh wand starts full) */
14
+ current?: number;
15
+ /** turns of banked time needed to regenerate one charge */
16
+ regenRate: number;
17
+ }
18
+ export declare class Charges {
19
+ readonly max: number;
20
+ private regenRate;
21
+ private value;
22
+ private progress;
23
+ constructor(options: ChargesOptions);
24
+ get current(): number;
25
+ canAfford(cost: number): boolean;
26
+ /** @returns false, spending nothing, if `cost` is not affordable right now */
27
+ spend(cost: number): boolean;
28
+ /** banks `turns` of regeneration time, converting whole `regenRate`-sized chunks into charges */
29
+ advance(turns?: number): void;
30
+ }
31
+ //# sourceMappingURL=Charges.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Charges.d.ts","sourceRoot":"","sources":["../../src/actors/Charges.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC9B,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IAEZ,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,OAAO;IACnB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAK;IAErB,YAAY,OAAO,EAAE,cAAc,EAIlC;IAED,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE/B;IAED,8EAA8E;IAC9E,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAI3B;IAED,iGAAiG;IACjG,OAAO,CAAC,KAAK,SAAI,GAAG,IAAI,CAWvB;CACD"}
@@ -0,0 +1,35 @@
1
+ export class Charges {
2
+ constructor(options) {
3
+ this.progress = 0;
4
+ this.max = options.max;
5
+ this.regenRate = options.regenRate;
6
+ this.value = options.current ?? options.max;
7
+ }
8
+ get current() {
9
+ return this.value;
10
+ }
11
+ canAfford(cost) {
12
+ return this.value >= cost;
13
+ }
14
+ /** @returns false, spending nothing, if `cost` is not affordable right now */
15
+ spend(cost) {
16
+ if (!this.canAfford(cost))
17
+ return false;
18
+ this.value -= cost;
19
+ return true;
20
+ }
21
+ /** banks `turns` of regeneration time, converting whole `regenRate`-sized chunks into charges */
22
+ advance(turns = 1) {
23
+ if (this.value >= this.max)
24
+ return;
25
+ this.progress += turns;
26
+ while (this.progress >= this.regenRate && this.value < this.max) {
27
+ this.progress -= this.regenRate;
28
+ this.value++;
29
+ }
30
+ //full again: no point banking further progress towards a charge there is no room for
31
+ if (this.value >= this.max)
32
+ this.progress = 0;
33
+ }
34
+ }
35
+ //# sourceMappingURL=Charges.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Charges.js","sourceRoot":"","sources":["../../src/actors/Charges.ts"],"names":[],"mappings":"AAoBA,MAAM,OAAO,OAAO;IAMnB,YAAY,OAAuB;QAF3B,aAAQ,GAAG,CAAC,CAAC;QAGpB,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC;IAC7C,CAAC;IAED,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED,SAAS,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC;IAC3B,CAAC;IAED,8EAA8E;IAC9E,KAAK,CAAC,IAAY;QACjB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACxC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC;QACnB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,iGAAiG;IACjG,OAAO,CAAC,KAAK,GAAG,CAAC;QAChB,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG;YAAE,OAAO;QAEnC,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC;QACvB,OAAO,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACjE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC;YAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACd,CAAC;QAED,qFAAqF;QACrF,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG;YAAE,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;IAC/C,CAAC;CACD"}
@@ -0,0 +1,40 @@
1
+ import type { StatBlock, Modifier } from './StatBlock.ts';
2
+ export interface EquippableItem {
3
+ /** applied to the wearer's StatBlock while equipped, removed together on unequip */
4
+ modifiers?: Modifier[];
5
+ }
6
+ export interface EquipmentOptions<Slot extends string, Item extends EquippableItem> {
7
+ /**
8
+ * Whether whatever is currently in `slot` refuses to come off - a cursed ring, a
9
+ * quest-bound relic. A locked slot also refuses a swap, since swapping starts by
10
+ * removing what is there.
11
+ */
12
+ locked?: (slot: Slot, item: Item) => boolean;
13
+ }
14
+ /**
15
+ * Equipment slots, defined per game rather than fixed by the framework - `'leftHand'` and
16
+ * `'rightHand'`, or `'weapon'` / `'armor'` / `'amulet'`, or a dozen Diablo-style slots.
17
+ * Whatever an item's `modifiers` are, equipping it applies them to the given `StatBlock` and
18
+ * unequipping removes exactly those - tagged by the item itself as their `source`, so two
19
+ * rings of the same kind never remove each other's bonus by mistake.
20
+ */
21
+ export declare class EquipmentSlots<Slot extends string, Item extends EquippableItem> {
22
+ private readonly names;
23
+ private worn;
24
+ private stats;
25
+ private isSlotLocked;
26
+ constructor(slots: readonly Slot[], stats?: StatBlock | null, options?: EquipmentOptions<Slot, Item>);
27
+ get(slot: Slot): Item | undefined;
28
+ /** true when the slot holds something that refuses to come off - check this, since a refused `unequip` is otherwise indistinguishable from an empty slot */
29
+ isLocked(slot: Slot): boolean;
30
+ /**
31
+ * @returns the item that was previously in this slot, if any - or undefined without
32
+ * changing anything when the slot is locked
33
+ */
34
+ equip(slot: Slot, item: Item): Item | undefined;
35
+ /** @returns the removed item, or undefined for an empty slot - or a locked one, which stays put */
36
+ unequip(slot: Slot): Item | undefined;
37
+ get slots(): readonly Slot[];
38
+ private assertSlot;
39
+ }
40
+ //# sourceMappingURL=Equipment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Equipment.d.ts","sourceRoot":"","sources":["../../src/actors/Equipment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1D,MAAM,WAAW,cAAc;IAC9B,oFAAoF;IACpF,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB,CAAC,IAAI,SAAS,MAAM,EAAE,IAAI,SAAS,cAAc;IACjF;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;CAC7C;AAED;;;;;;GAMG;AACH,qBAAa,cAAc,CAAC,IAAI,SAAS,MAAM,EAAE,IAAI,SAAS,cAAc;IAC3E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,IAAI,CAAyB;IACrC,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,YAAY,CAAsC;IAE1D,YAAY,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,KAAK,GAAE,SAAS,GAAG,IAAW,EAAE,OAAO,GAAE,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAM,EAI7G;IAED,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,CAEhC;IAED,4JAA4J;IAC5J,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAG5B;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,CAU9C;IAED,mGAAmG;IACnG,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,CAQpC;IAED,IAAI,KAAK,IAAI,SAAS,IAAI,EAAE,CAE3B;IAED,OAAO,CAAC,UAAU;CAGlB"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Equipment slots, defined per game rather than fixed by the framework - `'leftHand'` and
3
+ * `'rightHand'`, or `'weapon'` / `'armor'` / `'amulet'`, or a dozen Diablo-style slots.
4
+ * Whatever an item's `modifiers` are, equipping it applies them to the given `StatBlock` and
5
+ * unequipping removes exactly those - tagged by the item itself as their `source`, so two
6
+ * rings of the same kind never remove each other's bonus by mistake.
7
+ */
8
+ export class EquipmentSlots {
9
+ constructor(slots, stats = null, options = {}) {
10
+ this.worn = new Map();
11
+ this.names = new Set(slots);
12
+ this.stats = stats;
13
+ this.isSlotLocked = options.locked ?? (() => false);
14
+ }
15
+ get(slot) {
16
+ return this.worn.get(slot);
17
+ }
18
+ /** true when the slot holds something that refuses to come off - check this, since a refused `unequip` is otherwise indistinguishable from an empty slot */
19
+ isLocked(slot) {
20
+ const item = this.worn.get(slot);
21
+ return item !== undefined && this.isSlotLocked(slot, item);
22
+ }
23
+ /**
24
+ * @returns the item that was previously in this slot, if any - or undefined without
25
+ * changing anything when the slot is locked
26
+ */
27
+ equip(slot, item) {
28
+ this.assertSlot(slot);
29
+ if (this.isLocked(slot))
30
+ return undefined;
31
+ const previous = this.unequip(slot);
32
+ this.worn.set(slot, item);
33
+ for (const modifier of item.modifiers ?? []) {
34
+ this.stats?.addModifier({ ...modifier, source: item });
35
+ }
36
+ return previous;
37
+ }
38
+ /** @returns the removed item, or undefined for an empty slot - or a locked one, which stays put */
39
+ unequip(slot) {
40
+ const item = this.worn.get(slot);
41
+ if (!item)
42
+ return undefined;
43
+ if (this.isSlotLocked(slot, item))
44
+ return undefined;
45
+ this.worn.delete(slot);
46
+ this.stats?.removeModifiersFrom(item);
47
+ return item;
48
+ }
49
+ get slots() {
50
+ return [...this.names];
51
+ }
52
+ assertSlot(slot) {
53
+ if (!this.names.has(slot))
54
+ throw new Error(`no such equipment slot: "${slot}"`);
55
+ }
56
+ }
57
+ //# sourceMappingURL=Equipment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Equipment.js","sourceRoot":"","sources":["../../src/actors/Equipment.ts"],"names":[],"mappings":"AAgBA;;;;;;GAMG;AACH,MAAM,OAAO,cAAc;IAM1B,YAAY,KAAsB,EAAE,KAAK,GAAqB,IAAI,EAAE,OAAO,GAAiC,EAAE;QAJtG,SAAI,GAAG,IAAI,GAAG,EAAc,CAAC;QAKpC,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC;IAED,GAAG,CAAC,IAAU;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,4JAA4J;IAC5J,QAAQ,CAAC,IAAU;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5D,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAU,EAAE,IAAU;QAC3B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,SAAS,CAAC;QAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEpC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1B,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;YAC7C,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,mGAAmG;IACnG,OAAO,CAAC,IAAU;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAC;QAC5B,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC;YAAE,OAAO,SAAS,CAAC;QAEpD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,KAAK,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,IAAI,KAAK;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IAEO,UAAU,CAAC,IAAU;QAC5B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,GAAG,CAAC,CAAC;IACjF,CAAC;CACD"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Items a character carries: stacking, weight, and containers within containers.
3
+ *
4
+ * A slot holds a quantity of one kind of item rather than one entry per item, which is what
5
+ * stacking means in practice - forty arrows are one inventory slot, not forty. Weight and
6
+ * capacity are optional: a game that does not track carry weight simply never sets a
7
+ * capacity, and every check trivially passes.
8
+ */
9
+ export interface InventoryItem {
10
+ /** identifies the kind of item; two stackable entries with the same id merge */
11
+ id: string;
12
+ quantity: number;
13
+ stackable?: boolean;
14
+ weight?: number;
15
+ /** an unidentified potion, a cursed ring the player does not yet know is cursed */
16
+ identified?: boolean;
17
+ cursed?: boolean;
18
+ blessed?: boolean;
19
+ /** an enchantment or upgrade level above the item's base, such as a weapon's "+2" */
20
+ level?: number;
21
+ /** a named affix - an enchantment, glyph, augment or curse id from an `AffixTable` */
22
+ affix?: string;
23
+ /** remaining durability; omit for an item that cannot wear out at all */
24
+ durability?: number;
25
+ maxDurability?: number;
26
+ /** a container - a bag, a chest - whose own weight adds to whatever is inside it */
27
+ contents?: Inventory;
28
+ }
29
+ export interface InventoryOptions {
30
+ /** total weight this inventory can hold; omit for no limit */
31
+ capacity?: number;
32
+ }
33
+ export declare class Inventory {
34
+ private slots;
35
+ readonly capacity?: number;
36
+ constructor(options?: InventoryOptions);
37
+ get items(): readonly InventoryItem[];
38
+ get totalWeight(): number;
39
+ private weightOf;
40
+ find(id: string): InventoryItem | undefined;
41
+ /**
42
+ * Adds an item, merging into an existing stack when both are stackable.
43
+ *
44
+ * @returns false when a capacity is set and this would exceed it - nothing is added
45
+ */
46
+ add(item: InventoryItem): boolean;
47
+ /** removes up to `quantity` (default: the whole stack); the slot disappears once empty */
48
+ remove(id: string, quantity?: number): void;
49
+ }
50
+ //# sourceMappingURL=Inventory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Inventory.d.ts","sourceRoot":"","sources":["../../src/actors/Inventory.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,aAAa;IAC7B,gFAAgF;IAChF,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,mFAAmF;IACnF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,qFAAqF;IACrF,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,SAAS;IACrB,OAAO,CAAC,KAAK,CAAuB;IACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,YAAY,OAAO,GAAE,gBAAqB,EAEzC;IAED,IAAI,KAAK,IAAI,SAAS,aAAa,EAAE,CAEpC;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,OAAO,CAAC,QAAQ;IAIhB,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAE1C;IAED;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAehC;IAED,0FAA0F;IAC1F,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAO1C;CACD"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Items a character carries: stacking, weight, and containers within containers.
3
+ *
4
+ * A slot holds a quantity of one kind of item rather than one entry per item, which is what
5
+ * stacking means in practice - forty arrows are one inventory slot, not forty. Weight and
6
+ * capacity are optional: a game that does not track carry weight simply never sets a
7
+ * capacity, and every check trivially passes.
8
+ */
9
+ export class Inventory {
10
+ constructor(options = {}) {
11
+ this.slots = [];
12
+ this.capacity = options.capacity;
13
+ }
14
+ get items() {
15
+ return this.slots;
16
+ }
17
+ get totalWeight() {
18
+ return this.slots.reduce((sum, item) => sum + this.weightOf(item), 0);
19
+ }
20
+ weightOf(item) {
21
+ return (item.weight ?? 0) * item.quantity + (item.contents?.totalWeight ?? 0);
22
+ }
23
+ find(id) {
24
+ return this.slots.find((item) => item.id === id);
25
+ }
26
+ /**
27
+ * Adds an item, merging into an existing stack when both are stackable.
28
+ *
29
+ * @returns false when a capacity is set and this would exceed it - nothing is added
30
+ */
31
+ add(item) {
32
+ if (this.capacity !== undefined && this.totalWeight + this.weightOf(item) > this.capacity) {
33
+ return false;
34
+ }
35
+ if (item.stackable) {
36
+ const existing = this.slots.find((s) => s.id === item.id && s.stackable);
37
+ if (existing) {
38
+ existing.quantity += item.quantity;
39
+ return true;
40
+ }
41
+ }
42
+ this.slots.push({ ...item });
43
+ return true;
44
+ }
45
+ /** removes up to `quantity` (default: the whole stack); the slot disappears once empty */
46
+ remove(id, quantity) {
47
+ const index = this.slots.findIndex((item) => item.id === id);
48
+ if (index === -1)
49
+ return;
50
+ const item = this.slots[index];
51
+ item.quantity -= quantity ?? item.quantity;
52
+ if (item.quantity <= 0)
53
+ this.slots.splice(index, 1);
54
+ }
55
+ }
56
+ //# sourceMappingURL=Inventory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Inventory.js","sourceRoot":"","sources":["../../src/actors/Inventory.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAiCH,MAAM,OAAO,SAAS;IAIrB,YAAY,OAAO,GAAqB,EAAE;QAHlC,UAAK,GAAoB,EAAE,CAAC;QAInC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,CAAC;IAED,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED,IAAI,WAAW;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACvE,CAAC;IAEO,QAAQ,CAAC,IAAmB;QACnC,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,IAAI,CAAC,CAAC,CAAC;IAC/E,CAAC;IAED,IAAI,CAAC,EAAU;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,GAAG,CAAC,IAAmB;QACtB,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3F,OAAO,KAAK,CAAC;QACd,CAAC;QAED,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;YACzE,IAAI,QAAQ,EAAE,CAAC;gBACd,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;gBACnC,OAAO,IAAI,CAAC;YACb,CAAC;QACF,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IACb,CAAC;IAED,0FAA0F;IAC1F,MAAM,CAAC,EAAU,EAAE,QAAiB;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7D,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,OAAO;QAEzB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,QAAQ,IAAI,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;QAC3C,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC;YAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACrD,CAAC;CACD"}
@@ -0,0 +1,21 @@
1
+ import type { InventoryItem } from './Inventory.ts';
2
+ /**
3
+ * The three item-shaped states `Inventory` only had fields for, not behaviour: identification,
4
+ * an enchantment/upgrade level, and durability that wears down with use. Small, focused
5
+ * functions over a plain `InventoryItem` - the same size of primitive `skillCheck` already is -
6
+ * rather than a class, since none of the three need to remember anything beyond the item.
7
+ */
8
+ /** reveals an item's real nature - a potion's true effect, a ring's curse - once identified */
9
+ export declare function identify(item: InventoryItem): void;
10
+ /** raises (or, given a negative delta, lowers) an item's enchantment/upgrade level */
11
+ export declare function enchant(item: InventoryItem, delta: number): number;
12
+ /**
13
+ * Wears an item down by `amount`. An item with no `maxDurability` set cannot wear out at all
14
+ * and this is a no-op - durability is opt-in per item, not a hidden default every item pays for.
15
+ *
16
+ * @returns true once the item's durability has reached zero and it should break
17
+ */
18
+ export declare function damageItem(item: InventoryItem, amount: number): boolean;
19
+ /** restores durability, capped at `maxDurability`; a no-op for an item with none set */
20
+ export declare function repairItem(item: InventoryItem, amount: number): void;
21
+ //# sourceMappingURL=ItemState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ItemState.d.ts","sourceRoot":"","sources":["../../src/actors/ItemState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD;;;;;GAKG;AAEH,+FAA+F;AAC/F,wBAAgB,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAElD;AAED,sFAAsF;AACtF,wBAAgB,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGlE;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAKvE;AAED,wFAAwF;AACxF,wBAAgB,UAAU,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAGpE"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * The three item-shaped states `Inventory` only had fields for, not behaviour: identification,
3
+ * an enchantment/upgrade level, and durability that wears down with use. Small, focused
4
+ * functions over a plain `InventoryItem` - the same size of primitive `skillCheck` already is -
5
+ * rather than a class, since none of the three need to remember anything beyond the item.
6
+ */
7
+ /** reveals an item's real nature - a potion's true effect, a ring's curse - once identified */
8
+ export function identify(item) {
9
+ item.identified = true;
10
+ }
11
+ /** raises (or, given a negative delta, lowers) an item's enchantment/upgrade level */
12
+ export function enchant(item, delta) {
13
+ item.level = (item.level ?? 0) + delta;
14
+ return item.level;
15
+ }
16
+ /**
17
+ * Wears an item down by `amount`. An item with no `maxDurability` set cannot wear out at all
18
+ * and this is a no-op - durability is opt-in per item, not a hidden default every item pays for.
19
+ *
20
+ * @returns true once the item's durability has reached zero and it should break
21
+ */
22
+ export function damageItem(item, amount) {
23
+ if (item.maxDurability === undefined)
24
+ return false;
25
+ item.durability = Math.max(0, (item.durability ?? item.maxDurability) - amount);
26
+ return item.durability <= 0;
27
+ }
28
+ /** restores durability, capped at `maxDurability`; a no-op for an item with none set */
29
+ export function repairItem(item, amount) {
30
+ if (item.maxDurability === undefined)
31
+ return;
32
+ item.durability = Math.min(item.maxDurability, (item.durability ?? item.maxDurability) + amount);
33
+ }
34
+ //# sourceMappingURL=ItemState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ItemState.js","sourceRoot":"","sources":["../../src/actors/ItemState.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,+FAA+F;AAC/F,MAAM,UAAU,QAAQ,CAAC,IAAmB;IAC3C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;AACxB,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,OAAO,CAAC,IAAmB,EAAE,KAAa;IACzD,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC;IACvC,OAAO,IAAI,CAAC,KAAK,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,IAAmB,EAAE,MAAc;IAC7D,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAEnD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,MAAM,CAAC,CAAC;IAChF,OAAO,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,UAAU,CAAC,IAAmB,EAAE,MAAc;IAC7D,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS;QAAE,OAAO;IAC7C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,MAAM,CAAC,CAAC;AAClG,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * A weighted drop table for what a monster leaves behind - the same shape as
3
+ * `mwg/world`'s `EncounterTable`, deliberately: both are "roll whether anything happens at
4
+ * all, then weight-pick which," just naming an item instead of an encounter value. A corpse
5
+ * as a lootable world object needs no code of its own beyond this - it is an `Inventory`
6
+ * placed at the monster's last position, exactly like any other dropped item already is.
7
+ */
8
+ export interface LootEntry {
9
+ id: string;
10
+ weight: number;
11
+ /** how many of `id` this entry grants; defaults to 1 */
12
+ quantity?: number;
13
+ }
14
+ export interface LootTable {
15
+ entries: readonly LootEntry[];
16
+ /** probability that this table drops anything at all, 0 to 1; defaults to 1 (always) */
17
+ chance?: number;
18
+ }
19
+ /** @returns what dropped, or null when the roll misses or the table is empty */
20
+ export declare function rollLoot(table: LootTable): {
21
+ id: string;
22
+ quantity: number;
23
+ } | null;
24
+ //# sourceMappingURL=Loot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Loot.d.ts","sourceRoot":"","sources":["../../src/actors/Loot.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACzB,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;IAE9B,wFAAwF;IACxF,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,gFAAgF;AAChF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CASlF"}
@@ -0,0 +1,14 @@
1
+ import * as Random from '../core/Random.js';
2
+ /** @returns what dropped, or null when the roll misses or the table is empty */
3
+ export function rollLoot(table) {
4
+ if (table.entries.length === 0)
5
+ return null;
6
+ if (!Random.chance(table.chance ?? 1))
7
+ return null;
8
+ const index = Random.weighted(table.entries.map((entry) => entry.weight));
9
+ if (index === -1)
10
+ return null;
11
+ const entry = table.entries[index];
12
+ return { id: entry.id, quantity: entry.quantity ?? 1 };
13
+ }
14
+ //# sourceMappingURL=Loot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Loot.js","sourceRoot":"","sources":["../../src/actors/Loot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAuB5C,gFAAgF;AAChF,MAAM,UAAU,QAAQ,CAAC,KAAgB;IACxC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1E,IAAI,KAAK,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAE9B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,CAAC,EAAE,CAAC;AACxD,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Levels, experience, and the growth curve between them.
3
+ *
4
+ * The curve is a small interface rather than a formula, so it is entirely replaceable: a
5
+ * game that wants Pokémon-style fast/medium/slow curves, or a flat curve with no cap, or one
6
+ * read from a spreadsheet, supplies its own `GrowthCurve` and everything else here still
7
+ * works unchanged.
8
+ */
9
+ export interface GrowthCurve {
10
+ /** total experience needed to *reach* this level; level 1 should be 0 */
11
+ experienceFor(level: number): number;
12
+ /** the highest level the curve defines; levelling stops here */
13
+ maxLevel: number;
14
+ }
15
+ /** a curve reaching `maxLevel` at roughly `base * (level - 1) ^ power` total experience */
16
+ export declare function powerCurve(base: number, power: number, maxLevel: number): GrowthCurve;
17
+ export declare class Progression {
18
+ private curve;
19
+ level: number;
20
+ experience: number;
21
+ constructor(curve: GrowthCurve, start?: {
22
+ level?: number;
23
+ experience?: number;
24
+ });
25
+ /** experience still needed for the next level; null once the curve's cap is reached */
26
+ get experienceToNext(): number | null;
27
+ /** @returns how many levels were gained, 0 if none - a single large gain may span several */
28
+ addExperience(amount: number): number;
29
+ }
30
+ //# sourceMappingURL=Progression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Progression.d.ts","sourceRoot":"","sources":["../../src/actors/Progression.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,WAAW;IAC3B,yEAAyE;IACzE,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAErC,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,CAKrF;AAED,qBAAa,WAAW;IACvB,OAAO,CAAC,KAAK,CAAc;IAE3B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IAEnB,YAAY,KAAK,EAAE,WAAW,EAAE,KAAK,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAO,EAIlF;IAED,uFAAuF;IACvF,IAAI,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAGpC;IAED,6FAA6F;IAC7F,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CASpC;CACD"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Levels, experience, and the growth curve between them.
3
+ *
4
+ * The curve is a small interface rather than a formula, so it is entirely replaceable: a
5
+ * game that wants Pokémon-style fast/medium/slow curves, or a flat curve with no cap, or one
6
+ * read from a spreadsheet, supplies its own `GrowthCurve` and everything else here still
7
+ * works unchanged.
8
+ */
9
+ /** a curve reaching `maxLevel` at roughly `base * (level - 1) ^ power` total experience */
10
+ export function powerCurve(base, power, maxLevel) {
11
+ return {
12
+ maxLevel,
13
+ experienceFor: (level) => (level <= 1 ? 0 : Math.round(base * Math.pow(level - 1, power))),
14
+ };
15
+ }
16
+ export class Progression {
17
+ constructor(curve, start = {}) {
18
+ this.curve = curve;
19
+ this.level = start.level ?? 1;
20
+ this.experience = start.experience ?? this.curve.experienceFor(this.level);
21
+ }
22
+ /** experience still needed for the next level; null once the curve's cap is reached */
23
+ get experienceToNext() {
24
+ if (this.level >= this.curve.maxLevel)
25
+ return null;
26
+ return this.curve.experienceFor(this.level + 1) - this.experience;
27
+ }
28
+ /** @returns how many levels were gained, 0 if none - a single large gain may span several */
29
+ addExperience(amount) {
30
+ this.experience += amount;
31
+ let gained = 0;
32
+ while (this.level < this.curve.maxLevel && this.experience >= this.curve.experienceFor(this.level + 1)) {
33
+ this.level++;
34
+ gained++;
35
+ }
36
+ return gained;
37
+ }
38
+ }
39
+ //# sourceMappingURL=Progression.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Progression.js","sourceRoot":"","sources":["../../src/actors/Progression.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,2FAA2F;AAC3F,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,KAAa,EAAE,QAAgB;IACvE,OAAO;QACN,QAAQ;QACR,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;KAC1F,CAAC;AACH,CAAC;AAED,MAAM,OAAO,WAAW;IAMvB,YAAY,KAAkB,EAAE,KAAK,GAA4C,EAAE;QAClF,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;QAC9B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5E,CAAC;IAED,uFAAuF;IACvF,IAAI,gBAAgB;QACnB,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;IACnE,CAAC;IAED,6FAA6F;IAC7F,aAAa,CAAC,MAAc;QAC3B,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC;QAE1B,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,OAAO,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;YACxG,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,MAAM,EAAE,CAAC;QACV,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;CACD"}
@@ -0,0 +1,23 @@
1
+ import type { StatBlock } from './StatBlock.ts';
2
+ /**
3
+ * One spendable cost: `amount` of the `stat` pool, the way a spell costs mana.
4
+ *
5
+ * Costs operate on the stat's *base* value - the stored pool - not its modified
6
+ * total: a buff that raises maximum mana changes the ceiling, not what is left
7
+ * to spend. Restoring the pool is just `stats.setBase`; only spending needed a
8
+ * primitive of its own.
9
+ */
10
+ export interface ResourceCost {
11
+ stat: string;
12
+ amount: number;
13
+ }
14
+ /** True when every cost in `cost` is currently affordable, without spending anything. */
15
+ export declare function canAfford(stats: StatBlock, cost: ResourceCost | readonly ResourceCost[]): boolean;
16
+ /**
17
+ * Spends every cost in `cost` at once, the way `craft` resolves a recipe.
18
+ *
19
+ * All or nothing: when any one cost is unaffordable nothing is deducted and
20
+ * this returns false. A zero cost is always affordable and deducts nothing.
21
+ */
22
+ export declare function spend(stats: StatBlock, cost: ResourceCost | readonly ResourceCost[]): boolean;
23
+ //# sourceMappingURL=Resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Resource.d.ts","sourceRoot":"","sources":["../../src/actors/Resource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CACf;AAYD,yFAAyF;AACzF,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,SAAS,YAAY,EAAE,GAAG,OAAO,CAEjG;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,SAAS,YAAY,EAAE,GAAG,OAAO,CAK7F"}
@@ -0,0 +1,28 @@
1
+ function all(cost) {
2
+ const list = Array.isArray(cost) ? cost : [cost];
3
+ for (const c of list) {
4
+ if (!Number.isFinite(c.amount) || c.amount < 0) {
5
+ throw new Error(`a resource cost must be a non-negative number, "${c.stat}" costs ${c.amount}`);
6
+ }
7
+ }
8
+ return list;
9
+ }
10
+ /** True when every cost in `cost` is currently affordable, without spending anything. */
11
+ export function canAfford(stats, cost) {
12
+ return all(cost).every((c) => stats.base(c.stat) >= c.amount);
13
+ }
14
+ /**
15
+ * Spends every cost in `cost` at once, the way `craft` resolves a recipe.
16
+ *
17
+ * All or nothing: when any one cost is unaffordable nothing is deducted and
18
+ * this returns false. A zero cost is always affordable and deducts nothing.
19
+ */
20
+ export function spend(stats, cost) {
21
+ const list = all(cost);
22
+ if (!list.every((c) => stats.base(c.stat) >= c.amount))
23
+ return false;
24
+ for (const c of list)
25
+ stats.setBase(c.stat, stats.base(c.stat) - c.amount);
26
+ return true;
27
+ }
28
+ //# sourceMappingURL=Resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Resource.js","sourceRoot":"","sources":["../../src/actors/Resource.ts"],"names":[],"mappings":"AAeA,SAAS,GAAG,CAAC,IAA4C;IACxD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACjD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACjG,CAAC;IACF,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,SAAS,CAAC,KAAgB,EAAE,IAA4C;IACvF,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,KAAK,CAAC,KAAgB,EAAE,IAA4C;IACnF,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACrE,KAAK,MAAM,CAAC,IAAI,IAAI;QAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IAC3E,OAAO,IAAI,CAAC;AACb,CAAC"}