@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.
- package/bundle/typescript/package.json +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/archetypes.d.ts +20 -1
- package/bundle/typescript/src/commands/game/sideQuest/archetypes.js +76 -11
- package/bundle/typescript/src/commands/game/sideQuest/archetypes.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/advance.d.ts +16 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/advance.js +65 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/advance.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/assense.d.ts +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/assense.js +72 -29
- package/bundle/typescript/src/commands/game/sideQuest/commands/assense.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js +21 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.d.ts +16 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js +39 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/brandish.d.ts +21 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/brandish.js +82 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/brandish.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/call.js +71 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/call.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js +21 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/drone.js +13 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/drone.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/drop.js +3 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/drop.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/equip.js +19 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/equip.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.js +9 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.d.ts +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js +33 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js +43 -20
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/haggle.d.ts +15 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/haggle.js +75 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/haggle.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/inv.js +5 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/inv.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/look.js +16 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/look.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/persuade.d.ts +18 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/persuade.js +100 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/persuade.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/pick.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js +22 -7
- package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/say.js +8 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/say.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/search.js +55 -8
- package/bundle/typescript/src/commands/game/sideQuest/commands/search.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js +11 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/sneak.d.ts +15 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/sneak.js +35 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/sneak.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/spells.js +21 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/spells.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/subdue.js +4 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/subdue.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/take.js +70 -13
- package/bundle/typescript/src/commands/game/sideQuest/commands/take.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/talk.js +8 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/talk.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/unequip.js +6 -3
- package/bundle/typescript/src/commands/game/sideQuest/commands/unequip.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/use.js +5 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/use.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/room-factory.js +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/room-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.d.ts +175 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +673 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.d.ts +64 -9
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.js +265 -434
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +69 -1
- package/bundle/typescript/src/commands/game/sideQuest/game.js +388 -67
- package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.d.ts +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +92 -3
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +66 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js +151 -15
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js +29 -4
- package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/room.d.ts +4 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/room.js +14 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/room.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.d.ts +4 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.js +35 -3
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/scenes/scene1.json +275 -105
- package/bundle/typescript/src/commands/game/sideQuest/scenes/scene2.json +662 -233
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/player-seed.d.ts +8 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/puzzle-seed.d.ts +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/room-seed.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/scene-seed.d.ts +6 -3
- package/bundle/typescript/src/commands/game/sideQuest/ui.js +19 -20
- package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.d.ts +6 -4
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js +31 -5
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.d.ts +34 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js +72 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +27 -3
- package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
- package/bundle/typescript/src/tools/ai/ai.class.d.ts +8 -1
- package/bundle/typescript/src/tools/ai/ai.class.js +8 -3
- package/bundle/typescript/src/tools/ai/ai.class.js.map +1 -1
- package/bundle/typescript/src/tools/https/https.class.d.ts +2 -2
- package/bundle/typescript/src/tools/https/https.class.js +10 -4
- package/bundle/typescript/src/tools/https/https.class.js.map +1 -1
- package/bundle/typescript/src/tools/https/https.interface.d.ts +2 -0
- 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 {
|
|
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
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
|
|
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
|
|
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,
|
|
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
|
-
//
|
|
8
|
-
//
|
|
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
|
-
|
|
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
|
-
.
|
|
16
|
-
let description =
|
|
17
|
-
if (
|
|
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
|
-
|
|
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: ${
|
|
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;
|
|
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":"AAAA,OAAO,EAAE,OAAO,EAAY,MAAM,cAAc,CAAC;
|
|
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":"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"}
|
|
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:
|
|
35
|
-
//
|
|
36
|
-
|
|
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,
|
|
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"}
|