@maka/maka-cli 5.64.0 → 5.65.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 (161) hide show
  1. package/bundle/typescript/package.json +1 -1
  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 +146 -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/jobs.js +2 -1
  32. package/bundle/typescript/src/commands/game/sideQuest/commands/jobs.js.map +1 -1
  33. package/bundle/typescript/src/commands/game/sideQuest/commands/look.js +58 -2
  34. package/bundle/typescript/src/commands/game/sideQuest/commands/look.js.map +1 -1
  35. package/bundle/typescript/src/commands/game/sideQuest/commands/map.js +18 -4
  36. package/bundle/typescript/src/commands/game/sideQuest/commands/map.js.map +1 -1
  37. package/bundle/typescript/src/commands/game/sideQuest/commands/move.js +1 -1
  38. package/bundle/typescript/src/commands/game/sideQuest/commands/pick.d.ts +2 -3
  39. package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js +2 -2
  40. package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js.map +1 -1
  41. package/bundle/typescript/src/commands/game/sideQuest/commands/posture.d.ts +45 -0
  42. package/bundle/typescript/src/commands/game/sideQuest/commands/posture.js +115 -0
  43. package/bundle/typescript/src/commands/game/sideQuest/commands/posture.js.map +1 -0
  44. package/bundle/typescript/src/commands/game/sideQuest/commands/search.js +35 -24
  45. package/bundle/typescript/src/commands/game/sideQuest/commands/search.js.map +1 -1
  46. package/bundle/typescript/src/commands/game/sideQuest/commands/take.js +12 -0
  47. package/bundle/typescript/src/commands/game/sideQuest/commands/take.js.map +1 -1
  48. package/bundle/typescript/src/commands/game/sideQuest/commands/unlock.js +1 -1
  49. package/bundle/typescript/src/commands/game/sideQuest/commands/unlock.js.map +1 -1
  50. package/bundle/typescript/src/commands/game/sideQuest/commands/use.d.ts +17 -0
  51. package/bundle/typescript/src/commands/game/sideQuest/commands/use.js +136 -1
  52. package/bundle/typescript/src/commands/game/sideQuest/commands/use.js.map +1 -1
  53. package/bundle/typescript/src/commands/game/sideQuest/engine-version.d.ts +1 -1
  54. package/bundle/typescript/src/commands/game/sideQuest/engine-version.js +15 -1
  55. package/bundle/typescript/src/commands/game/sideQuest/engine-version.js.map +1 -1
  56. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.d.ts +82 -43
  57. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +419 -263
  58. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js.map +1 -1
  59. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js +82 -84
  60. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js.map +1 -1
  61. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.d.ts +23 -4
  62. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.js +95 -79
  63. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.js.map +1 -1
  64. package/bundle/typescript/src/commands/game/sideQuest/factories/seed-migration.d.ts +30 -0
  65. package/bundle/typescript/src/commands/game/sideQuest/factories/seed-migration.js +176 -0
  66. package/bundle/typescript/src/commands/game/sideQuest/factories/seed-migration.js.map +1 -0
  67. package/bundle/typescript/src/commands/game/sideQuest/game.js +11 -5
  68. package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
  69. package/bundle/typescript/src/commands/game/sideQuest/headless.js +24 -0
  70. package/bundle/typescript/src/commands/game/sideQuest/headless.js.map +1 -1
  71. package/bundle/typescript/src/commands/game/sideQuest/models/_index.d.ts +0 -1
  72. package/bundle/typescript/src/commands/game/sideQuest/models/_index.js +0 -1
  73. package/bundle/typescript/src/commands/game/sideQuest/models/_index.js.map +1 -1
  74. package/bundle/typescript/src/commands/game/sideQuest/models/device.d.ts +121 -0
  75. package/bundle/typescript/src/commands/game/sideQuest/models/device.js +145 -0
  76. package/bundle/typescript/src/commands/game/sideQuest/models/device.js.map +1 -0
  77. package/bundle/typescript/src/commands/game/sideQuest/models/door.d.ts +27 -8
  78. package/bundle/typescript/src/commands/game/sideQuest/models/door.js +15 -10
  79. package/bundle/typescript/src/commands/game/sideQuest/models/door.js.map +1 -1
  80. package/bundle/typescript/src/commands/game/sideQuest/models/npc.d.ts +81 -0
  81. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +132 -21
  82. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
  83. package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +68 -0
  84. package/bundle/typescript/src/commands/game/sideQuest/models/player.js +102 -0
  85. package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
  86. package/bundle/typescript/src/commands/game/sideQuest/models/room.d.ts +32 -46
  87. package/bundle/typescript/src/commands/game/sideQuest/models/room.js +38 -63
  88. package/bundle/typescript/src/commands/game/sideQuest/models/room.js.map +1 -1
  89. package/bundle/typescript/src/commands/game/sideQuest/models/scene.d.ts +1 -4
  90. package/bundle/typescript/src/commands/game/sideQuest/models/scene.js +0 -22
  91. package/bundle/typescript/src/commands/game/sideQuest/models/scene.js.map +1 -1
  92. package/bundle/typescript/src/commands/game/sideQuest/scenes/scene1.json +78 -109
  93. package/bundle/typescript/src/commands/game/sideQuest/scenes/scene2.json +4 -101
  94. package/bundle/typescript/src/commands/game/sideQuest/types/save-file.d.ts +24 -0
  95. package/bundle/typescript/src/commands/game/sideQuest/types/seed/device-seed.d.ts +52 -0
  96. package/bundle/typescript/src/commands/game/sideQuest/types/seed/device-seed.js +2 -0
  97. package/bundle/typescript/src/commands/game/sideQuest/types/seed/device-seed.js.map +1 -0
  98. package/bundle/typescript/src/commands/game/sideQuest/types/seed/legacy-puzzle-seed.d.ts +63 -0
  99. package/bundle/typescript/src/commands/game/sideQuest/types/seed/legacy-puzzle-seed.js +2 -0
  100. package/bundle/typescript/src/commands/game/sideQuest/types/seed/legacy-puzzle-seed.js.map +1 -0
  101. package/bundle/typescript/src/commands/game/sideQuest/types/seed/player-seed.d.ts +6 -0
  102. package/bundle/typescript/src/commands/game/sideQuest/types/seed/room-seed.d.ts +4 -0
  103. package/bundle/typescript/src/commands/game/sideQuest/types/seed/scene-seed.d.ts +3 -2
  104. package/bundle/typescript/src/commands/game/sideQuest/types/shared/abstracts.d.ts +2 -28
  105. package/bundle/typescript/src/commands/game/sideQuest/types/shared/abstracts.js +1 -14
  106. package/bundle/typescript/src/commands/game/sideQuest/types/shared/abstracts.js.map +1 -1
  107. package/bundle/typescript/src/commands/game/sideQuest/ui.js +24 -0
  108. package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
  109. package/bundle/typescript/src/commands/game/sideQuest/utilities/affordances.d.ts +55 -0
  110. package/bundle/typescript/src/commands/game/sideQuest/utilities/affordances.js +36 -0
  111. package/bundle/typescript/src/commands/game/sideQuest/utilities/affordances.js.map +1 -0
  112. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-review.d.ts +45 -0
  113. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-review.js +116 -0
  114. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-review.js.map +1 -0
  115. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog.d.ts +67 -1
  116. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog.js +56 -1
  117. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog.js.map +1 -1
  118. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js +37 -4
  119. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js.map +1 -1
  120. package/bundle/typescript/src/commands/game/sideQuest/utilities/credentials.d.ts +26 -0
  121. package/bundle/typescript/src/commands/game/sideQuest/utilities/credentials.js +48 -0
  122. package/bundle/typescript/src/commands/game/sideQuest/utilities/credentials.js.map +1 -0
  123. package/bundle/typescript/src/commands/game/sideQuest/utilities/devices.d.ts +23 -0
  124. package/bundle/typescript/src/commands/game/sideQuest/utilities/devices.js +55 -0
  125. package/bundle/typescript/src/commands/game/sideQuest/utilities/devices.js.map +1 -0
  126. package/bundle/typescript/src/commands/game/sideQuest/utilities/fuzzy-match.d.ts +57 -2
  127. package/bundle/typescript/src/commands/game/sideQuest/utilities/fuzzy-match.js +46 -3
  128. package/bundle/typescript/src/commands/game/sideQuest/utilities/fuzzy-match.js.map +1 -1
  129. package/bundle/typescript/src/commands/game/sideQuest/utilities/log-style.d.ts +16 -0
  130. package/bundle/typescript/src/commands/game/sideQuest/utilities/log-style.js +18 -0
  131. package/bundle/typescript/src/commands/game/sideQuest/utilities/log-style.js.map +1 -1
  132. package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js +68 -38
  133. package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js.map +1 -1
  134. package/bundle/typescript/src/commands/game/sideQuest/utilities/room-grid.d.ts +3 -3
  135. package/bundle/typescript/src/commands/game/sideQuest/utilities/room-grid.js +3 -3
  136. package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.d.ts +36 -12
  137. package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js +101 -27
  138. package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js.map +1 -1
  139. package/bundle/typescript/src/commands/game/sideQuest/utilities/use-target.d.ts +88 -0
  140. package/bundle/typescript/src/commands/game/sideQuest/utilities/use-target.js +113 -0
  141. package/bundle/typescript/src/commands/game/sideQuest/utilities/use-target.js.map +1 -0
  142. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +54 -5
  143. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
  144. package/bundle/typescript/src/maka.js +1 -1
  145. package/bundle/typescript/src/maka.js.map +1 -1
  146. package/bundle/typescript/src/tools/sdk-loader/relocate.d.ts +19 -2
  147. package/bundle/typescript/src/tools/sdk-loader/relocate.js +22 -2
  148. package/bundle/typescript/src/tools/sdk-loader/relocate.js.map +1 -1
  149. package/package.json +1 -1
  150. package/bundle/typescript/src/commands/game/sideQuest/commands/solve.d.ts +0 -6
  151. package/bundle/typescript/src/commands/game/sideQuest/commands/solve.js +0 -72
  152. package/bundle/typescript/src/commands/game/sideQuest/commands/solve.js.map +0 -1
  153. package/bundle/typescript/src/commands/game/sideQuest/factories/puzzle-factory.d.ts +0 -6
  154. package/bundle/typescript/src/commands/game/sideQuest/factories/puzzle-factory.js +0 -26
  155. package/bundle/typescript/src/commands/game/sideQuest/factories/puzzle-factory.js.map +0 -1
  156. package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.d.ts +0 -152
  157. package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js +0 -393
  158. package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js.map +0 -1
  159. package/bundle/typescript/src/commands/game/sideQuest/types/seed/puzzle-seed.d.ts +0 -28
  160. package/bundle/typescript/src/commands/game/sideQuest/types/seed/puzzle-seed.js +0 -2
  161. package/bundle/typescript/src/commands/game/sideQuest/types/seed/puzzle-seed.js.map +0 -1
@@ -1,152 +0,0 @@
1
- import { Logger } from '../utilities/logger.js';
2
- import { Item } from './item.js';
3
- import { Inventory } from './inventory.js';
4
- import { PuzzleBypassType } from '../types/seed/puzzle-seed.js';
5
- import { AbstractPuzzle } from '../types/shared/abstracts.js';
6
- /**
7
- * Why a bypass was refused, so the CALLING command can re-voice a
8
- * message the puzzle can't word correctly on its own: two verbs share
9
- * one bypassType (pick/breach both work 'lockpick'), and the puzzle
10
- * only knows the type. See BypassCommand.burnedFlavor.
11
- */
12
- export type BypassRefusal = 'solved' | 'locked' | 'mismatch' | 'burned';
13
- export interface BypassGate {
14
- allowed: boolean;
15
- reason?: BypassRefusal;
16
- message?: string;
17
- }
18
- export interface IPuzzleConstructorConfig {
19
- name: string;
20
- requiredItem?: Item;
21
- requiredPhrase?: string;
22
- riddle?: string;
23
- rewardItem?: Item;
24
- successMessage?: string;
25
- failureMessage?: string;
26
- hobbyTags?: string[];
27
- bypassType?: PuzzleBypassType;
28
- atSpot?: string;
29
- }
30
- export declare class Puzzle extends AbstractPuzzle {
31
- protected logger: Logger;
32
- protected solved: boolean;
33
- private hasAIRiddle;
34
- name: string;
35
- requiredItem?: Item;
36
- requiredPhrase?: string;
37
- riddle?: string;
38
- rewardItem?: Item;
39
- atSpot?: string;
40
- successMessage: string;
41
- failureMessage: string;
42
- hobbyTags?: string[];
43
- requiresPuzzle?: Puzzle;
44
- lockedMessage: string;
45
- bypassType?: PuzzleBypassType;
46
- private static readonly BYPASS_SUCCESS_CHANCE;
47
- bypassBurned: boolean;
48
- constructor(config: IPuzzleConstructorConfig);
49
- /**
50
- * Player-facing hint that a risky bypass exists, without which nothing
51
- * in the game ever tells the player "pick"/"hack"/"cast" is even an
52
- * option here -- found via a real session where a player had no idea
53
- * what they were supposed to "pick".
54
- */
55
- /** Just the bypass verb ("pick"/"hack"/"cast"/"bluff"), for refusal
56
- * one-liners that need to NAME the mechanism without the full
57
- * coaching text getBypassHint() carries. */
58
- getBypassVerb(): string | undefined;
59
- /**
60
- * EVERY verb that works this barrier, not just the canonical one --
61
- * one bypassType can have two (pick/breach both work a lockpick;
62
- * cast/dispel both work a ward). For telling the player exactly what
63
- * they may type (item B, 2026-08-27: "the 'thing' to
64
- * hack/breach/pick/dispell needs to be very very clear"), where
65
- * naming only half the routes is its own small lie.
66
- */
67
- getBypassVerbs(): string[];
68
- getBypassHint(): string | undefined;
69
- /**
70
- * Wired in after all puzzles in a scene exist (scene-factory.ts), since
71
- * a prerequisite may not have been constructed yet at this puzzle's own
72
- * construction time.
73
- */
74
- setRequiresPuzzle(prerequisite: Puzzle, lockedMessage?: string): void;
75
- /**
76
- * Persistence-only (utilities/persistence.ts): flags in, nothing out --
77
- * no reward items, no success message, no door side effects (door lock
78
- * state is restored independently, so a solved-then-relocked door stays
79
- * relocked on load).
80
- */
81
- restoreState(state: {
82
- solved: boolean;
83
- bypassBurned: boolean;
84
- }): void;
85
- isSolved(): boolean;
86
- /**
87
- * Rewrites the riddle's presentation once per scene load, while keeping
88
- * `requiredPhrase` (the exact-match answer key used by `solve()`) fixed --
89
- * so the correctness gate never drifts from what the player was actually
90
- * asked.
91
- */
92
- ensureAIRiddle(sceneContext: string, roomName?: string, kind?: 'device' | 'terrain'): Promise<void>;
93
- hasRequiredItem(playerInventory: Inventory): boolean;
94
- /**
95
- * Clue items are only required to CONTAIN the answer somewhere in their
96
- * text (e.g. "kill the power to bypass security" for a required phrase
97
- * of "kill the power"), so a player who reasonably quotes the clue back
98
- * verbatim types more words than the exact answer. Strict equality
99
- * rejected that. Normalizing punctuation/whitespace and accepting the
100
- * required phrase as a substring of the input (not just an exact match)
101
- * fixes it without loosening things enough for a wrong guess to pass.
102
- */
103
- matchesRequiredPhrase(inputPhrase: string): boolean;
104
- solve(providedAnswer: string, playerInventory: Inventory): {
105
- success: boolean;
106
- message: string;
107
- };
108
- /**
109
- * The risky alternate route never requires knowing requiredPhrase. Split
110
- * into a gate check (run first, before any outcome is determined -- an
111
- * already-solved, blocked, or type-mismatched puzzle should never make
112
- * the player sit through an interactive minigame they were never going
113
- * to be allowed to attempt) and applying an already-determined outcome.
114
- * A failed attempt BURNS the route (see bypassBurned) -- the gate
115
- * refuses retries with the burned flavor -- but never touches the safe
116
- * solve() path: finding the actual answer remains deterministic. Further
117
- * consequences (the alarm world event, spell backlash) belong to the
118
- * calling command (see commands/bypass-command.ts).
119
- */
120
- checkBypassGate(type: PuzzleBypassType): BypassGate;
121
- /**
122
- * The wrong-verb answer, spoken in the barrier's OWN fiction. Keyed on
123
- * this.bypassType (what the thing IS), never on the verb attempted --
124
- * see the note on BYPASS_FLAVOR.resists. Always names a route that
125
- * works, so a player never gets a dead end in front of a visible
126
- * barrier; a barrier with no shortcut at all says so plainly instead
127
- * of pretending not to exist, which is what a solve-only puzzle used
128
- * to do (it was filtered out before this gate ever ran).
129
- */
130
- private wrongRouteMessage;
131
- /**
132
- * Applies an outcome already determined elsewhere (a coin flip, or a live
133
- * minigame's win/loss) to this puzzle. Assumes checkBypassGate() already
134
- * passed -- doesn't re-check it.
135
- */
136
- resolveBypass(type: PuzzleBypassType, succeeded: boolean): {
137
- success: boolean;
138
- message: string;
139
- alarmed: boolean;
140
- };
141
- /**
142
- * Convenience wrapper: gate check + a flat coin-flip outcome. Used for
143
- * any bypass type without its own interactive minigame yet -- see
144
- * BypassCommand.determineOutcome(), which lockpicking overrides to run a
145
- * real player-skill challenge instead of this coin flip.
146
- */
147
- attemptBypass(type: PuzzleBypassType): {
148
- success: boolean;
149
- message: string;
150
- alarmed: boolean;
151
- };
152
- }
@@ -1,393 +0,0 @@
1
- import { Logger } from '../utilities/logger.js';
2
- import { hint } from '../utilities/hints.js';
3
- import { AI } from '../../../../tools/ai/ai.class.js';
4
- import { AbstractPuzzle } from '../types/shared/abstracts.js';
5
- /**
6
- * `resists` is the WRONG-VERB voice, and it is keyed on what the barrier
7
- * IS, never on what the player typed (blocker 2026-08-27, "the barrier
8
- * isn't allowing me to hack/pick/breach it"): a player who reaches for
9
- * the wrong route is not making an error to be reported, they are asking
10
- * what this thing is. So the line says what it is, why the attempted
11
- * route finds no purchase on it, and which verb DOES bite -- the same
12
- * job spots.ts:terrainRefusal() does for a blocked crossing. Never a
13
- * bare denial: a denial in front of an obvious door is what made a real
14
- * session conclude the barrier was broken.
15
- */
16
- const BYPASS_FLAVOR = {
17
- lockpick: {
18
- verb: 'pick',
19
- verbs: ['pick', 'breach'],
20
- resists: `It's a mechanism, not a system -- no console to intrude on, no weave to unpick, nobody to talk round. It gives to HANDS: "pick" it quietly, or "breach" it with your shoulder.`,
21
- failureMessage: `Your pick snaps in the mechanism -- and the lock's alarm isn't silent anymore.`,
22
- hint: `This looks forceable -- "pick" works it quietly (Agility + locksmith); "breach" forces it with raw muscle (Strength + Body, LOUD even when it works). Fail either way and the mechanism seizes for good -- and the noise carries.`,
23
- burnedMessage: `The mechanism is seized solid around your snapped pick -- no tool opens it now. Only the real code will.`,
24
- },
25
- hack: {
26
- verb: 'hack',
27
- verbs: ['hack'],
28
- resists: `No keyway, no seam, no tumblers to feel for -- it's a sealed SYSTEM, and it only argues with a deck. "hack" it.`,
29
- failureMessage: `Your intrusion trips a countermeasure -- the system logs the attempt and pings whoever's watching.`,
30
- hint: `This looks hackable -- try "hack" to skip finding the code (Logic + hacking). Fail, and the system locks you out for good -- and pings whoever's watching.`,
31
- burnedMessage: `The system remembers your intrusion -- hard lockout, your signature blacklisted. Only the real code opens it now.`,
32
- },
33
- spell: {
34
- verb: 'cast',
35
- verbs: ['cast', 'dispel'],
36
- resists: `Your hands find nothing to work and your tools find nothing to bite -- the barrier isn't matter. It answers to the Art: "cast" at it, or "dispel" it.`,
37
- failureMessage: `The weave slips through your fingers -- backlash crackles outward, and something out there felt it.`,
38
- hint: `This could be unwoven magically -- try "dispel" (Magic + counterspelling) or "cast" (the casting pool) to skip finding the code. Fail, and the backlash BITES -- and the barrier seals against you for good.`,
39
- burnedMessage: `The barrier has sealed itself against your signature -- no working of yours touches it again. Only the real answer opens it now.`,
40
- },
41
- // The Face's route: a barrier that's really a PERSON or a voice-gate --
42
- // a doorman, an intercom challenge, a receptionist with a checklist.
43
- // Born from a real generated scene that emitted bypassType "con" for a
44
- // keypad "used by trusted business partners" before the type existed
45
- // (and crashed search doing it) -- the model wanted social engineering,
46
- // so now it's real. See commands/bluff.ts.
47
- con: {
48
- verb: 'bluff',
49
- verbs: ['bluff'],
50
- resists: `There's no lock here at all. There's a PERSON -- and people don't open to tools, they open to a story. "bluff" your way past.`,
51
- failureMessage: `The story comes apart mid-sentence -- and now they KNOW someone's running a game on them.`,
52
- hint: `This could be TALKED past -- try "bluff" to fast-talk through without the code (Charisma + con). Blow the story, and they'll never buy another word from you.`,
53
- burnedMessage: `They've made you -- no story you tell holds water here anymore. Only the real credential works now.`,
54
- },
55
- };
56
- export class Puzzle extends AbstractPuzzle {
57
- logger = Logger.getInstance();
58
- solved = false;
59
- hasAIRiddle = false;
60
- name;
61
- requiredItem;
62
- requiredPhrase;
63
- riddle;
64
- // Optional: a room-anchored puzzle typically grants one, but a door-
65
- // guarding puzzle (see Door.puzzle) usually doesn't need one -- opening
66
- // the door already IS the reward.
67
- rewardItem;
68
- // See IPuzzleConstructorConfig.atSpot.
69
- atSpot;
70
- successMessage;
71
- failureMessage;
72
- hobbyTags;
73
- // Points only at this puzzle's immediate predecessor -- chains of any
74
- // length fall out of that naturally, since a puzzle can't become solved
75
- // until its own prerequisite is, which cascades transitively up the
76
- // chain with no special traversal needed at solve() time.
77
- requiresPuzzle;
78
- lockedMessage;
79
- // The riddle/requiredPhrase path above is the "first layer" -- a lock,
80
- // code, or passphrase that exists to be found and always works once
81
- // known. bypassType is a SEPARATE, optional route past that same barrier
82
- // that never requires knowing the answer, matching the barrier's actual
83
- // in-fiction nature (a lock, a terminal, a ward) -- rolled on the
84
- // matching skill by the bypass command, and failure isn't quiet: it
85
- // BURNS the route (see bypassBurned) and raises the world. See
86
- // resolveBypass().
87
- bypassType;
88
- static BYPASS_SUCCESS_CHANCE = 0.5;
89
- // One shot at the shortcut: a failed bypass seizes the mechanism /
90
- // blacklists the intruder / seals the ward / burns the cover story.
91
- // The safe solve() route (the findable answer) is deliberately never
92
- // touched by this -- "no second chances" applies to the trick, not to
93
- // the barrier.
94
- bypassBurned = false;
95
- constructor(config) {
96
- super();
97
- this.name = config.name;
98
- this.requiredItem = config.requiredItem;
99
- this.requiredPhrase = config.requiredPhrase;
100
- this.riddle = config.riddle;
101
- this.successMessage = config.successMessage || 'You solved the puzzle!';
102
- this.failureMessage = config.failureMessage || `You don't have the necessary item or the correct phrase to solve the puzzle.`;
103
- this.hobbyTags = config.hobbyTags ?? [];
104
- this.lockedMessage = `Something else needs to happen first.`;
105
- this.bypassType = config.bypassType;
106
- this.atSpot = config.atSpot;
107
- this.rewardItem = config.rewardItem;
108
- }
109
- /**
110
- * Player-facing hint that a risky bypass exists, without which nothing
111
- * in the game ever tells the player "pick"/"hack"/"cast" is even an
112
- * option here -- found via a real session where a player had no idea
113
- * what they were supposed to "pick".
114
- */
115
- /** Just the bypass verb ("pick"/"hack"/"cast"/"bluff"), for refusal
116
- * one-liners that need to NAME the mechanism without the full
117
- * coaching text getBypassHint() carries. */
118
- getBypassVerb() {
119
- return this.bypassType ? BYPASS_FLAVOR[this.bypassType]?.verb : undefined;
120
- }
121
- /**
122
- * EVERY verb that works this barrier, not just the canonical one --
123
- * one bypassType can have two (pick/breach both work a lockpick;
124
- * cast/dispel both work a ward). For telling the player exactly what
125
- * they may type (item B, 2026-08-27: "the 'thing' to
126
- * hack/breach/pick/dispell needs to be very very clear"), where
127
- * naming only half the routes is its own small lie.
128
- */
129
- getBypassVerbs() {
130
- if (!this.bypassType)
131
- return [];
132
- return BYPASS_FLAVOR[this.bypassType]?.verbs ?? [];
133
- }
134
- getBypassHint() {
135
- if (!this.bypassType)
136
- return undefined;
137
- // DEFENSIVE lookup: bypassType ultimately comes from generated JSON,
138
- // and an unknown value here used to crash every "search" in the room
139
- // (real session: five straight TypeErrors on an unvalidated type).
140
- // Generation now validates the value too, but static seeds and old
141
- // saved scenes don't re-validate -- unknown types read as "no bypass".
142
- const flavor = BYPASS_FLAVOR[this.bypassType];
143
- if (!flavor)
144
- return undefined;
145
- // A burned route stops advertising itself -- the hint becomes the
146
- // reminder of what the failed attempt cost.
147
- if (this.bypassBurned) {
148
- return `${flavor.burnedMessage}`;
149
- }
150
- // The clue reminder is a real promise -- generation validates that
151
- // every puzzle's answer IS discoverable somewhere else (see
152
- // scene-seed-generator.validateClueItems). A real session took the
153
- // risky gamble first and only found the written-down code afterward.
154
- // The whole block is COACHING (the barrier itself still shows) --
155
- // behind the hints toggle since a real session's "hints off" left
156
- // this printing anyway.
157
- const text = hint(`${flavor.hint}\n(The safe route: the answer is recorded somewhere out in the world -- case the other rooms before you gamble.)`);
158
- return text.length > 0 ? text : undefined;
159
- }
160
- /**
161
- * Wired in after all puzzles in a scene exist (scene-factory.ts), since
162
- * a prerequisite may not have been constructed yet at this puzzle's own
163
- * construction time.
164
- */
165
- setRequiresPuzzle(prerequisite, lockedMessage) {
166
- this.requiresPuzzle = prerequisite;
167
- if (lockedMessage) {
168
- this.lockedMessage = lockedMessage;
169
- }
170
- }
171
- /**
172
- * Persistence-only (utilities/persistence.ts): flags in, nothing out --
173
- * no reward items, no success message, no door side effects (door lock
174
- * state is restored independently, so a solved-then-relocked door stays
175
- * relocked on load).
176
- */
177
- restoreState(state) {
178
- this.solved = state.solved;
179
- this.bypassBurned = state.bypassBurned;
180
- }
181
- isSolved() {
182
- return this.solved;
183
- }
184
- /**
185
- * Rewrites the riddle's presentation once per scene load, while keeping
186
- * `requiredPhrase` (the exact-match answer key used by `solve()`) fixed --
187
- * so the correctness gate never drifts from what the player was actually
188
- * asked.
189
- */
190
- async ensureAIRiddle(sceneContext, roomName, kind = 'device') {
191
- if (this.hasAIRiddle)
192
- return;
193
- if (!AI.isConfigured())
194
- return;
195
- if (!this.riddle || !this.requiredPhrase)
196
- return;
197
- // TERRAIN framing (spatial wave 2026-08-25, closing a real-session
198
- // complaint: a barrier's prose read "way too insightful on how
199
- // Doc Halloran is feeling" and exposed history no BARRIER should
200
- // know -- "it's a BARRIER, not a book"): a terrain-kind puzzle
201
- // seals a PASSAGE, not a device, so the rewrite must say what
202
- // physically blocks the way and how it might yield, never lean on
203
- // scene lore for color.
204
- const framing = kind === 'terrain'
205
- ? `This barrier is IMPASSABLE TERRAIN blocking a passage -- rubble, a collapsed structure, a security shutter -- NOT a device with a credential. State WHAT physically blocks the way and HOW it looks like it might yield (cut apart, hauled aside, powered down, dispelled). Never a book, riddle, or poem, and never lean on the scene's story or any character's feelings/history for color -- describe the physical obstacle only.`
206
- : `You are a game narrator rewriting what a player sees when they search a room and find a
207
- barrier (a lock, scanner, terminal, or ward) -- NOT a riddle or poem.`;
208
- const prompt = `
209
- ${framing}
210
-
211
- Scene context: ${sceneContext}
212
- ${roomName ? `This puzzle is found in: ${roomName}` : ''}
213
- ${this.bypassType ? `This barrier is physically a: ${this.bypassType === 'lockpick' ? 'mechanical lock or maglock' : this.bypassType === 'hack' ? 'electronic terminal, console, or scanner' : this.bypassType === 'con' ? 'person or voice-gate that must be talked past (a doorman, an intercom challenge, a checkpoint)' : 'magical ward or sigil'}` : ''}
214
-
215
- The exact credential that opens it MUST remain: "${this.requiredPhrase}"
216
- The existing description is: "${this.riddle}"
217
-
218
- Write a NEW version, evocative but PLAIN. Start with "You see", "You find", or similar,
219
- and name the barrier concretely -- e.g. "You see a maglock safe." or "You see a biometric
220
- scanner beside the door." -- then say what it demands (a code, a passphrase, a name, a
221
- fingerprint), the way an NPC would actually describe it. Describe the OBSTACLE only --
222
- never write people, guards, or dialogue into it, and never state a character's feelings
223
- or private history; anyone standing watch does their own talking in play. Do not phrase
224
- it as a riddle, wordplay, or puzzle to decode, and do not state the credential itself
225
- outright.
226
-
227
- THE CREDENTIAL YOU DESCRIBE MUST MATCH THE ONE ABOVE IN KIND. The exact credential is
228
- "${this.requiredPhrase}" -- ${/^\d+$/.test((this.requiredPhrase ?? '').trim())
229
- ? `that is a NUMBER, so describe something that takes a number: a keypad, a dial, a numeric counter.`
230
- : `that is a PHRASE OF WORDS, so describe something that takes words: an intercom, a voice-gate, a sign asking for a passphrase. Do NOT describe a numeric keypad, a digit pad, or a combination dial -- a player who reads "keypad" hunts for a number that does not exist, and the words in their pocket stop looking like the answer.`}
231
- Write NO other number into the description either -- no unit number, model number, or
232
- serial. Every code-shaped string a player reads is one they will go and type, and a second
233
- plausible number is indistinguishable from the real one.
234
-
235
- No more than 3 sentences. Respond with ONLY the description text.`;
236
- try {
237
- const reply = await AI.ask(prompt);
238
- this.riddle = reply;
239
- this.hasAIRiddle = true;
240
- this.logger.write(`Generated AI riddle for puzzle "${this.name}"`);
241
- }
242
- catch (err) {
243
- this.logger.write(`AI fallback for riddle (${this.name}): ${err}`);
244
- }
245
- }
246
- hasRequiredItem(playerInventory) {
247
- if (this.requiredItem) {
248
- return playerInventory.hasItem(this.requiredItem.name);
249
- }
250
- return false;
251
- }
252
- /**
253
- * Clue items are only required to CONTAIN the answer somewhere in their
254
- * text (e.g. "kill the power to bypass security" for a required phrase
255
- * of "kill the power"), so a player who reasonably quotes the clue back
256
- * verbatim types more words than the exact answer. Strict equality
257
- * rejected that. Normalizing punctuation/whitespace and accepting the
258
- * required phrase as a substring of the input (not just an exact match)
259
- * fixes it without loosening things enough for a wrong guess to pass.
260
- */
261
- matchesRequiredPhrase(inputPhrase) {
262
- if (!this.requiredPhrase)
263
- return false;
264
- // Punctuation is normalized BOTH ways, because the two readings
265
- // disagree and players use both. Deleting it is right for a code
266
- // ("44-71" is the same code as "4471"); treating it as a separator is
267
- // right for words (a player typing the hyphenated "gate-7-alpha" for
268
- // an answer of "gate 7 alpha" has the right answer and was being told
269
- // otherwise -- which reads to them exactly like being handed a wrong
270
- // code, this bug's own symptom arriving by a second road). Accepting
271
- // a match under EITHER reading covers both without loosening
272
- // anything: every variant still has to contain the whole answer.
273
- const variants = (s) => {
274
- const lower = s.toLowerCase();
275
- const stripped = lower.replace(/[^\w\s]/g, '').replace(/\s+/g, ' ').trim();
276
- const separated = lower.replace(/[^\w\s]/g, ' ').replace(/\s+/g, ' ').trim();
277
- return stripped === separated ? [stripped] : [stripped, separated];
278
- };
279
- const required = variants(this.requiredPhrase).filter(r => r.length > 0);
280
- const input = variants(inputPhrase);
281
- return required.some(r => input.some(i => i.includes(r)));
282
- }
283
- solve(providedAnswer, playerInventory) {
284
- if (this.solved) {
285
- this.logger.write('Puzzle: Attempted to solve an already solved puzzle.');
286
- return {
287
- success: false,
288
- message: 'You have already solved this puzzle.',
289
- };
290
- }
291
- if (this.requiresPuzzle && !this.requiresPuzzle.isSolved()) {
292
- this.logger.write(`Puzzle: Attempted "${this.name}" before prerequisite "${this.requiresPuzzle.name}" was solved.`);
293
- return {
294
- success: false,
295
- message: this.lockedMessage,
296
- };
297
- }
298
- if (this.hasRequiredItem(playerInventory) || this.matchesRequiredPhrase(providedAnswer)) {
299
- this.solved = true;
300
- this.logger.write('Puzzle: Correct solution provided.');
301
- return {
302
- success: true,
303
- message: this.successMessage,
304
- };
305
- }
306
- else {
307
- this.logger.write('Puzzle: Necessary item or correct phrase not provided.');
308
- return {
309
- success: false,
310
- message: this.failureMessage,
311
- };
312
- }
313
- }
314
- /**
315
- * The risky alternate route never requires knowing requiredPhrase. Split
316
- * into a gate check (run first, before any outcome is determined -- an
317
- * already-solved, blocked, or type-mismatched puzzle should never make
318
- * the player sit through an interactive minigame they were never going
319
- * to be allowed to attempt) and applying an already-determined outcome.
320
- * A failed attempt BURNS the route (see bypassBurned) -- the gate
321
- * refuses retries with the burned flavor -- but never touches the safe
322
- * solve() path: finding the actual answer remains deterministic. Further
323
- * consequences (the alarm world event, spell backlash) belong to the
324
- * calling command (see commands/bypass-command.ts).
325
- */
326
- checkBypassGate(type) {
327
- if (this.solved) {
328
- this.logger.write('Puzzle: Attempted to bypass an already solved puzzle.');
329
- return { allowed: false, reason: 'solved', message: 'You have already solved this puzzle.' };
330
- }
331
- if (this.requiresPuzzle && !this.requiresPuzzle.isSolved()) {
332
- this.logger.write(`Puzzle: Attempted to bypass "${this.name}" before prerequisite "${this.requiresPuzzle.name}" was solved.`);
333
- return { allowed: false, reason: 'locked', message: this.lockedMessage };
334
- }
335
- if (this.bypassType !== type) {
336
- return { allowed: false, reason: 'mismatch', message: this.wrongRouteMessage() };
337
- }
338
- if (this.bypassBurned) {
339
- this.logger.write(`Puzzle: Attempted a burned ${type} bypass on "${this.name}".`);
340
- return { allowed: false, reason: 'burned', message: BYPASS_FLAVOR[type]?.burnedMessage ?? `That route is burned -- only the real answer works now.` };
341
- }
342
- return { allowed: true };
343
- }
344
- /**
345
- * The wrong-verb answer, spoken in the barrier's OWN fiction. Keyed on
346
- * this.bypassType (what the thing IS), never on the verb attempted --
347
- * see the note on BYPASS_FLAVOR.resists. Always names a route that
348
- * works, so a player never gets a dead end in front of a visible
349
- * barrier; a barrier with no shortcut at all says so plainly instead
350
- * of pretending not to exist, which is what a solve-only puzzle used
351
- * to do (it was filtered out before this gate ever ran).
352
- */
353
- wrongRouteMessage() {
354
- const safeRoute = `(The answer itself always works, if you turn it up: "solve <the answer>".)`;
355
- const flavor = this.bypassType ? BYPASS_FLAVOR[this.bypassType] : undefined;
356
- if (!flavor) {
357
- return `That finds no purchase -- this one has no shortcut in it. No mechanism to trip, no system to crack, nothing to unweave or talk round. Only the real answer opens it.\n${safeRoute}`;
358
- }
359
- return `That finds no purchase here. ${flavor.resists}\n${safeRoute}`;
360
- }
361
- /**
362
- * Applies an outcome already determined elsewhere (a coin flip, or a live
363
- * minigame's win/loss) to this puzzle. Assumes checkBypassGate() already
364
- * passed -- doesn't re-check it.
365
- */
366
- resolveBypass(type, succeeded) {
367
- if (succeeded) {
368
- this.solved = true;
369
- this.logger.write(`Puzzle: Successful ${type} bypass.`);
370
- return { success: true, message: this.successMessage, alarmed: false };
371
- }
372
- // The trick is spent: mechanism seized, signature blacklisted, ward
373
- // sealed, cover blown. The findable answer still works -- solve() never
374
- // consults this flag.
375
- this.bypassBurned = true;
376
- this.logger.write(`Puzzle: Failed ${type} bypass -- alarmed, route burned.`);
377
- return { success: false, message: BYPASS_FLAVOR[type]?.failureMessage ?? this.failureMessage, alarmed: true };
378
- }
379
- /**
380
- * Convenience wrapper: gate check + a flat coin-flip outcome. Used for
381
- * any bypass type without its own interactive minigame yet -- see
382
- * BypassCommand.determineOutcome(), which lockpicking overrides to run a
383
- * real player-skill challenge instead of this coin flip.
384
- */
385
- attemptBypass(type) {
386
- const gate = this.checkBypassGate(type);
387
- if (!gate.allowed) {
388
- return { success: false, message: gate.message ?? 'You can\'t do that here.', alarmed: false };
389
- }
390
- return this.resolveBypass(type, Math.random() < Puzzle.BYPASS_SUCCESS_CHANCE);
391
- }
392
- }
393
- //# sourceMappingURL=puzzle.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"puzzle.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/models/puzzle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAG7C,OAAO,EAAE,EAAE,EAAE,MAAM,kCAAkC,CAAC;AAGtD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAiC9D;;;;;;;;;;GAUG;AACH,MAAM,aAAa,GAA8I;IAC/J,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;QACzB,OAAO,EAAE,gLAAgL;QACzL,cAAc,EAAE,gFAAgF;QAChG,IAAI,EAAE,mOAAmO;QACzO,aAAa,EAAE,0GAA0G;KAC1H;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,CAAC,MAAM,CAAC;QACf,OAAO,EAAE,iHAAiH;QAC1H,cAAc,EAAE,oGAAoG;QACpH,IAAI,EAAE,4JAA4J;QAClK,aAAa,EAAE,mHAAmH;KACnI;IACD,KAAK,EAAE;QACL,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;QACzB,OAAO,EAAE,uJAAuJ;QAChK,cAAc,EAAE,qGAAqG;QACrH,IAAI,EAAE,8MAA8M;QACpN,aAAa,EAAE,kIAAkI;KAClJ;IACD,wEAAwE;IACxE,qEAAqE;IACrE,uEAAuE;IACvE,qEAAqE;IACrE,wEAAwE;IACxE,2CAA2C;IAC3C,GAAG,EAAE;QACH,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,CAAC,OAAO,CAAC;QAChB,OAAO,EAAE,+HAA+H;QACxI,cAAc,EAAE,2FAA2F;QAC3G,IAAI,EAAE,+JAA+J;QACrK,aAAa,EAAE,qGAAqG;KACrH;CACF,CAAC;AAEF,MAAM,OAAO,MAAO,SAAQ,cAAc;IAC9B,MAAM,GAAW,MAAM,CAAC,WAAW,EAAE,CAAC;IACtC,MAAM,GAAG,KAAK,CAAC;IACjB,WAAW,GAAG,KAAK,CAAC;IAErB,IAAI,CAAS;IACb,YAAY,CAAQ;IACpB,cAAc,CAAU;IACxB,MAAM,CAAU;IACvB,qEAAqE;IACrE,wEAAwE;IACxE,kCAAkC;IAC3B,UAAU,CAAQ;IACzB,uCAAuC;IAChC,MAAM,CAAU;IAChB,cAAc,CAAS;IACvB,cAAc,CAAS;IACvB,SAAS,CAAY;IAE5B,sEAAsE;IACtE,wEAAwE;IACxE,oEAAoE;IACpE,0DAA0D;IACnD,cAAc,CAAU;IACxB,aAAa,CAAS;IAE7B,uEAAuE;IACvE,oEAAoE;IACpE,yEAAyE;IACzE,wEAAwE;IACxE,kEAAkE;IAClE,oEAAoE;IACpE,+DAA+D;IAC/D,mBAAmB;IACZ,UAAU,CAAoB;IAC7B,MAAM,CAAU,qBAAqB,GAAG,GAAG,CAAC;IAEpD,mEAAmE;IACnE,oEAAoE;IACpE,qEAAqE;IACrE,sEAAsE;IACtE,eAAe;IACR,YAAY,GAAG,KAAK,CAAC;IAE5B,YAAY,MAAgC;QAC1C,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACxB,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;QAC5C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,IAAI,wBAAwB,CAAC;QACxE,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,IAAI,8EAA8E,CAAC;QAC9H,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;QACxC,IAAI,CAAC,aAAa,GAAG,uCAAuC,CAAC;QAC7D,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACtC,CAAC;IAED;;;;;OAKG;IACH;;iDAE6C;IAC7C,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5E,CAAC;IAED;;;;;;;OAOG;IACH,cAAc;QACZ,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO,EAAE,CAAC;QAChC,OAAO,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;IACrD,CAAC;IAED,aAAa;QACX,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO,SAAS,CAAC;QACvC,qEAAqE;QACrE,qEAAqE;QACrE,mEAAmE;QACnE,mEAAmE;QACnE,uEAAuE;QACvE,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QAC9B,kEAAkE;QAClE,4CAA4C;QAC5C,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,OAAO,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;QACnC,CAAC;QACD,mEAAmE;QACnE,4DAA4D;QAC5D,mEAAmE;QACnE,qEAAqE;QACrE,kEAAkE;QAClE,kEAAkE;QAClE,wBAAwB;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,kHAAkH,CAAC,CAAC;QACpJ,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5C,CAAC;IAED;;;;OAIG;IACH,iBAAiB,CAAC,YAAoB,EAAE,aAAsB;QAC5D,IAAI,CAAC,cAAc,GAAG,YAAY,CAAC;QACnC,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACrC,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,KAAiD;QAC5D,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC3B,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IACzC,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,cAAc,CAAC,YAAoB,EAAE,QAAiB,EAAE,OAA6B,QAAQ;QACxG,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC7B,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE;YAAE,OAAO;QAC/B,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO;QAEjD,mEAAmE;QACnE,+DAA+D;QAC/D,iEAAiE;QACjE,+DAA+D;QAC/D,8DAA8D;QAC9D,kEAAkE;QAClE,wBAAwB;QACxB,MAAM,OAAO,GAAG,IAAI,KAAK,SAAS;YAChC,CAAC,CAAC,saAAsa;YACxa,CAAC,CAAC;sEAC8D,CAAC;QAEnE,MAAM,MAAM,GAAG;EACjB,OAAO;;iBAEQ,YAAY;EAC3B,QAAQ,CAAC,CAAC,CAAC,4BAA4B,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE;EACtD,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,iCAAiC,IAAI,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,0CAA0C,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,gGAAgG,CAAC,CAAC,CAAC,uBAAuB,EAAE,CAAC,CAAC,CAAC,EAAE;;mDAEzS,IAAI,CAAC,cAAc;gCACtC,IAAI,CAAC,MAAM;;;;;;;;;;;;GAYxC,IAAI,CAAC,cAAc,QAAQ,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC1E,CAAC,CAAC,mGAAmG;YACrG,CAAC,CAAC,uUAAuU;;;;;kEAK3Q,CAAC;QAE/D,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACnC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;YACpB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QACrE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,IAAI,CAAC,IAAI,MAAM,GAAG,EAAE,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IAED,eAAe,CAAC,eAA0B;QACxC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,OAAO,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;;OAQG;IACH,qBAAqB,CAAC,WAAmB;QACvC,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO,KAAK,CAAC;QAEvC,gEAAgE;QAChE,iEAAiE;QACjE,sEAAsE;QACtE,qEAAqE;QACrE,sEAAsE;QACtE,qEAAqE;QACrE,qEAAqE;QACrE,6DAA6D;QAC7D,iEAAiE;QACjE,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,EAAE;YAC7B,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAC3E,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAC7E,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QACrE,CAAC,CAAC;QAEF,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACzE,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;QAEpC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,cAAsB,EAAE,eAA0B;QACtD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;YAC1E,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,sCAAsC;aAChD,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC3D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,IAAI,CAAC,IAAI,0BAA0B,IAAI,CAAC,cAAc,CAAC,IAAI,eAAe,CAAC,CAAC;YACpH,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,IAAI,CAAC,aAAa;aAC5B,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,qBAAqB,CAAC,cAAc,CAAC,EAAE,CAAC;YACxF,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;YACxD,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,IAAI,CAAC,cAAc;aAC7B,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;YAC5E,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,IAAI,CAAC,cAAc;aAC7B,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,IAAsB;QACpC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;YAC3E,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,sCAAsC,EAAE,CAAC;QAC/F,CAAC;QAED,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC3D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,IAAI,CAAC,IAAI,0BAA0B,IAAI,CAAC,cAAc,CAAC,IAAI,eAAe,CAAC,CAAC;YAC9H,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC;QAC3E,CAAC;QAED,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC7B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC;QACnF,CAAC;QAED,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,IAAI,eAAe,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;YAClF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE,aAAa,IAAI,yDAAyD,EAAE,CAAC;QACxJ,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED;;;;;;;;OAQG;IACK,iBAAiB;QACvB,MAAM,SAAS,GAAG,4EAA4E,CAAC;QAC/F,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5E,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,yKAAyK,SAAS,EAAE,CAAC;QAC9L,CAAC;QACD,OAAO,gCAAgC,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;IACxE,CAAC;IAED;;;;OAIG;IACH,aAAa,CAAC,IAAsB,EAAE,SAAkB;QACtD,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,IAAI,UAAU,CAAC,CAAC;YACxD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACzE,CAAC;QAED,oEAAoE;QACpE,wEAAwE;QACxE,sBAAsB;QACtB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,IAAI,mCAAmC,CAAC,CAAC;QAC7E,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE,cAAc,IAAI,IAAI,CAAC,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAChH,CAAC;IAED;;;;;OAKG;IACH,aAAa,CAAC,IAAsB;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,0BAA0B,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACjG,CAAC;QACD,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAChF,CAAC"}
@@ -1,28 +0,0 @@
1
- export type PuzzleBypassType = 'lockpick' | 'hack' | 'spell' | 'con';
2
- export interface IPuzzleSeedJson {
3
- name: string;
4
- room?: string;
5
- riddle: string;
6
- requiredPhrase?: string;
7
- requiredItem?: string;
8
- rewardItem?: string;
9
- successMessage?: string;
10
- failureMessage?: string;
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;
25
- atSpot?: string;
26
- guardsExit?: string;
27
- footprint?: 'small' | 'medium' | 'large';
28
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=puzzle-seed.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"puzzle-seed.js","sourceRoot":"","sources":["../../../../../../../../src/commands/game/sideQuest/types/seed/puzzle-seed.ts"],"names":[],"mappings":""}