@maka/maka-cli 5.64.0 → 5.65.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/bundle/typescript/package.json +4 -3
  2. package/bundle/typescript/src/commands/game/sideQuest/commands/backlog.d.ts +29 -2
  3. package/bundle/typescript/src/commands/game/sideQuest/commands/backlog.js +165 -1
  4. package/bundle/typescript/src/commands/game/sideQuest/commands/backlog.js.map +1 -1
  5. package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.d.ts +40 -13
  6. package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js +107 -25
  7. package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js.map +1 -1
  8. package/bundle/typescript/src/commands/game/sideQuest/commands/breach.d.ts +11 -15
  9. package/bundle/typescript/src/commands/game/sideQuest/commands/breach.js +13 -16
  10. package/bundle/typescript/src/commands/game/sideQuest/commands/breach.js.map +1 -1
  11. package/bundle/typescript/src/commands/game/sideQuest/commands/buy.d.ts +8 -0
  12. package/bundle/typescript/src/commands/game/sideQuest/commands/buy.js +30 -2
  13. package/bundle/typescript/src/commands/game/sideQuest/commands/buy.js.map +1 -1
  14. package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.d.ts +40 -49
  15. package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js +121 -160
  16. package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js.map +1 -1
  17. package/bundle/typescript/src/commands/game/sideQuest/commands/cast.d.ts +7 -8
  18. package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js +13 -13
  19. package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js.map +1 -1
  20. package/bundle/typescript/src/commands/game/sideQuest/commands/cover.d.ts +30 -0
  21. package/bundle/typescript/src/commands/game/sideQuest/commands/cover.js +65 -0
  22. package/bundle/typescript/src/commands/game/sideQuest/commands/cover.js.map +1 -0
  23. package/bundle/typescript/src/commands/game/sideQuest/commands/dispel.d.ts +1 -1
  24. package/bundle/typescript/src/commands/game/sideQuest/commands/dispel.js +2 -2
  25. package/bundle/typescript/src/commands/game/sideQuest/commands/dispel.js.map +1 -1
  26. package/bundle/typescript/src/commands/game/sideQuest/commands/go.js +25 -3
  27. package/bundle/typescript/src/commands/game/sideQuest/commands/go.js.map +1 -1
  28. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.d.ts +2 -3
  29. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js +2 -2
  30. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js.map +1 -1
  31. package/bundle/typescript/src/commands/game/sideQuest/commands/job-offer.js +9 -1
  32. package/bundle/typescript/src/commands/game/sideQuest/commands/job-offer.js.map +1 -1
  33. package/bundle/typescript/src/commands/game/sideQuest/commands/jobs.js +2 -1
  34. package/bundle/typescript/src/commands/game/sideQuest/commands/jobs.js.map +1 -1
  35. package/bundle/typescript/src/commands/game/sideQuest/commands/look.js +58 -2
  36. package/bundle/typescript/src/commands/game/sideQuest/commands/look.js.map +1 -1
  37. package/bundle/typescript/src/commands/game/sideQuest/commands/map.js +18 -4
  38. package/bundle/typescript/src/commands/game/sideQuest/commands/map.js.map +1 -1
  39. package/bundle/typescript/src/commands/game/sideQuest/commands/move.js +1 -1
  40. package/bundle/typescript/src/commands/game/sideQuest/commands/pick.d.ts +2 -3
  41. package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js +2 -2
  42. package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js.map +1 -1
  43. package/bundle/typescript/src/commands/game/sideQuest/commands/posture.d.ts +45 -0
  44. package/bundle/typescript/src/commands/game/sideQuest/commands/posture.js +115 -0
  45. package/bundle/typescript/src/commands/game/sideQuest/commands/posture.js.map +1 -0
  46. package/bundle/typescript/src/commands/game/sideQuest/commands/say.d.ts +1 -0
  47. package/bundle/typescript/src/commands/game/sideQuest/commands/say.js +80 -9
  48. package/bundle/typescript/src/commands/game/sideQuest/commands/say.js.map +1 -1
  49. package/bundle/typescript/src/commands/game/sideQuest/commands/search.js +35 -24
  50. package/bundle/typescript/src/commands/game/sideQuest/commands/search.js.map +1 -1
  51. package/bundle/typescript/src/commands/game/sideQuest/commands/take.js +12 -0
  52. package/bundle/typescript/src/commands/game/sideQuest/commands/take.js.map +1 -1
  53. package/bundle/typescript/src/commands/game/sideQuest/commands/unlock.js +1 -1
  54. package/bundle/typescript/src/commands/game/sideQuest/commands/unlock.js.map +1 -1
  55. package/bundle/typescript/src/commands/game/sideQuest/commands/use.d.ts +17 -0
  56. package/bundle/typescript/src/commands/game/sideQuest/commands/use.js +158 -1
  57. package/bundle/typescript/src/commands/game/sideQuest/commands/use.js.map +1 -1
  58. package/bundle/typescript/src/commands/game/sideQuest/engine-version.d.ts +1 -1
  59. package/bundle/typescript/src/commands/game/sideQuest/engine-version.js +15 -1
  60. package/bundle/typescript/src/commands/game/sideQuest/engine-version.js.map +1 -1
  61. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.d.ts +82 -43
  62. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +419 -263
  63. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js.map +1 -1
  64. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js +82 -84
  65. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js.map +1 -1
  66. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.d.ts +23 -4
  67. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.js +95 -79
  68. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.js.map +1 -1
  69. package/bundle/typescript/src/commands/game/sideQuest/factories/seed-migration.d.ts +30 -0
  70. package/bundle/typescript/src/commands/game/sideQuest/factories/seed-migration.js +176 -0
  71. package/bundle/typescript/src/commands/game/sideQuest/factories/seed-migration.js.map +1 -0
  72. package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +10 -0
  73. package/bundle/typescript/src/commands/game/sideQuest/game.js +21 -5
  74. package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
  75. package/bundle/typescript/src/commands/game/sideQuest/headless.js +24 -0
  76. package/bundle/typescript/src/commands/game/sideQuest/headless.js.map +1 -1
  77. package/bundle/typescript/src/commands/game/sideQuest/models/_index.d.ts +0 -1
  78. package/bundle/typescript/src/commands/game/sideQuest/models/_index.js +0 -1
  79. package/bundle/typescript/src/commands/game/sideQuest/models/_index.js.map +1 -1
  80. package/bundle/typescript/src/commands/game/sideQuest/models/device.d.ts +121 -0
  81. package/bundle/typescript/src/commands/game/sideQuest/models/device.js +145 -0
  82. package/bundle/typescript/src/commands/game/sideQuest/models/device.js.map +1 -0
  83. package/bundle/typescript/src/commands/game/sideQuest/models/door.d.ts +27 -8
  84. package/bundle/typescript/src/commands/game/sideQuest/models/door.js +15 -10
  85. package/bundle/typescript/src/commands/game/sideQuest/models/door.js.map +1 -1
  86. package/bundle/typescript/src/commands/game/sideQuest/models/npc.d.ts +81 -0
  87. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +138 -21
  88. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
  89. package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +68 -0
  90. package/bundle/typescript/src/commands/game/sideQuest/models/player.js +102 -0
  91. package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
  92. package/bundle/typescript/src/commands/game/sideQuest/models/room.d.ts +72 -43
  93. package/bundle/typescript/src/commands/game/sideQuest/models/room.js +82 -59
  94. package/bundle/typescript/src/commands/game/sideQuest/models/room.js.map +1 -1
  95. package/bundle/typescript/src/commands/game/sideQuest/models/scene.d.ts +1 -4
  96. package/bundle/typescript/src/commands/game/sideQuest/models/scene.js +0 -22
  97. package/bundle/typescript/src/commands/game/sideQuest/models/scene.js.map +1 -1
  98. package/bundle/typescript/src/commands/game/sideQuest/scenes/scene1.json +78 -109
  99. package/bundle/typescript/src/commands/game/sideQuest/scenes/scene2.json +4 -101
  100. package/bundle/typescript/src/commands/game/sideQuest/types/save-file.d.ts +24 -0
  101. package/bundle/typescript/src/commands/game/sideQuest/types/seed/device-seed.d.ts +52 -0
  102. package/bundle/typescript/src/commands/game/sideQuest/types/seed/device-seed.js +2 -0
  103. package/bundle/typescript/src/commands/game/sideQuest/types/seed/device-seed.js.map +1 -0
  104. package/bundle/typescript/src/commands/game/sideQuest/types/seed/legacy-puzzle-seed.d.ts +63 -0
  105. package/bundle/typescript/src/commands/game/sideQuest/types/seed/legacy-puzzle-seed.js +2 -0
  106. package/bundle/typescript/src/commands/game/sideQuest/types/seed/legacy-puzzle-seed.js.map +1 -0
  107. package/bundle/typescript/src/commands/game/sideQuest/types/seed/player-seed.d.ts +6 -0
  108. package/bundle/typescript/src/commands/game/sideQuest/types/seed/room-seed.d.ts +4 -0
  109. package/bundle/typescript/src/commands/game/sideQuest/types/seed/scene-seed.d.ts +3 -2
  110. package/bundle/typescript/src/commands/game/sideQuest/types/shared/abstracts.d.ts +2 -28
  111. package/bundle/typescript/src/commands/game/sideQuest/types/shared/abstracts.js +1 -14
  112. package/bundle/typescript/src/commands/game/sideQuest/types/shared/abstracts.js.map +1 -1
  113. package/bundle/typescript/src/commands/game/sideQuest/ui.js +24 -0
  114. package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
  115. package/bundle/typescript/src/commands/game/sideQuest/utilities/affordances.d.ts +55 -0
  116. package/bundle/typescript/src/commands/game/sideQuest/utilities/affordances.js +36 -0
  117. package/bundle/typescript/src/commands/game/sideQuest/utilities/affordances.js.map +1 -0
  118. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-review.d.ts +65 -0
  119. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-review.js +137 -0
  120. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-review.js.map +1 -0
  121. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog.d.ts +90 -1
  122. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog.js +103 -1
  123. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog.js.map +1 -1
  124. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js +37 -4
  125. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js.map +1 -1
  126. package/bundle/typescript/src/commands/game/sideQuest/utilities/credentials.d.ts +26 -0
  127. package/bundle/typescript/src/commands/game/sideQuest/utilities/credentials.js +48 -0
  128. package/bundle/typescript/src/commands/game/sideQuest/utilities/credentials.js.map +1 -0
  129. package/bundle/typescript/src/commands/game/sideQuest/utilities/devices.d.ts +23 -0
  130. package/bundle/typescript/src/commands/game/sideQuest/utilities/devices.js +55 -0
  131. package/bundle/typescript/src/commands/game/sideQuest/utilities/devices.js.map +1 -0
  132. package/bundle/typescript/src/commands/game/sideQuest/utilities/fuzzy-match.d.ts +57 -2
  133. package/bundle/typescript/src/commands/game/sideQuest/utilities/fuzzy-match.js +46 -3
  134. package/bundle/typescript/src/commands/game/sideQuest/utilities/fuzzy-match.js.map +1 -1
  135. package/bundle/typescript/src/commands/game/sideQuest/utilities/log-style.d.ts +16 -0
  136. package/bundle/typescript/src/commands/game/sideQuest/utilities/log-style.js +18 -0
  137. package/bundle/typescript/src/commands/game/sideQuest/utilities/log-style.js.map +1 -1
  138. package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js +68 -38
  139. package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js.map +1 -1
  140. package/bundle/typescript/src/commands/game/sideQuest/utilities/room-grid.d.ts +3 -3
  141. package/bundle/typescript/src/commands/game/sideQuest/utilities/room-grid.js +3 -3
  142. package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.d.ts +36 -12
  143. package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js +101 -27
  144. package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js.map +1 -1
  145. package/bundle/typescript/src/commands/game/sideQuest/utilities/use-target.d.ts +106 -0
  146. package/bundle/typescript/src/commands/game/sideQuest/utilities/use-target.js +184 -0
  147. package/bundle/typescript/src/commands/game/sideQuest/utilities/use-target.js.map +1 -0
  148. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +54 -5
  149. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
  150. package/bundle/typescript/src/maka.js +1 -1
  151. package/bundle/typescript/src/maka.js.map +1 -1
  152. package/bundle/typescript/src/tools/sdk-loader/relocate.d.ts +19 -2
  153. package/bundle/typescript/src/tools/sdk-loader/relocate.js +22 -2
  154. package/bundle/typescript/src/tools/sdk-loader/relocate.js.map +1 -1
  155. package/package.json +4 -3
  156. package/bundle/typescript/src/commands/game/sideQuest/commands/solve.d.ts +0 -6
  157. package/bundle/typescript/src/commands/game/sideQuest/commands/solve.js +0 -72
  158. package/bundle/typescript/src/commands/game/sideQuest/commands/solve.js.map +0 -1
  159. package/bundle/typescript/src/commands/game/sideQuest/factories/puzzle-factory.d.ts +0 -6
  160. package/bundle/typescript/src/commands/game/sideQuest/factories/puzzle-factory.js +0 -26
  161. package/bundle/typescript/src/commands/game/sideQuest/factories/puzzle-factory.js.map +0 -1
  162. package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.d.ts +0 -152
  163. package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js +0 -393
  164. package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js.map +0 -1
  165. package/bundle/typescript/src/commands/game/sideQuest/types/seed/puzzle-seed.d.ts +0 -28
  166. package/bundle/typescript/src/commands/game/sideQuest/types/seed/puzzle-seed.js +0 -2
  167. package/bundle/typescript/src/commands/game/sideQuest/types/seed/puzzle-seed.js.map +0 -1
@@ -3,27 +3,24 @@ import { rollPool, formatRoll } from '../utilities/dice.js';
3
3
  /**
4
4
  * The FORCEFUL route past a physical barrier (player ruling: "solve" was
5
5
  * too broad -- a maglock wants finesse OR muscle, and muscle deserves its
6
- * own verb). Same barrier class as "pick" (bypassType lockpick), opposite
6
+ * own verb). Same device kind as "pick" (a lock), opposite
7
7
  * philosophy: raw Strength + Body instead of Agility + locksmith, and it
8
8
  * is LOUD no matter what -- a successful breach still raises the world
9
9
  * and ends any sneak (onBypassSuccess), where a clean pick stays quiet.
10
- * The two verbs share the barrier's one burned flag: a seized mechanism
11
- * or a sprung frame spends the shortcut for both -- the findable answer
12
- * remains untouched, as always. The SHARED flag is deliberate; the
13
- * shared WORDING was not. This used to carry a note calling it an
14
- * accepted wart that a breach-burned barrier re-refused with the
15
- * snapped-pick line -- it stopped being acceptable the moment a player
16
- * noticed being told about a pick they never owned (2026-08-27). Hence
17
- * burnedFlavor below: same flag, own fiction. Do not reinstate the wart.
10
+ * NOTHING BURNS ANY MORE. Both verbs used to share the barrier's one
11
+ * "burned" flag -- a failed attempt spent the shortcut for good -- and
12
+ * that flag went with the puzzle mechanic. A lock you failed to force
13
+ * is a lock you can throw yourself at again, which is what a lock is.
14
+ * The trade against "pick" is undiminished: breach is loud whether or
15
+ * not it works, and that is what you are choosing.
18
16
  */
19
17
  export class BreachCommand extends BypassCommand {
20
18
  static verb = 'breach';
21
- static description = 'Force a physical barrier open with raw muscle -- Strength + Body, no skill needed. Loud EVEN WHEN IT WORKS: the crash carries and any sneak is over. Fail, and the frame seizes for good (the real code still works). "breach north" or "breach <name>" if there\'s more than one.';
22
- bypassType = 'lockpick';
19
+ static description = 'Force a physical barrier open with raw muscle -- Strength + Body, no skill needed. Loud EVEN WHEN IT WORKS: the crash carries and any sneak is over. Fail and it holds -- try again if you like, but the boom has already carried. "breach north" or "breach <name>" if there\'s more than one.';
20
+ deviceKind = 'lock';
23
21
  verbName = 'breach';
24
- noPuzzleMessage = "There's nothing here to breach -- no physical barrier holds this room.";
22
+ noDeviceMessage = "There's nothing here to breach -- no physical barrier holds this room.";
25
23
  failureFlavor = `You slam into it and it HOLDS -- the frame seizes solid, and the boom rolls down every corridor on the floor.`;
26
- burnedFlavor = `The frame is sprung and jammed hard in its seat -- you've already thrown everything you have at it, and it won't give twice. Only the real code opens it now.`;
27
24
  async execute(args) {
28
25
  // Shoulders are meat -- same plane fiction as pick.ts.
29
26
  if (this.actor.plane === 'matrix') {
@@ -51,11 +48,11 @@ export class BreachCommand extends BypassCommand {
51
48
  /** Breaching is loud when it WORKS, too -- the defining trade against
52
49
  * pick. The world event lets every listening NPC react (same channel
53
50
  * the failure alarm uses); the sneak is over either way. */
54
- async onBypassSuccess(target) {
51
+ async onForceSuccess(device) {
55
52
  this.actor.sneaking = false;
56
- this.scene.addWorldEvent(`${this.actor.name} breached "${target.puzzle.name}" in ${this.actor.currentLocation.name} -- the crash carried.`);
53
+ this.scene.addWorldEvent(`${this.actor.name} breached "${device.name}" in ${this.actor.currentLocation.name} -- the crash carried.`);
57
54
  // A breach is loud past the walls too (heat -- SINs & getting caught).
58
- this.game?.addHeat(2, `breached "${target.puzzle.name}"`);
55
+ this.game?.addHeat(2, `breached "${device.name}"`);
59
56
  return [` The crash CARRIES -- anyone nearby knows exactly where you are now.`];
60
57
  }
61
58
  }
@@ -1 +1 @@
1
- {"version":3,"file":"breach.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/breach.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE5D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,aAAc,SAAQ,aAAa;IACpC,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;IACvB,MAAM,CAAC,WAAW,GAAG,oRAAoR,CAAC;IAC1S,UAAU,GAAqB,UAAU,CAAC;IAC1C,QAAQ,GAAG,QAAQ,CAAC;IACpB,eAAe,GAAG,wEAAwE,CAAC;IAC3F,aAAa,GAAG,+GAA+G,CAAC;IAChI,YAAY,GAAG,+JAA+J,CAAC;IAEzL,KAAK,CAAC,OAAO,CAAC,IAAc;QAC1B,uDAAuD;QACvD,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,+DAA+D,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,IAAI,cAAc,uCAAuC,CAAC;QAC3J,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,uGAAuG,CAAC;QACjH,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;YACjC,OAAO,4EAA4E,CAAC;QACtF,CAAC;QACD,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAES,KAAK,CAAC,gBAAgB;QAC9B,kEAAkE;QAClE,qEAAqE;QACrE,6BAA6B;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC1H,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;IACxB,CAAC;IAED;;gEAE4D;IAClD,KAAK,CAAC,eAAe,CAAC,MAAoB;QAClD,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,cAAc,MAAM,CAAC,MAAM,CAAC,IAAI,QAAQ,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,wBAAwB,CAAC,CAAC;QAC5I,uEAAuE;QACvE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,EAAE,aAAa,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;QAC1D,OAAO,CAAC,uEAAuE,CAAC,CAAC;IACnF,CAAC"}
1
+ {"version":3,"file":"breach.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/breach.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE5D;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,aAAc,SAAQ,aAAa;IACpC,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;IACvB,MAAM,CAAC,WAAW,GAAG,iSAAiS,CAAC;IACvT,UAAU,GAAG,MAAe,CAAC;IAC7B,QAAQ,GAAG,QAAQ,CAAC;IACpB,eAAe,GAAG,wEAAwE,CAAC;IAC3F,aAAa,GAAG,+GAA+G,CAAC;IAE1I,KAAK,CAAC,OAAO,CAAC,IAAc;QAC1B,uDAAuD;QACvD,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,+DAA+D,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,IAAI,cAAc,uCAAuC,CAAC;QAC3J,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,uGAAuG,CAAC;QACjH,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;YACjC,OAAO,4EAA4E,CAAC;QACtF,CAAC;QACD,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAES,KAAK,CAAC,gBAAgB;QAC9B,kEAAkE;QAClE,qEAAqE;QACrE,6BAA6B;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC1H,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;IACxB,CAAC;IAED;;gEAE4D;IAClD,KAAK,CAAC,cAAc,CAAC,MAAc;QAC3C,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,cAAc,MAAM,CAAC,IAAI,QAAQ,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,wBAAwB,CAAC,CAAC;QACrI,uEAAuE;QACvE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,EAAE,aAAa,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;QACnD,OAAO,CAAC,uEAAuE,CAAC,CAAC;IACnF,CAAC"}
@@ -11,6 +11,14 @@ export declare class BuyCommand extends Command implements ICommand {
11
11
  protected static verb: string;
12
12
  protected static description: string;
13
13
  execute(args?: string[]): Promise<string>;
14
+ /**
15
+ * The shelf, flattened in PRINT ORDER across every vendor in the room
16
+ * -- the list "buy <n>" indexes into. One function so the numbers a
17
+ * player reads and the numbers the parser honours cannot drift apart:
18
+ * browse() and purchase() both call it rather than each walking the
19
+ * vendors themselves.
20
+ */
21
+ private shelf;
14
22
  private browse;
15
23
  /** Is what they asked for inside a present contact's TRADE (the same
16
24
  * domain list their AI is briefed on in npc.ts)? Returns the item
@@ -2,6 +2,8 @@ import { Command } from './command.js';
2
2
  import { hint } from '../utilities/hints.js';
3
3
  import { priceOf, vendorsInRoom, waresOf, shelfNote } from '../utilities/commerce.js';
4
4
  import { findCatalogItem, ROLE_DOMAINS } from '../utilities/catalog.js';
5
+ import { optionMark } from '../utilities/log-style.js';
6
+ import { fuzzyPickName } from '../utilities/fuzzy-match.js';
5
7
  /**
6
8
  * Diegetic shopping: "browse" (or bare "buy") in a vendor's room reads
7
9
  * their shelves with live prices; "buy <item>" slides the nuyen across
@@ -31,19 +33,36 @@ export class BuyCommand extends Command {
31
33
  }
32
34
  return this.purchase(args.join(' '), vendors);
33
35
  }
36
+ /**
37
+ * The shelf, flattened in PRINT ORDER across every vendor in the room
38
+ * -- the list "buy <n>" indexes into. One function so the numbers a
39
+ * player reads and the numbers the parser honours cannot drift apart:
40
+ * browse() and purchase() both call it rather than each walking the
41
+ * vendors themselves.
42
+ */
43
+ shelf(vendors) {
44
+ const out = [];
45
+ for (const vendor of vendors) {
46
+ for (const item of waresOf(this.actor.currentLocation, vendor.name))
47
+ out.push(item);
48
+ }
49
+ return out;
50
+ }
34
51
  browse(vendors, room) {
35
52
  const lines = [];
53
+ let nth = 0;
36
54
  for (const vendor of vendors) {
37
55
  const wares = waresOf(this.actor.currentLocation, vendor.name);
38
56
  lines.push(`${vendor.name}'s wares:`);
39
57
  for (const item of wares) {
58
+ nth += 1;
40
59
  const price = priceOf(item);
41
60
  const dots = '.'.repeat(Math.max(2, 28 - item.name.length));
42
- lines.push(` ${item.name} ${dots} ${price} nuyen${shelfNote(item)}`);
61
+ lines.push(`${optionMark(nth)}${item.name} ${dots} ${price} nuyen${shelfNote(item)}`);
43
62
  }
44
63
  }
45
64
  lines.push('');
46
- lines.push(`You're carrying ${this.actor.currency} nuyen.${hint(` "buy <item>" to make it yours.`)}`);
65
+ lines.push(`You're carrying ${this.actor.currency} nuyen.${hint(` "buy <item>" -- or "buy <number>" off this list.`)}`);
47
66
  this.logger.write(`BuyCommand: ${this.actor.name} browsed in ${room.name}.`);
48
67
  return lines.join('\n');
49
68
  }
@@ -71,6 +90,15 @@ export class BuyCommand extends Command {
71
90
  purchase(wanted, vendors) {
72
91
  const actor = this.actor;
73
92
  const room = actor.currentLocation;
93
+ // "buy 3" -- the row browse() printed. Resolved through the shared
94
+ // resolver against the same flattened shelf, so the index can only
95
+ // ever mean what was on screen. A name that IS a number still wins
96
+ // (see fuzzy-match.ts), and an out-of-range number falls through to
97
+ // the ordinary not-on-the-shelf refusal.
98
+ const shelf = this.shelf(vendors);
99
+ const byIndex = fuzzyPickName(wanted, shelf.map(i => i.name), { index: true });
100
+ if (byIndex)
101
+ wanted = byIndex;
74
102
  const item = room.inventory.getItem(wanted) ?? undefined;
75
103
  if (!item) {
76
104
  // NOT ON THE SHELF IS NOT THE SAME AS NOT AVAILABLE (playtest
@@ -1 +1 @@
1
- {"version":3,"file":"buy.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/buy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"buy.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/buy.ts"],"names":[],"mappings":"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"}
@@ -1,61 +1,52 @@
1
1
  import { Command, ICommand } from './command.js';
2
- import { PuzzleBypassType } from '../types/seed/puzzle-seed.js';
3
- import { PuzzleTarget } from '../models/room.js';
2
+ import { Device } from '../models/device.js';
4
3
  /**
5
- * Shared implementation for pick/hack/cast/bluff. The gate check (already
6
- * solved? prerequisite met? does this puzzle even have this bypassType?
7
- * route already burned?) always runs first and synchronously, so a doomed
8
- * attempt never makes the player sit through an interactive challenge they
9
- * were never going to be allowed to attempt. Each concrete command differs
10
- * in its verb, description, bypass type, the "nothing to do that to"
11
- * message, how the outcome gets determined (see determineOutcome() --
12
- * every real bypass overrides it with a skill roll), and what failure
13
- * costs beyond the burned route (onBypassFailure()).
4
+ * Shared implementation for pick/breach/hack/cast/dispel -- FORCING a
5
+ * device rather than opening it the way it was meant to open.
6
+ *
7
+ * The gate check (is it already open? does this verb even bite on this
8
+ * kind of thing?) always runs first and synchronously, so a doomed
9
+ * attempt never makes the player sit through an interactive challenge
10
+ * they were never going to be allowed to attempt. Each concrete command
11
+ * differs in its verb, the kind of device it works, the "nothing to do
12
+ * that to" message, how the outcome gets determined (see
13
+ * determineOutcome() -- every real one overrides it with a skill roll),
14
+ * and what failure costs beyond the noise (onForceFailure()).
15
+ *
16
+ * WHAT LEFT WITH THE PUZZLE MECHANIC: there is no burned route any
17
+ * more. A lock you failed to pick is a lock you can try again, which is
18
+ * what a lock IS -- the one-shot shortcut was a property of a riddle
19
+ * pretending to be an object. Failure is still loud and still raises
20
+ * the world; it just doesn't spend the thing.
14
21
  */
15
22
  export declare abstract class BypassCommand extends Command implements ICommand {
16
- protected abstract bypassType: PuzzleBypassType;
17
- protected abstract noPuzzleMessage: string;
23
+ /** The kind of device this verb works. */
24
+ protected abstract deviceKind: Device['kind'];
25
+ protected abstract noDeviceMessage: string;
18
26
  /** The word the player typed -- used in disambiguation prompts. Two
19
- * commands can share a bypassType (pick and breach both work 'lockpick'
20
- * barriers), so this can't be derived from the type. */
27
+ * commands can share a kind (pick and breach both work a lock), so
28
+ * this can't be derived from it. */
21
29
  protected abstract verbName: string;
22
- /** Optional: replaces the puzzle's stock per-type failure line -- for a
23
- * verb that shares a bypassType but fails differently (a breach doesn't
24
- * snap a pick). */
30
+ /** Optional: replaces the stock per-kind failure line -- for a verb
31
+ * that shares a kind but fails differently (a breach doesn't snap a
32
+ * pick). */
25
33
  protected failureFlavor?: string;
26
- /** Optional: same idea one step later. The puzzle stores ONE burned
27
- * flag per barrier and words it per TYPE, so a barrier burned by a
28
- * breach used to re-refuse a breach with the snapped-pick line -- a
29
- * pick the player never owned (playtest 2026-08-27). A verb that
30
- * shares a bypassType but burns differently says so here. */
31
- protected burnedFlavor?: string;
32
- /** Fallback: a flat coin flip. Every real bypass overrides this with a
33
- * skill roll (pick: Agility+locksmith, hack: Logic+hacking, bluff:
34
- * Charisma+con, cast: the casting pool). */
34
+ /** Fallback: a flat coin flip. Every real one overrides this with a
35
+ * skill roll. */
35
36
  protected determineOutcome(): Promise<boolean>;
37
+ /** Type-specific teeth for a failed forcing, beyond the noise.
38
+ * Returns narration lines. */
39
+ protected onForceFailure(): Promise<string[]>;
40
+ /** Type-specific consequences of a forcing that WORKED, before the
41
+ * success message renders (see breach.ts: smashing through is loud
42
+ * whether or not it gives). */
43
+ protected onForceSuccess(device: Device): Promise<string[]>;
36
44
  /**
37
- * Type-specific teeth for a failed bypass, beyond the burned route and
38
- * the alarm world event both applied by execute(). Returns narration
39
- * lines. Default: nothing extra -- the cost of a snapped pick or a blown
40
- * story is the burned shortcut and a district that heard about it. The
41
- * spell bypass overrides this with ward backlash (see cast.ts), which
42
- * runs through the real damage tracks and can still knock out or kill.
43
- */
44
- protected onBypassFailure(): Promise<string[]>;
45
- /**
46
- * Type-specific consequences of a bypass that WORKED, before the success
47
- * message renders. Default: nothing -- picking, hacking, and bluffing
48
- * are quiet when they land. The forceful bypass overrides this (see
49
- * breach.ts): smashing through a barrier is loud whether or not it
50
- * gives, so success still raises the world and ends any sneak.
51
- */
52
- protected onBypassSuccess(target: PuzzleTarget): Promise<string[]>;
53
- /**
54
- * There's no typed answer here to disambiguate with (unlike solve.ts),
55
- * so with more than one barrier in the room the player has to name which
56
- * one: a direction ("pick north", for a locked door) or a word from the
57
- * barrier's own name ("pick maglock"). With only one candidate, a bare
58
- * "pick" still works exactly as before.
45
+ * There's no typed answer here to disambiguate with, so with more
46
+ * than one device in the room the player has to name which one: a
47
+ * direction ("pick north", for a device holding a door) or a word
48
+ * from its own name ("pick maglock"). With only one candidate, a bare
49
+ * "pick" still works.
59
50
  */
60
51
  private resolveTarget;
61
52
  execute(args: string[]): Promise<string>;