@maka/maka-cli 5.40.0 → 5.42.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.
- package/bundle/typescript/package.json +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/jobs.d.ts +12 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/jobs.js +126 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/jobs.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/persuade.js +17 -10
- package/bundle/typescript/src/commands/game/sideQuest/commands/persuade.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/search.js +30 -19
- package/bundle/typescript/src/commands/game/sideQuest/commands/search.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +6 -0
- package/bundle/typescript/src/commands/game/sideQuest/game.js +18 -5
- package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +17 -2
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/shared-run.d.ts +17 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/shared-run.js +44 -3
- package/bundle/typescript/src/commands/game/sideQuest/utilities/shared-run.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maka/maka-cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.42.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"summary": "A command line tool for scaffolding Meteor 2.x applications using either React.",
|
|
6
6
|
"description": "A command line tool for scaffolding Meteor 2.x applications using React.",
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command, ICommand } from './command.js';
|
|
2
|
+
export declare class JobsCommand extends Command implements ICommand {
|
|
3
|
+
protected static verb: string;
|
|
4
|
+
protected static description: string;
|
|
5
|
+
execute(args?: string[]): Promise<string>;
|
|
6
|
+
private fixerName;
|
|
7
|
+
private liveCrewNames;
|
|
8
|
+
private buildBoard;
|
|
9
|
+
private gameAnonymous;
|
|
10
|
+
private take;
|
|
11
|
+
private dismiss;
|
|
12
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Command } from './command.js';
|
|
2
|
+
import { hint } from '../utilities/hints.js';
|
|
3
|
+
export class JobsCommand extends Command {
|
|
4
|
+
static verb = 'jobs';
|
|
5
|
+
static description = 'The job board: what\'s on offer, CREW vs LOCAL. "jobs take <n>" puts one on the table, "jobs dismiss <n>" scraps it.';
|
|
6
|
+
async execute(args = []) {
|
|
7
|
+
const game = this.game;
|
|
8
|
+
if (!game?.hasHub) {
|
|
9
|
+
return `The board lives at home -- out here the only job is the one you're on.`;
|
|
10
|
+
}
|
|
11
|
+
const board = await this.buildBoard();
|
|
12
|
+
const sub = (args[0] ?? '').toLowerCase();
|
|
13
|
+
if (sub === 'take' || sub === 'dismiss') {
|
|
14
|
+
const n = Number.parseInt(args[1] ?? '', 10);
|
|
15
|
+
const entry = Number.isFinite(n) ? board[n - 1] : undefined;
|
|
16
|
+
if (!entry) {
|
|
17
|
+
return board.length === 0
|
|
18
|
+
? `The board is empty -- "call ${this.fixerName()}" to drum something up.`
|
|
19
|
+
: `Which one? "jobs" lists ${board.length === 1 ? 'the entry' : `1-${board.length}`}.`;
|
|
20
|
+
}
|
|
21
|
+
return sub === 'take' ? this.take(entry) : this.dismiss(entry);
|
|
22
|
+
}
|
|
23
|
+
if (board.length === 0) {
|
|
24
|
+
return `=== THE JOB BOARD ===\nNothing on offer. "call ${this.fixerName()}" to drum something up.`;
|
|
25
|
+
}
|
|
26
|
+
const lines = board.map((e, i) => ` ${i + 1}. [${e.tag}] "${e.name}"${e.detail ? ` -- ${e.detail}` : ''}${e.kind === 'standing' ? ' (standing -- "jobs take ' + (i + 1) + '")' : ''}`);
|
|
27
|
+
return `=== THE JOB BOARD ===\n${lines.join('\n')}${hint(`\n("jobs take <n>" puts one on the table, "jobs dismiss <n>" scraps it -- crew jobs die for the whole table.)`)}`;
|
|
28
|
+
}
|
|
29
|
+
fixerName() {
|
|
30
|
+
return 'Mr. Krow';
|
|
31
|
+
}
|
|
32
|
+
liveCrewNames() {
|
|
33
|
+
return (this.game?.crew ?? []).filter(m => m.ghost?.liveOnly).map(m => m.name).sort();
|
|
34
|
+
}
|
|
35
|
+
async buildBoard() {
|
|
36
|
+
const game = this.game;
|
|
37
|
+
const entries = [];
|
|
38
|
+
const pending = game.pendingRun;
|
|
39
|
+
if (pending) {
|
|
40
|
+
if (game.pendingSharedRun) {
|
|
41
|
+
const seats = game.pendingSharedRun.party?.filter(n => n !== this.actor.name);
|
|
42
|
+
const forWho = seats && seats.length > 0 ? `quoted for you + ${seats.join(', ')}` : 'quoted for the table';
|
|
43
|
+
entries.push({
|
|
44
|
+
tag: 'CREW', kind: 'active', name: pending.name,
|
|
45
|
+
detail: `${forWho}${game.pendingRunAccepted ? ' -- ACCEPTED, "call taxi" rolls' : ` -- "call ${this.fixerName()}" to hear it`}`,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
entries.push({
|
|
50
|
+
tag: 'LOCAL', kind: 'active', name: pending.name,
|
|
51
|
+
detail: `this machine only${game.pendingRunAccepted ? ' -- ACCEPTED, "travel" goes' : ` -- "call ${this.fixerName()}" to hear it`}`,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Standing drafts: ONLY the ones whose quoted crew is seated right
|
|
56
|
+
// now (the ruling), and never the one already on the table.
|
|
57
|
+
if (game.hasHub && !this.gameAnonymous()) {
|
|
58
|
+
try {
|
|
59
|
+
const sr = await import('../utilities/shared-run.js');
|
|
60
|
+
const seated = this.liveCrewNames().join('|');
|
|
61
|
+
for (const d of sr.HubLink.myStandingDrafts()) {
|
|
62
|
+
if (d.sessionID === game.pendingSharedRun?.sessionID)
|
|
63
|
+
continue;
|
|
64
|
+
if (seated.length === 0 || d.members.slice().sort().join('|') !== seated)
|
|
65
|
+
continue;
|
|
66
|
+
entries.push({
|
|
67
|
+
tag: 'CREW', kind: 'standing', name: d.pitch ?? 'a job on ice',
|
|
68
|
+
detail: `quoted for you + ${d.members.join(', ')}`,
|
|
69
|
+
sessionID: d.sessionID,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch { /* offline -- the board just shows local state */ }
|
|
74
|
+
}
|
|
75
|
+
return entries;
|
|
76
|
+
}
|
|
77
|
+
gameAnonymous() {
|
|
78
|
+
return this.game?._anonymous === true;
|
|
79
|
+
}
|
|
80
|
+
async take(entry) {
|
|
81
|
+
const game = this.game;
|
|
82
|
+
if (entry.kind === 'active') {
|
|
83
|
+
return game.pendingRunAccepted
|
|
84
|
+
? `"${entry.name}" is already locked -- ${entry.tag === 'CREW' ? '"call taxi" rolls' : '"travel" goes'}.`
|
|
85
|
+
: `"${entry.name}" is already on the table -- "call ${this.fixerName()}" to hear it.`;
|
|
86
|
+
}
|
|
87
|
+
// Swap the current offer aside (the server draft behind a CREW offer
|
|
88
|
+
// survives -- fingerprint reuse brings it back to the board).
|
|
89
|
+
if (game.pendingRun) {
|
|
90
|
+
game.clearPendingRun({ keepServerDraft: true });
|
|
91
|
+
}
|
|
92
|
+
const gate = game.canDraftNextScene();
|
|
93
|
+
if (!gate.allowed)
|
|
94
|
+
return gate.message ?? `${this.fixerName()} is mid-call -- give it a beat.`;
|
|
95
|
+
// Name the pick: without this, fingerprint reuse hands back the
|
|
96
|
+
// NEWEST matching draft, not the chosen one (2026-08-24 playtest).
|
|
97
|
+
game.preferredDraftSessionID = entry.sessionID;
|
|
98
|
+
game.draftNextSceneInBackground();
|
|
99
|
+
this.logger.write(`Jobs board: taking standing draft ${entry.sessionID} ("${entry.name}").`);
|
|
100
|
+
return `You flag "${entry.name}" -- ${this.fixerName()} pulls the paperwork. He'll ping you.`;
|
|
101
|
+
}
|
|
102
|
+
async dismiss(entry) {
|
|
103
|
+
const game = this.game;
|
|
104
|
+
if (entry.kind === 'active') {
|
|
105
|
+
const wasCrew = entry.tag === 'CREW';
|
|
106
|
+
// Explicit dismissal kills the server draft too -- that's the
|
|
107
|
+
// point of the button (the crew-change scrap is the path that
|
|
108
|
+
// preserves it).
|
|
109
|
+
game.clearPendingRun();
|
|
110
|
+
this.logger.write(`Jobs board: dismissed active ${wasCrew ? 'crew' : 'local'} offer "${entry.name}".`);
|
|
111
|
+
return wasCrew
|
|
112
|
+
? `You scrap "${entry.name}" -- for the whole table. ${this.fixerName()} will hear about it.`
|
|
113
|
+
: `You wave off "${entry.name}". The client will hear it from ${this.fixerName()}.`;
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
const sr = await import('../utilities/shared-run.js');
|
|
117
|
+
sr.HubLink.abortDraft(entry.sessionID);
|
|
118
|
+
this.logger.write(`Jobs board: dismissed standing draft ${entry.sessionID} ("${entry.name}").`);
|
|
119
|
+
return `You tell ${this.fixerName()} to shred "${entry.name}". Gone for the whole table.`;
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return `The street doesn't answer -- that one stays in ${this.fixerName()}'s drawer for now.`;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=jobs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/jobs.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,7 +17,7 @@ import { sameSpot, spotOf, spotRefusal } from '../utilities/spots.js';
|
|
|
17
17
|
*/
|
|
18
18
|
export class PersuadeCommand extends Command {
|
|
19
19
|
static verb = 'persuade';
|
|
20
|
-
static description = 'Work someone over: "persuade <name> [pitch]" -- opposed Charisma + negotiation; winning genuinely inclines them to cooperate.
|
|
20
|
+
static description = 'Work someone over: "persuade <name> [pitch]" -- opposed Charisma + negotiation; winning genuinely inclines them to cooperate. Retries stack -2 dice each (SR5e p.49).';
|
|
21
21
|
async execute(args = []) {
|
|
22
22
|
const actor = this.actor;
|
|
23
23
|
if (!args || args.length === 0) {
|
|
@@ -54,11 +54,14 @@ export class PersuadeCommand extends Command {
|
|
|
54
54
|
if (!sameSpot(actor, target)) {
|
|
55
55
|
return spotRefusal(target.name, spotOf(target));
|
|
56
56
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
target.socialMarks.
|
|
57
|
+
// TRYING AGAIN (SR5e p.49, canon check 2026-08-24): retries are
|
|
58
|
+
// legal at a CUMULATIVE -2 dice each -- the hard once-per-job block
|
|
59
|
+
// is gone. The count lives in socialMarks so it rides the NPC.
|
|
60
|
+
const markPrefix = `persuaded-by:${actor.name}:`;
|
|
61
|
+
const priorAttempts = [...target.socialMarks].filter(m => m.startsWith(markPrefix)).length
|
|
62
|
+
+ (target.socialMarks.has(`persuaded-by:${actor.name}`) ? 1 : 0);
|
|
63
|
+
target.socialMarks.add(`${markPrefix}${priorAttempts + 1}`);
|
|
64
|
+
const retryPenalty = priorAttempts * 2;
|
|
62
65
|
// Talking someone around is not a quiet activity (see sneak.ts).
|
|
63
66
|
actor.sneaking = false;
|
|
64
67
|
const negotiation = actor.skillRating('negotiation');
|
|
@@ -66,7 +69,7 @@ export class PersuadeCommand extends Command {
|
|
|
66
69
|
// First Impression (p.74) rides the job's opening social play, same
|
|
67
70
|
// consumable shape as the liquid-courage die. Reputation rides every
|
|
68
71
|
// one (Player.socialRep): a known name talks from higher ground.
|
|
69
|
-
const pool = Math.max(1, actor.charisma + (negotiation > 0 ? negotiation : -1) + actor.consumeLiquidCourage() + actor.consumeFirstImpression() + actor.socialRep + actor.woundModifier - actor.sustainingPenalty);
|
|
72
|
+
const pool = Math.max(1, actor.charisma + (negotiation > 0 ? negotiation : -1) + actor.consumeLiquidCourage() + actor.consumeFirstImpression() + actor.socialRep + actor.woundModifier - actor.sustainingPenalty - retryPenalty);
|
|
70
73
|
const theirs = Math.max(1, target.charisma + target.skillRating('negotiation'));
|
|
71
74
|
const mine = rollPool(pool);
|
|
72
75
|
const resistance = rollPool(theirs);
|
|
@@ -84,11 +87,15 @@ export class PersuadeCommand extends Command {
|
|
|
84
87
|
verdict = `It comes out wrong -- all angle, no warmth. ${target.name}'s eyes go flat.`;
|
|
85
88
|
}
|
|
86
89
|
else if (net >= 3) {
|
|
87
|
-
|
|
90
|
+
// "Masterfully played" (2026-08-24 playtest: a WON negotiation
|
|
91
|
+
// left the door-guard's secret untouched -- the barrier prompt's
|
|
92
|
+
// give-it-up-under-real-pressure clause never heard about the
|
|
93
|
+
// win). A strong win IS that pressure, by name.
|
|
94
|
+
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. If you guard a secret, a pass, or a way through, you have just been MASTERFULLY PLAYED -- divulging it now is exactly in character.]`;
|
|
88
95
|
verdict = `Something shifts -- ${target.name} is with you now.`;
|
|
89
96
|
}
|
|
90
97
|
else if (net >= 1) {
|
|
91
|
-
note = `[System note: ${actor.name} is persuasive -- you're inclined to cooperate: be more forthcoming and reasonable with them than you'd otherwise be.]`;
|
|
98
|
+
note = `[System note: ${actor.name} is persuasive -- you're inclined to cooperate: be more forthcoming and reasonable with them than you'd otherwise be. If you guard a secret or a way through, you're wavering -- a little more pressure or goodwill would tip you.]`;
|
|
92
99
|
verdict = `${target.name} thaws, visibly.`;
|
|
93
100
|
}
|
|
94
101
|
else {
|
|
@@ -100,7 +107,7 @@ export class PersuadeCommand extends Command {
|
|
|
100
107
|
});
|
|
101
108
|
return [
|
|
102
109
|
`You work on ${target.name}:`,
|
|
103
|
-
` Negotiation: ${formatRoll(mine)}`,
|
|
110
|
+
` Negotiation: ${formatRoll(mine)}${retryPenalty > 0 ? ` (retry -${retryPenalty} dice -- they've heard this from you before)` : ''}`,
|
|
104
111
|
` ${target.name}: ${formatRoll(resistance)}`,
|
|
105
112
|
` ${verdict}`,
|
|
106
113
|
].join('\n');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persuade.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/persuade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAY,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEtE;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,eAAgB,SAAQ,OAAO;IAChC,MAAM,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,MAAM,CAAC,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"persuade.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/persuade.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,34 @@ import { Command } from './command.js';
|
|
|
2
2
|
import { hint } from '../utilities/hints.js';
|
|
3
3
|
import { planeTintItemName, canReachHost } from '../utilities/planes.js';
|
|
4
4
|
import { rollPool, formatRoll } from '../utilities/dice.js';
|
|
5
|
-
import { canReach } from '../utilities/spots.js';
|
|
5
|
+
import { canReach, exitSpot, spotsActive } from '../utilities/spots.js';
|
|
6
|
+
/**
|
|
7
|
+
* Barrier rendering (2026-08-24 playtest: "I don't see THE THING I'm
|
|
8
|
+
* supposed to act on -- just a description... and I still see the
|
|
9
|
+
* 'puzzle' even when I'm not at it"): a NAMED, structured header so the
|
|
10
|
+
* barrier reads as an actable object, and the full riddle only up
|
|
11
|
+
* close -- from a distance it's one pointer line, like items at other
|
|
12
|
+
* spots.
|
|
13
|
+
*/
|
|
14
|
+
function describeBarriers(room, actor) {
|
|
15
|
+
let out = '';
|
|
16
|
+
for (const target of room.getPuzzleTargets()) {
|
|
17
|
+
const anchor = target.direction && spotsActive(room) ? exitSpot(room, target.direction) : undefined;
|
|
18
|
+
const sealing = target.direction ? ` -- sealing the way ${target.direction}` : '';
|
|
19
|
+
if (anchor && !canReach(actor, anchor)) {
|
|
20
|
+
out += `\n\n{yellow-fg}BARRIER${sealing}:{/yellow-fg} worked from the ${anchor} -- "move to ${anchor}" for a proper look.`;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
out += `\n\n{yellow-fg}BARRIER${sealing}${anchor ? ` (at the ${anchor})` : ''}:{/yellow-fg} ${target.puzzle.riddle}`;
|
|
24
|
+
const bypassHint = target.puzzle.getBypassHint();
|
|
25
|
+
if (bypassHint)
|
|
26
|
+
out += `\n${bypassHint}`;
|
|
27
|
+
if (target.puzzle.requiresPuzzle && !target.puzzle.requiresPuzzle.isSolved()) {
|
|
28
|
+
out += `\n(This seems locked -- something else needs to happen first.)`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
6
33
|
export class SearchCommand extends Command {
|
|
7
34
|
static verb = 'search';
|
|
8
35
|
static description = 'Search for items in your area';
|
|
@@ -32,12 +59,7 @@ export class SearchCommand extends Command {
|
|
|
32
59
|
this.logger.meta(`Perception: ${formatRoll(roll)}`);
|
|
33
60
|
const rollPrefix = isPlayer ? '' : `Perception: ${formatRoll(roll)}\n`;
|
|
34
61
|
if (roll.hits === 0) {
|
|
35
|
-
|
|
36
|
-
for (const target of room.getPuzzleTargets()) {
|
|
37
|
-
const directionNote = target.direction ? ` (blocking the way ${target.direction})` : '';
|
|
38
|
-
missed += `\n\n${target.puzzle.riddle}${directionNote}`;
|
|
39
|
-
}
|
|
40
|
-
return missed;
|
|
62
|
+
return `${rollPrefix}You sweep the room and come up empty... you think.${describeBarriers(room, this.actor)}`;
|
|
41
63
|
}
|
|
42
64
|
// Casing the room is what unlocks "take all" here (see take.ts).
|
|
43
65
|
room.searchedBy.add(this.actor.name);
|
|
@@ -99,18 +121,7 @@ export class SearchCommand extends Command {
|
|
|
99
121
|
? `\n{cyan-fg}The node here is air-gapped -- hard lines only.${hint(` "jack in" right here to touch its files.`)}{/cyan-fg}`
|
|
100
122
|
: `\n{cyan-fg}The node here hums with locked files -- whatever's worth taking lives on the grid.${hint(` "jack in" and search again.`)}{/cyan-fg}`;
|
|
101
123
|
}
|
|
102
|
-
|
|
103
|
-
const locked = target.puzzle.requiresPuzzle && !target.puzzle.requiresPuzzle.isSolved();
|
|
104
|
-
const directionNote = target.direction ? ` (blocking the way ${target.direction})` : '';
|
|
105
|
-
description += `\n\n${target.puzzle.riddle}${directionNote}`;
|
|
106
|
-
const bypassHint = target.puzzle.getBypassHint();
|
|
107
|
-
if (bypassHint) {
|
|
108
|
-
description += `\n${bypassHint}`;
|
|
109
|
-
}
|
|
110
|
-
if (locked) {
|
|
111
|
-
description += `\n(This seems locked -- something else needs to happen first.)`;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
124
|
+
description += describeBarriers(room, this.actor);
|
|
114
125
|
return description;
|
|
115
126
|
}
|
|
116
127
|
}
|
|
@@ -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;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -404,7 +404,13 @@ export default class Game {
|
|
|
404
404
|
*/
|
|
405
405
|
pendingSharedRun?: {
|
|
406
406
|
sessionID: string;
|
|
407
|
+
party?: string[];
|
|
407
408
|
};
|
|
409
|
+
/** One-shot: the jobs board's "take <n>" names WHICH standing draft
|
|
410
|
+
* the next Krow call should pull (2026-08-24 playtest: reuse always
|
|
411
|
+
* returned the newest match, ignoring the pick). Consumed by
|
|
412
|
+
* draftNextScene's shared path. */
|
|
413
|
+
preferredDraftSessionID?: string;
|
|
408
414
|
/**
|
|
409
415
|
* A live shared run: every typed command delegates here (handleInput)
|
|
410
416
|
* and the panes render the server's event stream. Set/cleared by
|
|
@@ -92,6 +92,7 @@ import { BuyCommand } from './commands/buy.js';
|
|
|
92
92
|
import { SellCommand } from './commands/sell.js';
|
|
93
93
|
import { PayCommand } from './commands/pay.js';
|
|
94
94
|
import { LifestyleCommand } from './commands/lifestyle.js';
|
|
95
|
+
import { JobsCommand } from './commands/jobs.js';
|
|
95
96
|
import { TreatCommand } from './commands/treat.js';
|
|
96
97
|
import { WorkCommand } from './commands/work.js';
|
|
97
98
|
import { EatCommand } from './commands/eat.js';
|
|
@@ -1298,6 +1299,11 @@ export default class Game {
|
|
|
1298
1299
|
* taxi starts the remote session instead of activating a scene.
|
|
1299
1300
|
*/
|
|
1300
1301
|
pendingSharedRun;
|
|
1302
|
+
/** One-shot: the jobs board's "take <n>" names WHICH standing draft
|
|
1303
|
+
* the next Krow call should pull (2026-08-24 playtest: reuse always
|
|
1304
|
+
* returned the newest match, ignoring the pick). Consumed by
|
|
1305
|
+
* draftNextScene's shared path. */
|
|
1306
|
+
preferredDraftSessionID;
|
|
1301
1307
|
/**
|
|
1302
1308
|
* A live shared run: every typed command delegates here (handleInput)
|
|
1303
1309
|
* and the panes render the server's event stream. Set/cleared by
|
|
@@ -1716,6 +1722,7 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
1716
1722
|
CommandFactory.registerCommand('eat', EatCommand);
|
|
1717
1723
|
CommandFactory.registerCommand('drink', DrinkCommand);
|
|
1718
1724
|
CommandFactory.registerCommand('lifestyle', LifestyleCommand);
|
|
1725
|
+
CommandFactory.registerCommand('jobs', JobsCommand);
|
|
1719
1726
|
CommandFactory.registerCommand('treat', TreatCommand);
|
|
1720
1727
|
CommandFactory.registerCommand('work', WorkCommand);
|
|
1721
1728
|
CommandFactory.registerCommand('gig', WorkCommand);
|
|
@@ -2519,7 +2526,9 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
2519
2526
|
let sharedDeclineNote = '';
|
|
2520
2527
|
if (this.hasHub && !this._anonymous) {
|
|
2521
2528
|
const srMod = await import('./utilities/shared-run.js').catch(() => undefined);
|
|
2522
|
-
const
|
|
2529
|
+
const preferred = this.preferredDraftSessionID;
|
|
2530
|
+
this.preferredDraftSessionID = undefined;
|
|
2531
|
+
const shared = srMod ? await srMod.tryCreateSharedSession(this, preferred).catch(() => undefined) : undefined;
|
|
2523
2532
|
if (shared && 'declined' in shared) {
|
|
2524
2533
|
// The crew was invited but the table couldn't seat them -- the
|
|
2525
2534
|
// job drafts locally and KROW SAYS WHY (a real playtest lost a
|
|
@@ -2538,7 +2547,11 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
2538
2547
|
: ` "Couldn't raise the whole crew -- ${shared.declined} This one's quoted without them."`;
|
|
2539
2548
|
}
|
|
2540
2549
|
else if (shared) {
|
|
2541
|
-
this.pendingSharedRun = {
|
|
2550
|
+
this.pendingSharedRun = {
|
|
2551
|
+
sessionID: shared.sessionID,
|
|
2552
|
+
// Who the quote seats -- the jobs board reads this.
|
|
2553
|
+
party: shared.party?.map(p => p.actorName),
|
|
2554
|
+
};
|
|
2542
2555
|
this._pendingRunSeed = {
|
|
2543
2556
|
name: shared.pitch.name,
|
|
2544
2557
|
story: shared.pitch.story,
|
|
@@ -2568,7 +2581,7 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
2568
2581
|
? ` "${unvettedNames.join(', ')}? No vouch on the street, no seat at my table. They square their paperwork, they ride the next one."\n{yellow-fg}(Out of character: ${unvettedNames.join(', ')} needs a verified account email -- \`maka register --resend-verification\` on their machine.){/yellow-fg}`
|
|
2569
2582
|
: '';
|
|
2570
2583
|
const reusedNote = shared.reused ? ` "Same job as before, chummer -- the client's still waiting."` : '';
|
|
2571
|
-
return `Your link pings -- 1 new message: ${FIXER_NAME}.${absentNote}${unvettedNote}${reusedNote} The crew's channel is already humming.${hint(` ("call ${FIXER_NAME}" to hear the job.)`)}`;
|
|
2584
|
+
return `Your link pings -- 1 new message: ${FIXER_NAME}.${absentNote}${unvettedNote}${reusedNote} The crew's channel is already humming.${hint(` ("call ${FIXER_NAME}" to hear the job -- "jobs" shows the board.)`)}`;
|
|
2572
2585
|
}
|
|
2573
2586
|
}
|
|
2574
2587
|
// Each run invents its OWN client Johnson (canon roles: the fixer
|
|
@@ -2622,7 +2635,7 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
2622
2635
|
this._pendingRunTier = nextTier;
|
|
2623
2636
|
this._pendingRide = Game.RIDE_POOL[Math.floor(Math.random() * Game.RIDE_POOL.length)];
|
|
2624
2637
|
this.pendingRunAccepted = false;
|
|
2625
|
-
return `Your link pings -- 1 new message: ${FIXER_NAME}.${sharedDeclineNote}${hint(` ("call ${FIXER_NAME}" to hear the job.)`)}`;
|
|
2638
|
+
return `Your link pings -- 1 new message: ${FIXER_NAME}.${sharedDeclineNote}${hint(` ("call ${FIXER_NAME}" to hear the job -- "jobs" shows the board.)`)}`;
|
|
2626
2639
|
}
|
|
2627
2640
|
// Classic sessions transition immediately, hideout-first, as always.
|
|
2628
2641
|
return await this.activateRunScene(nextSeed, nextTier, { startInHideout: true });
|
|
@@ -3497,7 +3510,7 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
3497
3510
|
// resonance" -- matrix is the place, Resonance is the talent).
|
|
3498
3511
|
{ title: 'resonance', entries: [['compile', 'decompile'], ['thread'], ['register']] },
|
|
3499
3512
|
{ title: 'social', entries: [['say'], ['emote', 'me'], ['talk-to'], ['call'], ['end-call', 'end', 'hangup'], ['accept'], ['decline', 'deny', 'refuse'], ['haggle', 'negotiate'], ['persuade', 'convince'], ['ask'], ['contacts']] },
|
|
3500
|
-
{ title: 'street', entries: [['browse', 'buy'], ['sell'], ['catalog'], ['source', 'procure'], ['work', 'gig'], ['perform'], ['palm'], ['docwagon'], ['treat'], ['eat'], ['drink'], ['lifestyle'], ['pay']] },
|
|
3513
|
+
{ title: 'street', entries: [['browse', 'buy'], ['sell'], ['catalog'], ['source', 'procure'], ['work', 'gig'], ['jobs'], ['perform'], ['palm'], ['docwagon'], ['treat'], ['eat'], ['drink'], ['lifestyle'], ['pay']] },
|
|
3501
3514
|
{ title: 'barriers', entries: [['solve'], ['pick'], ['breach'], ['dispel', 'dispell'], ['bluff'], ['unlock'], ['lock']] },
|
|
3502
3515
|
{ title: 'character', entries: [['sheet', 'stats'], ['advance'], ['qualities', 'quality'], ['initiate', 'submerge'], ['install', 'chrome']] },
|
|
3503
3516
|
{ title: 'session', entries: [['help'], ['hints'], ['clear'], ['quit', 'exit']] },
|