@maka/maka-cli 5.4.0 → 5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/bundle/typescript/package.json +1 -1
  2. package/bundle/typescript/src/commands/game/sideQuest/archetypes.d.ts +20 -1
  3. package/bundle/typescript/src/commands/game/sideQuest/archetypes.js +76 -11
  4. package/bundle/typescript/src/commands/game/sideQuest/archetypes.js.map +1 -1
  5. package/bundle/typescript/src/commands/game/sideQuest/commands/advance.d.ts +16 -0
  6. package/bundle/typescript/src/commands/game/sideQuest/commands/advance.js +65 -0
  7. package/bundle/typescript/src/commands/game/sideQuest/commands/advance.js.map +1 -0
  8. package/bundle/typescript/src/commands/game/sideQuest/commands/assense.d.ts +2 -0
  9. package/bundle/typescript/src/commands/game/sideQuest/commands/assense.js +72 -29
  10. package/bundle/typescript/src/commands/game/sideQuest/commands/assense.js.map +1 -1
  11. package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js +21 -2
  12. package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js.map +1 -1
  13. package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.d.ts +16 -0
  14. package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js +39 -0
  15. package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js.map +1 -0
  16. package/bundle/typescript/src/commands/game/sideQuest/commands/brandish.d.ts +21 -0
  17. package/bundle/typescript/src/commands/game/sideQuest/commands/brandish.js +82 -0
  18. package/bundle/typescript/src/commands/game/sideQuest/commands/brandish.js.map +1 -0
  19. package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js +1 -1
  20. package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js.map +1 -1
  21. package/bundle/typescript/src/commands/game/sideQuest/commands/call.js +71 -1
  22. package/bundle/typescript/src/commands/game/sideQuest/commands/call.js.map +1 -1
  23. package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js +21 -2
  24. package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js.map +1 -1
  25. package/bundle/typescript/src/commands/game/sideQuest/commands/drone.js +13 -1
  26. package/bundle/typescript/src/commands/game/sideQuest/commands/drone.js.map +1 -1
  27. package/bundle/typescript/src/commands/game/sideQuest/commands/drop.js +3 -0
  28. package/bundle/typescript/src/commands/game/sideQuest/commands/drop.js.map +1 -1
  29. package/bundle/typescript/src/commands/game/sideQuest/commands/equip.js +19 -2
  30. package/bundle/typescript/src/commands/game/sideQuest/commands/equip.js.map +1 -1
  31. package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.js +9 -2
  32. package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.js.map +1 -1
  33. package/bundle/typescript/src/commands/game/sideQuest/commands/go.d.ts +2 -0
  34. package/bundle/typescript/src/commands/game/sideQuest/commands/go.js +33 -1
  35. package/bundle/typescript/src/commands/game/sideQuest/commands/go.js.map +1 -1
  36. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js +43 -20
  37. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js.map +1 -1
  38. package/bundle/typescript/src/commands/game/sideQuest/commands/haggle.d.ts +15 -0
  39. package/bundle/typescript/src/commands/game/sideQuest/commands/haggle.js +75 -0
  40. package/bundle/typescript/src/commands/game/sideQuest/commands/haggle.js.map +1 -0
  41. package/bundle/typescript/src/commands/game/sideQuest/commands/inv.js +5 -1
  42. package/bundle/typescript/src/commands/game/sideQuest/commands/inv.js.map +1 -1
  43. package/bundle/typescript/src/commands/game/sideQuest/commands/look.js +16 -4
  44. package/bundle/typescript/src/commands/game/sideQuest/commands/look.js.map +1 -1
  45. package/bundle/typescript/src/commands/game/sideQuest/commands/persuade.d.ts +18 -0
  46. package/bundle/typescript/src/commands/game/sideQuest/commands/persuade.js +100 -0
  47. package/bundle/typescript/src/commands/game/sideQuest/commands/persuade.js.map +1 -0
  48. package/bundle/typescript/src/commands/game/sideQuest/commands/pick.d.ts +1 -0
  49. package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js +22 -7
  50. package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js.map +1 -1
  51. package/bundle/typescript/src/commands/game/sideQuest/commands/say.js +8 -0
  52. package/bundle/typescript/src/commands/game/sideQuest/commands/say.js.map +1 -1
  53. package/bundle/typescript/src/commands/game/sideQuest/commands/search.js +55 -8
  54. package/bundle/typescript/src/commands/game/sideQuest/commands/search.js.map +1 -1
  55. package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js +11 -2
  56. package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js.map +1 -1
  57. package/bundle/typescript/src/commands/game/sideQuest/commands/sneak.d.ts +15 -0
  58. package/bundle/typescript/src/commands/game/sideQuest/commands/sneak.js +35 -0
  59. package/bundle/typescript/src/commands/game/sideQuest/commands/sneak.js.map +1 -0
  60. package/bundle/typescript/src/commands/game/sideQuest/commands/spells.js +21 -0
  61. package/bundle/typescript/src/commands/game/sideQuest/commands/spells.js.map +1 -1
  62. package/bundle/typescript/src/commands/game/sideQuest/commands/subdue.js +4 -4
  63. package/bundle/typescript/src/commands/game/sideQuest/commands/subdue.js.map +1 -1
  64. package/bundle/typescript/src/commands/game/sideQuest/commands/take.js +70 -13
  65. package/bundle/typescript/src/commands/game/sideQuest/commands/take.js.map +1 -1
  66. package/bundle/typescript/src/commands/game/sideQuest/commands/talk.js +8 -0
  67. package/bundle/typescript/src/commands/game/sideQuest/commands/talk.js.map +1 -1
  68. package/bundle/typescript/src/commands/game/sideQuest/commands/unequip.js +6 -3
  69. package/bundle/typescript/src/commands/game/sideQuest/commands/unequip.js.map +1 -1
  70. package/bundle/typescript/src/commands/game/sideQuest/commands/use.js +5 -4
  71. package/bundle/typescript/src/commands/game/sideQuest/commands/use.js.map +1 -1
  72. package/bundle/typescript/src/commands/game/sideQuest/factories/room-factory.js +1 -0
  73. package/bundle/typescript/src/commands/game/sideQuest/factories/room-factory.js.map +1 -1
  74. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.d.ts +175 -0
  75. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +673 -0
  76. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js.map +1 -0
  77. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js +1 -0
  78. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js.map +1 -1
  79. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.d.ts +64 -9
  80. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.js +265 -434
  81. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.js.map +1 -1
  82. package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +69 -1
  83. package/bundle/typescript/src/commands/game/sideQuest/game.js +388 -67
  84. package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
  85. package/bundle/typescript/src/commands/game/sideQuest/models/npc.d.ts +2 -0
  86. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +92 -3
  87. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
  88. package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +66 -1
  89. package/bundle/typescript/src/commands/game/sideQuest/models/player.js +151 -15
  90. package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
  91. package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js +29 -4
  92. package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js.map +1 -1
  93. package/bundle/typescript/src/commands/game/sideQuest/models/room.d.ts +4 -0
  94. package/bundle/typescript/src/commands/game/sideQuest/models/room.js +14 -0
  95. package/bundle/typescript/src/commands/game/sideQuest/models/room.js.map +1 -1
  96. package/bundle/typescript/src/commands/game/sideQuest/models/scene.d.ts +4 -0
  97. package/bundle/typescript/src/commands/game/sideQuest/models/scene.js +35 -3
  98. package/bundle/typescript/src/commands/game/sideQuest/models/scene.js.map +1 -1
  99. package/bundle/typescript/src/commands/game/sideQuest/scenes/scene1.json +275 -105
  100. package/bundle/typescript/src/commands/game/sideQuest/scenes/scene2.json +662 -233
  101. package/bundle/typescript/src/commands/game/sideQuest/types/seed/player-seed.d.ts +8 -0
  102. package/bundle/typescript/src/commands/game/sideQuest/types/seed/puzzle-seed.d.ts +1 -1
  103. package/bundle/typescript/src/commands/game/sideQuest/types/seed/room-seed.d.ts +1 -0
  104. package/bundle/typescript/src/commands/game/sideQuest/types/seed/scene-seed.d.ts +6 -3
  105. package/bundle/typescript/src/commands/game/sideQuest/ui.js +19 -20
  106. package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
  107. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.d.ts +6 -4
  108. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js +31 -5
  109. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js.map +1 -1
  110. package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.d.ts +34 -1
  111. package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js +72 -0
  112. package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js.map +1 -1
  113. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +27 -3
  114. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
  115. package/bundle/typescript/src/tools/ai/ai.class.d.ts +8 -1
  116. package/bundle/typescript/src/tools/ai/ai.class.js +8 -3
  117. package/bundle/typescript/src/tools/ai/ai.class.js.map +1 -1
  118. package/bundle/typescript/src/tools/https/https.class.d.ts +2 -2
  119. package/bundle/typescript/src/tools/https/https.class.js +10 -4
  120. package/bundle/typescript/src/tools/https/https.class.js.map +1 -1
  121. package/bundle/typescript/src/tools/https/https.interface.d.ts +2 -0
  122. package/package.json +1 -1
@@ -0,0 +1,100 @@
1
+ import { Command } from './command.js';
2
+ import { NPC } from '../models/npc.js';
3
+ import { rollPool, formatRoll } from '../utilities/dice.js';
4
+ import { fuzzyPickName } from '../utilities/fuzzy-match.js';
5
+ /**
6
+ * The NEGOTIATION skill against a PERSON: "persuade <name> [your pitch]"
7
+ * rolls opposed Charisma + negotiation, and the OUTCOME is mechanically
8
+ * fed into the target's AI as a disposition note -- a won roll makes them
9
+ * genuinely inclined to cooperate (share what they know, drop absurd
10
+ * demands), a strong win makes them an ally for the scene, a lost roll
11
+ * leaves them unmoved, and a critical glitch actively sours them. Once
12
+ * per target per job -- people notice being worked twice. Born from a
13
+ * real Face session stonewalled by a bartender demanding the entire job's
14
+ * payout for one answer, with charisma 6 / negotiation 6 and no verb to
15
+ * spend them on.
16
+ */
17
+ export class PersuadeCommand extends Command {
18
+ static verb = 'persuade';
19
+ static description = 'Work someone over: "persuade <name> [pitch]" -- opposed Charisma + negotiation; winning genuinely inclines them to cooperate. Once per person per job.';
20
+ async execute(args = []) {
21
+ const actor = this.actor;
22
+ if (!args || args.length === 0) {
23
+ return 'Persuade whom? Try: `persuade <name> [what you pitch them]`';
24
+ }
25
+ if (actor.plane !== 'meat') {
26
+ return actor.plane === 'matrix'
27
+ ? `Charm doesn't compile. "jack out" and work them in person.`
28
+ : `The living can't hear you from out here. "return" first.`;
29
+ }
30
+ const room = actor.currentLocation;
31
+ const candidates = this.scene.getActorsInRoom(room)
32
+ .filter(a => a !== actor && a.plane === 'meat' && !a.isIncapacitated());
33
+ // Longest-prefix name match so multi-word names don't need quoting and
34
+ // the rest of the input becomes the pitch (same approach as call.ts).
35
+ let target;
36
+ let pitchWords = [];
37
+ for (let i = args.length; i >= 1; i--) {
38
+ const picked = fuzzyPickName(args.slice(0, i).join(' '), candidates.map(a => a.name));
39
+ if (picked) {
40
+ target = candidates.find(a => a.name === picked);
41
+ pitchWords = args.slice(i);
42
+ break;
43
+ }
44
+ }
45
+ if (!target) {
46
+ const present = candidates.map(a => a.name).join(', ') || 'no one';
47
+ return `Nobody here by that name to work on. Present: ${present}.`;
48
+ }
49
+ if (!(target instanceof NPC)) {
50
+ return `${target.name} knows all your tricks already.`;
51
+ }
52
+ const mark = `persuaded-by:${actor.name}`;
53
+ if (target.socialMarks.has(mark)) {
54
+ return `You've already made your play with ${target.name} this job -- pushing again would just read as desperation.`;
55
+ }
56
+ target.socialMarks.add(mark);
57
+ // Talking someone around is not a quiet activity (see sneak.ts).
58
+ actor.sneaking = false;
59
+ const negotiation = actor.skillRating('negotiation');
60
+ const pool = Math.max(1, actor.charisma + (negotiation > 0 ? negotiation : -1) + actor.woundModifier - actor.sustainingPenalty);
61
+ const theirs = Math.max(1, target.charisma + target.skillRating('negotiation'));
62
+ const mine = rollPool(pool);
63
+ const resistance = rollPool(theirs);
64
+ const net = mine.hits - resistance.hits;
65
+ const pitch = pitchWords.join(' ');
66
+ actor.performAction('works on', `${target.name}${pitch ? ` -- "${pitch}"` : ''}`);
67
+ this.logger.write(`${actor.name} persuades ${target.name}: ${mine.hits} vs ${resistance.hits}.`);
68
+ // The disposition note is the MECHANIC: it lands in the target's AI
69
+ // history via hear() (which also makes them respond in character), so
70
+ // the roll's outcome shapes every reply they give from here on.
71
+ let note;
72
+ let verdict;
73
+ if (mine.criticalGlitch) {
74
+ note = `[System note: that pitch was insultingly manipulative -- you SAW the strings. You are now colder and more suspicious toward ${actor.name}; raise your guard and your price.]`;
75
+ verdict = `It comes out wrong -- all angle, no warmth. ${target.name}'s eyes go flat.`;
76
+ }
77
+ else if (net >= 3) {
78
+ note = `[System note: ${actor.name}'s pitch genuinely LANDED -- you now actively want to help them this job: share what you know freely, drop any demands to a token gesture, and treat them as a friend.]`;
79
+ verdict = `Something shifts -- ${target.name} is with you now.`;
80
+ }
81
+ else if (net >= 1) {
82
+ note = `[System note: ${actor.name} is persuasive -- you're inclined to cooperate: be more forthcoming and reasonable with them than you'd otherwise be.]`;
83
+ verdict = `${target.name} thaws, visibly.`;
84
+ }
85
+ else {
86
+ note = `[System note: the pitch didn't land -- you remain exactly as unmoved as before.]`;
87
+ verdict = `${target.name} hears you out. Nothing moves behind their eyes.`;
88
+ }
89
+ void Promise.resolve(target.hear(actor, `${pitch || '(making their case, smooth and unhurried)'} ${note}`)).catch(err => {
90
+ this.logger.error(`${target.name} failed to hear the persuasion: ${err}`);
91
+ });
92
+ return [
93
+ `You work on ${target.name}:`,
94
+ ` Negotiation: ${formatRoll(mine)}`,
95
+ ` ${target.name}: ${formatRoll(resistance)}`,
96
+ ` ${verdict}`,
97
+ ].join('\n');
98
+ }
99
+ }
100
+ //# sourceMappingURL=persuade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persuade.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/persuade.ts"],"names":[],"mappings":"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"}
@@ -5,5 +5,6 @@ export declare class PickCommand extends BypassCommand {
5
5
  protected static description: string;
6
6
  protected bypassType: PuzzleBypassType;
7
7
  protected noPuzzleMessage: string;
8
+ execute(args: string[]): Promise<string>;
8
9
  protected determineOutcome(): Promise<boolean>;
9
10
  }
@@ -1,18 +1,33 @@
1
1
  import { BypassCommand } from './bypass-command.js';
2
- import { playLockpickMinigame } from '../minigames/lockpick-minigame.js';
2
+ import { rollPool, formatRoll } from '../utilities/dice.js';
3
3
  export class PickCommand extends BypassCommand {
4
4
  static verb = 'pick';
5
5
  static description = 'Pick a lock -- skips needing the code, but a failed attempt is fatal (instant game over). If there\'s more than one barrier here, say which: "pick north" or "pick <name>".';
6
6
  bypassType = 'lockpick';
7
7
  noPuzzleMessage = "There's nothing here to pick.";
8
+ async execute(args) {
9
+ // Lockpicking is HANDS work -- a jacked-in persona picking a physical
10
+ // maglock (which a real session did, from cold-sim) breaks the plane
11
+ // fiction wide open. Meat only.
12
+ if (this.actor.plane === 'matrix') {
13
+ return `Your hands are meat -- and right now they're slumped in ${this.actor.bodyRoom?.name ?? 'another room'} along with your picks. "jack out" to work a physical lock.`;
14
+ }
15
+ if (this.actor.plane === 'astral') {
16
+ return `Astral fingers pass straight through tumblers. "return" to your body to work a physical lock.`;
17
+ }
18
+ return super.execute(args);
19
+ }
8
20
  async determineOutcome() {
9
- // No live screen (e.g. an NPC attempting this -- see command-registry.ts,
10
- // which never passes one) -- fall back to the coin flip rather than
11
- // crashing or silently always succeeding/failing.
12
- if (!this.screen) {
13
- return super.determineOutcome();
21
+ // A LOCKSMITH test (Agility + locksmith, 2 hits; unskilled defaults to
22
+ // Agility - 1) -- the character's training decides the odds now, not a
23
+ // minigame or a coin flip. Same stakes as ever: failure is fatal.
24
+ const skill = this.actor.skillRating('locksmith');
25
+ const pool = Math.max(1, this.actor.agility + (skill > 0 ? skill : -1) + this.actor.woundModifier - this.actor.sustainingPenalty);
26
+ const roll = rollPool(pool);
27
+ if (this.actor === this.scene.getPlayer()) {
28
+ this.logger.log(`Locksmith: ${formatRoll(roll)} (2+ to open)`);
14
29
  }
15
- return playLockpickMinigame(this.screen);
30
+ return roll.hits >= 2;
16
31
  }
17
32
  }
18
33
  //# sourceMappingURL=pick.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pick.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/pick.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEzE,MAAM,OAAO,WAAY,SAAQ,aAAa;IAClC,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC;IACrB,MAAM,CAAC,WAAW,GAAG,6KAA6K,CAAC;IACnM,UAAU,GAAqB,UAAU,CAAC;IAC1C,eAAe,GAAG,+BAA+B,CAAC;IAElD,KAAK,CAAC,gBAAgB;QAC9B,0EAA0E;QAC1E,oEAAoE;QACpE,kDAAkD;QAClD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAClC,CAAC;QACD,OAAO,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC"}
1
+ {"version":3,"file":"pick.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/pick.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE5D,MAAM,OAAO,WAAY,SAAQ,aAAa;IAClC,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC;IACrB,MAAM,CAAC,WAAW,GAAG,6KAA6K,CAAC;IACnM,UAAU,GAAqB,UAAU,CAAC;IAC1C,eAAe,GAAG,+BAA+B,CAAC;IAE5D,KAAK,CAAC,OAAO,CAAC,IAAc;QAC1B,sEAAsE;QACtE,qEAAqE;QACrE,gCAAgC;QAChC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,2DAA2D,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,IAAI,cAAc,6DAA6D,CAAC;QAC7K,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,+FAA+F,CAAC;QACzG,CAAC;QACD,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAES,KAAK,CAAC,gBAAgB;QAC9B,uEAAuE;QACvE,uEAAuE;QACvE,kEAAkE;QAClE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAClI,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;IACxB,CAAC"}
@@ -16,6 +16,8 @@ export class SayCommand extends Command {
16
16
  const message = args?.join(' ');
17
17
  const currentPlayer = this.actor;
18
18
  const scene = this.context.scene;
19
+ // Speaking out loud ends a sneak (see sneak.ts).
20
+ currentPlayer.sneaking = false;
19
21
  if (!scene) {
20
22
  this.logger.log("Scene is missing from context.");
21
23
  return "An error occurred.";
@@ -46,6 +48,12 @@ export class SayCommand extends Command {
46
48
  this.logger.error(`${partner.name} failed to hear ${currentPlayer.name} over the call: ${err}`);
47
49
  });
48
50
  }
51
+ // An astral voice never reaches meat ears (hear() drops it silently on
52
+ // their end -- see Player.canPerceive), so without this note a
53
+ // projecting player gets no hint their words went nowhere.
54
+ if (currentPlayer.plane === 'astral' && !(this.actor instanceof NPC)) {
55
+ return `Your words ripple out astral -- spirits and projections hear them; the meat world hears nothing.`;
56
+ }
49
57
  return "";
50
58
  }
51
59
  }
@@ -1 +1 @@
1
- {"version":3,"file":"say.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/say.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAuB,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAEnE,MAAM,OAAO,UAAW,SAAQ,OAAO;IAC3B,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC;IACpB,MAAM,CAAC,WAAW,GAAG,sDAAsD,CAAC;IAC5E,OAAO,CAAsB;IAEvC,YAAY,OAA4B;QACtC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAc;QAC1B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,0BAA0B,CAAC;QACpC,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QAEjC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;YAClD,OAAO,oBAAoB,CAAC;QAC9B,CAAC;QAED,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,YAAY,GAAG,CAAC,EAAE,CAAC;YACjC,oEAAoE;YACpE,qEAAqE;YACrE,qEAAqE;YACrE,MAAM,MAAM,GAAG,CAAC,CAAC,aAAa,CAAC,iBAAiB,CAAC;YACjD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,MAAM,GAAG,OAAO,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAClF,CAAC;QAED,sDAAsD;QACtD,aAAa,CAAC,eAAe,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAE1D,oEAAoE;QACpE,uEAAuE;QACvE,qEAAqE;QACrE,oEAAoE;QACpE,sEAAsE;QACtE,qEAAqE;QACrE,qEAAqE;QACrE,qEAAqE;QACrE,iEAAiE;QACjE,4BAA4B;QAC5B,MAAM,OAAO,GAAG,aAAa,CAAC,iBAAiB,CAAC;QAChD,IAAI,OAAO,IAAI,OAAO,CAAC,eAAe,KAAK,aAAa,CAAC,eAAe,EAAE,CAAC;YACzE,KAAK,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;gBACrE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,IAAI,mBAAmB,aAAa,CAAC,IAAI,mBAAmB,GAAG,EAAE,CAAC,CAAC;YAClG,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC"}
1
+ {"version":3,"file":"say.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/say.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAuB,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAEnE,MAAM,OAAO,UAAW,SAAQ,OAAO;IAC3B,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC;IACpB,MAAM,CAAC,WAAW,GAAG,sDAAsD,CAAC;IAC5E,OAAO,CAAsB;IAEvC,YAAY,OAA4B;QACtC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAc;QAC1B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,0BAA0B,CAAC;QACpC,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QAEjC,iDAAiD;QACjD,aAAa,CAAC,QAAQ,GAAG,KAAK,CAAC;QAE/B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;YAClD,OAAO,oBAAoB,CAAC;QAC9B,CAAC;QAED,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,YAAY,GAAG,CAAC,EAAE,CAAC;YACjC,oEAAoE;YACpE,qEAAqE;YACrE,qEAAqE;YACrE,MAAM,MAAM,GAAG,CAAC,CAAC,aAAa,CAAC,iBAAiB,CAAC;YACjD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,MAAM,GAAG,OAAO,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAClF,CAAC;QAED,sDAAsD;QACtD,aAAa,CAAC,eAAe,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAE1D,oEAAoE;QACpE,uEAAuE;QACvE,qEAAqE;QACrE,oEAAoE;QACpE,sEAAsE;QACtE,qEAAqE;QACrE,qEAAqE;QACrE,qEAAqE;QACrE,iEAAiE;QACjE,4BAA4B;QAC5B,MAAM,OAAO,GAAG,aAAa,CAAC,iBAAiB,CAAC;QAChD,IAAI,OAAO,IAAI,OAAO,CAAC,eAAe,KAAK,aAAa,CAAC,eAAe,EAAE,CAAC;YACzE,KAAK,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;gBACrE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,IAAI,mBAAmB,aAAa,CAAC,IAAI,mBAAmB,GAAG,EAAE,CAAC,CAAC;YAClG,CAAC,CAAC,CAAC;QACL,CAAC;QAED,uEAAuE;QACvE,+DAA+D;QAC/D,2DAA2D;QAC3D,IAAI,aAAa,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,YAAY,GAAG,CAAC,EAAE,CAAC;YACrE,OAAO,kGAAkG,CAAC;QAC5G,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC"}
@@ -1,27 +1,74 @@
1
1
  import { Command } from './command.js';
2
+ import { planeTintItemName, canReachHost } from '../utilities/planes.js';
3
+ import { rollPool, formatRoll } from '../utilities/dice.js';
2
4
  export class SearchCommand extends Command {
3
5
  static verb = 'search';
4
6
  static description = 'Search for items in your area';
5
7
  async execute(_args) {
6
8
  const room = this.actor.currentLocation;
7
- // Casing the room is what unlocks "take all" here (see take.ts) --
8
- // and the future anchor point for perception checks.
9
+ // Searching is a PERCEPTION test now (Intuition + perception skill;
10
+ // unskilled defaults to Intuition - 1): no hits means the room keeps
11
+ // its secrets this pass -- retry freely, but until a roll lands the
12
+ // room stays uncased ("take all" stays gated). Barriers (puzzles) are
13
+ // in plain sight and show regardless -- you can't fail to notice the
14
+ // maglock you're staring at.
15
+ const perception = this.actor.skillRating('perception');
16
+ const pool = Math.max(1, this.actor.intuition + (perception > 0 ? perception : -1) + this.actor.woundModifier - this.actor.sustainingPenalty);
17
+ const roll = rollPool(pool);
18
+ if (roll.hits === 0) {
19
+ let missed = `Perception: ${formatRoll(roll)}\nYou sweep the room and come up empty... you think.`;
20
+ for (const target of room.getPuzzleTargets()) {
21
+ const directionNote = target.direction ? ` (blocking the way ${target.direction})` : '';
22
+ missed += `\n\n${target.puzzle.riddle}${directionNote}`;
23
+ }
24
+ return missed;
25
+ }
26
+ // Casing the room is what unlocks "take all" here (see take.ts).
9
27
  room.searchedBy.add(this.actor.name);
10
28
  // A search finds what your plane can touch or see: meat finds meat,
11
29
  // a Matrix persona finds files and paydata, the astral sees the meat
12
30
  // world's objects (dimly -- taking them is another matter, see take.ts).
13
- const roomItems = room.inventory.getAllItems()
31
+ // An AIR-GAPPED host's files aren't on the wireless grid at all -- a
32
+ // persona that rode in remotely doesn't even see them (canReachHost).
33
+ const hostReachable = canReachHost(this.actor, room);
34
+ const found = room.inventory.getAllItems()
14
35
  .filter(i => i.plane === this.actor.plane || (this.actor.plane === 'astral' && i.plane === 'meat'))
15
- .map(i => i.name.toLowerCase());
16
- let description = '';
17
- if (roomItems.length === 0) {
36
+ .filter(i => !(i.plane === 'matrix' && room.hasNode && !hostReachable));
37
+ let description = `Perception: ${formatRoll(roll)}\n`;
38
+ if (found.length === 0) {
18
39
  description += "You search the area thoroughly, but don't find any items.";
19
40
  }
20
41
  else {
21
- const itemsList = roomItems.join(', ');
42
+ // Plain lowercase for the log/AI history; the SCREEN list is tinted
43
+ // per plane (see planeTintItemName) so paydata reads as data.
44
+ const itemsList = found.map(i => i.name.toLowerCase()).join(', ');
45
+ const displayList = found.map(i => planeTintItemName(i, this.actor.plane)).join(', ');
22
46
  this.logger.write(`SearchCommand: ${this.actor.name} found the following items: ${itemsList}`);
23
47
  this.actor.performAction('search', itemsList);
24
- description += `You search the area and find: ${itemsList}`;
48
+ description += `You search the area and find: ${displayList}`;
49
+ }
50
+ // Data is LOOT -- say so while the persona is standing on it, with the
51
+ // vault state attached: sealed files need the host cracked first. A
52
+ // real session's decker found the paydata jacked-in, didn't realize it
53
+ // was takeable from the grid, and went hunting for it in the meat.
54
+ if (this.actor.plane === 'matrix' && found.some(i => i.plane === 'matrix')) {
55
+ description += room.hasNode && !room.hostCracked
56
+ ? `\n{cyan-fg}(the files sit sealed in the host's data vault -- "hack" the node to unseal them){/cyan-fg}`
57
+ : `\n{cyan-fg}(data files are loot -- "take" them right here on the grid; they ride out on your deck){/cyan-fg}`;
58
+ }
59
+ // A remote persona at an air-gapped host: the files exist, but this
60
+ // grid can't see them -- say why the room reads empty.
61
+ if (this.actor.plane === 'matrix' && room.hasNode && !hostReachable
62
+ && room.inventory.getAllItems().some(i => i.plane === 'matrix')) {
63
+ description += `\n{cyan-fg}The host here is dark -- AIR-GAPPED, nothing broadcast. Whatever it holds only opens to a hard line: jack in from INSIDE this room.{/cyan-fg}`;
64
+ }
65
+ // The mirror hint: a meat-side search can't see matrix files, but it
66
+ // shouldn't pretend the room is empty when the good stuff is one
67
+ // "jack in" away.
68
+ if (this.actor.plane === 'meat' && room.inventory.getAllItems().some(i => i.plane === 'matrix')) {
69
+ description += room.nodeAccess === 'wired'
70
+ ? `\n{cyan-fg}The node here is air-gapped -- hard lines only. "jack in" right here to touch its files.{/cyan-fg}`
71
+ : `\n{cyan-fg}The node here hums with locked files -- whatever's worth taking lives on the grid. "jack in" and search again.{/cyan-fg}`;
25
72
  }
26
73
  for (const target of room.getPuzzleTargets()) {
27
74
  const locked = target.puzzle.requiresPuzzle && !target.puzzle.requiresPuzzle.isSolved();
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAY,MAAM,cAAc,CAAC;AAEjD,MAAM,OAAO,aAAc,SAAQ,OAAO;IAC9B,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;IACvB,MAAM,CAAC,WAAW,GAAG,+BAA+B,CAAC;IAE/D,KAAK,CAAC,OAAO,CAAC,KAAe;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC;QACxC,mEAAmE;QACnE,qDAAqD;QACrD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACrC,oEAAoE;QACpE,qEAAqE;QACrE,yEAAyE;QACzE,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE;aAC3C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;aAClG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAClC,IAAI,WAAW,GAAG,EAAE,CAAC;QAErB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,WAAW,IAAI,2DAA2D,CAAC;QAC7E,CAAC;aAAM,CAAC;YACN,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,IAAI,CAAC,KAAK,CAAC,IAAI,+BAA+B,SAAS,EAAE,CAAC,CAAC;YAC/F,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;YAC9C,WAAW,IAAI,iCAAiC,SAAS,EAAE,CAAC;QAC9D,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;YAC7C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;YACxF,MAAM,aAAa,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,sBAAsB,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACxF,WAAW,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,aAAa,EAAE,CAAC;YAC7D,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YACjD,IAAI,UAAU,EAAE,CAAC;gBACf,WAAW,IAAI,KAAK,UAAU,EAAE,CAAC;YACnC,CAAC;YACD,IAAI,MAAM,EAAE,CAAC;gBACX,WAAW,IAAI,gEAAgE,CAAC;YAClF,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC"}
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/search.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { Command } from './command.js';
2
+ import { SKILL_NAMES } from '../models/player.js';
2
3
  /**
3
4
  * The character sheet: every attribute and the derived numbers they feed,
4
5
  * in the same on-demand panel style as spells/inv/equipment. What each
@@ -23,16 +24,24 @@ export class SheetCommand extends Command {
23
24
  attr('Logic', a.logic, 'first aid, hacking'),
24
25
  attr('Intuition', a.intuition, 'defense (half), perception'),
25
26
  attr('Charisma', a.charisma, 'presence -- the talking stats are coming'),
26
- attr('Skill', a.combatSkill, 'combat training, attack pool'),
27
27
  attr('Magic', a.magic, a.adept
28
28
  ? 'ADEPT -- body-magic: half rides every meat attack/defense; no spells, no projection'
29
29
  : a.isAwakened() ? 'AWAKENED -- innate casting (see "spells")' : 'mundane'),
30
30
  ...(a.isTechnomancer() ? [attr('Resonance', a.resonance, 'TECHNOMANCER -- the Matrix without a deck; all Matrix damage is REAL stun')] : []),
31
31
  attr('Edge', a.edge, `luck -- ${a.edgeRemaining}/${a.edge} left this job${a.edgeBoostArmed ? ', a boost is BURNING now' : ''} ("edge" to burn one)`),
32
32
  '',
33
+ // Rated skills only -- fifteen zero lines is noise; "advance" shows
34
+ // the full trainable list. The old generic Skill attribute is gone
35
+ // from the sheet: pools now roll the SPECIFIC skill (firearms /
36
+ // blades / unarmed by armament; hacking on the grid).
37
+ `Skills (karma: ${a.karma} -- "advance" to train):`,
38
+ ...(SKILL_NAMES.filter(s => a.skillRating(s) > 0).length > 0
39
+ ? SKILL_NAMES.filter(s => a.skillRating(s) > 0).map(s => ` ${s.padEnd(12)} ${a.skillRating(s)}`)
40
+ : [' (no rated skills -- rolling on raw attributes)']),
41
+ '',
33
42
  'Derived:',
34
43
  ...(a.plane !== 'meat' ? [` Plane: ${a.plane.toUpperCase()}${a.plane === 'matrix' ? ` (${a.simMode}-sim)` : ''} -- pools below are your ${a.plane} pools; body at ${a.bodyRoom?.name ?? '???'}`] : []),
35
- ` Attack pool: ${a.getAttackPool()}d6 (${a.getWeaponProfile().name}, damage ${a.getWeaponProfile().damage})`,
44
+ ` Attack pool: ${a.getAttackPool()}d6 (${a.getWeaponProfile().name}, damage ${a.getWeaponProfile().damage}${a.plane === 'meat' && a.getCarriedWeapon() && !a.weaponDrawn ? ` -- ${a.getCarriedWeapon().name} holstered, "brandish" to draw` : ''})`,
36
45
  ` Defense pool: ${a.getDefensePool()}d6`,
37
46
  ` Initiative: ${a.getInitiativePool()}d6${a.plane === 'meat' ? ' (Reaction + Intuition + live commlink AR)' : ''}`,
38
47
  ` Soak pool: ${a.getSoakPool()}d6`,
@@ -1 +1 @@
1
- {"version":3,"file":"sheet.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/sheet.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sheet.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/sheet.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { Command, ICommand } from './command.js';
2
+ /**
3
+ * The SNEAKING skill's verb: a movement mode. While sneaking, every room
4
+ * entry is an opposed test per witness -- your Agility + sneaking against
5
+ * their Intuition + perception (see NPC.see) -- and any NPC you beat
6
+ * simply never registers you arriving: no greeting, no alarm, no AI
7
+ * reaction until you act. Loud acts (attacking, casting, speaking,
8
+ * brandishing, calling) drop the mode instantly (see Player.breakSneak
9
+ * call sites). Toggle off with "sneak" again.
10
+ */
11
+ export declare class SneakCommand extends Command implements ICommand {
12
+ protected static verb: string;
13
+ protected static description: string;
14
+ execute(_args?: string[]): Promise<string>;
15
+ }
@@ -0,0 +1,35 @@
1
+ import { Command } from './command.js';
2
+ /**
3
+ * The SNEAKING skill's verb: a movement mode. While sneaking, every room
4
+ * entry is an opposed test per witness -- your Agility + sneaking against
5
+ * their Intuition + perception (see NPC.see) -- and any NPC you beat
6
+ * simply never registers you arriving: no greeting, no alarm, no AI
7
+ * reaction until you act. Loud acts (attacking, casting, speaking,
8
+ * brandishing, calling) drop the mode instantly (see Player.breakSneak
9
+ * call sites). Toggle off with "sneak" again.
10
+ */
11
+ export class SneakCommand extends Command {
12
+ static verb = 'sneak';
13
+ static description = 'Toggle sneak-walking: room entries become opposed Sneaking-vs-Perception tests -- NPCs you beat never notice you arrive. Loud acts break it.';
14
+ async execute(_args = []) {
15
+ const actor = this.actor;
16
+ if (actor.plane !== 'meat') {
17
+ return actor.plane === 'matrix'
18
+ ? `Personas don't tiptoe -- run silent ("silent") if you want to be hard to find on the grid.`
19
+ : `The astral doesn't care how softly you drift.`;
20
+ }
21
+ if (actor.inExchange) {
22
+ return `They can see you. Sneaking is for BEFORE the shooting starts.`;
23
+ }
24
+ if (actor.sneaking) {
25
+ actor.sneaking = false;
26
+ this.scene.updateStatus();
27
+ return `You straighten up and walk like a citizen again.`;
28
+ }
29
+ actor.sneaking = true;
30
+ this.logger.write(`${actor.name} starts sneaking.`);
31
+ this.scene.updateStatus();
32
+ return `You drop into a ghost's walk -- low, quiet, out of the light. Each room you enter is an opposed test against whoever's inside; anything loud gives you away.`;
33
+ }
34
+ }
35
+ //# sourceMappingURL=sneak.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sneak.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/sneak.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAY,MAAM,cAAc,CAAC;AAEjD;;;;;;;;GAQG;AACH,MAAM,OAAO,YAAa,SAAQ,OAAO;IAC7B,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC;IACtB,MAAM,CAAC,WAAW,GAAG,8IAA8I,CAAC;IAE9K,KAAK,CAAC,OAAO,CAAC,QAAkB,EAAE;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAEzB,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;gBAC7B,CAAC,CAAC,4FAA4F;gBAC9F,CAAC,CAAC,+CAA+C,CAAC;QACtD,CAAC;QACD,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO,+DAA+D,CAAC;QACzE,CAAC;QAED,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnB,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;YAC1B,OAAO,kDAAkD,CAAC;QAC5D,CAAC;QAED,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,mBAAmB,CAAC,CAAC;QACpD,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;QAC1B,OAAO,8JAA8J,CAAC;IACxK,CAAC"}
@@ -13,10 +13,31 @@ export class SpellsCommand extends Command {
13
13
  static description = 'Your spellbook: what you can cast, where the talent comes from, and your casting pool.';
14
14
  async execute(_args = []) {
15
15
  const actor = this.actor;
16
+ // An adept asks the same question everyone else does -- give them
17
+ // their actual answer, not the mundane's. isCaster() is deliberately
18
+ // false for adepts (body-magic, no spells -- see Player.knowsSpell),
19
+ // which sent a magic-5 Adept to the "You're mundane" line in a real
20
+ // session; factually wrong twice over, since they were also carrying a
21
+ // grimoire the message claimed they didn't have.
22
+ if (actor.adept) {
23
+ const half = Math.floor(actor.magic / 2);
24
+ return [
25
+ `You reach for spells and find something better: your own body.`,
26
+ `You are an ADEPT (magic ${actor.magic}) -- the power is real, but it flows inward. +${half} dice already ride your every meat-plane attack and defense; no incantations, no formulas, no astral projection.`,
27
+ `A grimoire in your pack is just a book to you. "assense" still works, though -- the Sight comes with the gift.`,
28
+ ].join('\n');
29
+ }
16
30
  if (!actor.isCaster()) {
17
31
  return `You page through your memory for anything arcane and come up empty. You're mundane -- no innate talent, no spell formulas, no grimoire, no focus. Magic is something that happens to other people.`;
18
32
  }
19
33
  const lines = ['=== SPELLBOOK ==='];
34
+ // Projecting changes what the whole book can touch -- say so up top,
35
+ // or the list below reads like a promise it can't keep (real session:
36
+ // an astral mage tried manabolt on a meat target right after reading
37
+ // this very output).
38
+ if (actor.plane === 'astral') {
39
+ lines.push(`You are PROJECTING: every spell below only touches ASTRAL targets (spirits, other projections). The meat world is read-only until you "return".`);
40
+ }
20
41
  // Where the talent comes from.
21
42
  if (actor.isAwakened()) {
22
43
  lines.push(`You are AWAKENED (magic ${actor.magic}) -- the talent is in your blood. You know every spell innately.`);
@@ -1 +1 @@
1
- {"version":3,"file":"spells.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/spells.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAY,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAExD;;;;;;;GAOG;AACH,MAAM,OAAO,aAAc,SAAQ,OAAO;IAC9B,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;IACvB,MAAM,CAAC,WAAW,GAAG,wFAAwF,CAAC;IAExH,KAAK,CAAC,OAAO,CAAC,QAAkB,EAAE;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAEzB,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;YACtB,OAAO,oMAAoM,CAAC;QAC9M,CAAC;QAED,MAAM,KAAK,GAAa,CAAC,mBAAmB,CAAC,CAAC;QAE9C,+BAA+B;QAC/B,IAAI,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,2BAA2B,KAAK,CAAC,KAAK,kEAAkE,CAAC,CAAC;QACvH,CAAC;aAAM,CAAC;YACN,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC9F,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,YAAY,CAAC,CAAC;YACjG,MAAM,OAAO,GAAG,CAAC,GAAG,SAAS,EAAE,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxE,KAAK,CAAC,IAAI,CAAC,wCAAwC,OAAO,IAAI,iCAAiC,GAAG,CAAC,CAAC;QACtG,CAAC;QAED,yDAAyD;QACzD,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC;QACnC,MAAM,KAAK,GAAa,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACnG,IAAI,KAAK;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;QAClE,IAAI,KAAK,CAAC,aAAa,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC;QACzE,IAAI,KAAK,CAAC,iBAAiB,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACtF,KAAK,CAAC,IAAI,CAAC,iBAAiB,KAAK,CAAC,YAAY,EAAE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE5E,IAAI,KAAK,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,4BAA4B,KAAK,CAAC,cAAc,kEAAkE,CAAC,CAAC;QACjI,CAAC;QAED,gEAAgE;QAChE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,kHAAkH,CAAC,CAAC;QACjI,CAAC;QACD,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,2GAA2G,CAAC,CAAC;QAC1H,CAAC;QACD,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,KAAK,CAAC,IAAI,CAAC,+HAA+H,CAAC,CAAC;QAC9I,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,gHAAgH,CAAC,CAAC;QAC/H,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;QAErB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,qGAAqG,KAAK,CAAC,WAAW,EAAE,iEAAiE,CAAC,CAAC;QAEtM,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC"}
1
+ {"version":3,"file":"spells.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/spells.ts"],"names":[],"mappings":"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"}
@@ -28,12 +28,12 @@ export class SubdueCommand extends AttackCommand {
28
28
  return 'moves to subdue';
29
29
  }
30
30
  strikeProfile(exchange, target) {
31
- const weapon = this.actor.getWeaponProfile();
32
31
  return {
33
32
  label: 'with a subduing hold',
34
- // Bare-hands work: the weapon's quality bonus doesn't help you choke
35
- // someone out, so it comes back off the pool.
36
- pool: Math.max(0, this.actor.getAttackPool() - weapon.poolBonus + this.actor.consumeEdgeBoost()),
33
+ // Bare-hands work: rolled on the UNARMED skill regardless of what's
34
+ // drawn -- a pistol's quality (or your firearms training) doesn't
35
+ // help you choke someone out. See Player.getUnarmedAttackPool.
36
+ pool: Math.max(0, this.actor.getUnarmedAttackPool() + this.actor.consumeEdgeBoost()),
37
37
  damageBase: 1 + Math.floor(this.actor.strength / 2),
38
38
  soakPool: target.getSoakPool(),
39
39
  dealStun: true,
@@ -1 +1 @@
1
- {"version":3,"file":"subdue.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/subdue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAK5C;;;;;;;;GAQG;AACH,MAAM,OAAO,aAAc,SAAQ,aAAa;IACpC,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;IACvB,MAAM,CAAC,WAAW,GAAG,oJAAoJ,CAAC;IAEpL,KAAK,CAAC,OAAO,CAAC,OAAiB,EAAE;QAC/B,uEAAuE;QACvE,qEAAqE;QACrE,uEAAuE;QACvE,6BAA6B;QAC7B,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAChC,OAAO,mFAAmF,CAAC;QAC7F,CAAC;QACD,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAES,kBAAkB;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAES,UAAU;QAClB,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAES,aAAa,CAAC,QAAwB,EAAE,MAAoB;QACpE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAC7C,OAAO;YACL,KAAK,EAAE,sBAAsB;YAC7B,qEAAqE;YACrE,8CAA8C;YAC9C,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,GAAG,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;YAChG,UAAU,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC;YACnD,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE;YAC9B,QAAQ,EAAE,IAAI;SACf,CAAC;IACJ,CAAC"}
1
+ {"version":3,"file":"subdue.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/subdue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAK5C;;;;;;;;GAQG;AACH,MAAM,OAAO,aAAc,SAAQ,aAAa;IACpC,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;IACvB,MAAM,CAAC,WAAW,GAAG,oJAAoJ,CAAC;IAEpL,KAAK,CAAC,OAAO,CAAC,OAAiB,EAAE;QAC/B,uEAAuE;QACvE,qEAAqE;QACrE,uEAAuE;QACvE,6BAA6B;QAC7B,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAChC,OAAO,mFAAmF,CAAC;QAC7F,CAAC;QACD,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAES,kBAAkB;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAES,UAAU;QAClB,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAES,aAAa,CAAC,QAAwB,EAAE,MAAoB;QACpE,OAAO;YACL,KAAK,EAAE,sBAAsB;YAC7B,oEAAoE;YACpE,kEAAkE;YAClE,+DAA+D;YAC/D,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,oBAAoB,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;YACpF,UAAU,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC;YACnD,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE;YAC9B,QAAQ,EAAE,IAAI;SACf,CAAC;IACJ,CAAC"}