@maka/maka-cli 5.3.17 → 5.5.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 (245) hide show
  1. package/bundle/typescript/package.json +1 -1
  2. package/bundle/typescript/src/commands/game/sideQuest/archetypes.d.ts +62 -0
  3. package/bundle/typescript/src/commands/game/sideQuest/archetypes.js +196 -0
  4. package/bundle/typescript/src/commands/game/sideQuest/archetypes.js.map +1 -0
  5. package/bundle/typescript/src/commands/game/sideQuest/commands/advance.d.ts +16 -0
  6. package/bundle/typescript/src/commands/game/sideQuest/commands/advance.js +65 -0
  7. package/bundle/typescript/src/commands/game/sideQuest/commands/advance.js.map +1 -0
  8. package/bundle/typescript/src/commands/game/sideQuest/commands/assense.d.ts +16 -0
  9. package/bundle/typescript/src/commands/game/sideQuest/commands/assense.js +122 -0
  10. package/bundle/typescript/src/commands/game/sideQuest/commands/assense.js.map +1 -0
  11. package/bundle/typescript/src/commands/game/sideQuest/commands/attack.d.ts +42 -0
  12. package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js +243 -0
  13. package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js.map +1 -0
  14. package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.d.ts +16 -0
  15. package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js +39 -0
  16. package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js.map +1 -0
  17. package/bundle/typescript/src/commands/game/sideQuest/commands/brandish.d.ts +21 -0
  18. package/bundle/typescript/src/commands/game/sideQuest/commands/brandish.js +82 -0
  19. package/bundle/typescript/src/commands/game/sideQuest/commands/brandish.js.map +1 -0
  20. package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.d.ts +28 -0
  21. package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js +101 -0
  22. package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js.map +1 -0
  23. package/bundle/typescript/src/commands/game/sideQuest/commands/call.d.ts +19 -0
  24. package/bundle/typescript/src/commands/game/sideQuest/commands/call.js +219 -0
  25. package/bundle/typescript/src/commands/game/sideQuest/commands/call.js.map +1 -0
  26. package/bundle/typescript/src/commands/game/sideQuest/commands/cast.d.ts +58 -0
  27. package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js +397 -0
  28. package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js.map +1 -0
  29. package/bundle/typescript/src/commands/game/sideQuest/commands/command-registry.d.ts +11 -1
  30. package/bundle/typescript/src/commands/game/sideQuest/commands/command-registry.js +8 -3
  31. package/bundle/typescript/src/commands/game/sideQuest/commands/command-registry.js.map +1 -1
  32. package/bundle/typescript/src/commands/game/sideQuest/commands/command.d.ts +6 -0
  33. package/bundle/typescript/src/commands/game/sideQuest/commands/command.js +4 -0
  34. package/bundle/typescript/src/commands/game/sideQuest/commands/command.js.map +1 -1
  35. package/bundle/typescript/src/commands/game/sideQuest/commands/drone.d.ts +15 -0
  36. package/bundle/typescript/src/commands/game/sideQuest/commands/drone.js +72 -0
  37. package/bundle/typescript/src/commands/game/sideQuest/commands/drone.js.map +1 -0
  38. package/bundle/typescript/src/commands/game/sideQuest/commands/drop.js +3 -0
  39. package/bundle/typescript/src/commands/game/sideQuest/commands/drop.js.map +1 -1
  40. package/bundle/typescript/src/commands/game/sideQuest/commands/edge.d.ts +13 -0
  41. package/bundle/typescript/src/commands/game/sideQuest/commands/edge.js +31 -0
  42. package/bundle/typescript/src/commands/game/sideQuest/commands/edge.js.map +1 -0
  43. package/bundle/typescript/src/commands/game/sideQuest/commands/end-call.d.ts +6 -0
  44. package/bundle/typescript/src/commands/game/sideQuest/commands/end-call.js +27 -0
  45. package/bundle/typescript/src/commands/game/sideQuest/commands/end-call.js.map +1 -0
  46. package/bundle/typescript/src/commands/game/sideQuest/commands/equip.d.ts +4 -0
  47. package/bundle/typescript/src/commands/game/sideQuest/commands/equip.js +59 -2
  48. package/bundle/typescript/src/commands/game/sideQuest/commands/equip.js.map +1 -1
  49. package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.d.ts +13 -0
  50. package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.js +50 -0
  51. package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.js.map +1 -0
  52. package/bundle/typescript/src/commands/game/sideQuest/commands/give.js +7 -1
  53. package/bundle/typescript/src/commands/game/sideQuest/commands/give.js.map +1 -1
  54. package/bundle/typescript/src/commands/game/sideQuest/commands/go.d.ts +13 -0
  55. package/bundle/typescript/src/commands/game/sideQuest/commands/go.js +147 -4
  56. package/bundle/typescript/src/commands/game/sideQuest/commands/go.js.map +1 -1
  57. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.d.ts +25 -0
  58. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js +199 -0
  59. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js.map +1 -0
  60. package/bundle/typescript/src/commands/game/sideQuest/commands/haggle.d.ts +15 -0
  61. package/bundle/typescript/src/commands/game/sideQuest/commands/haggle.js +75 -0
  62. package/bundle/typescript/src/commands/game/sideQuest/commands/haggle.js.map +1 -0
  63. package/bundle/typescript/src/commands/game/sideQuest/commands/inv.d.ts +12 -0
  64. package/bundle/typescript/src/commands/game/sideQuest/commands/inv.js +43 -0
  65. package/bundle/typescript/src/commands/game/sideQuest/commands/inv.js.map +1 -0
  66. package/bundle/typescript/src/commands/game/sideQuest/commands/jack.d.ts +17 -0
  67. package/bundle/typescript/src/commands/game/sideQuest/commands/jack.js +64 -0
  68. package/bundle/typescript/src/commands/game/sideQuest/commands/jack.js.map +1 -0
  69. package/bundle/typescript/src/commands/game/sideQuest/commands/kill.d.ts +10 -3
  70. package/bundle/typescript/src/commands/game/sideQuest/commands/kill.js +11 -33
  71. package/bundle/typescript/src/commands/game/sideQuest/commands/kill.js.map +1 -1
  72. package/bundle/typescript/src/commands/game/sideQuest/commands/look.js +47 -4
  73. package/bundle/typescript/src/commands/game/sideQuest/commands/look.js.map +1 -1
  74. package/bundle/typescript/src/commands/game/sideQuest/commands/map.d.ts +12 -0
  75. package/bundle/typescript/src/commands/game/sideQuest/commands/map.js +46 -0
  76. package/bundle/typescript/src/commands/game/sideQuest/commands/map.js.map +1 -0
  77. package/bundle/typescript/src/commands/game/sideQuest/commands/pan.d.ts +12 -0
  78. package/bundle/typescript/src/commands/game/sideQuest/commands/pan.js +55 -0
  79. package/bundle/typescript/src/commands/game/sideQuest/commands/pan.js.map +1 -0
  80. package/bundle/typescript/src/commands/game/sideQuest/commands/persuade.d.ts +18 -0
  81. package/bundle/typescript/src/commands/game/sideQuest/commands/persuade.js +100 -0
  82. package/bundle/typescript/src/commands/game/sideQuest/commands/persuade.js.map +1 -0
  83. package/bundle/typescript/src/commands/game/sideQuest/commands/pick.d.ts +10 -0
  84. package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js +33 -0
  85. package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js.map +1 -0
  86. package/bundle/typescript/src/commands/game/sideQuest/commands/project.d.ts +19 -0
  87. package/bundle/typescript/src/commands/game/sideQuest/commands/project.js +54 -0
  88. package/bundle/typescript/src/commands/game/sideQuest/commands/project.js.map +1 -0
  89. package/bundle/typescript/src/commands/game/sideQuest/commands/read.js +6 -5
  90. package/bundle/typescript/src/commands/game/sideQuest/commands/read.js.map +1 -1
  91. package/bundle/typescript/src/commands/game/sideQuest/commands/reboot.d.ts +12 -0
  92. package/bundle/typescript/src/commands/game/sideQuest/commands/reboot.js +52 -0
  93. package/bundle/typescript/src/commands/game/sideQuest/commands/reboot.js.map +1 -0
  94. package/bundle/typescript/src/commands/game/sideQuest/commands/reload.d.ts +14 -0
  95. package/bundle/typescript/src/commands/game/sideQuest/commands/reload.js +40 -0
  96. package/bundle/typescript/src/commands/game/sideQuest/commands/reload.js.map +1 -0
  97. package/bundle/typescript/src/commands/game/sideQuest/commands/rest.d.ts +15 -0
  98. package/bundle/typescript/src/commands/game/sideQuest/commands/rest.js +59 -0
  99. package/bundle/typescript/src/commands/game/sideQuest/commands/rest.js.map +1 -0
  100. package/bundle/typescript/src/commands/game/sideQuest/commands/say.js +31 -2
  101. package/bundle/typescript/src/commands/game/sideQuest/commands/say.js.map +1 -1
  102. package/bundle/typescript/src/commands/game/sideQuest/commands/search.js +71 -7
  103. package/bundle/typescript/src/commands/game/sideQuest/commands/search.js.map +1 -1
  104. package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.d.ts +12 -0
  105. package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js +58 -0
  106. package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js.map +1 -0
  107. package/bundle/typescript/src/commands/game/sideQuest/commands/silent.d.ts +13 -0
  108. package/bundle/typescript/src/commands/game/sideQuest/commands/silent.js +50 -0
  109. package/bundle/typescript/src/commands/game/sideQuest/commands/silent.js.map +1 -0
  110. package/bundle/typescript/src/commands/game/sideQuest/commands/sneak.d.ts +15 -0
  111. package/bundle/typescript/src/commands/game/sideQuest/commands/sneak.js +35 -0
  112. package/bundle/typescript/src/commands/game/sideQuest/commands/sneak.js.map +1 -0
  113. package/bundle/typescript/src/commands/game/sideQuest/commands/solve.js +32 -11
  114. package/bundle/typescript/src/commands/game/sideQuest/commands/solve.js.map +1 -1
  115. package/bundle/typescript/src/commands/game/sideQuest/commands/spells.d.ts +14 -0
  116. package/bundle/typescript/src/commands/game/sideQuest/commands/spells.js +86 -0
  117. package/bundle/typescript/src/commands/game/sideQuest/commands/spells.js.map +1 -0
  118. package/bundle/typescript/src/commands/game/sideQuest/commands/stance.d.ts +12 -0
  119. package/bundle/typescript/src/commands/game/sideQuest/commands/stance.js +41 -0
  120. package/bundle/typescript/src/commands/game/sideQuest/commands/stance.js.map +1 -0
  121. package/bundle/typescript/src/commands/game/sideQuest/commands/subdue.d.ts +21 -0
  122. package/bundle/typescript/src/commands/game/sideQuest/commands/subdue.js +43 -0
  123. package/bundle/typescript/src/commands/game/sideQuest/commands/subdue.js.map +1 -0
  124. package/bundle/typescript/src/commands/game/sideQuest/commands/surrender.d.ts +20 -0
  125. package/bundle/typescript/src/commands/game/sideQuest/commands/surrender.js +45 -0
  126. package/bundle/typescript/src/commands/game/sideQuest/commands/surrender.js.map +1 -0
  127. package/bundle/typescript/src/commands/game/sideQuest/commands/take.d.ts +8 -0
  128. package/bundle/typescript/src/commands/game/sideQuest/commands/take.js +138 -2
  129. package/bundle/typescript/src/commands/game/sideQuest/commands/take.js.map +1 -1
  130. package/bundle/typescript/src/commands/game/sideQuest/commands/talk.js +8 -0
  131. package/bundle/typescript/src/commands/game/sideQuest/commands/talk.js.map +1 -1
  132. package/bundle/typescript/src/commands/game/sideQuest/commands/unequip.js +6 -3
  133. package/bundle/typescript/src/commands/game/sideQuest/commands/unequip.js.map +1 -1
  134. package/bundle/typescript/src/commands/game/sideQuest/commands/unlock.js +1 -0
  135. package/bundle/typescript/src/commands/game/sideQuest/commands/unlock.js.map +1 -1
  136. package/bundle/typescript/src/commands/game/sideQuest/commands/use.d.ts +24 -0
  137. package/bundle/typescript/src/commands/game/sideQuest/commands/use.js +102 -1
  138. package/bundle/typescript/src/commands/game/sideQuest/commands/use.js.map +1 -1
  139. package/bundle/typescript/src/commands/game/sideQuest/factories/item-factory.js +2 -1
  140. package/bundle/typescript/src/commands/game/sideQuest/factories/item-factory.js.map +1 -1
  141. package/bundle/typescript/src/commands/game/sideQuest/factories/npc-factory.js +7 -2
  142. package/bundle/typescript/src/commands/game/sideQuest/factories/npc-factory.js.map +1 -1
  143. package/bundle/typescript/src/commands/game/sideQuest/factories/puzzle-factory.js +2 -1
  144. package/bundle/typescript/src/commands/game/sideQuest/factories/puzzle-factory.js.map +1 -1
  145. package/bundle/typescript/src/commands/game/sideQuest/factories/room-factory.js +3 -0
  146. package/bundle/typescript/src/commands/game/sideQuest/factories/room-factory.js.map +1 -1
  147. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.d.ts +175 -0
  148. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +673 -0
  149. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js.map +1 -0
  150. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.d.ts +8 -1
  151. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js +139 -21
  152. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js.map +1 -1
  153. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.d.ts +174 -0
  154. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.js +647 -0
  155. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.js.map +1 -0
  156. package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +138 -9
  157. package/bundle/typescript/src/commands/game/sideQuest/game.js +757 -197
  158. package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
  159. package/bundle/typescript/src/commands/game/sideQuest/minigames/hack-minigame.d.ts +16 -0
  160. package/bundle/typescript/src/commands/game/sideQuest/minigames/hack-minigame.js +101 -0
  161. package/bundle/typescript/src/commands/game/sideQuest/minigames/hack-minigame.js.map +1 -0
  162. package/bundle/typescript/src/commands/game/sideQuest/minigames/lockpick-minigame.d.ts +15 -0
  163. package/bundle/typescript/src/commands/game/sideQuest/minigames/lockpick-minigame.js +95 -0
  164. package/bundle/typescript/src/commands/game/sideQuest/minigames/lockpick-minigame.js.map +1 -0
  165. package/bundle/typescript/src/commands/game/sideQuest/models/door.d.ts +10 -0
  166. package/bundle/typescript/src/commands/game/sideQuest/models/door.js +15 -2
  167. package/bundle/typescript/src/commands/game/sideQuest/models/door.js.map +1 -1
  168. package/bundle/typescript/src/commands/game/sideQuest/models/inventory.d.ts +10 -0
  169. package/bundle/typescript/src/commands/game/sideQuest/models/inventory.js +54 -4
  170. package/bundle/typescript/src/commands/game/sideQuest/models/inventory.js.map +1 -1
  171. package/bundle/typescript/src/commands/game/sideQuest/models/item.d.ts +41 -0
  172. package/bundle/typescript/src/commands/game/sideQuest/models/item.js +106 -3
  173. package/bundle/typescript/src/commands/game/sideQuest/models/item.js.map +1 -1
  174. package/bundle/typescript/src/commands/game/sideQuest/models/npc.d.ts +27 -0
  175. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +312 -50
  176. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
  177. package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +278 -0
  178. package/bundle/typescript/src/commands/game/sideQuest/models/player.js +661 -9
  179. package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
  180. package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.d.ts +75 -1
  181. package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js +199 -6
  182. package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js.map +1 -1
  183. package/bundle/typescript/src/commands/game/sideQuest/models/room.d.ts +24 -0
  184. package/bundle/typescript/src/commands/game/sideQuest/models/room.js +53 -18
  185. package/bundle/typescript/src/commands/game/sideQuest/models/room.js.map +1 -1
  186. package/bundle/typescript/src/commands/game/sideQuest/models/scene.d.ts +73 -0
  187. package/bundle/typescript/src/commands/game/sideQuest/models/scene.js +208 -3
  188. package/bundle/typescript/src/commands/game/sideQuest/models/scene.js.map +1 -1
  189. package/bundle/typescript/src/commands/game/sideQuest/scenes/scene1.json +319 -70
  190. package/bundle/typescript/src/commands/game/sideQuest/scenes/scene2.json +661 -227
  191. package/bundle/typescript/src/commands/game/sideQuest/types/player-equipment.d.ts +1 -0
  192. package/bundle/typescript/src/commands/game/sideQuest/types/seed/exit-seed.d.ts +1 -0
  193. package/bundle/typescript/src/commands/game/sideQuest/types/seed/item-seed.d.ts +1 -0
  194. package/bundle/typescript/src/commands/game/sideQuest/types/seed/npc-seed.d.ts +1 -0
  195. package/bundle/typescript/src/commands/game/sideQuest/types/seed/player-seed.d.ts +42 -0
  196. package/bundle/typescript/src/commands/game/sideQuest/types/seed/puzzle-seed.d.ts +15 -1
  197. package/bundle/typescript/src/commands/game/sideQuest/types/seed/room-seed.d.ts +4 -0
  198. package/bundle/typescript/src/commands/game/sideQuest/types/seed/scene-seed.d.ts +8 -0
  199. package/bundle/typescript/src/commands/game/sideQuest/types/seed/win-condition-seed.d.ts +15 -0
  200. package/bundle/typescript/src/commands/game/sideQuest/types/seed/win-condition-seed.js +2 -0
  201. package/bundle/typescript/src/commands/game/sideQuest/types/seed/win-condition-seed.js.map +1 -0
  202. package/bundle/typescript/src/commands/game/sideQuest/types/shared/abstracts.d.ts +1 -0
  203. package/bundle/typescript/src/commands/game/sideQuest/types/shared/abstracts.js +5 -0
  204. package/bundle/typescript/src/commands/game/sideQuest/types/shared/abstracts.js.map +1 -1
  205. package/bundle/typescript/src/commands/game/sideQuest/types/shared/item-enum.d.ts +1 -0
  206. package/bundle/typescript/src/commands/game/sideQuest/types/shared/item-enum.js +1 -0
  207. package/bundle/typescript/src/commands/game/sideQuest/types/shared/item-enum.js.map +1 -1
  208. package/bundle/typescript/src/commands/game/sideQuest/ui.d.ts +3 -0
  209. package/bundle/typescript/src/commands/game/sideQuest/ui.js +95 -6
  210. package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
  211. package/bundle/typescript/src/commands/game/sideQuest/utilities/auto-fight.d.ts +60 -0
  212. package/bundle/typescript/src/commands/game/sideQuest/utilities/auto-fight.js +138 -0
  213. package/bundle/typescript/src/commands/game/sideQuest/utilities/auto-fight.js.map +1 -0
  214. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.d.ts +145 -0
  215. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js +354 -0
  216. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js.map +1 -0
  217. package/bundle/typescript/src/commands/game/sideQuest/utilities/comm-style.d.ts +2 -0
  218. package/bundle/typescript/src/commands/game/sideQuest/utilities/comm-style.js +12 -0
  219. package/bundle/typescript/src/commands/game/sideQuest/utilities/comm-style.js.map +1 -0
  220. package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.d.ts +22 -0
  221. package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.js +34 -0
  222. package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.js.map +1 -0
  223. package/bundle/typescript/src/commands/game/sideQuest/utilities/fuzzy-match.d.ts +36 -0
  224. package/bundle/typescript/src/commands/game/sideQuest/utilities/fuzzy-match.js +92 -0
  225. package/bundle/typescript/src/commands/game/sideQuest/utilities/fuzzy-match.js.map +1 -0
  226. package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.d.ts +77 -0
  227. package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js +265 -0
  228. package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js.map +1 -0
  229. package/bundle/typescript/src/commands/game/sideQuest/utilities/pursuit.d.ts +16 -0
  230. package/bundle/typescript/src/commands/game/sideQuest/utilities/pursuit.js +36 -0
  231. package/bundle/typescript/src/commands/game/sideQuest/utilities/pursuit.js.map +1 -0
  232. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +78 -7
  233. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
  234. package/bundle/typescript/src/commands/set/global.sub.cmd.js +59 -5
  235. package/bundle/typescript/src/commands/set/global.sub.cmd.js.map +1 -1
  236. package/bundle/typescript/src/tools/ai/ai.class.d.ts +42 -0
  237. package/bundle/typescript/src/tools/ai/ai.class.js +117 -0
  238. package/bundle/typescript/src/tools/ai/ai.class.js.map +1 -0
  239. package/bundle/typescript/src/tools/fsi/fsi.interfaces.d.ts +1 -0
  240. package/bundle/typescript/src/tools/fsi/fsi.interfaces.js.map +1 -1
  241. package/bundle/typescript/src/tools/https/https.class.d.ts +3 -2
  242. package/bundle/typescript/src/tools/https/https.class.js +51 -2
  243. package/bundle/typescript/src/tools/https/https.class.js.map +1 -1
  244. package/bundle/typescript/src/tools/https/https.interface.d.ts +10 -0
  245. package/package.json +1 -1
@@ -9,6 +9,7 @@ export type HeadEquipment = {
9
9
  commlink: Item | null;
10
10
  };
11
11
  export type TorsoEquipment = {
12
+ clothing: Item | null;
12
13
  armorVest: Item | null;
13
14
  armorCoat: Item | null;
14
15
  backpack: Item | null;
@@ -3,4 +3,5 @@ export interface IExitSeedJson {
3
3
  targetRoom: string;
4
4
  keyRequired?: string;
5
5
  doorName?: string;
6
+ puzzle?: string;
6
7
  }
@@ -20,4 +20,5 @@ export interface IItemSeedJson {
20
20
  heldBy?: string;
21
21
  owner?: string;
22
22
  transferable?: boolean;
23
+ plane?: 'meat' | 'matrix' | 'astral';
23
24
  }
@@ -2,5 +2,6 @@ import { IPlayerSeedJson } from './player-seed.js';
2
2
  export interface INPCSeedJson {
3
3
  dialogue?: string[];
4
4
  description?: string;
5
+ plane?: 'meat' | 'matrix' | 'astral';
5
6
  player: IPlayerSeedJson;
6
7
  }
@@ -1,8 +1,50 @@
1
1
  import { LifestyleChoice } from './lifestyle-seed.js';
2
2
  import { IItemSeedJson } from './item-seed.js';
3
+ /**
4
+ * Optional Shadowrun-style combat attributes (see Player's combat fields
5
+ * for the defaults applied when omitted). Street-level runners sit around
6
+ * 3-4 in everything; a hardened enforcer 5-6; a soft civilian 1-2.
7
+ */
8
+ export interface ICombatSeedJson {
9
+ body?: number;
10
+ agility?: number;
11
+ reaction?: number;
12
+ combatSkill?: number;
13
+ /**
14
+ * Innate magical talent. Omit (or 0) for the mundane majority; 3-6 makes
15
+ * an Awakened mage/shaman who knows every spell without needing any
16
+ * formula or grimoire, casting from raw talent.
17
+ */
18
+ magic?: number;
19
+ /** Melee/unarmed damage and carrying capacity. */
20
+ strength?: number;
21
+ /** Stun track size and drain resistance. */
22
+ willpower?: number;
23
+ /** First aid effectiveness and hacking. */
24
+ logic?: number;
25
+ /** Defense (half weight) and perception. */
26
+ intuition?: number;
27
+ /** Social presence. */
28
+ charisma?: number;
29
+ /** Luck pool, burned to push key strikes. */
30
+ edge?: number;
31
+ /** Technomancer talent: the Matrix with no deck, all Matrix damage as real stun. */
32
+ resonance?: number;
33
+ /** Physical adept: magic channeled into meat combat -- no spells, no projection. */
34
+ adept?: boolean;
35
+ /**
36
+ * Per-skill ratings 1-8 (see Player SkillName: firearms, blades,
37
+ * unarmed, sneaking, perception, athletics, hacking, locksmith,
38
+ * negotiation, con, intimidation, first-aid, assensing, spellcasting,
39
+ * piloting). Optional: combat skills default to combatSkill, others to
40
+ * 0 -- so a plain combatSkill block keeps working exactly as before.
41
+ */
42
+ skills?: Record<string, number>;
43
+ }
3
44
  export interface IPlayerSeedJson {
4
45
  name: string;
5
46
  startLocation: string;
6
47
  lifestyleChoices: LifestyleChoice[];
7
48
  startingItems?: IItemSeedJson[];
49
+ combat?: ICombatSeedJson;
8
50
  }
@@ -1,6 +1,7 @@
1
+ export type PuzzleBypassType = 'lockpick' | 'hack' | 'spell' | 'con';
1
2
  export interface IPuzzleSeedJson {
2
3
  name: string;
3
- room: string;
4
+ room?: string;
4
5
  riddle: string;
5
6
  requiredPhrase?: string;
6
7
  requiredItem?: string;
@@ -8,4 +9,17 @@ export interface IPuzzleSeedJson {
8
9
  successMessage?: string;
9
10
  failureMessage?: string;
10
11
  hobbyTags?: string[];
12
+ /** Name of another puzzle in this same scene that must be solved first. */
13
+ requiresPuzzle?: string;
14
+ /** Shown when attempting to solve this puzzle before requiresPuzzle is met. */
15
+ lockedMessage?: string;
16
+ /**
17
+ * Optional risky alternate route to the same reward, matching this
18
+ * barrier's in-fiction nature (a lock -> "pick", a terminal -> "hack", a
19
+ * ward -> "cast") -- a coin-flip chance to bypass without ever knowing
20
+ * requiredPhrase, but a failed attempt is loud (see Puzzle.attemptBypass).
21
+ * Leave unset for a puzzle with no such physical/technical/magical route
22
+ * (e.g. a purely social one, solvable only by knowing the actual answer).
23
+ */
24
+ bypassType?: PuzzleBypassType;
11
25
  }
@@ -7,6 +7,10 @@ export interface IRoomSeedJson {
7
7
  owner?: string;
8
8
  tags?: string[];
9
9
  exits: IExitSeedJson[];
10
+ reachable?: boolean;
11
+ hasNode?: boolean;
12
+ nodeAccess?: 'wireless' | 'wired';
13
+ warded?: boolean;
10
14
  supportedLifestyles?: {
11
15
  residenceTiers?: string[];
12
16
  employmentTags?: string[];
@@ -3,6 +3,7 @@ import { INPCSeedJson } from './npc-seed.js';
3
3
  import { IItemSeedJson } from './item-seed.js';
4
4
  import { IPuzzleSeedJson } from './puzzle-seed.js';
5
5
  import { IPlayerSeedJson } from './player-seed.js';
6
+ import { IWinConditionSeedJson } from './win-condition-seed.js';
6
7
  export interface ISceneSeedJson {
7
8
  name: string;
8
9
  currency: {
@@ -17,4 +18,11 @@ export interface ISceneSeedJson {
17
18
  story: string;
18
19
  /** The logging-in player who will be actively controlled */
19
20
  player: IPlayerSeedJson;
21
+ /** Optional. When set, the scene is a "completable" run: meeting it
22
+ * triggers a reward and an offer to continue. */
23
+ winCondition?: IWinConditionSeedJson;
24
+ /** A HUB scene: the runner's persistent home base (no winCondition).
25
+ * Calling the fixer from a hub is what initiates a run, and completing
26
+ * a run drops the player back into the hub -- see Game.returnToHub. */
27
+ hub?: boolean;
20
28
  }
@@ -0,0 +1,15 @@
1
+ export interface IWinConditionSeedJson {
2
+ type: 'give' | 'possess';
3
+ item: string;
4
+ toNpc?: string;
5
+ rewardItem?: string;
6
+ completionMessage: string;
7
+ /**
8
+ * The job's agreed pay in nuyen. The engine ACTUALLY transfers this to
9
+ * the player on completion (certified credstick), and every NPC's AI
10
+ * prompt is told the exact figure so what the fixer promises is what
11
+ * gets paid -- found via a real session where dialogue offered 50k and
12
+ * the seed's loot credstick held 2000.
13
+ */
14
+ payout?: number;
15
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=win-condition-seed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"win-condition-seed.js","sourceRoot":"","sources":["../../../../../../../../src/commands/game/sideQuest/types/seed/win-condition-seed.ts"],"names":[],"mappings":""}
@@ -60,6 +60,7 @@ export declare abstract class AbstractDoor {
60
60
  abstract roomB: Room;
61
61
  abstract isLocked: boolean;
62
62
  unlockItemOrSolution?: string;
63
+ puzzle?: Puzzle;
63
64
  abstract logger: Logger;
64
65
  abstract isLockable: boolean;
65
66
  abstract getOtherSide(currentRoom: Room): Room;
@@ -20,6 +20,11 @@ export class AbstractRoom extends EventEmitter {
20
20
  */
21
21
  export class AbstractDoor {
22
22
  unlockItemOrSolution;
23
+ // A door can be guarded by a real Puzzle instead of (or alongside) a
24
+ // physical key -- the only difference from a room's puzzle is that
25
+ // success unlocks the door rather than granting an item. See
26
+ // Door.attachPuzzle().
27
+ puzzle;
23
28
  }
24
29
  /**
25
30
  * The Inventory class represents a collection of items that can be carried by a player or stored
@@ -1 +1 @@
1
- {"version":3,"file":"abstracts.js","sourceRoot":"","sources":["../../../../../../../../src/commands/game/sideQuest/types/shared/abstracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAsBtC;;;GAGG;AACH,MAAM,OAAgB,aAAa;CAkBlC;AAED;;;;GAIG;AACH,MAAM,OAAgB,YAAa,SAAQ,YAAY;IAK9C,MAAM,CAAU;CAaxB;AAED;;;;GAIG;AACH,MAAM,OAAgB,YAAY;IAKhC,oBAAoB,CAAU;CAQ/B;AAED;;;GAGG;AACH,MAAM,OAAgB,iBAAiB;CAWtC;AAED;;;GAGG;AACH,MAAM,OAAgB,YAAY;CAYjC;AAED;;;;;;GAMG;AACH,MAAM,OAAgB,cAAe,SAAQ,YAAY;IAOvD;QACE,KAAK,EAAE,CAAC,CAAC,0BAA0B;IACrC,CAAC;CAsBF;AAED;;;;GAIG;AACH,MAAM,OAAgB,cAAc;CAgBnC"}
1
+ {"version":3,"file":"abstracts.js","sourceRoot":"","sources":["../../../../../../../../src/commands/game/sideQuest/types/shared/abstracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAsBtC;;;GAGG;AACH,MAAM,OAAgB,aAAa;CAkBlC;AAED;;;;GAIG;AACH,MAAM,OAAgB,YAAa,SAAQ,YAAY;IAK9C,MAAM,CAAU;CAaxB;AAED;;;;GAIG;AACH,MAAM,OAAgB,YAAY;IAKhC,oBAAoB,CAAU;IAC9B,qEAAqE;IACrE,mEAAmE;IACnE,6DAA6D;IAC7D,uBAAuB;IACvB,MAAM,CAAU;CAQjB;AAED;;;GAGG;AACH,MAAM,OAAgB,iBAAiB;CAWtC;AAED;;;GAGG;AACH,MAAM,OAAgB,YAAY;CAYjC;AAED;;;;;;GAMG;AACH,MAAM,OAAgB,cAAe,SAAQ,YAAY;IAOvD;QACE,KAAK,EAAE,CAAC,CAAC,0BAA0B;IACrC,CAAC;CAsBF;AAED;;;;GAIG;AACH,MAAM,OAAgB,cAAc;CAgBnC"}
@@ -46,6 +46,7 @@ export declare enum Category {
46
46
  Clothing = "clothing",
47
47
  ArmorClothing = "armor clothing",
48
48
  Medical = "medical",
49
+ StimPatch = "stim patch",
49
50
  Tool = "tool",
50
51
  Consumable = "consumable",
51
52
  Sensor = "sensor",
@@ -54,6 +54,7 @@ export var Category;
54
54
  Category["Clothing"] = "clothing";
55
55
  Category["ArmorClothing"] = "armor clothing";
56
56
  Category["Medical"] = "medical";
57
+ Category["StimPatch"] = "stim patch";
57
58
  Category["Tool"] = "tool";
58
59
  Category["Consumable"] = "consumable";
59
60
  Category["Sensor"] = "sensor";
@@ -1 +1 @@
1
- {"version":3,"file":"item-enum.js","sourceRoot":"","sources":["../../../../../../../../src/commands/game/sideQuest/types/shared/item-enum.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,IAMX;AAND,WAAY,IAAI;IACd,qBAAa,CAAA;IACX,uBAAe,CAAA;IACf,yBAAiB,CAAA;IACjB,uBAAe,CAAA;IACf,gCAAwB,CAAA;AAC5B,CAAC,EANW,IAAI,KAAJ,IAAI,QAMf;AAED,MAAM,CAAN,IAAY,MAMX;AAND,WAAY,MAAM;IAChB,2BAAiB,CAAA;IACf,+BAAqB,CAAA;IACrB,uBAAa,CAAA;IACb,iCAAuB,CAAA;IACvB,0CAAgC,CAAA;AACpC,CAAC,EANW,MAAM,KAAN,MAAM,QAMjB;AAED,MAAM,CAAN,IAAY,QAmEX;AAnED,WAAY,QAAQ;IAClB,SAAS;IACT,6BAAiB,CAAA;IACjB,wCAA4B,CAAA;IAC5B,0CAA8B,CAAA;IAC9B,qCAAyB,CAAA;IACzB,mCAAuB,CAAA;IACvB,oCAAwB,CAAA;IACxB,2BAAe,CAAA;IACf,6BAAiB,CAAA;IACjB,6BAAiB,CAAA;IACjB,kCAAsB,CAAA;IACtB,kCAAsB,CAAA;IACtB,2BAAe,CAAA;IACf,6BAAiB,CAAA;IAEjB,sCAAsC;IACtC,mCAAuB,CAAA;IACvB,+BAAmB,CAAA;IACnB,iCAAqB,CAAA;IACrB,iCAAqB,CAAA;IAErB,yBAAyB;IACzB,iCAAqB,CAAA;IACrB,mCAAuB,CAAA;IACvB,uBAAW,CAAA;IACX,2BAAe,CAAA;IACf,iCAAqB,CAAA;IACrB,uCAA2B,CAAA;IAC3B,oCAAwB,CAAA;IAExB,QAAQ;IACR,2BAAe,CAAA;IACf,0CAA8B,CAAA;IAC9B,8CAAkC,CAAA;IAClC,8CAAkC,CAAA;IAClC,6BAAiB,CAAA;IACjB,iCAAqB,CAAA;IAErB,mBAAmB;IACnB,iCAAqB,CAAA;IACrB,4CAAgC,CAAA;IAChC,+BAAmB,CAAA;IACnB,yBAAa,CAAA;IACb,qCAAyB,CAAA;IACzB,6BAAiB,CAAA;IACjB,oCAAwB,CAAA;IACxB,kDAAsC,CAAA;IACtC,uBAAW,CAAA;IACX,+BAAmB,CAAA;IAEnB,qBAAqB;IACrB,uBAAW,CAAA;IACX,gCAAoB,CAAA;IACpB,+BAAmB,CAAA;IACnB,oDAAwC,CAAA;IACxC,mCAAuB,CAAA;IAEvB,iBAAiB;IACjB,yBAAa,CAAA;IACb,yBAAa,CAAA;IACb,uBAAW,CAAA;IACX,+BAAmB,CAAA;IACnB,iCAAqB,CAAA;IACrB,iCAAqB,CAAA;IACrB,2BAAe,CAAA;IACf,+BAAmB,CAAA;AACrB,CAAC,EAnEW,QAAQ,KAAR,QAAQ,QAmEnB"}
1
+ {"version":3,"file":"item-enum.js","sourceRoot":"","sources":["../../../../../../../../src/commands/game/sideQuest/types/shared/item-enum.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,IAMX;AAND,WAAY,IAAI;IACd,qBAAa,CAAA;IACX,uBAAe,CAAA;IACf,yBAAiB,CAAA;IACjB,uBAAe,CAAA;IACf,gCAAwB,CAAA;AAC5B,CAAC,EANW,IAAI,KAAJ,IAAI,QAMf;AAED,MAAM,CAAN,IAAY,MAMX;AAND,WAAY,MAAM;IAChB,2BAAiB,CAAA;IACf,+BAAqB,CAAA;IACrB,uBAAa,CAAA;IACb,iCAAuB,CAAA;IACvB,0CAAgC,CAAA;AACpC,CAAC,EANW,MAAM,KAAN,MAAM,QAMjB;AAED,MAAM,CAAN,IAAY,QAoEX;AApED,WAAY,QAAQ;IAClB,SAAS;IACT,6BAAiB,CAAA;IACjB,wCAA4B,CAAA;IAC5B,0CAA8B,CAAA;IAC9B,qCAAyB,CAAA;IACzB,mCAAuB,CAAA;IACvB,oCAAwB,CAAA;IACxB,2BAAe,CAAA;IACf,6BAAiB,CAAA;IACjB,6BAAiB,CAAA;IACjB,kCAAsB,CAAA;IACtB,kCAAsB,CAAA;IACtB,2BAAe,CAAA;IACf,6BAAiB,CAAA;IAEjB,sCAAsC;IACtC,mCAAuB,CAAA;IACvB,+BAAmB,CAAA;IACnB,iCAAqB,CAAA;IACrB,iCAAqB,CAAA;IAErB,yBAAyB;IACzB,iCAAqB,CAAA;IACrB,mCAAuB,CAAA;IACvB,uBAAW,CAAA;IACX,2BAAe,CAAA;IACf,iCAAqB,CAAA;IACrB,uCAA2B,CAAA;IAC3B,oCAAwB,CAAA;IAExB,QAAQ;IACR,2BAAe,CAAA;IACf,0CAA8B,CAAA;IAC9B,8CAAkC,CAAA;IAClC,8CAAkC,CAAA;IAClC,6BAAiB,CAAA;IACjB,iCAAqB,CAAA;IAErB,mBAAmB;IACnB,iCAAqB,CAAA;IACrB,4CAAgC,CAAA;IAChC,+BAAmB,CAAA;IACnB,oCAAwB,CAAA;IACxB,yBAAa,CAAA;IACb,qCAAyB,CAAA;IACzB,6BAAiB,CAAA;IACjB,oCAAwB,CAAA;IACxB,kDAAsC,CAAA;IACtC,uBAAW,CAAA;IACX,+BAAmB,CAAA;IAEnB,qBAAqB;IACrB,uBAAW,CAAA;IACX,gCAAoB,CAAA;IACpB,+BAAmB,CAAA;IACnB,oDAAwC,CAAA;IACxC,mCAAuB,CAAA;IAEvB,iBAAiB;IACjB,yBAAa,CAAA;IACb,yBAAa,CAAA;IACb,uBAAW,CAAA;IACX,+BAAmB,CAAA;IACnB,iCAAqB,CAAA;IACrB,iCAAqB,CAAA;IACrB,2BAAe,CAAA;IACf,+BAAmB,CAAA;AACrB,CAAC,EApEW,QAAQ,KAAR,QAAQ,QAoEnB"}
@@ -3,5 +3,8 @@ export interface IMainGameConfig {
3
3
  debug?: boolean;
4
4
  logFilePath: string;
5
5
  useAi: boolean;
6
+ generationNotice?: string;
7
+ /** Archetype name picked at launch -- sets the player's attribute sheet. */
8
+ archetype?: string;
6
9
  }
7
10
  export declare function main(playerName: string, sceneSeed: ISceneSeedJson, options: IMainGameConfig): Promise<void>;
@@ -3,6 +3,9 @@ import { capitalCase } from 'change-case';
3
3
  import Game from './game.js';
4
4
  import { Player, Room, } from './models/_index.js';
5
5
  import { Logger } from './utilities/logger.js';
6
+ import { getArchetype, outfitArchetype } from './archetypes.js';
7
+ import { STANCE_CYCLE } from './models/player.js';
8
+ import { AutoFight } from './utilities/auto-fight.js';
6
9
  export async function main(playerName, sceneSeed, options) {
7
10
  // Create a screen object
8
11
  const screen = blessed.screen({
@@ -21,19 +24,67 @@ export async function main(playerName, sceneSeed, options) {
21
24
  description: 'A featureless room where lost souls drift.',
22
25
  roomType: 'void'
23
26
  });
24
- const player = new Player({ playerName, startLocation: nexus });
27
+ // The archetype spread picked at launch becomes the player's sheet,
28
+ // and its requisite gear comes with it -- granted on top of the
29
+ // scene's generic loadout, wearables equipped so a samurai starts
30
+ // with the Predator in hand and a Face wearing the good suit.
31
+ const archetype = getArchetype(options.archetype);
32
+ const player = new Player({ playerName, startLocation: nexus, combat: archetype.combat });
33
+ outfitArchetype(player, archetype);
25
34
  // Create the game instance
26
35
  const game = await Game.getInstance(player, sceneSeed);
27
36
  const ready = await game.init(options, screen);
28
37
  // Print welcome message or initial room description
29
- game.logBox.setContent(ready); // getWelcomeMessage should return the initial game introduction or room description
38
+ const notice = options.generationNotice
39
+ ? `{yellow-fg}${options.generationNotice}{/yellow-fg}\n\n`
40
+ : '';
41
+ game.logBox.setContent(notice + ready); // getWelcomeMessage should return the initial game introduction or room description
30
42
  game.updateEquipment(game.player.equipment);
31
43
  game.updateInventory(game.player.inventory, capitalCase(game.scene.getCurrencyType()));
32
44
  game.updateExits(game.player.currentLocation);
45
+ game.updateStatus();
46
+ // Tab cycles the fight autopilot: manual -> guarded -> aggressive (see
47
+ // utilities/auto-fight.ts; "stance" is the typed twin). Bound on the
48
+ // input box because that's where focus lives during play.
49
+ game.inputBox.key(['tab'], () => {
50
+ // Blessed's textarea reader appends the literal '\t' to the box
51
+ // value on this same keypress (listener order isn't guaranteed
52
+ // either way) -- strip it now AND on the next tick so Tab stays a
53
+ // pure control key.
54
+ const stripTab = () => {
55
+ const v = game.inputBox.getValue();
56
+ if (v.includes('\t')) {
57
+ game.inputBox.setValue(v.replace(/\t/g, ''));
58
+ }
59
+ };
60
+ stripTab();
61
+ setImmediate(() => { stripTab(); screen.render(); });
62
+ const cycle = STANCE_CYCLE;
63
+ const next = cycle[(cycle.indexOf(game.player.autoStance) + 1) % cycle.length];
64
+ game.player.autoStance = next;
65
+ game.autoFight.cancelPending();
66
+ // white for manual, not gray -- gray is ANSI bright-black, illegible
67
+ // on stock dark palettes (same fix as the HUD stance in game.ts).
68
+ const color = next === 'aggressive' ? 'red' : next === 'guarded' ? 'yellow' : 'white';
69
+ gameLog.logWithColor(`⚔ Stance: ${next.toUpperCase()} -- ${AutoFight.describe(next)}.`, color);
70
+ game.updateStatus();
71
+ screen.render();
72
+ });
33
73
  game.inputBox.key(['enter'], () => {
34
74
  void (async () => {
35
75
  try {
36
76
  const input = game.inputBox.getValue();
77
+ // Typing takes over: any submitted command cancels a pending
78
+ // auto-fight action (the interruptible beat -- see
79
+ // utilities/auto-fight.ts). The next settled exchange re-arms it.
80
+ game.autoFight.cancelPending();
81
+ // Clear the box the moment the command is submitted, not after
82
+ // it resolves -- a slow command (combat narration beats, an AI
83
+ // round trip on a call) used to leave the typed text sitting in
84
+ // the box for seconds, and worse, the late clear would wipe
85
+ // whatever the player had started typing NEXT during the wait.
86
+ game.inputBox.clearValue();
87
+ screen.render();
37
88
  const response = await game.handleInput(input); // handleInput is the method that processes commands
38
89
  if (['take', 'equip', 'unequip'].includes(input.split(' ')[0])) {
39
90
  // Example usage: update the inventory with a new list of items
@@ -43,6 +94,11 @@ export async function main(playerName, sceneSeed, options) {
43
94
  if (['go', 'lock', 'unlock'].includes(input.split(' ')[0])) {
44
95
  game.updateExits(game.player.currentLocation);
45
96
  }
97
+ // Unconditional (not gated on the verb typed) since a call can
98
+ // also end on the NPC's own initiative -- this stays in sync
99
+ // with whatever state actually resulted, not just what the
100
+ // player directly asked for.
101
+ game.updateStatus();
46
102
  if (input.split(' ')[0] === 'clear') {
47
103
  game.logBox.setContent('');
48
104
  }
@@ -53,13 +109,46 @@ export async function main(playerName, sceneSeed, options) {
53
109
  process.exit(0); // Exit the game
54
110
  }
55
111
  game.logBox.pushLine(response);
56
- game.logBox.scroll(1);
57
- game.inputBox.clearValue();
58
- game.inputBox.focus();
59
- screen.render();
112
+ game.logBox.scrollTo(game.logBox.getScrollHeight());
60
113
  }
61
114
  catch (error) {
115
+ // A crashed command must FAIL VISIBLY -- the old silent
116
+ // log-and-return left the player staring at a game that
117
+ // apparently ignored them (real session: a puzzle-data crash
118
+ // made "search" a no-op five times running, with the errors
119
+ // only in the log file).
62
120
  gameLog.error(`Error handling input: ${error}`);
121
+ game.logBox.pushLine(`{red-fg}Something glitched handling that command -- it's been logged. The game is still running.{/red-fg}`);
122
+ game.logBox.scrollTo(game.logBox.getScrollHeight());
123
+ }
124
+ finally {
125
+ // Focus restoration runs on EVERY path -- the same real session
126
+ // showed that when a command threw, this block (then inside the
127
+ // try) was skipped, the input reader died, and the player
128
+ // couldn't type at all ("focus is being removed").
129
+ //
130
+ // NEVER blind-focus() the input box here. Blessed's _focus() has
131
+ // no old === el guard, so focusing the box while it's already
132
+ // focused fires a self-blur that cancels the active input reader
133
+ // and starts another -- and because the reader attaches its
134
+ // keypress listener on a DELAYED tick, a fast (all-microtask)
135
+ // command lands this cancel while the previous attach is still
136
+ // pending: the cancel removes nothing, both attaches then land,
137
+ // and the orphaned listener doubles every subsequent keystroke
138
+ // (found via a real session typing "exit" and getting "eexxiitt").
139
+ // The submit path already re-focuses the box internally
140
+ // (rewindFocus), so the common case needs no touch at all; only
141
+ // actually restart things when focus genuinely went elsewhere
142
+ // (e.g. a lockpick/hack minigame took the screen) or reading
143
+ // somehow stopped while still focused.
144
+ const inputBox = game.inputBox;
145
+ if (screen.focused !== inputBox) {
146
+ inputBox.focus();
147
+ }
148
+ else if (!inputBox._reading) {
149
+ inputBox.readInput();
150
+ }
151
+ screen.render();
63
152
  }
64
153
  })();
65
154
  });
@@ -1 +1 @@
1
- {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../../../../src/commands/game/sideQuest/ui.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../../../../src/commands/game/sideQuest/ui.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import type Game from '../game.js';
2
+ import type { Player, FightStance } from '../models/player.js';
3
+ import type { NPC } from '../models/npc.js';
4
+ /**
5
+ * Fight-or-flight autopilot -- the FIGHT half. The player sets a
6
+ * temperature (Tab in the UI, or the "stance" command) and the game keeps
7
+ * swinging for them; flight stays manual, always, because stopping YOUR
8
+ * swings never stops THEIRS -- the only real defense is the door, and
9
+ * that's the player's call.
10
+ *
11
+ * manual -- today's behavior, every action typed
12
+ * guarded -- auto-fights, but wins non-lethally: switches to subdue
13
+ * when the target is nearly down, and stands down the
14
+ * moment they surrender
15
+ * aggressive -- fights until they're dead; a surrender changes nothing
16
+ *
17
+ * Wiring: CombatExchange.finishExchange() -> Scene.notifyExchangeSettled()
18
+ * -> onExchangeSettled() here. If the player was a combatant and the
19
+ * stance says fight, the next action is scheduled a short, interruptible
20
+ * beat later (REENGAGE_DELAY_MS). Submitting ANY command in the UI cancels
21
+ * the pending action and takes over (see ui.ts) -- the beat exists exactly
22
+ * so fleeing and healing stay possible mid-autofight. Everything is
23
+ * revalidated at fire time: the fight may have ended, moved, or been
24
+ * surrendered out of during the delay.
25
+ *
26
+ * Auto actions lead with whatever hits hardest: a caster whose manabolt
27
+ * out-damages their equipped weapon throws the bolt (and eats the drain);
28
+ * everyone else uses the gun/blade/fists they're holding. A dry gun's
29
+ * refusal (reload prompt) is surfaced to the player and auto simply waits
30
+ * for them to deal with it -- reloading is a decision, not a reflex.
31
+ */
32
+ export declare class AutoFight {
33
+ private game;
34
+ static REENGAGE_DELAY_MS: number;
35
+ private static MANABOLT_POWER;
36
+ private pending?;
37
+ constructor(game: Game);
38
+ /** The pending auto action, dropped. The player typed, or the stance changed. */
39
+ cancelPending(): void;
40
+ /**
41
+ * Called after every combat exchange resolves (player-involved or not).
42
+ * Schedules the player's next action when the autopilot should act.
43
+ */
44
+ onExchangeSettled(combatants: (Player | NPC)[]): void;
45
+ /**
46
+ * The beat elapsed uninterrupted -- act, if the fight still stands.
47
+ * Every guard here re-checks live state: the target may have died, fled,
48
+ * surrendered, or started another exchange during the delay.
49
+ */
50
+ private fire;
51
+ /**
52
+ * Lead with what hits hardest -- except Guarded near the end, which
53
+ * finishes non-lethally: when the target is within a few boxes of death,
54
+ * the next auto action is a subdue (stun damage, bare hands) instead of
55
+ * another killing blow.
56
+ */
57
+ private chooseAction;
58
+ /** One-line HUD/announce description for a stance. */
59
+ static describe(stance: FightStance): string;
60
+ }
@@ -0,0 +1,138 @@
1
+ import { Logger } from './logger.js';
2
+ /**
3
+ * Fight-or-flight autopilot -- the FIGHT half. The player sets a
4
+ * temperature (Tab in the UI, or the "stance" command) and the game keeps
5
+ * swinging for them; flight stays manual, always, because stopping YOUR
6
+ * swings never stops THEIRS -- the only real defense is the door, and
7
+ * that's the player's call.
8
+ *
9
+ * manual -- today's behavior, every action typed
10
+ * guarded -- auto-fights, but wins non-lethally: switches to subdue
11
+ * when the target is nearly down, and stands down the
12
+ * moment they surrender
13
+ * aggressive -- fights until they're dead; a surrender changes nothing
14
+ *
15
+ * Wiring: CombatExchange.finishExchange() -> Scene.notifyExchangeSettled()
16
+ * -> onExchangeSettled() here. If the player was a combatant and the
17
+ * stance says fight, the next action is scheduled a short, interruptible
18
+ * beat later (REENGAGE_DELAY_MS). Submitting ANY command in the UI cancels
19
+ * the pending action and takes over (see ui.ts) -- the beat exists exactly
20
+ * so fleeing and healing stay possible mid-autofight. Everything is
21
+ * revalidated at fire time: the fight may have ended, moved, or been
22
+ * surrendered out of during the delay.
23
+ *
24
+ * Auto actions lead with whatever hits hardest: a caster whose manabolt
25
+ * out-damages their equipped weapon throws the bolt (and eats the drain);
26
+ * everyone else uses the gun/blade/fists they're holding. A dry gun's
27
+ * refusal (reload prompt) is surfaced to the player and auto simply waits
28
+ * for them to deal with it -- reloading is a decision, not a reflex.
29
+ */
30
+ export class AutoFight {
31
+ game;
32
+ static REENGAGE_DELAY_MS = 2000;
33
+ // Manabolt's damage base, mirrored from cast.ts SPELLS (power). Used
34
+ // only for the "what hits hardest" comparison.
35
+ static MANABOLT_POWER = 4;
36
+ pending;
37
+ constructor(game) {
38
+ this.game = game;
39
+ }
40
+ /** The pending auto action, dropped. The player typed, or the stance changed. */
41
+ cancelPending() {
42
+ if (this.pending) {
43
+ clearTimeout(this.pending);
44
+ this.pending = undefined;
45
+ }
46
+ }
47
+ /**
48
+ * Called after every combat exchange resolves (player-involved or not).
49
+ * Schedules the player's next action when the autopilot should act.
50
+ */
51
+ onExchangeSettled(combatants) {
52
+ const player = this.game.player;
53
+ if (!combatants.includes(player))
54
+ return;
55
+ if (player.autoStance === 'manual')
56
+ return;
57
+ const target = combatants.find(c => c !== player);
58
+ if (!target)
59
+ return;
60
+ this.cancelPending();
61
+ this.pending = setTimeout(() => {
62
+ this.pending = undefined;
63
+ void this.fire(target);
64
+ }, AutoFight.REENGAGE_DELAY_MS);
65
+ }
66
+ /**
67
+ * The beat elapsed uninterrupted -- act, if the fight still stands.
68
+ * Every guard here re-checks live state: the target may have died, fled,
69
+ * surrendered, or started another exchange during the delay.
70
+ */
71
+ async fire(target) {
72
+ const player = this.game.player;
73
+ const logger = Logger.getInstance();
74
+ if (player.autoStance === 'manual')
75
+ return;
76
+ if (player.isIncapacitated() || target.isIncapacitated())
77
+ return;
78
+ if (player.currentLocation !== target.currentLocation)
79
+ return;
80
+ // Cross-plane fights don't exist: a dump or a return mid-beat (see
81
+ // utilities/planes.ts) ends the engagement, autopilot included.
82
+ if (player.plane !== target.plane)
83
+ return;
84
+ // A fresh exchange is already in flight -- when IT settles,
85
+ // onExchangeSettled reschedules us. No waiting here.
86
+ if (player.inExchange || target.inExchange)
87
+ return;
88
+ // Guarded honors a surrender -- the fight is over, hold fire. The
89
+ // stand-down is announced once; no reschedule, so the autopilot stays
90
+ // quiet unless violence actually resumes (a new exchange re-arms it).
91
+ if (player.autoStance === 'guarded' && target.surrendered) {
92
+ logger.logWithColor(`⚔ ${target.name} has surrendered -- you hold fire. (guarded)`, 'yellow');
93
+ this.game.updateStatus();
94
+ return;
95
+ }
96
+ const cmd = this.chooseAction(player, target);
97
+ // Cyan, not gray: the autopilot announcing it acted must be legible on
98
+ // stock dark palettes (gray = ANSI bright-black, near-invisible there).
99
+ logger.logWithColor(`⚔ [${player.autoStance}] ${cmd}`, 'cyan');
100
+ const result = await this.game.handleInput(cmd);
101
+ // Player-initiated exchanges self-announce ('' result); anything else
102
+ // (a dry-gun reload prompt, a refusal) is information the player needs.
103
+ if (result) {
104
+ logger.log(result);
105
+ }
106
+ this.game.updateStatus();
107
+ }
108
+ /**
109
+ * Lead with what hits hardest -- except Guarded near the end, which
110
+ * finishes non-lethally: when the target is within a few boxes of death,
111
+ * the next auto action is a subdue (stun damage, bare hands) instead of
112
+ * another killing blow.
113
+ */
114
+ chooseAction(player, target) {
115
+ // Subduing takes real hands (meat plane only); a guarded decker
116
+ // "killing" ice is just crashing a program, and astral entities go
117
+ // down by force -- no non-lethal switch off the meat plane.
118
+ if (player.autoStance === 'guarded' && player.plane === 'meat' &&
119
+ target.maxConditionBoxes - target.damageTaken <= 3) {
120
+ return `subdue ${target.name}`;
121
+ }
122
+ // Magic doesn't compile in the Matrix (see cast.ts); everywhere else,
123
+ // lead with the harder hit.
124
+ if (player.plane !== 'matrix' && player.isCaster() && AutoFight.MANABOLT_POWER > player.getWeaponProfile().damage) {
125
+ return `cast manabolt at ${target.name}`;
126
+ }
127
+ return `attack ${target.name}`;
128
+ }
129
+ /** One-line HUD/announce description for a stance. */
130
+ static describe(stance) {
131
+ switch (stance) {
132
+ case 'manual': return 'you type every action yourself';
133
+ case 'guarded': return 'auto-fight; subdues instead of killing when they are nearly down, holds fire on surrender';
134
+ case 'aggressive': return 'auto-fight to the death; surrender means nothing';
135
+ }
136
+ }
137
+ }
138
+ //# sourceMappingURL=auto-fight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-fight.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/utilities/auto-fight.ts"],"names":[],"mappings":"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"}