@maka/maka-cli 5.187.0 → 5.188.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/factories/scene-factory.js +12 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-view.js +26 -6
- package/bundle/typescript/src/commands/game/sideQuest/utilities/ic-actors.js +48 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maka/maka-cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.188.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"summary": "A command line tool for scaffolding Meteor 3.x applications using either React.",
|
|
6
6
|
"description": "A command line tool for scaffolding Meteor 3.x applications using React.",
|
|
@@ -13,6 +13,7 @@ import { Logger } from '../utilities/logger.js';
|
|
|
13
13
|
import { migrateLegacySeed } from './seed-migration.js';
|
|
14
14
|
import { Device } from '../models/device.js';
|
|
15
15
|
import { fuzzyPickName } from '../utilities/fuzzy-match.js';
|
|
16
|
+
import { adoptSeededIce } from '../utilities/ic-actors.js';
|
|
16
17
|
/**
|
|
17
18
|
* How many AI enrichment calls may be in flight at once.
|
|
18
19
|
*
|
|
@@ -252,6 +253,17 @@ Key Locations: ${json.rooms.map(r => r.name).join(', ')}
|
|
|
252
253
|
// architecture nobody wrote.
|
|
253
254
|
if (isIce && npc.currentLocation?.hasNode) {
|
|
254
255
|
npc.insideHost = npc.currentLocation;
|
|
256
|
+
// ...AND THE HOST HAS TO KNOW IT IS RUNNING IT (mPCh2FJykPsyJKmcc's
|
|
257
|
+
// bench, 2026-09-14). Standing inside the node was only half the
|
|
258
|
+
// adoption: nothing registered the construct with the Host, so it
|
|
259
|
+
// was ice by every reading except the one the host itself uses.
|
|
260
|
+
// The host then launched its own twin on the first Combat Turn
|
|
261
|
+
// (p.247 forbids two of a type), the construct swung with an
|
|
262
|
+
// Attack of 0 because "IC uses the Matrix attributes of its host"
|
|
263
|
+
// is read off icHost, and the grid view listed it twice. See
|
|
264
|
+
// adoptSeededIce for the three-for-one.
|
|
265
|
+
if (npc.currentLocation.host)
|
|
266
|
+
adoptSeededIce(npc, npc.currentLocation.host);
|
|
255
267
|
}
|
|
256
268
|
npc.scene = scene;
|
|
257
269
|
builtNpcs.push(npc);
|
|
@@ -299,8 +299,23 @@ function hostInteriorIcons(scene, actor, room) {
|
|
|
299
299
|
// and that would put the wrong noun on a person.
|
|
300
300
|
// Inside a host, the roster is who is INSIDE it (matrix-roster.ts) -- a
|
|
301
301
|
// persona's body is never in this room.
|
|
302
|
+
// THE HOST'S OWN PROGRAMS ARE LISTED ONCE, BELOW, NOT TWICE, HERE AND
|
|
303
|
+
// BELOW (mPCh2FJykPsyJKmcc's bench, 2026-09-14). A running IC is an
|
|
304
|
+
// actor inside the host AND a name in room.runningIC, and both loops
|
|
305
|
+
// printed it -- in different words, with only the second offering the
|
|
306
|
+
// verbs, so one program read as two and the reader had to guess which
|
|
307
|
+
// line was real:
|
|
308
|
+
//
|
|
309
|
+
// ▲ Patrol IC #2 -- intrusion countermeasures, and you are inside its host.
|
|
310
|
+
// ▲ Patrol IC #2 -- hunting, and it has your icon. (0/10) ("attack ..." crash it)
|
|
311
|
+
//
|
|
312
|
+
// hostInteriorPanel already resolved this the right way round -- it
|
|
313
|
+
// skips `a.icHost === host` in its persona list -- so this matches it
|
|
314
|
+
// rather than inventing a third rule. Everything else inside the host
|
|
315
|
+
// still comes through here: a rival decker's persona, a companion, a
|
|
316
|
+
// construct nothing registered as the host's.
|
|
302
317
|
for (const a of (room.host ? personasInside(scene, room.host) : [])) {
|
|
303
|
-
if (a === actor)
|
|
318
|
+
if (a === actor || a.icHost === room.host)
|
|
304
319
|
continue;
|
|
305
320
|
if (a.plane === 'matrix' && sameHostSide(actor, a) && actor.canPerceive(a)) {
|
|
306
321
|
const companion = scene.ownerGame?.companions.find(c => c.npc === a);
|
|
@@ -350,11 +365,16 @@ function hostInteriorIcons(scene, actor, room) {
|
|
|
350
365
|
// game will not name, and a room that contradicts the damage log reads
|
|
351
366
|
// as broken rules rather than thin prose.
|
|
352
367
|
//
|
|
353
|
-
//
|
|
354
|
-
// in room.runningIC as names
|
|
355
|
-
//
|
|
356
|
-
//
|
|
357
|
-
//
|
|
368
|
+
// A VERB IS OFFERED NOW, where there is an actor to point it at. When
|
|
369
|
+
// this loop was written IC lived in room.runningIC as names only and
|
|
370
|
+
// nothing could target them, so it deliberately advertised nothing;
|
|
371
|
+
// ic-actors.ts made each running program an actor, and the line grew
|
|
372
|
+
// the monitor and the verbs to match. A kind with no actor behind it
|
|
373
|
+
// (a scene that cannot host actors at all) still gets named and still
|
|
374
|
+
// offers nothing, for the original reason.
|
|
375
|
+
//
|
|
376
|
+
// THIS IS THE ONE PLACE THE HOST'S OWN PROGRAMS ARE LISTED -- see the
|
|
377
|
+
// skip in the persona loop above.
|
|
358
378
|
for (const name of room.runningIC) {
|
|
359
379
|
const ice = room.host?.iceActors.get(name);
|
|
360
380
|
icons.push(`▲ ${ice?.name ?? name} -- hunting, and it has your icon.${ice ? ` (${ice.conditionSummary()}) ("thread resonance-spike ${ice.name}" / "attack ${ice.name}" crash it)` : ''}`);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NPC } from '../models/npc.js';
|
|
2
2
|
import { CommandRegistry } from '../commands/command-registry.js';
|
|
3
3
|
import { Logger } from './logger.js';
|
|
4
|
+
import { IC_TYPES } from './ic.js';
|
|
4
5
|
/**
|
|
5
6
|
* IC AS ICONS (increment 5 of the Matrix position model, 2026-09-02).
|
|
6
7
|
* SR5 p.247: "Each IC program has a persona with its own Condition
|
|
@@ -95,4 +96,51 @@ export function crashedIC(host) {
|
|
|
95
96
|
}
|
|
96
97
|
return out;
|
|
97
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* ADOPT A SEEDED CONSTRUCT AS ONE OF ITS HOST'S PROGRAMS
|
|
101
|
+
* (mPCh2FJykPsyJKmcc's bench, 2026-09-14).
|
|
102
|
+
*
|
|
103
|
+
* scene-factory already settles what a matrix-plane NPC IS -- "a
|
|
104
|
+
* matrix-plane NPC in this engine IS intrusion countermeasures" -- and
|
|
105
|
+
* already stands it inside the node it guards. What it never did was
|
|
106
|
+
* tell the HOST. So a seeded construct was ice by every reading except
|
|
107
|
+
* the one the host itself uses, and three things went wrong at once,
|
|
108
|
+
* all of them visible in one bench transcript:
|
|
109
|
+
*
|
|
110
|
+
* 1. THE HOST LAUNCHED ITS TWIN. hostLaunchStep picks the first
|
|
111
|
+
* IC_TYPE not in `runningIC`, and a seeded "Patrol IC" was not in
|
|
112
|
+
* it -- so the host launched a second Patrol on the first Combat
|
|
113
|
+
* Turn and the player fought "Patrol IC" and "Patrol IC #2" at
|
|
114
|
+
* once. Straight against p.247: a host "can't launch more than one
|
|
115
|
+
* of each type of IC program at once."
|
|
116
|
+
* 2. IT ATTACKED WITH NO LIMIT. "IC uses the Matrix attributes of its
|
|
117
|
+
* host" (p.247) is read off `icHost` (Player.baseMatrixAttribute).
|
|
118
|
+
* Unset, a construct's Attack was 0, so every swing it took
|
|
119
|
+
* printed dice.ts's caller-bug diagnostic to the player:
|
|
120
|
+
* `[LIMIT IGNORED -- a caller computed one that is not a limit]`.
|
|
121
|
+
* 3. IT WAS LISTED TWICE, once as an icon inside the host and again
|
|
122
|
+
* off `runningIC` (grid-view.ts), with different words each time.
|
|
123
|
+
*
|
|
124
|
+
* One registration, three symptoms -- which is the argument for fixing
|
|
125
|
+
* it here at the seam rather than three times downstream.
|
|
126
|
+
*
|
|
127
|
+
* THE KIND IS THE CANON NAME WHEN THE SEED USED ONE. A construct called
|
|
128
|
+
* "Patrol IC" IS the host's Patrol, and registering it under its own
|
|
129
|
+
* name would leave the launch step free to add the real one beside it --
|
|
130
|
+
* the bug. A construct with a name of its own ("Sentinel", "the
|
|
131
|
+
* Gatekeeper") registers under that name: it counts against the host's
|
|
132
|
+
* Rating cap because it is a program the host is running, and it blocks
|
|
133
|
+
* no canon type, because it is not one.
|
|
134
|
+
*/
|
|
135
|
+
export function adoptSeededIce(npc, host) {
|
|
136
|
+
const canon = IC_TYPES.find(t => t.name.toLowerCase() === npc.name.trim().toLowerCase());
|
|
137
|
+
const kind = canon?.name ?? npc.name;
|
|
138
|
+
npc.icHost = host;
|
|
139
|
+
npc.icKind = kind;
|
|
140
|
+
npc.matrixPosition = { kind: 'host', host };
|
|
141
|
+
if (!host.iceActors.has(kind))
|
|
142
|
+
host.iceActors.set(kind, npc);
|
|
143
|
+
if (!host.runningIC.includes(kind))
|
|
144
|
+
host.runningIC.push(kind);
|
|
145
|
+
}
|
|
98
146
|
//# sourceMappingURL=ic-actors.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maka/maka-cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.188.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"summary": "A command line tool for scaffolding Meteor 3.x applications using either React.",
|
|
6
6
|
"description": "A command line tool for scaffolding Meteor 3.x applications using React.",
|