@maka/maka-cli 5.3.17 → 5.4.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 (218) hide show
  1. package/bundle/typescript/package.json +1 -1
  2. package/bundle/typescript/src/commands/game/sideQuest/archetypes.d.ts +43 -0
  3. package/bundle/typescript/src/commands/game/sideQuest/archetypes.js +131 -0
  4. package/bundle/typescript/src/commands/game/sideQuest/archetypes.js.map +1 -0
  5. package/bundle/typescript/src/commands/game/sideQuest/commands/assense.d.ts +14 -0
  6. package/bundle/typescript/src/commands/game/sideQuest/commands/assense.js +79 -0
  7. package/bundle/typescript/src/commands/game/sideQuest/commands/assense.js.map +1 -0
  8. package/bundle/typescript/src/commands/game/sideQuest/commands/attack.d.ts +42 -0
  9. package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js +224 -0
  10. package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js.map +1 -0
  11. package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.d.ts +28 -0
  12. package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js +101 -0
  13. package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js.map +1 -0
  14. package/bundle/typescript/src/commands/game/sideQuest/commands/call.d.ts +19 -0
  15. package/bundle/typescript/src/commands/game/sideQuest/commands/call.js +149 -0
  16. package/bundle/typescript/src/commands/game/sideQuest/commands/call.js.map +1 -0
  17. package/bundle/typescript/src/commands/game/sideQuest/commands/cast.d.ts +58 -0
  18. package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js +378 -0
  19. package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js.map +1 -0
  20. package/bundle/typescript/src/commands/game/sideQuest/commands/command-registry.d.ts +11 -1
  21. package/bundle/typescript/src/commands/game/sideQuest/commands/command-registry.js +8 -3
  22. package/bundle/typescript/src/commands/game/sideQuest/commands/command-registry.js.map +1 -1
  23. package/bundle/typescript/src/commands/game/sideQuest/commands/command.d.ts +6 -0
  24. package/bundle/typescript/src/commands/game/sideQuest/commands/command.js +4 -0
  25. package/bundle/typescript/src/commands/game/sideQuest/commands/command.js.map +1 -1
  26. package/bundle/typescript/src/commands/game/sideQuest/commands/drone.d.ts +15 -0
  27. package/bundle/typescript/src/commands/game/sideQuest/commands/drone.js +60 -0
  28. package/bundle/typescript/src/commands/game/sideQuest/commands/drone.js.map +1 -0
  29. package/bundle/typescript/src/commands/game/sideQuest/commands/edge.d.ts +13 -0
  30. package/bundle/typescript/src/commands/game/sideQuest/commands/edge.js +31 -0
  31. package/bundle/typescript/src/commands/game/sideQuest/commands/edge.js.map +1 -0
  32. package/bundle/typescript/src/commands/game/sideQuest/commands/end-call.d.ts +6 -0
  33. package/bundle/typescript/src/commands/game/sideQuest/commands/end-call.js +27 -0
  34. package/bundle/typescript/src/commands/game/sideQuest/commands/end-call.js.map +1 -0
  35. package/bundle/typescript/src/commands/game/sideQuest/commands/equip.d.ts +4 -0
  36. package/bundle/typescript/src/commands/game/sideQuest/commands/equip.js +40 -0
  37. package/bundle/typescript/src/commands/game/sideQuest/commands/equip.js.map +1 -1
  38. package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.d.ts +13 -0
  39. package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.js +43 -0
  40. package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.js.map +1 -0
  41. package/bundle/typescript/src/commands/game/sideQuest/commands/give.js +7 -1
  42. package/bundle/typescript/src/commands/game/sideQuest/commands/give.js.map +1 -1
  43. package/bundle/typescript/src/commands/game/sideQuest/commands/go.d.ts +11 -0
  44. package/bundle/typescript/src/commands/game/sideQuest/commands/go.js +115 -4
  45. package/bundle/typescript/src/commands/game/sideQuest/commands/go.js.map +1 -1
  46. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.d.ts +25 -0
  47. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js +176 -0
  48. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js.map +1 -0
  49. package/bundle/typescript/src/commands/game/sideQuest/commands/inv.d.ts +12 -0
  50. package/bundle/typescript/src/commands/game/sideQuest/commands/inv.js +39 -0
  51. package/bundle/typescript/src/commands/game/sideQuest/commands/inv.js.map +1 -0
  52. package/bundle/typescript/src/commands/game/sideQuest/commands/jack.d.ts +17 -0
  53. package/bundle/typescript/src/commands/game/sideQuest/commands/jack.js +64 -0
  54. package/bundle/typescript/src/commands/game/sideQuest/commands/jack.js.map +1 -0
  55. package/bundle/typescript/src/commands/game/sideQuest/commands/kill.d.ts +10 -3
  56. package/bundle/typescript/src/commands/game/sideQuest/commands/kill.js +11 -33
  57. package/bundle/typescript/src/commands/game/sideQuest/commands/kill.js.map +1 -1
  58. package/bundle/typescript/src/commands/game/sideQuest/commands/look.js +35 -4
  59. package/bundle/typescript/src/commands/game/sideQuest/commands/look.js.map +1 -1
  60. package/bundle/typescript/src/commands/game/sideQuest/commands/map.d.ts +12 -0
  61. package/bundle/typescript/src/commands/game/sideQuest/commands/map.js +46 -0
  62. package/bundle/typescript/src/commands/game/sideQuest/commands/map.js.map +1 -0
  63. package/bundle/typescript/src/commands/game/sideQuest/commands/pan.d.ts +12 -0
  64. package/bundle/typescript/src/commands/game/sideQuest/commands/pan.js +55 -0
  65. package/bundle/typescript/src/commands/game/sideQuest/commands/pan.js.map +1 -0
  66. package/bundle/typescript/src/commands/game/sideQuest/commands/pick.d.ts +9 -0
  67. package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js +18 -0
  68. package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js.map +1 -0
  69. package/bundle/typescript/src/commands/game/sideQuest/commands/project.d.ts +19 -0
  70. package/bundle/typescript/src/commands/game/sideQuest/commands/project.js +54 -0
  71. package/bundle/typescript/src/commands/game/sideQuest/commands/project.js.map +1 -0
  72. package/bundle/typescript/src/commands/game/sideQuest/commands/read.js +6 -5
  73. package/bundle/typescript/src/commands/game/sideQuest/commands/read.js.map +1 -1
  74. package/bundle/typescript/src/commands/game/sideQuest/commands/reboot.d.ts +12 -0
  75. package/bundle/typescript/src/commands/game/sideQuest/commands/reboot.js +52 -0
  76. package/bundle/typescript/src/commands/game/sideQuest/commands/reboot.js.map +1 -0
  77. package/bundle/typescript/src/commands/game/sideQuest/commands/reload.d.ts +14 -0
  78. package/bundle/typescript/src/commands/game/sideQuest/commands/reload.js +40 -0
  79. package/bundle/typescript/src/commands/game/sideQuest/commands/reload.js.map +1 -0
  80. package/bundle/typescript/src/commands/game/sideQuest/commands/rest.d.ts +15 -0
  81. package/bundle/typescript/src/commands/game/sideQuest/commands/rest.js +59 -0
  82. package/bundle/typescript/src/commands/game/sideQuest/commands/rest.js.map +1 -0
  83. package/bundle/typescript/src/commands/game/sideQuest/commands/say.js +23 -2
  84. package/bundle/typescript/src/commands/game/sideQuest/commands/say.js.map +1 -1
  85. package/bundle/typescript/src/commands/game/sideQuest/commands/search.js +20 -3
  86. package/bundle/typescript/src/commands/game/sideQuest/commands/search.js.map +1 -1
  87. package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.d.ts +12 -0
  88. package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js +49 -0
  89. package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js.map +1 -0
  90. package/bundle/typescript/src/commands/game/sideQuest/commands/silent.d.ts +13 -0
  91. package/bundle/typescript/src/commands/game/sideQuest/commands/silent.js +50 -0
  92. package/bundle/typescript/src/commands/game/sideQuest/commands/silent.js.map +1 -0
  93. package/bundle/typescript/src/commands/game/sideQuest/commands/solve.js +32 -11
  94. package/bundle/typescript/src/commands/game/sideQuest/commands/solve.js.map +1 -1
  95. package/bundle/typescript/src/commands/game/sideQuest/commands/spells.d.ts +14 -0
  96. package/bundle/typescript/src/commands/game/sideQuest/commands/spells.js +65 -0
  97. package/bundle/typescript/src/commands/game/sideQuest/commands/spells.js.map +1 -0
  98. package/bundle/typescript/src/commands/game/sideQuest/commands/stance.d.ts +12 -0
  99. package/bundle/typescript/src/commands/game/sideQuest/commands/stance.js +41 -0
  100. package/bundle/typescript/src/commands/game/sideQuest/commands/stance.js.map +1 -0
  101. package/bundle/typescript/src/commands/game/sideQuest/commands/subdue.d.ts +21 -0
  102. package/bundle/typescript/src/commands/game/sideQuest/commands/subdue.js +43 -0
  103. package/bundle/typescript/src/commands/game/sideQuest/commands/subdue.js.map +1 -0
  104. package/bundle/typescript/src/commands/game/sideQuest/commands/surrender.d.ts +20 -0
  105. package/bundle/typescript/src/commands/game/sideQuest/commands/surrender.js +45 -0
  106. package/bundle/typescript/src/commands/game/sideQuest/commands/surrender.js.map +1 -0
  107. package/bundle/typescript/src/commands/game/sideQuest/commands/take.d.ts +8 -0
  108. package/bundle/typescript/src/commands/game/sideQuest/commands/take.js +80 -1
  109. package/bundle/typescript/src/commands/game/sideQuest/commands/take.js.map +1 -1
  110. package/bundle/typescript/src/commands/game/sideQuest/commands/unlock.js +1 -0
  111. package/bundle/typescript/src/commands/game/sideQuest/commands/unlock.js.map +1 -1
  112. package/bundle/typescript/src/commands/game/sideQuest/commands/use.d.ts +24 -0
  113. package/bundle/typescript/src/commands/game/sideQuest/commands/use.js +101 -1
  114. package/bundle/typescript/src/commands/game/sideQuest/commands/use.js.map +1 -1
  115. package/bundle/typescript/src/commands/game/sideQuest/factories/item-factory.js +2 -1
  116. package/bundle/typescript/src/commands/game/sideQuest/factories/item-factory.js.map +1 -1
  117. package/bundle/typescript/src/commands/game/sideQuest/factories/npc-factory.js +7 -2
  118. package/bundle/typescript/src/commands/game/sideQuest/factories/npc-factory.js.map +1 -1
  119. package/bundle/typescript/src/commands/game/sideQuest/factories/puzzle-factory.js +2 -1
  120. package/bundle/typescript/src/commands/game/sideQuest/factories/puzzle-factory.js.map +1 -1
  121. package/bundle/typescript/src/commands/game/sideQuest/factories/room-factory.js +2 -0
  122. package/bundle/typescript/src/commands/game/sideQuest/factories/room-factory.js.map +1 -1
  123. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.d.ts +8 -1
  124. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js +138 -21
  125. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js.map +1 -1
  126. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.d.ts +119 -0
  127. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.js +816 -0
  128. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.js.map +1 -0
  129. package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +70 -9
  130. package/bundle/typescript/src/commands/game/sideQuest/game.js +403 -164
  131. package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
  132. package/bundle/typescript/src/commands/game/sideQuest/minigames/hack-minigame.d.ts +16 -0
  133. package/bundle/typescript/src/commands/game/sideQuest/minigames/hack-minigame.js +101 -0
  134. package/bundle/typescript/src/commands/game/sideQuest/minigames/hack-minigame.js.map +1 -0
  135. package/bundle/typescript/src/commands/game/sideQuest/minigames/lockpick-minigame.d.ts +15 -0
  136. package/bundle/typescript/src/commands/game/sideQuest/minigames/lockpick-minigame.js +95 -0
  137. package/bundle/typescript/src/commands/game/sideQuest/minigames/lockpick-minigame.js.map +1 -0
  138. package/bundle/typescript/src/commands/game/sideQuest/models/door.d.ts +10 -0
  139. package/bundle/typescript/src/commands/game/sideQuest/models/door.js +15 -2
  140. package/bundle/typescript/src/commands/game/sideQuest/models/door.js.map +1 -1
  141. package/bundle/typescript/src/commands/game/sideQuest/models/inventory.d.ts +10 -0
  142. package/bundle/typescript/src/commands/game/sideQuest/models/inventory.js +54 -4
  143. package/bundle/typescript/src/commands/game/sideQuest/models/inventory.js.map +1 -1
  144. package/bundle/typescript/src/commands/game/sideQuest/models/item.d.ts +41 -0
  145. package/bundle/typescript/src/commands/game/sideQuest/models/item.js +106 -3
  146. package/bundle/typescript/src/commands/game/sideQuest/models/item.js.map +1 -1
  147. package/bundle/typescript/src/commands/game/sideQuest/models/npc.d.ts +25 -0
  148. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +220 -47
  149. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
  150. package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +213 -0
  151. package/bundle/typescript/src/commands/game/sideQuest/models/player.js +525 -9
  152. package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
  153. package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.d.ts +75 -1
  154. package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js +174 -6
  155. package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js.map +1 -1
  156. package/bundle/typescript/src/commands/game/sideQuest/models/room.d.ts +20 -0
  157. package/bundle/typescript/src/commands/game/sideQuest/models/room.js +39 -18
  158. package/bundle/typescript/src/commands/game/sideQuest/models/room.js.map +1 -1
  159. package/bundle/typescript/src/commands/game/sideQuest/models/scene.d.ts +69 -0
  160. package/bundle/typescript/src/commands/game/sideQuest/models/scene.js +175 -2
  161. package/bundle/typescript/src/commands/game/sideQuest/models/scene.js.map +1 -1
  162. package/bundle/typescript/src/commands/game/sideQuest/scenes/scene1.json +80 -1
  163. package/bundle/typescript/src/commands/game/sideQuest/scenes/scene2.json +7 -2
  164. package/bundle/typescript/src/commands/game/sideQuest/types/player-equipment.d.ts +1 -0
  165. package/bundle/typescript/src/commands/game/sideQuest/types/seed/exit-seed.d.ts +1 -0
  166. package/bundle/typescript/src/commands/game/sideQuest/types/seed/item-seed.d.ts +1 -0
  167. package/bundle/typescript/src/commands/game/sideQuest/types/seed/npc-seed.d.ts +1 -0
  168. package/bundle/typescript/src/commands/game/sideQuest/types/seed/player-seed.d.ts +34 -0
  169. package/bundle/typescript/src/commands/game/sideQuest/types/seed/puzzle-seed.d.ts +15 -1
  170. package/bundle/typescript/src/commands/game/sideQuest/types/seed/room-seed.d.ts +3 -0
  171. package/bundle/typescript/src/commands/game/sideQuest/types/seed/scene-seed.d.ts +5 -0
  172. package/bundle/typescript/src/commands/game/sideQuest/types/seed/win-condition-seed.d.ts +15 -0
  173. package/bundle/typescript/src/commands/game/sideQuest/types/seed/win-condition-seed.js +2 -0
  174. package/bundle/typescript/src/commands/game/sideQuest/types/seed/win-condition-seed.js.map +1 -0
  175. package/bundle/typescript/src/commands/game/sideQuest/types/shared/abstracts.d.ts +1 -0
  176. package/bundle/typescript/src/commands/game/sideQuest/types/shared/abstracts.js +5 -0
  177. package/bundle/typescript/src/commands/game/sideQuest/types/shared/abstracts.js.map +1 -1
  178. package/bundle/typescript/src/commands/game/sideQuest/types/shared/item-enum.d.ts +1 -0
  179. package/bundle/typescript/src/commands/game/sideQuest/types/shared/item-enum.js +1 -0
  180. package/bundle/typescript/src/commands/game/sideQuest/types/shared/item-enum.js.map +1 -1
  181. package/bundle/typescript/src/commands/game/sideQuest/ui.d.ts +3 -0
  182. package/bundle/typescript/src/commands/game/sideQuest/ui.js +95 -5
  183. package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
  184. package/bundle/typescript/src/commands/game/sideQuest/utilities/auto-fight.d.ts +60 -0
  185. package/bundle/typescript/src/commands/game/sideQuest/utilities/auto-fight.js +138 -0
  186. package/bundle/typescript/src/commands/game/sideQuest/utilities/auto-fight.js.map +1 -0
  187. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.d.ts +143 -0
  188. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js +328 -0
  189. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js.map +1 -0
  190. package/bundle/typescript/src/commands/game/sideQuest/utilities/comm-style.d.ts +2 -0
  191. package/bundle/typescript/src/commands/game/sideQuest/utilities/comm-style.js +12 -0
  192. package/bundle/typescript/src/commands/game/sideQuest/utilities/comm-style.js.map +1 -0
  193. package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.d.ts +22 -0
  194. package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.js +34 -0
  195. package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.js.map +1 -0
  196. package/bundle/typescript/src/commands/game/sideQuest/utilities/fuzzy-match.d.ts +36 -0
  197. package/bundle/typescript/src/commands/game/sideQuest/utilities/fuzzy-match.js +92 -0
  198. package/bundle/typescript/src/commands/game/sideQuest/utilities/fuzzy-match.js.map +1 -0
  199. package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.d.ts +44 -0
  200. package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js +193 -0
  201. package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js.map +1 -0
  202. package/bundle/typescript/src/commands/game/sideQuest/utilities/pursuit.d.ts +16 -0
  203. package/bundle/typescript/src/commands/game/sideQuest/utilities/pursuit.js +36 -0
  204. package/bundle/typescript/src/commands/game/sideQuest/utilities/pursuit.js.map +1 -0
  205. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +54 -7
  206. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
  207. package/bundle/typescript/src/commands/set/global.sub.cmd.js +59 -5
  208. package/bundle/typescript/src/commands/set/global.sub.cmd.js.map +1 -1
  209. package/bundle/typescript/src/tools/ai/ai.class.d.ts +35 -0
  210. package/bundle/typescript/src/tools/ai/ai.class.js +112 -0
  211. package/bundle/typescript/src/tools/ai/ai.class.js.map +1 -0
  212. package/bundle/typescript/src/tools/fsi/fsi.interfaces.d.ts +1 -0
  213. package/bundle/typescript/src/tools/fsi/fsi.interfaces.js.map +1 -1
  214. package/bundle/typescript/src/tools/https/https.class.d.ts +2 -1
  215. package/bundle/typescript/src/tools/https/https.class.js +43 -0
  216. package/bundle/typescript/src/tools/https/https.class.js.map +1 -1
  217. package/bundle/typescript/src/tools/https/https.interface.d.ts +8 -0
  218. package/package.json +1 -1
@@ -0,0 +1,143 @@
1
+ import { Player } from '../models/player.js';
2
+ import { NPC } from '../models/npc.js';
3
+ import { Scene } from '../models/scene.js';
4
+ import { Logger } from './logger.js';
5
+ /**
6
+ * What one directed strike looks like mechanically -- defaults come from
7
+ * the attacker's equipped weapon (see weaponProfile()), but a spell attack
8
+ * supplies its own: a casting pool instead of Agility+skill, and a soak
9
+ * pool that ignores armor (magic's whole niche -- see commands/cast.ts).
10
+ */
11
+ export interface IStrikeProfile {
12
+ /** e.g. "with Ares Light Fire 75", "with a manabolt" */
13
+ label: string;
14
+ pool: number;
15
+ damageBase: number;
16
+ soakPool: number;
17
+ /** The physical weapon behind the strike, when there is one -- lets
18
+ * resolveStrike() spend a round of its ammunition. */
19
+ weaponItem?: import('../models/item.js').Item;
20
+ /** Subdual (see subdue.ts): damage lands on the STUN track instead of
21
+ * physical -- knockouts, not kills (though stun overflow still bleeds
22
+ * into the body). */
23
+ dealStun?: boolean;
24
+ }
25
+ /**
26
+ * The shared combat-exchange engine, extracted from AttackCommand so spell
27
+ * combat (cast.ts) rides the exact same rails: progressive block-by-block
28
+ * narration with beats, opposed strike resolution, death handling through
29
+ * the flows that already exist (removeActor for NPCs, endGame for the
30
+ * player), and the NPC follow-up pause that gives the player a window to
31
+ * act between an NPC's exchanges. See AttackCommand's class doc for the
32
+ * full rationale on pacing and self-announcement -- all of it lives here
33
+ * now, unchanged in behavior.
34
+ */
35
+ export declare class CombatExchange {
36
+ private scene;
37
+ private logger;
38
+ private actor;
39
+ /** Pause between narration blocks so a fight reads as a fight. */
40
+ static readonly BEAT_MS = 900;
41
+ /**
42
+ * Extra breathing room tacked onto the END of an NPC-initiated exchange,
43
+ * before the command returns to the NPC's AI reflect loop (which awaits
44
+ * it, so delaying the return directly throttles its next swing). This is
45
+ * the player's window to heal or flee. Player-typed actions skip it.
46
+ */
47
+ static readonly NPC_FOLLOWUP_PAUSE_MS = 2500;
48
+ constructor(scene: Scene, logger: Logger, actor: Player | NPC);
49
+ /**
50
+ * Call once combat is actually joined (gates passed, target resolved).
51
+ * While an exchange involving the player is resolving, the player can't
52
+ * "go" (see go.ts) -- you don't get to walk out from between an
53
+ * attacker's narration beats mid-exchange. finishExchange() releases the
54
+ * lock BEFORE the between-exchanges pause, which remains the legitimate
55
+ * window to flee or heal. Safe to call for NPC-vs-NPC fights too: the
56
+ * lock only engages when the player is one of the combatants.
57
+ */
58
+ private _combatants;
59
+ beginExchange(target: Player | NPC): void;
60
+ /** Clears the per-combatant serialization flags. Safe to call twice. */
61
+ releaseExchange(): void;
62
+ /**
63
+ * Parks an NPC-driven action until every listed combatant's in-flight
64
+ * exchange settles, so the action fires in the lull instead of being
65
+ * discarded. Without this, an NPC's whole turn evaporated: its AI reacts
66
+ * to the player's attack within a second or two -- always mid-exchange --
67
+ * so every counterattack AND every wounded-NPC flee attempt was refused
68
+ * into its private history. Two real sessions of Krow talking trash while
69
+ * never once shooting back or making the door he was trying to flee
70
+ * through, which read to the player as the game stalling out.
71
+ *
72
+ * Resolves true when the flags clear (caller must revalidate everything:
73
+ * the waiter or its target may have died in the very exchange it sat
74
+ * out); false on timeout, meaning something is stuck and the caller
75
+ * should fall back to a plain refusal.
76
+ */
77
+ static waitForLull(combatants: (Player | NPC)[], timeoutMs?: number): Promise<boolean>;
78
+ /**
79
+ * The initiative roll-off that opens an exchange: Reaction + Intuition
80
+ * (+ live commlink AR bonus, see Player.getInitiativePool). The winner
81
+ * acts first -- attacking someone faster than you means eating their
82
+ * strike before yours lands -- with ties going to the aggressor. Winning
83
+ * by 3+ net hits earns an INITIATIVE PASS: one extra strike at the end
84
+ * of the exchange (the wired-reflexes speed fantasy, without a full
85
+ * action-economy system).
86
+ */
87
+ rollInitiative(aggressor: Player | NPC, defender: Player | NPC): {
88
+ first: Player | NPC;
89
+ second: Player | NPC;
90
+ extraStriker: Player | NPC | null;
91
+ lines: string[];
92
+ };
93
+ /**
94
+ * The player should see a fight's blow-by-blow only when they're actually
95
+ * there for it -- as a combatant or as a bystander in the same room. A
96
+ * brawl between two NPCs elsewhere in the scene stays off-screen, and
97
+ * skips the narration beats entirely.
98
+ */
99
+ playerWitnesses(): boolean;
100
+ /**
101
+ * Pushes one narration block to the player's screen (when they're present
102
+ * for it) and holds a beat before whatever happens next. Only results of
103
+ * commands the PLAYER typed flow through ui.ts's response pipeline; an
104
+ * NPC's command result goes solely into that NPC's own AI history, so
105
+ * without self-announcing here the player would never see the dice of a
106
+ * fight an NPC started. The status box refreshes with every block so the
107
+ * condition monitor visibly ticks as damage lands.
108
+ */
109
+ announce(lines: string[]): Promise<void>;
110
+ /**
111
+ * The default, weapon-based strike profile. A firearm with a dry
112
+ * magazine automatically falls back to bare fists -- this covers the
113
+ * involuntary strikes (retaliation) where refusing to swing at all would
114
+ * make no sense; a deliberately INITIATED attack with a dry gun is
115
+ * blocked with a reload prompt before ever reaching here (attack.ts).
116
+ */
117
+ weaponProfile(attacker: Player | NPC, defender: Player | NPC): IStrikeProfile;
118
+ /** One directed strike: attack vs defense, then soak. Mutates the defender. */
119
+ resolveStrike(attacker: Player | NPC, defender: Player | NPC, profile?: IStrikeProfile): string[];
120
+ /**
121
+ * Death/knockout narration is announced BEFORE the removal side effects
122
+ * run -- removeActor() fires "on death drops" observer lines straight to
123
+ * the screen, so running it first would put the gear hitting the floor
124
+ * before the kill itself. `fallLine`/`gameOverLine` let a caller replace
125
+ * the default gunned-down flavor; `fatal: false` marks a knockout (a
126
+ * full STUN track -- see cast.ts drain) rather than a death: same
127
+ * out-of-the-run consequences, honestly narrated as unconsciousness.
128
+ */
129
+ resolveDeath(fallen: Player | NPC, killer: Player | NPC, opts?: {
130
+ fallLine?: string;
131
+ gameOverLine?: string;
132
+ fatal?: boolean;
133
+ }): Promise<string[]>;
134
+ /**
135
+ * The screen already got everything block-by-block, so the player-typed
136
+ * path returns '' (ui.ts prints the return value -- a second copy would
137
+ * double-display). An NPC actor gets the full report back instead: that
138
+ * return value is what lands in the NPC's AI history, which is how it
139
+ * knows how its own fight went -- but only after the follow-up pause,
140
+ * which is the player's window to act before the NPC's next exchange.
141
+ */
142
+ finishExchange(report: string[]): Promise<string>;
143
+ }
@@ -0,0 +1,328 @@
1
+ import { rollPool, formatRoll } from './dice.js';
2
+ import { leaveMatrix } from './planes.js';
3
+ /**
4
+ * The shared combat-exchange engine, extracted from AttackCommand so spell
5
+ * combat (cast.ts) rides the exact same rails: progressive block-by-block
6
+ * narration with beats, opposed strike resolution, death handling through
7
+ * the flows that already exist (removeActor for NPCs, endGame for the
8
+ * player), and the NPC follow-up pause that gives the player a window to
9
+ * act between an NPC's exchanges. See AttackCommand's class doc for the
10
+ * full rationale on pacing and self-announcement -- all of it lives here
11
+ * now, unchanged in behavior.
12
+ */
13
+ export class CombatExchange {
14
+ scene;
15
+ logger;
16
+ actor;
17
+ /** Pause between narration blocks so a fight reads as a fight. */
18
+ static BEAT_MS = 900;
19
+ /**
20
+ * Extra breathing room tacked onto the END of an NPC-initiated exchange,
21
+ * before the command returns to the NPC's AI reflect loop (which awaits
22
+ * it, so delaying the return directly throttles its next swing). This is
23
+ * the player's window to heal or flee. Player-typed actions skip it.
24
+ */
25
+ static NPC_FOLLOWUP_PAUSE_MS = 2500;
26
+ constructor(scene, logger, actor) {
27
+ this.scene = scene;
28
+ this.logger = logger;
29
+ this.actor = actor;
30
+ }
31
+ /**
32
+ * Call once combat is actually joined (gates passed, target resolved).
33
+ * While an exchange involving the player is resolving, the player can't
34
+ * "go" (see go.ts) -- you don't get to walk out from between an
35
+ * attacker's narration beats mid-exchange. finishExchange() releases the
36
+ * lock BEFORE the between-exchanges pause, which remains the legitimate
37
+ * window to flee or heal. Safe to call for NPC-vs-NPC fights too: the
38
+ * lock only engages when the player is one of the combatants.
39
+ */
40
+ _combatants = [];
41
+ beginExchange(target) {
42
+ const player = this.scene.getPlayer();
43
+ if (this.actor === player || target === player) {
44
+ this.scene.beginPlayerExchange();
45
+ }
46
+ // Serialize combat per combatant (see Player.inExchange) -- callers
47
+ // gate on these flags BEFORE calling beginExchange.
48
+ this._combatants = [this.actor, target];
49
+ this.actor.inExchange = true;
50
+ target.inExchange = true;
51
+ // Initiating violence revokes your own surrender -- hands up means
52
+ // hands up (see commands/surrender.ts). The TARGET's surrender flag
53
+ // stays: being attacked while surrendered doesn't un-surrender you.
54
+ this.actor.surrendered = false;
55
+ // Both sides remember the fight -- this is what a parting shot keys
56
+ // off when either of them tries to walk away (see go.ts).
57
+ const now = Date.now();
58
+ this.actor.combatOpponent = target;
59
+ this.actor.lastExchangeAt = now;
60
+ target.combatOpponent = this.actor;
61
+ target.lastExchangeAt = now;
62
+ }
63
+ /** Clears the per-combatant serialization flags. Safe to call twice. */
64
+ releaseExchange() {
65
+ for (const combatant of this._combatants) {
66
+ combatant.inExchange = false;
67
+ }
68
+ }
69
+ /**
70
+ * Parks an NPC-driven action until every listed combatant's in-flight
71
+ * exchange settles, so the action fires in the lull instead of being
72
+ * discarded. Without this, an NPC's whole turn evaporated: its AI reacts
73
+ * to the player's attack within a second or two -- always mid-exchange --
74
+ * so every counterattack AND every wounded-NPC flee attempt was refused
75
+ * into its private history. Two real sessions of Krow talking trash while
76
+ * never once shooting back or making the door he was trying to flee
77
+ * through, which read to the player as the game stalling out.
78
+ *
79
+ * Resolves true when the flags clear (caller must revalidate everything:
80
+ * the waiter or its target may have died in the very exchange it sat
81
+ * out); false on timeout, meaning something is stuck and the caller
82
+ * should fall back to a plain refusal.
83
+ */
84
+ static async waitForLull(combatants, timeoutMs = 15000) {
85
+ const busy = () => combatants.some(c => c.inExchange);
86
+ const deadline = Date.now() + timeoutMs;
87
+ while (busy()) {
88
+ if (Date.now() >= deadline)
89
+ return false;
90
+ await new Promise(resolve => setTimeout(resolve, 250));
91
+ }
92
+ return true;
93
+ }
94
+ /**
95
+ * The initiative roll-off that opens an exchange: Reaction + Intuition
96
+ * (+ live commlink AR bonus, see Player.getInitiativePool). The winner
97
+ * acts first -- attacking someone faster than you means eating their
98
+ * strike before yours lands -- with ties going to the aggressor. Winning
99
+ * by 3+ net hits earns an INITIATIVE PASS: one extra strike at the end
100
+ * of the exchange (the wired-reflexes speed fantasy, without a full
101
+ * action-economy system).
102
+ */
103
+ rollInitiative(aggressor, defender) {
104
+ const aggRoll = rollPool(aggressor.getInitiativePool());
105
+ const defRoll = rollPool(defender.getInitiativePool());
106
+ const aggressorFirst = aggRoll.hits >= defRoll.hits;
107
+ const first = aggressorFirst ? aggressor : defender;
108
+ const second = aggressorFirst ? defender : aggressor;
109
+ const net = Math.abs(aggRoll.hits - defRoll.hits);
110
+ const extraStriker = net >= 3 ? first : null;
111
+ this.logger.write(`Initiative: ${aggressor.name} ${aggRoll.hits} vs ${defender.name} ${defRoll.hits} -- ${first.name} first${extraStriker ? ' with an extra strike' : ''}.`);
112
+ const lines = [
113
+ `Initiative: ${aggressor.name} ${formatRoll(aggRoll)} vs ${defender.name} ${formatRoll(defRoll)}`,
114
+ ` ${first.name} moves first.${extraStriker ? ` And they're FAST -- an extra strike this exchange.` : ''}`,
115
+ ];
116
+ return { first, second, extraStriker, lines };
117
+ }
118
+ /**
119
+ * The player should see a fight's blow-by-blow only when they're actually
120
+ * there for it -- as a combatant or as a bystander in the same room. A
121
+ * brawl between two NPCs elsewhere in the scene stays off-screen, and
122
+ * skips the narration beats entirely.
123
+ */
124
+ playerWitnesses() {
125
+ // Same room AND perceivable plane (see Player.canPerceive): a Matrix
126
+ // brawl is invisible static to a meat bystander in the same room; an
127
+ // astral observer sees a meat fight below, dimly.
128
+ const player = this.scene.getPlayer();
129
+ return player.currentLocation === this.actor.currentLocation && player.canPerceive(this.actor);
130
+ }
131
+ /**
132
+ * Pushes one narration block to the player's screen (when they're present
133
+ * for it) and holds a beat before whatever happens next. Only results of
134
+ * commands the PLAYER typed flow through ui.ts's response pipeline; an
135
+ * NPC's command result goes solely into that NPC's own AI history, so
136
+ * without self-announcing here the player would never see the dice of a
137
+ * fight an NPC started. The status box refreshes with every block so the
138
+ * condition monitor visibly ticks as damage lands.
139
+ */
140
+ async announce(lines) {
141
+ if (lines.length === 0 || !this.playerWitnesses())
142
+ return;
143
+ this.logger.log(lines.join('\n'));
144
+ this.scene.updateStatus();
145
+ await new Promise(resolve => setTimeout(resolve, CombatExchange.BEAT_MS));
146
+ }
147
+ /**
148
+ * The default, weapon-based strike profile. A firearm with a dry
149
+ * magazine automatically falls back to bare fists -- this covers the
150
+ * involuntary strikes (retaliation) where refusing to swing at all would
151
+ * make no sense; a deliberately INITIATED attack with a dry gun is
152
+ * blocked with a reload prompt before ever reaching here (attack.ts).
153
+ */
154
+ weaponProfile(attacker, defender) {
155
+ const weapon = attacker.getWeaponProfile();
156
+ const weaponItem = attacker.equipment.rightHand?.weapon ?? attacker.equipment.leftHand?.weapon ?? undefined;
157
+ // An armed edge boost (see edge.ts) lands on whichever strike this
158
+ // builds -- the attacker's next swing.
159
+ const edgeBoost = attacker.consumeEdgeBoost();
160
+ if (weaponItem?.isFirearm() && (weaponItem.ammo <= 0 || weaponItem.jammed)) {
161
+ return {
162
+ label: `with bare fists -- ${weaponItem.name} is ${weaponItem.jammed ? 'locked (smartlink hacked)' : 'dry'}`,
163
+ pool: Math.max(0, attacker.getAttackPool() - weapon.poolBonus + edgeBoost),
164
+ damageBase: 2,
165
+ soakPool: defender.getSoakPool(),
166
+ };
167
+ }
168
+ return {
169
+ label: `with ${weapon.name}`,
170
+ pool: attacker.getAttackPool() + edgeBoost,
171
+ damageBase: weapon.damage,
172
+ soakPool: defender.getSoakPool(),
173
+ weaponItem: weaponItem ?? undefined,
174
+ };
175
+ }
176
+ /** One directed strike: attack vs defense, then soak. Mutates the defender. */
177
+ resolveStrike(attacker, defender, profile) {
178
+ const strike = profile ?? this.weaponProfile(attacker, defender);
179
+ const lines = [];
180
+ // Firing costs a round; the last one gets a warning line.
181
+ if (strike.weaponItem?.isFirearm()) {
182
+ strike.weaponItem.fireRound();
183
+ this.logger.write(`${attacker.name} fired ${strike.weaponItem.name} (${strike.weaponItem.ammo} rounds left).`);
184
+ }
185
+ const attack = rollPool(strike.pool);
186
+ const defense = rollPool(defender.getDefensePool());
187
+ lines.push(`${attacker.name} attacks ${defender.name} ${strike.label}:`);
188
+ lines.push(` Attack: ${formatRoll(attack)}`);
189
+ lines.push(` Defense: ${formatRoll(defense)}`);
190
+ const dryWarning = strike.weaponItem?.isFirearm() && strike.weaponItem.ammo === 0
191
+ ? [` ${attacker.name}'s ${strike.weaponItem.name} clicks empty -- that was the last round.`]
192
+ : [];
193
+ const netHits = attack.hits - defense.hits;
194
+ if (attack.criticalGlitch) {
195
+ lines.push(` ${attacker.name}'s attack goes catastrophically wrong -- a clean miss, and everyone nearby heard it.`);
196
+ return [...lines, ...dryWarning];
197
+ }
198
+ if (netHits <= 0) {
199
+ lines.push(` ${defender.name} evades the attack.`);
200
+ return [...lines, ...dryWarning];
201
+ }
202
+ const incoming = strike.damageBase + netHits;
203
+ const soak = rollPool(strike.soakPool);
204
+ const dealt = Math.max(0, incoming - soak.hits);
205
+ lines.push(` Hit! ${netHits} net -- ${incoming} damage incoming.`);
206
+ lines.push(` Soak: ${formatRoll(soak)}`);
207
+ if (dealt === 0) {
208
+ lines.push(` ${defender.name} shrugs it off -- no damage gets through.`);
209
+ return [...lines, ...dryWarning];
210
+ }
211
+ // A jacked-in visitor takes MATRIX damage (only visitors have a
212
+ // simMode -- native ice's normal track IS its integrity, so it takes
213
+ // damage the ordinary way below). Matrix damage is HARDWARE damage:
214
+ // deck rider -- every box lands on the deck's device monitor; a
215
+ // full track BRICKS it: forced dump, dumpshock, fight
216
+ // over. Hot-sim ADDITIONALLY bleeds half the hit
217
+ // (rounded up) into the rider's real stun track.
218
+ // technomancer (no deck) -- a living persona has no hardware to
219
+ // sacrifice: EVERY box is real stun, both sim modes.
220
+ if (defender.plane === 'matrix' && defender.simMode) {
221
+ const deck = defender.activeDeck;
222
+ if (deck) {
223
+ deck.takeDeckDamage(dealt);
224
+ this.logger.write(`${attacker.name} dealt ${dealt} MATRIX damage to ${defender.name}'s ${deck.name} (${deck.deckDamage}/${deck.maxDeckBoxes}).`);
225
+ lines.push(` ${defender.name}'s ${deck.name} takes ${dealt} box${dealt === 1 ? '' : 'es'}: ${deck.deckSummary()}`);
226
+ if (defender.simMode === 'hot') {
227
+ const bio = Math.ceil(dealt / 2);
228
+ const { stun, overflow } = defender.takeStun(bio);
229
+ lines.push(` Biofeedback claws through the hot-sim link -- ${stun} stun: ${defender.stunSummary()}`);
230
+ if (overflow > 0) {
231
+ lines.push(` It's more than a mind can hold -- ${overflow} box${overflow === 1 ? '' : 'es'} spill physical: ${defender.conditionSummary()}`);
232
+ }
233
+ }
234
+ if (deck.isBricked) {
235
+ lines.push(` ${deck.name} BRICKS -- the persona collapses into static --`);
236
+ lines.push(...leaveMatrix(this.scene, defender, { forced: true, reason: `The ice burns your deck out from under you.` }));
237
+ }
238
+ return [...lines, ...dryWarning];
239
+ }
240
+ // Deckless: the living persona. Fall through to the stun branch.
241
+ }
242
+ const asStun = strike.dealStun || (defender.plane === 'matrix' && !!defender.simMode);
243
+ if (asStun) {
244
+ const { stun, overflow } = defender.takeStun(dealt);
245
+ this.logger.write(`${attacker.name} dealt ${dealt} STUN to ${defender.name} (stun ${defender.stunTaken}/${defender.maxStunBoxes}, overflow ${overflow}).`);
246
+ const bioNote = !strike.dealStun ? ' (biofeedback)' : '';
247
+ lines.push(` ${defender.name} takes ${stun} stun${bioNote}: ${defender.stunSummary()}`);
248
+ if (overflow > 0) {
249
+ lines.push(` The beating goes past unconsciousness -- ${overflow} box${overflow === 1 ? '' : 'es'} spill into their body: ${defender.conditionSummary()}`);
250
+ }
251
+ }
252
+ else {
253
+ defender.takeDamage(dealt);
254
+ this.logger.write(`${attacker.name} dealt ${dealt} boxes to ${defender.name} (${defender.damageTaken}/${defender.maxConditionBoxes}).`);
255
+ lines.push(` ${defender.name} takes ${dealt} box${dealt === 1 ? '' : 'es'}: ${defender.conditionSummary()}`);
256
+ }
257
+ return [...lines, ...dryWarning];
258
+ }
259
+ /**
260
+ * Death/knockout narration is announced BEFORE the removal side effects
261
+ * run -- removeActor() fires "on death drops" observer lines straight to
262
+ * the screen, so running it first would put the gear hitting the floor
263
+ * before the kill itself. `fallLine`/`gameOverLine` let a caller replace
264
+ * the default gunned-down flavor; `fatal: false` marks a knockout (a
265
+ * full STUN track -- see cast.ts drain) rather than a death: same
266
+ * out-of-the-run consequences, honestly narrated as unconsciousness.
267
+ */
268
+ async resolveDeath(fallen, killer, opts) {
269
+ const room = fallen.currentLocation;
270
+ const isPlayer = fallen === this.scene.getPlayer();
271
+ // Idempotence: if this NPC was already removed (a concurrent exchange
272
+ // beat us to the kill), don't narrate a second death or re-drop gear.
273
+ if (!isPlayer && this.scene.getActor(fallen.name) !== fallen) {
274
+ this.logger.write(`CombatExchange: ${fallen.name} already resolved as down -- skipping duplicate death.`);
275
+ return [];
276
+ }
277
+ const verb = (opts?.fatal ?? true) ? 'killed' : 'knocked out';
278
+ this.logger.write(`CombatExchange: ${killer.name} ${verb} ${fallen.name} in ${room.name}.`);
279
+ this.scene.addWorldEvent(`${killer.name} ${verb} ${fallen.name} in ${room.name}.`);
280
+ if (isPlayer) {
281
+ const lines = [opts?.fallLine ?? `You collapse. The last thing you see is ${killer.name} standing over you.`];
282
+ await this.announce(lines);
283
+ // Same flow as kill.ts and a fatal bypass: freeze input, self-announce
284
+ // so the reason stays on screen, and wait for ctrl-c ("You died!").
285
+ const gameOverLine = opts?.gameOverLine ?? `💀 GAME OVER: ${fallen.name} was gunned down by ${killer.name}.`;
286
+ void this.scene.endGame().then(() => {
287
+ this.logger.logWithColor(gameOverLine, 'red');
288
+ this.logger.logWithColor(`Press ctrl-c to quit.`, 'red');
289
+ });
290
+ return ['', ...lines];
291
+ }
292
+ const npcFall = (opts?.fatal ?? true)
293
+ ? `${fallen.name} goes down -- dead before they hit the floor. Their gear scatters across ${room.name}.`
294
+ : `${fallen.name} collapses, out cold -- down for the count. Their gear scatters across ${room.name}.`;
295
+ const lines = [opts?.fallLine ?? npcFall];
296
+ await this.announce(lines);
297
+ // scene.removeActor drops everything they carried AND wore where they
298
+ // fell -- its observer lines now correctly land after the kill above.
299
+ this.scene.removeActor(fallen.name);
300
+ return ['', ...lines];
301
+ }
302
+ /**
303
+ * The screen already got everything block-by-block, so the player-typed
304
+ * path returns '' (ui.ts prints the return value -- a second copy would
305
+ * double-display). An NPC actor gets the full report back instead: that
306
+ * return value is what lands in the NPC's AI history, which is how it
307
+ * knows how its own fight went -- but only after the follow-up pause,
308
+ * which is the player's window to act before the NPC's next exchange.
309
+ */
310
+ async finishExchange(report) {
311
+ // The exchange is resolved -- movement unlocks BEFORE the follow-up
312
+ // pause below, so the pause stays the window to flee or heal.
313
+ this.scene.endPlayerExchange();
314
+ this.releaseExchange();
315
+ this.scene.updateStatus();
316
+ // The fight autopilot's trigger: a settled exchange involving the
317
+ // player schedules their next auto action (see utilities/auto-fight.ts).
318
+ this.scene.notifyExchangeSettled(this._combatants);
319
+ if (this.actor === this.scene.getPlayer()) {
320
+ return '';
321
+ }
322
+ if (this.playerWitnesses()) {
323
+ await new Promise(resolve => setTimeout(resolve, CombatExchange.NPC_FOLLOWUP_PAUSE_MS));
324
+ }
325
+ return report.join('\n');
326
+ }
327
+ }
328
+ //# sourceMappingURL=combat-exchange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combat-exchange.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/utilities/combat-exchange.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const CALL_ICON = "\uD83D\uDCDE";
2
+ export declare const CALL_COLOR = "cyan";
@@ -0,0 +1,12 @@
1
+ // Visual styling for commlink/AR-context messages. A call stays in the main
2
+ // log window (it's not a separate view -- it's augmented reality laid over
3
+ // wherever the player already is), but is tagged with a distinct icon and
4
+ // color so it visibly reads as a different "space" than in-person dialogue.
5
+ //
6
+ // Future contexts (the Astral Plane, VR hot-sim/cold-sim) are expected to
7
+ // follow the same shape: their own icon/color pair, applied the same way --
8
+ // not a bigger context system, just more constants like this one, until
9
+ // there's an actual second context to justify one.
10
+ export const CALL_ICON = '📞';
11
+ export const CALL_COLOR = 'cyan';
12
+ //# sourceMappingURL=comm-style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comm-style.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/utilities/comm-style.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,2EAA2E;AAC3E,0EAA0E;AAC1E,4EAA4E;AAC5E,EAAE;AACF,0EAA0E;AAC1E,4EAA4E;AAC5E,wEAAwE;AACxE,mDAAmD;AACnD,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC;AAC9B,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Shadowrun-style d6 dice pools: roll N six-siders, every 5 or 6 is a hit.
3
+ * A "glitch" is rolling 1s on more than half the pool (something went ugly
4
+ * even if you succeeded); a "critical glitch" is glitching with zero hits
5
+ * (it went ugly AND you failed). Pure functions, no game-state knowledge --
6
+ * combat resolution lives in commands/attack.ts.
7
+ */
8
+ export interface IDiceRoll {
9
+ pool: number;
10
+ rolls: number[];
11
+ hits: number;
12
+ glitch: boolean;
13
+ criticalGlitch: boolean;
14
+ }
15
+ export declare function rollPool(pool: number): IDiceRoll;
16
+ /**
17
+ * One-line render of a roll for the game log, e.g.:
18
+ * "8d6 [6 5 5 3 2 1 4 6] -> 4 hits"
19
+ * The raw dice faces are shown on purpose -- watching the pool land is
20
+ * most of the fun of dice-pool combat.
21
+ */
22
+ export declare function formatRoll(roll: IDiceRoll): string;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Shadowrun-style d6 dice pools: roll N six-siders, every 5 or 6 is a hit.
3
+ * A "glitch" is rolling 1s on more than half the pool (something went ugly
4
+ * even if you succeeded); a "critical glitch" is glitching with zero hits
5
+ * (it went ugly AND you failed). Pure functions, no game-state knowledge --
6
+ * combat resolution lives in commands/attack.ts.
7
+ */
8
+ export function rollPool(pool) {
9
+ const size = Math.max(0, Math.floor(pool));
10
+ const rolls = Array.from({ length: size }, () => 1 + Math.floor(Math.random() * 6));
11
+ const hits = rolls.filter(r => r >= 5).length;
12
+ const ones = rolls.filter(r => r === 1).length;
13
+ const glitch = size > 0 && ones > size / 2;
14
+ return {
15
+ pool: size,
16
+ rolls,
17
+ hits,
18
+ glitch,
19
+ criticalGlitch: glitch && hits === 0,
20
+ };
21
+ }
22
+ /**
23
+ * One-line render of a roll for the game log, e.g.:
24
+ * "8d6 [6 5 5 3 2 1 4 6] -> 4 hits"
25
+ * The raw dice faces are shown on purpose -- watching the pool land is
26
+ * most of the fun of dice-pool combat.
27
+ */
28
+ export function formatRoll(roll) {
29
+ if (roll.pool === 0)
30
+ return '0d6 -> no dice to roll';
31
+ const glitchTag = roll.criticalGlitch ? ' -- CRITICAL GLITCH' : roll.glitch ? ' -- glitch' : '';
32
+ return `${roll.pool}d6 [${roll.rolls.join(' ')}] -> ${roll.hits} hit${roll.hits === 1 ? '' : 's'}${glitchTag}`;
33
+ }
34
+ //# sourceMappingURL=dice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dice.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/utilities/dice.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACpF,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IAC/C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;IAE3C,OAAO;QACL,IAAI,EAAE,IAAI;QACV,KAAK;QACL,IAAI;QACJ,MAAM;QACN,cAAc,EAAE,MAAM,IAAI,IAAI,KAAK,CAAC;KACrC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,IAAe;IACxC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,wBAAwB,CAAC;IACrD,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAChG,OAAO,GAAG,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,SAAS,EAAE,CAAC;AACjH,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Shared fuzzy name-matching, extracted from Inventory's item resolution so
3
+ * actor targeting (attack.ts, cast.ts) behaves the same way "take" does --
4
+ * found via a real session where "cast manabolt at mr krow" failed against
5
+ * "Mr. Krow" over a missing period. Three tiers, in order of confidence:
6
+ *
7
+ * 1. Exact match on the loosely-normalized strings (case, punctuation,
8
+ * and extra whitespace ignored -- "mr krow" == "Mr. Krow").
9
+ * 2. Substring containment, either direction -- short aliases ("krow"),
10
+ * or extra/missing words at the edges.
11
+ * 3. Word-overlap with light per-word typo tolerance (Levenshtein <= 1
12
+ * on words longer than 3 chars, stopwords ignored) -- misspellings
13
+ * and reordered/inserted words.
14
+ *
15
+ * A tier only matches when it produces exactly ONE candidate (or a clear
16
+ * best score) -- an ambiguous guess deliberately misses rather than
17
+ * picking someone at random.
18
+ */
19
+ export declare const STOPWORDS: Set<string>;
20
+ /** Lowercase, strip punctuation, collapse whitespace. */
21
+ export declare function normalizeLoose(s: string): string;
22
+ export declare function significantWords(s: string): string[];
23
+ export declare function wordsAreCloseEnough(a: string, b: string): boolean;
24
+ /**
25
+ * Damerau-Levenshtein (OSA variant): like plain Levenshtein but a swap of
26
+ * two adjacent letters counts as ONE edit, not two -- transpositions
27
+ * ("jhonson" for "johnson", "teh" for "the") are the single most common
28
+ * typo class, and plain Levenshtein prices them out of the <=1 tolerance.
29
+ */
30
+ export declare function levenshteinDistance(a: string, b: string): number;
31
+ /**
32
+ * Picks the single name from `names` that `input` most plausibly refers
33
+ * to, or undefined when nothing (or more than one thing) qualifies.
34
+ * Returns the ORIGINAL name string, not the normalized form.
35
+ */
36
+ export declare function fuzzyPickName(input: string, names: string[]): string | undefined;