@maka/maka-cli 5.67.0 → 5.69.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.js +6 -1
- package/bundle/typescript/src/commands/game/sideQuest/archetypes.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/abandon.d.ts +30 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/abandon.js +54 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/abandon.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/ar.js +4 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/ar.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js +5 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js +12 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/call.d.ts +28 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/call.js +105 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/call.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/climb.d.ts +48 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/climb.js +107 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/climb.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/companions.d.ts +39 -3
- package/bundle/typescript/src/commands/game/sideQuest/commands/companions.js +89 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/companions.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/compile.d.ts +37 -17
- package/bundle/typescript/src/commands/game/sideQuest/commands/compile.js +53 -115
- package/bundle/typescript/src/commands/game/sideQuest/commands/compile.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/decompile.d.ts +55 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/decompile.js +203 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/decompile.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.d.ts +23 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js +44 -9
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.d.ts +24 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js +70 -12
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/lock.js +17 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/lock.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/look.js +12 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/look.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/map.js +12 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/map.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/mark.js +8 -6
- package/bundle/typescript/src/commands/game/sideQuest/commands/mark.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/move.d.ts +11 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/move.js +107 -14
- package/bundle/typescript/src/commands/game/sideQuest/commands/move.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/order.js +69 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/order.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/overwatch.js +5 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/overwatch.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/register.d.ts +15 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/register.js +32 -6
- package/bundle/typescript/src/commands/game/sideQuest/commands/register.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/search.js +33 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/search.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/sprites.d.ts +35 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/sprites.js +108 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/sprites.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/standby.d.ts +40 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/standby.js +91 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/standby.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/tap.js +10 -11
- package/bundle/typescript/src/commands/game/sideQuest/commands/tap.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/thread.d.ts +27 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/thread.js +7 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/thread.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/unlock.js +4 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/unlock.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/unravel.d.ts +57 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/unravel.js +162 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/unravel.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/use.js +12 -5
- package/bundle/typescript/src/commands/game/sideQuest/commands/use.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/engine-version.d.ts +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/engine-version.js +17 -1
- package/bundle/typescript/src/commands/game/sideQuest/engine-version.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/repro-scene.js +41 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/repro-scene.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/room-factory.js +4 -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 +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +91 -6
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js +6 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +135 -11
- package/bundle/typescript/src/commands/game/sideQuest/game.js +361 -30
- package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/headless-harness.d.ts +24 -12
- package/bundle/typescript/src/commands/game/sideQuest/headless-harness.js +53 -13
- package/bundle/typescript/src/commands/game/sideQuest/headless-harness.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/item.d.ts +25 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/item.js +31 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/item.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.d.ts +98 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +98 -4
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +95 -4
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js +179 -20
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/room.d.ts +90 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/room.js +114 -5
- package/bundle/typescript/src/commands/game/sideQuest/models/room.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/resonance-actions.d.ts +108 -0
- package/bundle/typescript/src/commands/game/sideQuest/resonance-actions.js +186 -0
- package/bundle/typescript/src/commands/game/sideQuest/resonance-actions.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/scenes/scene1.json +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/scenes/scene2.json +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/sprite-powers.d.ts +88 -0
- package/bundle/typescript/src/commands/game/sideQuest/sprite-powers.js +137 -0
- package/bundle/typescript/src/commands/game/sideQuest/sprite-powers.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/repro.d.ts +42 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/save-file.d.ts +32 -1
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/player-seed.d.ts +12 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/room-seed.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/ui.js +3 -0
- package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js +5 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.d.ts +41 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.js +52 -4
- package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-view.d.ts +14 -2
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-view.js +78 -7
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-view.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/outdoors.d.ts +7 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/outdoors.js +24 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/outdoors.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js +14 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/room-grid.d.ts +46 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/room-grid.js +90 -5
- package/bundle/typescript/src/commands/game/sideQuest/utilities/room-grid.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.d.ts +70 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js +168 -22
- package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +83 -0
- package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
- package/package.json +1 -1
|
@@ -8,8 +8,21 @@ import { hint } from '../utilities/hints.js';
|
|
|
8
8
|
* REGISTERED: it survives travel (folds into your PAN and re-shells at
|
|
9
9
|
* the curb) and rides your save file across sessions. Fading is 2x the
|
|
10
10
|
* sprite's hits (min 2), resisted with Resonance + Willpower --
|
|
11
|
-
* PHYSICAL past your Resonance, the usual overreach law.
|
|
12
|
-
*
|
|
11
|
+
* PHYSICAL past your Resonance, the usual overreach law.
|
|
12
|
+
*
|
|
13
|
+
* WHAT REGISTERING IS FOR (item Av93mThv54YRH26gj, 2026-08-28). p.254
|
|
14
|
+
* caps you at one COMPILED sprite; p.254-256 then says the registered
|
|
15
|
+
* one "no longer counts toward your limit of one compiled sprite at a
|
|
16
|
+
* time". Registering is precisely the move that FREES THE SLOT, and
|
|
17
|
+
* until now it did not: compile.ts counted every sprite on the roster,
|
|
18
|
+
* so the reward for making a companion permanent was that the next
|
|
19
|
+
* compile destroyed it. The `registered` flag set below is what that
|
|
20
|
+
* check reads.
|
|
21
|
+
*
|
|
22
|
+
* The ceiling on registered sprites is LOGIC (p.254-256: "You can
|
|
23
|
+
* register a number of sprites equal to or less than your Logic
|
|
24
|
+
* attribute") -- not Resonance, which is the plausible-looking number a
|
|
25
|
+
* reader would assume and which would be wrong.
|
|
13
26
|
*/
|
|
14
27
|
export class RegisterCommand extends Command {
|
|
15
28
|
static verb = 'register';
|
|
@@ -20,16 +33,29 @@ export class RegisterCommand extends Command {
|
|
|
20
33
|
if (!actor.isTechnomancer()) {
|
|
21
34
|
return `The Resonance doesn't know your voice. Registering is technomancer work.`;
|
|
22
35
|
}
|
|
23
|
-
|
|
36
|
+
// The COMPILED sprite is the one you can register -- prefer it over
|
|
37
|
+
// any registered sprite already standing, or holding two would make
|
|
38
|
+
// "register" report the wrong one as "already registered" and there
|
|
39
|
+
// would be no way to say which you meant.
|
|
40
|
+
const sprites = game?.companions.filter(c => c.kind === 'sprite') ?? [];
|
|
41
|
+
const entry = sprites.find(c => !c.registered);
|
|
24
42
|
if (!entry) {
|
|
43
|
+
if (sprites.length > 0) {
|
|
44
|
+
return `${sprites.length === 1 ? `${sprites[0].npc.name} is` : `They are all`} already registered -- nothing here is waiting to be bound.${hint(` ("compile" a new one to register it too.)`)}`;
|
|
45
|
+
}
|
|
25
46
|
return `No sprite rides with you -- "compile" one first.`;
|
|
26
47
|
}
|
|
27
|
-
if (entry.registered) {
|
|
28
|
-
return `${entry.npc.name} is already registered -- it isn't going anywhere.${hint(` ("compile" decompiles it when you're done.)`)}`;
|
|
29
|
-
}
|
|
30
48
|
if (actor.inExchange) {
|
|
31
49
|
return `Registering takes more focus than the fight will give you.`;
|
|
32
50
|
}
|
|
51
|
+
// THE LOGIC CEILING (p.254-256): "You can register a number of
|
|
52
|
+
// sprites equal to or less than your Logic attribute." Counts the
|
|
53
|
+
// ones waiting in the Resonance as well as the ones standing here --
|
|
54
|
+
// a registered sprite is registered whether or not it is manifest.
|
|
55
|
+
const alreadyRegistered = (game?.registeredSpriteCount() ?? 0);
|
|
56
|
+
if (alreadyRegistered >= actor.logic) {
|
|
57
|
+
return `Your Logic (${actor.logic}) holds ${actor.logic} registration${actor.logic === 1 ? '' : 's'}, and ${alreadyRegistered === 1 ? 'one is' : `all ${alreadyRegistered} are`} spoken for. Let one go before you bind another.`;
|
|
58
|
+
}
|
|
33
59
|
const level = entry.force;
|
|
34
60
|
// REGISTERING, not Compiling (playtest 2026-08-27, confirmed against
|
|
35
61
|
// the books: "Test: Registering + Resonance [Level] v. Sprite Level
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAY,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE7C
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/register.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { Command } from './command.js';
|
|
|
2
2
|
import { hint } from '../utilities/hints.js';
|
|
3
3
|
import { planeTintItemName, emphasizeFind, canReachHost, objectiveMark } from '../utilities/planes.js';
|
|
4
4
|
import { rollPool, formatRoll } from '../utilities/dice.js';
|
|
5
|
-
import { canReach, exitSpot, spotsActive, revealWithPerception, theSpot } from '../utilities/spots.js';
|
|
5
|
+
import { canReach, exitSpot, spotsActive, revealWithPerception, theSpot, spotOf, pathBetweenSpots, blockingRegion, terrainRefusal, } from '../utilities/spots.js';
|
|
6
6
|
import { placeName } from '../utilities/log-style.js';
|
|
7
7
|
/**
|
|
8
8
|
* Barrier rendering (2026-08-24 playtest: "I don't see THE THING I'm
|
|
@@ -37,10 +37,41 @@ function describeBarriers(room, actor) {
|
|
|
37
37
|
const at = anchor ? `, at ${theSpot(anchor, placeName)}` : '';
|
|
38
38
|
const header = `{yellow-fg}BARRIER: ${device.name}{/yellow-fg}${sealing}${at}`;
|
|
39
39
|
if (anchor && !canReach(actor, anchor)) {
|
|
40
|
+
// ADVERTISE A WALK YOU CAN ACTUALLY TAKE (2D6uZWqiWn9Mrhunc --
|
|
41
|
+
// "cannot move to steel door, there is a wall around it").
|
|
42
|
+
//
|
|
43
|
+
// This line asked canReach, which is spot EQUALITY, while the
|
|
44
|
+
// walk it advertises is gated by pathBetweenSpots, which is a
|
|
45
|
+
// ROUTE. Two notions of "can I get there", computed by different
|
|
46
|
+
// code, with the advice using the weaker one -- so a barrier
|
|
47
|
+
// whose anchor sits behind blocking terrain printed "move to
|
|
48
|
+
// <it>", and `move` then answered "The <wall> seals the way to
|
|
49
|
+
// the <it> -- "hack" to clear it."
|
|
50
|
+
//
|
|
51
|
+
// The barrier's own listing told you to walk to it, and the
|
|
52
|
+
// barrier was what sealed the walk. Asking the same question the
|
|
53
|
+
// move asks ends the loop: when the route is sealed, name what
|
|
54
|
+
// seals it and the verb that clears it, in the voice the move
|
|
55
|
+
// already uses (utilities/spots.ts terrainRefusal), rather than
|
|
56
|
+
// sending the player at a wall.
|
|
57
|
+
// The pathfind comes FIRST and is not optional: blockingRegionFor
|
|
58
|
+
// answers "would clearing this region open a path", never "is the
|
|
59
|
+
// way shut", so it names a region even when the route is already
|
|
60
|
+
// open. Every other call site (move.ts, ensureAtSpot) gates it
|
|
61
|
+
// behind a failed pathBetweenSpots for that reason, and the first
|
|
62
|
+
// cut of this fix did not -- which would have reported a seal on
|
|
63
|
+
// a room you could walk straight across.
|
|
64
|
+
const mine = spotOf(actor);
|
|
65
|
+
const sealed = mine !== undefined && !pathBetweenSpots(room, mine, anchor)
|
|
66
|
+
? blockingRegion(room, mine, anchor)
|
|
67
|
+
: undefined;
|
|
68
|
+
const advice = sealed
|
|
69
|
+
? terrainRefusal(sealed.region, anchor, sealed.device)
|
|
70
|
+
: `Too far to work from here -- "move to ${anchor}" for a proper look.`;
|
|
40
71
|
out += `
|
|
41
72
|
|
|
42
73
|
${header}
|
|
43
|
-
|
|
74
|
+
${advice}`;
|
|
44
75
|
continue;
|
|
45
76
|
}
|
|
46
77
|
out += `
|
|
@@ -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,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvG,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Command, ICommand } from './command.js';
|
|
2
|
+
/**
|
|
3
|
+
* "sprites" -- the sprite database (SR5e p.256-259), the technomancer's
|
|
4
|
+
* answer to the spellbook.
|
|
5
|
+
*
|
|
6
|
+
* Backlog item Sz7EmXnyRYK4RYqxt: "sprite actions should be listed some
|
|
7
|
+
* how ... sprites have abilities unique to them that not even
|
|
8
|
+
* technomancers have." The gap was real and specific: `compile` names
|
|
9
|
+
* five types and gives each a one-line blurb, which tells you a machine
|
|
10
|
+
* sprite is "the device whisperer" but not that it can seize a maglock,
|
|
11
|
+
* steady a failing deck, or read a drone's guts for a repair bonus. So
|
|
12
|
+
* the choice of which sprite to compile -- the one real decision in the
|
|
13
|
+
* whole subsystem -- was being made blind.
|
|
14
|
+
*
|
|
15
|
+
* Built to the shape `spells` and `catalog` already established rather
|
|
16
|
+
* than a new one: a reference panel, always available, archetype-aware,
|
|
17
|
+
* citing the page each figure comes from. A technomancer reads
|
|
18
|
+
* "sprites" the way a mage reads "spells".
|
|
19
|
+
*
|
|
20
|
+
* THE PANEL IS HONEST ABOUT WHAT IS NOT WIRED UP. None of the nine
|
|
21
|
+
* powers is a die roll in this engine yet, and the footer says so in
|
|
22
|
+
* plain words. Listing an ability the game cannot perform, while
|
|
23
|
+
* letting it read like a move you could make, is the same defect as a
|
|
24
|
+
* refusal naming a route that does not exist -- `bluff` advertised
|
|
25
|
+
* "solve" after the Puzzle mechanic was deleted, and dispel.ts still
|
|
26
|
+
* describes a Resonance hole it had no verb for. A catalogue that
|
|
27
|
+
* quietly implies mechanics would have been a third instance, shipped
|
|
28
|
+
* deliberately. Reference that says it is reference is worth having;
|
|
29
|
+
* reference wearing a verb's clothes is not.
|
|
30
|
+
*/
|
|
31
|
+
export declare class SpritesCommand extends Command implements ICommand {
|
|
32
|
+
protected static verb: string;
|
|
33
|
+
protected static description: string;
|
|
34
|
+
execute(args?: string[]): Promise<string>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Command } from './command.js';
|
|
2
|
+
import { hint } from '../utilities/hints.js';
|
|
3
|
+
import { SPRITE_TYPES } from './compile.js';
|
|
4
|
+
import { SPRITE_POWER_SETS, SPRITE_POWER_TASK_RULE, powersForSprite, skillsForSprite, } from '../sprite-powers.js';
|
|
5
|
+
/**
|
|
6
|
+
* "sprites" -- the sprite database (SR5e p.256-259), the technomancer's
|
|
7
|
+
* answer to the spellbook.
|
|
8
|
+
*
|
|
9
|
+
* Backlog item Sz7EmXnyRYK4RYqxt: "sprite actions should be listed some
|
|
10
|
+
* how ... sprites have abilities unique to them that not even
|
|
11
|
+
* technomancers have." The gap was real and specific: `compile` names
|
|
12
|
+
* five types and gives each a one-line blurb, which tells you a machine
|
|
13
|
+
* sprite is "the device whisperer" but not that it can seize a maglock,
|
|
14
|
+
* steady a failing deck, or read a drone's guts for a repair bonus. So
|
|
15
|
+
* the choice of which sprite to compile -- the one real decision in the
|
|
16
|
+
* whole subsystem -- was being made blind.
|
|
17
|
+
*
|
|
18
|
+
* Built to the shape `spells` and `catalog` already established rather
|
|
19
|
+
* than a new one: a reference panel, always available, archetype-aware,
|
|
20
|
+
* citing the page each figure comes from. A technomancer reads
|
|
21
|
+
* "sprites" the way a mage reads "spells".
|
|
22
|
+
*
|
|
23
|
+
* THE PANEL IS HONEST ABOUT WHAT IS NOT WIRED UP. None of the nine
|
|
24
|
+
* powers is a die roll in this engine yet, and the footer says so in
|
|
25
|
+
* plain words. Listing an ability the game cannot perform, while
|
|
26
|
+
* letting it read like a move you could make, is the same defect as a
|
|
27
|
+
* refusal naming a route that does not exist -- `bluff` advertised
|
|
28
|
+
* "solve" after the Puzzle mechanic was deleted, and dispel.ts still
|
|
29
|
+
* describes a Resonance hole it had no verb for. A catalogue that
|
|
30
|
+
* quietly implies mechanics would have been a third instance, shipped
|
|
31
|
+
* deliberately. Reference that says it is reference is worth having;
|
|
32
|
+
* reference wearing a verb's clothes is not.
|
|
33
|
+
*/
|
|
34
|
+
export class SpritesCommand extends Command {
|
|
35
|
+
static verb = 'sprites';
|
|
36
|
+
static description = 'The sprite database (SR5e p.256-259): the five sprite types, the powers unique to each, and the skills they roll. "sprites <type>" for one in full. Reference for choosing what to "compile" -- the powers themselves are not yet playable moves.';
|
|
37
|
+
async execute(args = []) {
|
|
38
|
+
const actor = this.actor;
|
|
39
|
+
const query = args.join(' ').trim().toLowerCase();
|
|
40
|
+
// The mundane's honest answer, in the shape spells.ts gives one.
|
|
41
|
+
// Deliberately NOT a refusal: the database is public knowledge and
|
|
42
|
+
// reading it costs nothing, so a non-technomancer gets the list too
|
|
43
|
+
// -- with the reason it will never be theirs said once, up front.
|
|
44
|
+
// (A decker in particular is one archetype away and will ask.)
|
|
45
|
+
const emerged = actor?.isTechnomancer?.() ?? false;
|
|
46
|
+
const lines = [];
|
|
47
|
+
if (!emerged) {
|
|
48
|
+
lines.push(`Sprites answer to the Resonance, and the Resonance doesn't know your name -- this is reference, not a roster. Only a TECHNOMANCER compiles them.`);
|
|
49
|
+
lines.push('');
|
|
50
|
+
}
|
|
51
|
+
// Which one currently rides with you, so the panel says "yours"
|
|
52
|
+
// rather than making you hold the roster in your head. Read through
|
|
53
|
+
// the companion list rather than a sprite-specific store -- the
|
|
54
|
+
// lifecycle surface is being reworked and this only needs the type.
|
|
55
|
+
const mine = this.game?.companions?.find(c => c.kind === 'sprite');
|
|
56
|
+
const mineType = mine?.spriteType;
|
|
57
|
+
const wanted = query
|
|
58
|
+
? SPRITE_POWER_SETS.filter(s => s.spriteKey.startsWith(query) || SPRITE_TYPES[s.spriteKey]?.name.toLowerCase().startsWith(query))
|
|
59
|
+
: SPRITE_POWER_SETS;
|
|
60
|
+
if (query && wanted.length === 0) {
|
|
61
|
+
const names = SPRITE_POWER_SETS.map(s => SPRITE_TYPES[s.spriteKey]?.name ?? s.spriteKey).join(', ');
|
|
62
|
+
return `No sprite by that name in the database. The five: ${names}.`;
|
|
63
|
+
}
|
|
64
|
+
// SECTIONS-THEN-NARROW, the shape `catalog` already uses, and the
|
|
65
|
+
// first draft did not: rendering all nine powers in full for all
|
|
66
|
+
// five types put a forty-line wall in a side panel. The decision a
|
|
67
|
+
// player is actually making here is "which one do I compile", and
|
|
68
|
+
// that is answered by the power NAMES against the type -- so the
|
|
69
|
+
// roster stays scannable and the long read is one word away.
|
|
70
|
+
const detailed = wanted.length === 1;
|
|
71
|
+
for (const set of wanted) {
|
|
72
|
+
const type = SPRITE_TYPES[set.spriteKey];
|
|
73
|
+
const name = type?.name ?? set.spriteKey;
|
|
74
|
+
const isMine = mineType === set.spriteKey;
|
|
75
|
+
const powers = powersForSprite(set.spriteKey);
|
|
76
|
+
lines.push(`${name.toUpperCase()} SPRITE${isMine ? ' {cyan-fg}(yours){/cyan-fg}' : ''}${type ? ` -- ${type.blurb}` : ''}`);
|
|
77
|
+
lines.push(` Skills: ${skillsForSprite(set.spriteKey).join(', ')}${hint(` (${set.page})`)}`);
|
|
78
|
+
if (!detailed) {
|
|
79
|
+
// The names alone, which is the comparison view.
|
|
80
|
+
lines.push(` Powers: ${powers.map(p => p.name).join(', ')}`);
|
|
81
|
+
lines.push('');
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
for (const p of powers) {
|
|
85
|
+
lines.push(` ${p.name}${hint(` (${p.page})`)}`);
|
|
86
|
+
lines.push(` ${p.effect}`);
|
|
87
|
+
// The Test line is the sharpest thing on the panel for a player
|
|
88
|
+
// deciding between two types -- it says what the power rolls
|
|
89
|
+
// AGAINST, which is what makes a fault sprite an attack and a
|
|
90
|
+
// data sprite a librarian.
|
|
91
|
+
if (p.test)
|
|
92
|
+
lines.push(` Test: ${p.test}`);
|
|
93
|
+
}
|
|
94
|
+
lines.push('');
|
|
95
|
+
}
|
|
96
|
+
const footer = [
|
|
97
|
+
SPRITE_POWER_TASK_RULE,
|
|
98
|
+
// Said plainly, not buried: see the class comment.
|
|
99
|
+
`These powers are CANON REFERENCE -- none is a move you can type yet. What a compiled sprite actually does today is fight ice at your side and take "order".`,
|
|
100
|
+
detailed ? `"sprites" lists all five.` : `"sprites <type>" for what each power actually does. "compile <type> <level>" calls one up.`,
|
|
101
|
+
].join(' ');
|
|
102
|
+
const tail = hint(footer);
|
|
103
|
+
if (tail)
|
|
104
|
+
lines.push(tail);
|
|
105
|
+
return lines.join('\n').trimEnd();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=sprites.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sprites.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/sprites.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Command, ICommand } from './command.js';
|
|
2
|
+
/**
|
|
3
|
+
* STANDBY (SR5 p.256, a REGISTERED SPRITE TASK) -- "standby [<name>]".
|
|
4
|
+
*
|
|
5
|
+
* Canon, verbatim: standby "tells the sprite to return to the Resonance
|
|
6
|
+
* but come when you call it. This keeps the sprite from giving away
|
|
7
|
+
* your presence or getting in harm's way." It costs ONE task.
|
|
8
|
+
*
|
|
9
|
+
* THE GAP THIS FILLS WAS MADE VISIBLE BY ITS OWN FIX. Call/Dismiss
|
|
10
|
+
* (p.250) landed on `recall`, and dismissing "releas[es] it from any
|
|
11
|
+
* tasks it still owes you" -- so the warning on that command told
|
|
12
|
+
* players, correctly, that parking a sprite cost every favour it had
|
|
13
|
+
* left. That is exactly the trade p.256 exists to avoid: one task to
|
|
14
|
+
* go quiet and keep the rest. A player who wanted their sprite out of
|
|
15
|
+
* a room for one scene had only the expensive door.
|
|
16
|
+
*
|
|
17
|
+
* A TASK, NOT AN ACTION, which is why it is not in the p.250 table
|
|
18
|
+
* (resonance-actions.ts). Those are seven Resonance ACTIONS; this is
|
|
19
|
+
* one of the eight things you can spend a REGISTERED sprite's tasks on
|
|
20
|
+
* (p.256, alongside Aid Study, Assist Threading, Loaned Task, Remote
|
|
21
|
+
* Task, Re-register, and Sustain Complex Form). Adding it to that table
|
|
22
|
+
* would make the table wrong about what it is.
|
|
23
|
+
*
|
|
24
|
+
* ITS OWN VERB rather than a mode of `recall`. `recall` is already
|
|
25
|
+
* carrying two canon directions on one word, and its bare form is
|
|
26
|
+
* deliberately the safe one; hanging a third meaning off it would make
|
|
27
|
+
* the safe default harder to see, not easier. The verb also has to be
|
|
28
|
+
* discoverable on its own, because the whole point is that a player
|
|
29
|
+
* reaching for "get out of sight" should not land on the destructive
|
|
30
|
+
* option first.
|
|
31
|
+
*
|
|
32
|
+
* REGISTERED ONLY. A compiled sprite has no Resonance to wait in --
|
|
33
|
+
* that is what registering buys (p.254-256) -- so sending one away is
|
|
34
|
+
* simply unmaking it, which is decompile's job and says so.
|
|
35
|
+
*/
|
|
36
|
+
export declare class StandbyCommand extends Command implements ICommand {
|
|
37
|
+
protected static verb: string;
|
|
38
|
+
protected static description: string;
|
|
39
|
+
execute(args?: string[]): Promise<string>;
|
|
40
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Command } from './command.js';
|
|
2
|
+
import { hint } from '../utilities/hints.js';
|
|
3
|
+
import { fuzzyPickName } from '../utilities/fuzzy-match.js';
|
|
4
|
+
/**
|
|
5
|
+
* STANDBY (SR5 p.256, a REGISTERED SPRITE TASK) -- "standby [<name>]".
|
|
6
|
+
*
|
|
7
|
+
* Canon, verbatim: standby "tells the sprite to return to the Resonance
|
|
8
|
+
* but come when you call it. This keeps the sprite from giving away
|
|
9
|
+
* your presence or getting in harm's way." It costs ONE task.
|
|
10
|
+
*
|
|
11
|
+
* THE GAP THIS FILLS WAS MADE VISIBLE BY ITS OWN FIX. Call/Dismiss
|
|
12
|
+
* (p.250) landed on `recall`, and dismissing "releas[es] it from any
|
|
13
|
+
* tasks it still owes you" -- so the warning on that command told
|
|
14
|
+
* players, correctly, that parking a sprite cost every favour it had
|
|
15
|
+
* left. That is exactly the trade p.256 exists to avoid: one task to
|
|
16
|
+
* go quiet and keep the rest. A player who wanted their sprite out of
|
|
17
|
+
* a room for one scene had only the expensive door.
|
|
18
|
+
*
|
|
19
|
+
* A TASK, NOT AN ACTION, which is why it is not in the p.250 table
|
|
20
|
+
* (resonance-actions.ts). Those are seven Resonance ACTIONS; this is
|
|
21
|
+
* one of the eight things you can spend a REGISTERED sprite's tasks on
|
|
22
|
+
* (p.256, alongside Aid Study, Assist Threading, Loaned Task, Remote
|
|
23
|
+
* Task, Re-register, and Sustain Complex Form). Adding it to that table
|
|
24
|
+
* would make the table wrong about what it is.
|
|
25
|
+
*
|
|
26
|
+
* ITS OWN VERB rather than a mode of `recall`. `recall` is already
|
|
27
|
+
* carrying two canon directions on one word, and its bare form is
|
|
28
|
+
* deliberately the safe one; hanging a third meaning off it would make
|
|
29
|
+
* the safe default harder to see, not easier. The verb also has to be
|
|
30
|
+
* discoverable on its own, because the whole point is that a player
|
|
31
|
+
* reaching for "get out of sight" should not land on the destructive
|
|
32
|
+
* option first.
|
|
33
|
+
*
|
|
34
|
+
* REGISTERED ONLY. A compiled sprite has no Resonance to wait in --
|
|
35
|
+
* that is what registering buys (p.254-256) -- so sending one away is
|
|
36
|
+
* simply unmaking it, which is decompile's job and says so.
|
|
37
|
+
*/
|
|
38
|
+
export class StandbyCommand extends Command {
|
|
39
|
+
static verb = 'standby';
|
|
40
|
+
static description = 'Send a registered sprite to wait in the Resonance for ONE task, keeping the rest (SR5 p.256): it stops giving away your presence and comes when you "recall" it. Dismissing with "recall <name>" is the other door -- free, but it releases every task the sprite still owes you.';
|
|
41
|
+
async execute(args = []) {
|
|
42
|
+
const game = this.game;
|
|
43
|
+
if (!game)
|
|
44
|
+
return `Not here.`;
|
|
45
|
+
if (!this.actor.isTechnomancer()) {
|
|
46
|
+
return `Sprites answer to the Resonance, and it doesn't know your voice.`;
|
|
47
|
+
}
|
|
48
|
+
const standing = game.companions.filter(c => c.kind === 'sprite');
|
|
49
|
+
if (standing.length === 0) {
|
|
50
|
+
const waiting = game.registeredSpritesWaiting();
|
|
51
|
+
// Already parked is not a failure -- say which, so "standby"
|
|
52
|
+
// twice reads as confirmation rather than an error.
|
|
53
|
+
return waiting.length > 0
|
|
54
|
+
? `Nothing of yours is standing here to send away.${hint(` Waiting in the Resonance: ${waiting.map(s => `"${s.name}"`).join(', ')} -- "recall <name>" brings one back.`)}`
|
|
55
|
+
: `No sprite rides with you.${hint(` ("compile <type> <level>" calls one up.)`)}`;
|
|
56
|
+
}
|
|
57
|
+
const query = (args ?? []).map(w => w.toLowerCase()).filter(w => !/^(a|an|the|sprite|on)$/.test(w)).join(' ').trim();
|
|
58
|
+
let target = standing[0];
|
|
59
|
+
if (query.length > 0) {
|
|
60
|
+
const picked = fuzzyPickName(query, standing.map(c => c.npc.name));
|
|
61
|
+
if (!picked) {
|
|
62
|
+
return `Nothing of yours answers to "${query}". With you: ${standing.map(c => `"${c.npc.name}"`).join(', ')}.`;
|
|
63
|
+
}
|
|
64
|
+
target = standing.find(c => c.npc.name === picked);
|
|
65
|
+
}
|
|
66
|
+
else if (standing.length > 1) {
|
|
67
|
+
return `Which one? With you: ${standing.map(c => `"${c.npc.name}"`).join(', ')}.`;
|
|
68
|
+
}
|
|
69
|
+
const name = target.npc.name;
|
|
70
|
+
// A COMPILED sprite has nowhere to wait. Refuse rather than
|
|
71
|
+
// silently unmaking it -- the two outcomes look identical in the
|
|
72
|
+
// moment and only one of them is recoverable.
|
|
73
|
+
if (!target.registered) {
|
|
74
|
+
return `${name} is compiled, not registered -- it has no Resonance to wait in, and sending it away would simply unmake it.${hint(` ("register" binds it first; "compile" again decompiles it.)`)}`;
|
|
75
|
+
}
|
|
76
|
+
const owed = target.services ?? 0;
|
|
77
|
+
if (owed < 1) {
|
|
78
|
+
// Nothing to spend, and nothing to lose either. Point at the door
|
|
79
|
+
// that is now genuinely free rather than refusing flatly.
|
|
80
|
+
return `${name} owes you nothing more, so there is no task left to spend on standby.${hint(` ("recall ${name}" sends it back and costs you nothing now -- there are no tasks left to release.)`)}`;
|
|
81
|
+
}
|
|
82
|
+
if (!game.standbySpriteToResonance(target)) {
|
|
83
|
+
return `${name} cannot go to standby right now.`;
|
|
84
|
+
}
|
|
85
|
+
const left = owed - 1;
|
|
86
|
+
this.actor.performAction('sends to standby', name);
|
|
87
|
+
this.scene.updateStatus();
|
|
88
|
+
return `${name} thins to nothing and waits in the Resonance -- out of sight, out of the way, and still yours. One task spent going quiet; ${left === 0 ? 'none' : left} ${left === 1 ? 'task' : 'tasks'} still owed.${hint(` ("recall ${name}" calls it back.)`)}`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=standby.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standby.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/standby.ts"],"names":[],"mappings":"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"}
|
|
@@ -84,18 +84,17 @@ export class TapCommand extends Command {
|
|
|
84
84
|
// watching its own edges.
|
|
85
85
|
const threshold = host.hostAlert ? 2 : 1;
|
|
86
86
|
const silence = actor.matrixActionPenalty;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
87
|
+
// A DIRECT CONNECTION DOES NOT CHANGE WHICH ACTION YOU TAKE -- it
|
|
88
|
+
// changes what the target defends with (p.233). The action is still
|
|
89
|
+
// Hack on the Fly or Brute Force against the device (p.240/p.238),
|
|
90
|
+
// so it carries the same bracket, capping hits rather than adding
|
|
91
|
+
// dice. Both routes share one pool now: the old pair differed only
|
|
92
|
+
// by which half-attribute they folded in, and that is exactly the
|
|
93
|
+
// substitution being removed.
|
|
94
|
+
const limit = actor.matrixAttribute(mode === 'attack' ? 'attack' : 'sleaze');
|
|
95
|
+
const pool = Math.max(1, actor.logic + actor.skillRating('hacking') + actor.qualityBonus('hacking') + silence + actor.woundModifier - actor.sustainingPenalty);
|
|
97
96
|
actor.performAction('cables into the cameras', `${room.name} -- a hand on the housing, a filament out of their deck`);
|
|
98
|
-
const roll = rollPool(pool);
|
|
97
|
+
const roll = rollPool(pool, limit);
|
|
99
98
|
if (this.scene.isHumanControlled(actor)) {
|
|
100
99
|
this.logger.meta(`Direct connection, camera (${mode === 'attack' ? 'brute force' : 'sleaze'}): ${formatRoll(roll)} (${threshold}+ -- its OWN ratings, not the host's)`);
|
|
101
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tap.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/tap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAY,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACpG,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,OAAO,UAAW,SAAQ,OAAO;IAC3B,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC;IACpB,MAAM,CAAC,WAAW,GAAG,kbAAkb,CAAC;IAEld,KAAK,CAAC,OAAO,CAAC,OAAiB,EAAE;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,eAAe,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAE/B,yEAAyE;QACzE,MAAM,KAAK,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QACrD,MAAM,IAAI,GAAwB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,6BAA6B,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;QAE/G,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,OAAO,oCAAoC,IAAI,CAAC,8DAA8D,CAAC,EAAE,CAAC;QACpH,CAAC;QAED,mEAAmE;QACnE,kEAAkE;QAClE,+CAA+C;QAC/C,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACrD,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;QAE5B,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,8LAA8L,IAAI,CAAC,sCAAsC,CAAC,EAAE,CAAC;QACtP,CAAC;QAED,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,OAAO,wBAAwB,IAAI,CAAC,IAAI,iGAAiG,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,qBAAqB,CAAC,EAAE,CAAC;QAC9L,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,IAAI,IAAI,SAAS,EAAE,CAAC;YACtB,OAAO,oBAAoB,SAAS,iBAAiB,IAAI,CAAC,IAAI,wEAAwE,IAAI,CAAC,yBAAyB,CAAC,EAAE,CAAC;QAC1K,CAAC;QAED,oEAAoE;QACpE,oEAAoE;QACpE,iEAAiE;QACjE,+DAA+D;QAC/D,0BAA0B;QAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,KAAK,CAAC,mBAAmB,CAAC;QAC1C,
|
|
1
|
+
{"version":3,"file":"tap.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/tap.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,31 @@
|
|
|
1
1
|
import { Command, ICommand } from './command.js';
|
|
2
|
+
/**
|
|
3
|
+
* Threading (SR5e p.251, engine-adapted): the technomancer's "spells".
|
|
4
|
+
* "thread <form> <level>" shapes a COMPLEX FORM out of raw Resonance --
|
|
5
|
+
* Resonance + software [Level] does the work, FADING is the toll
|
|
6
|
+
* (form's own value off the Level, min 2, resisted with Resonance +
|
|
7
|
+
* Willpower, PHYSICAL past your Resonance -- the same overreach law as
|
|
8
|
+
* compiling). Sustained forms hold at the spell school's -2 dice each
|
|
9
|
+
* ("thread drop <form>" lets go); instant forms resolve and fade.
|
|
10
|
+
*
|
|
11
|
+
* Canon note: Resonance actions happen IN the Matrix but are NOT
|
|
12
|
+
* Matrix actions (p.250) -- no deck, no hardware, and the numbers here
|
|
13
|
+
* are the engine's own balance over the book's shapes.
|
|
14
|
+
*/
|
|
15
|
+
/** Exported for unravel.ts (Kill Complex Form, p.250): killing a form
|
|
16
|
+
* resists Fading "as if you had threaded the complex form you
|
|
17
|
+
* targeted", so it needs that form's own fvDelta -- read from here
|
|
18
|
+
* rather than copied, which would be two fading tables that agree
|
|
19
|
+
* today and drift on the first balance change. */
|
|
20
|
+
export interface IComplexForm {
|
|
21
|
+
key: string;
|
|
22
|
+
name: string;
|
|
23
|
+
blurb: string;
|
|
24
|
+
/** Fading value = level + delta (min 2). */
|
|
25
|
+
fvDelta: number;
|
|
26
|
+
kind: 'instant' | 'sustained';
|
|
27
|
+
}
|
|
28
|
+
export declare const FORMS: IComplexForm[];
|
|
2
29
|
export declare class ThreadCommand extends Command implements ICommand {
|
|
3
30
|
protected static verb: string;
|
|
4
31
|
protected static description: string;
|
|
@@ -3,7 +3,7 @@ import { rollPool, formatRoll } from '../utilities/dice.js';
|
|
|
3
3
|
import { hint } from '../utilities/hints.js';
|
|
4
4
|
import { fuzzyPickName } from '../utilities/fuzzy-match.js';
|
|
5
5
|
import { NPC } from '../models/npc.js';
|
|
6
|
-
const FORMS = [
|
|
6
|
+
export const FORMS = [
|
|
7
7
|
{ key: 'resonance-spike', name: 'Resonance Spike', blurb: 'raw Resonance as a weapon -- boxes of Matrix damage, no marks, no mercy', fvDelta: -1, kind: 'instant' },
|
|
8
8
|
{ key: 'stitches', name: 'Stitches', blurb: 'rethread a damaged sprite -- repairs its condition monitor', fvDelta: 0, kind: 'instant' },
|
|
9
9
|
{ key: 'diagnostics', name: 'Diagnostics', blurb: 'the code shows you its seams -- +2 to your Matrix pools while held', fvDelta: -1, kind: 'sustained' },
|
|
@@ -156,7 +156,12 @@ export class ThreadCommand extends Command {
|
|
|
156
156
|
}
|
|
157
157
|
case 'diagnostics':
|
|
158
158
|
case 'static-veil': {
|
|
159
|
-
|
|
159
|
+
// HITS ARE RECORDED, not just the Level. Kill Complex Form
|
|
160
|
+
// (p.250) erodes "the hits from the complex form's original
|
|
161
|
+
// threading test" -- so the number canon attacks has to survive
|
|
162
|
+
// the roll that produced it. Before this the weave remembered
|
|
163
|
+
// how ambitious it was and not how well it went.
|
|
164
|
+
actor.sustainedForms.push({ key: form.key, level, hits });
|
|
160
165
|
const effect = form.key === 'diagnostics' ? '+2 to your Matrix pools' : '+2 Matrix defense';
|
|
161
166
|
return [` ${form.name} settles over your persona and HOLDS -- ${effect} while you sustain it (-2 dice to everything else).${hint(` ("thread drop ${form.key}" releases.)`)}`];
|
|
162
167
|
}
|