@maka/maka-cli 5.391.0 → 5.392.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/bundle/typescript/package.json +1 -1
  2. package/bundle/typescript/src/commands/game/sideQuest/commands/assense.js +1 -1
  3. package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js +60 -1
  4. package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js +1 -1
  5. package/bundle/typescript/src/commands/game/sideQuest/commands/breach.js +5 -2
  6. package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js +8 -2
  7. package/bundle/typescript/src/commands/game/sideQuest/commands/call.js +4 -2
  8. package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js +16 -150
  9. package/bundle/typescript/src/commands/game/sideQuest/commands/crack.js +76 -0
  10. package/bundle/typescript/src/commands/game/sideQuest/commands/disable.js +42 -6
  11. package/bundle/typescript/src/commands/game/sideQuest/commands/disarm.js +64 -0
  12. package/bundle/typescript/src/commands/game/sideQuest/commands/dispel.js +23 -46
  13. package/bundle/typescript/src/commands/game/sideQuest/commands/download.js +23 -6
  14. package/bundle/typescript/src/commands/game/sideQuest/commands/edit-file.js +15 -3
  15. package/bundle/typescript/src/commands/game/sideQuest/commands/go.js +55 -17
  16. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js +15 -1
  17. package/bundle/typescript/src/commands/game/sideQuest/commands/leap.js +23 -0
  18. package/bundle/typescript/src/commands/game/sideQuest/commands/look.js +40 -0
  19. package/bundle/typescript/src/commands/game/sideQuest/commands/move.js +16 -15
  20. package/bundle/typescript/src/commands/game/sideQuest/commands/tap.js +13 -3
  21. package/bundle/typescript/src/commands/game/sideQuest/engine-version.js +13 -1
  22. package/bundle/typescript/src/commands/game/sideQuest/factories/authored-run.js +632 -0
  23. package/bundle/typescript/src/commands/game/sideQuest/factories/catalog-item-seed.js +78 -0
  24. package/bundle/typescript/src/commands/game/sideQuest/factories/job-order.js +7 -44
  25. package/bundle/typescript/src/commands/game/sideQuest/factories/repro-scene.js +8 -10
  26. package/bundle/typescript/src/commands/game/sideQuest/factories/room-factory.js +12 -0
  27. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +30 -52
  28. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js +112 -0
  29. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.js +123 -3
  30. package/bundle/typescript/src/commands/game/sideQuest/factories/seed-migration.js +52 -4
  31. package/bundle/typescript/src/commands/game/sideQuest/game.js +17 -4
  32. package/bundle/typescript/src/commands/game/sideQuest/models/camera.js +8 -0
  33. package/bundle/typescript/src/commands/game/sideQuest/models/device.js +14 -21
  34. package/bundle/typescript/src/commands/game/sideQuest/models/host.js +8 -0
  35. package/bundle/typescript/src/commands/game/sideQuest/models/item.js +14 -0
  36. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +62 -9
  37. package/bundle/typescript/src/commands/game/sideQuest/models/player.js +11 -0
  38. package/bundle/typescript/src/commands/game/sideQuest/models/room.js +141 -3
  39. package/bundle/typescript/src/commands/game/sideQuest/models/scene.js +3 -0
  40. package/bundle/typescript/src/commands/game/sideQuest/utilities/affordances.js +18 -11
  41. package/bundle/typescript/src/commands/game/sideQuest/utilities/alarmed-staff.js +3 -0
  42. package/bundle/typescript/src/commands/game/sideQuest/utilities/ar.js +4 -2
  43. package/bundle/typescript/src/commands/game/sideQuest/utilities/astral-move.js +7 -2
  44. package/bundle/typescript/src/commands/game/sideQuest/utilities/barrier-combat.js +1 -1
  45. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-turn.js +9 -0
  46. package/bundle/typescript/src/commands/game/sideQuest/utilities/district-plane.js +109 -27
  47. package/bundle/typescript/src/commands/game/sideQuest/utilities/door-watch.js +70 -0
  48. package/bundle/typescript/src/commands/game/sideQuest/utilities/falling.js +27 -0
  49. package/bundle/typescript/src/commands/game/sideQuest/utilities/file-guard.js +120 -0
  50. package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-names.js +10 -1
  51. package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-view.js +12 -3
  52. package/bundle/typescript/src/commands/game/sideQuest/utilities/host-combat.js +23 -5
  53. package/bundle/typescript/src/commands/game/sideQuest/utilities/ic.js +29 -2
  54. package/bundle/typescript/src/commands/game/sideQuest/utilities/ledge-jump.js +86 -0
  55. package/bundle/typescript/src/commands/game/sideQuest/utilities/map-view.js +2 -1
  56. package/bundle/typescript/src/commands/game/sideQuest/utilities/npc-combat-brain.js +29 -0
  57. package/bundle/typescript/src/commands/game/sideQuest/utilities/owner-guard.js +77 -0
  58. package/bundle/typescript/src/commands/game/sideQuest/utilities/path-run.js +4 -2
  59. package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js +3 -1
  60. package/bundle/typescript/src/commands/game/sideQuest/utilities/room-grid.js +49 -3
  61. package/bundle/typescript/src/commands/game/sideQuest/utilities/spider.js +50 -0
  62. package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js +14 -4
  63. package/bundle/typescript/src/commands/game/sideQuest/utilities/surveillance.js +193 -8
  64. package/bundle/typescript/src/commands/game/sideQuest/utilities/use-target.js +1 -1
  65. package/bundle/typescript/src/commands/game/sideQuest/utilities/verb-index.js +2 -2
  66. package/bundle/typescript/src/commands/game/sideQuest/utilities/wards.js +116 -0
  67. package/package.json +1 -1
@@ -17,7 +17,8 @@ import { spotsActive, resolveSpot, spotOf, describeSpotRoster, OPEN_FLOOR, pathB
17
17
  // you from where you GOT to, which is a distance in metres, not a whole
18
18
  // storey. The storey-based wrapper still exists for callers that really
19
19
  // do fall a level.
20
- import { fallDamageDVMeters, climbHitsFor, climbMetersFrom, climbSurfaceModifier, METERS_PER_CELL, METERS_PER_LEVEL, key, distanceMeters } from '../utilities/room-grid.js';
20
+ import { resolveFall } from '../utilities/falling.js';
21
+ import { climbHitsFor, climbMetersFrom, climbSurfaceModifier, METERS_PER_CELL, METERS_PER_LEVEL, key, distanceMeters } from '../utilities/room-grid.js';
21
22
  import { rollPool, formatRoll } from '../utilities/dice.js';
22
23
  import { trailMaster } from '../utilities/companion-heel.js';
23
24
  import { spendMovementMeters, paceNote, walkOut } from '../utilities/movement-cost.js';
@@ -220,19 +221,18 @@ export class MoveCommand extends Command {
220
221
  }
221
222
  // "On an unsuccessful test you don't slow down" (p.134): the
222
223
  // rope runs and you arrive hard rather than not at all.
223
- const dv = fallDamageDVMeters(meters);
224
224
  let descentNote = `You kick off and the line runs faster than you meant -- you come down the rope in a rush.`;
225
225
  // Carried out to the arrival line, so a rushed rappel still
226
226
  // lands you and the story of it rides WITH the arrival rather
227
227
  // than replacing it. Lint caught this built-and-dropped -- the
228
228
  // player would have taken the damage and been told nothing
229
229
  // about where it came from.
230
- if (dv > 0) {
231
- const soak = rollPool(actor.getSoakPool());
232
- const dealt = Math.max(0, dv - soak.hits);
233
- this.logger.meta(` Hard landing: DV ${dv}, Soak: ${formatRoll(soak)}`);
230
+ // The one landing rule (utilities/falling.ts: p.172, AP -4).
231
+ const landing = resolveFall(actor, meters);
232
+ if (landing.dv > 0) {
233
+ const dealt = landing.dealt;
234
+ this.logger.meta(` Hard landing -- ${landing.meta}`);
234
235
  if (dealt > 0) {
235
- actor.takeDamage(dealt);
236
236
  descentNote += ` The landing costs you ${dealt} box${dealt === 1 ? '' : 'es'}: ${actor.conditionSummary()}`;
237
237
  }
238
238
  else {
@@ -441,14 +441,13 @@ export class MoveCommand extends Command {
441
441
  // storey up and billed for nothing. Invisible on a 3m ledge --
442
442
  // both figures soak to zero damage, which is exactly how it
443
443
  // survived -- and real the moment the drop is worth any DV.
444
- const dv = fallDamageDVMeters(heightNow);
445
444
  let fallNote = `Your grip goes, and there's nothing to catch -- you come off the wall about ${shownHeight} up.`;
446
- if (dv > 0) {
447
- const soak = rollPool(actor.getSoakPool());
448
- const dealt = Math.max(0, dv - soak.hits);
449
- this.logger.meta(` Fall damage: DV ${dv} (${Math.round(heightNow)}m, AP -4), Soak: ${formatRoll(soak)}`);
445
+ // The one landing rule (utilities/falling.ts: p.172, AP -4).
446
+ const landing = resolveFall(actor, heightNow);
447
+ if (landing.dv > 0) {
448
+ const dealt = landing.dealt;
449
+ this.logger.meta(` ${landing.meta}`);
450
450
  if (dealt > 0) {
451
- actor.takeDamage(dealt);
452
451
  fallNote += ` The landing costs you ${dealt} box${dealt === 1 ? '' : 'es'}: ${actor.conditionSummary()}`;
453
452
  }
454
453
  else {
@@ -1205,7 +1204,9 @@ export class MoveCommand extends Command {
1205
1204
  // somebody's working (barrier-geometry.ts).
1206
1205
  : blockedBy === 'barrier' ? `a shimmer-wall of hardened air stands there${blocker ? ` -- ${blocker}'s barrier` : ''}`
1207
1206
  : `there's a wall`;
1208
- const refusal = `You can't step ${direction} -- ${why}.${this.doorHint(room, cell, blockedBy)}`;
1207
+ // A LEDGE'S EDGE: going over it is its own, deliberate verb.
1208
+ const leap = blockedBy === 'edge' && room.outdoors ? hint(` ("leap off ${direction}" goes over the edge -- and you fall.)`) : '';
1209
+ const refusal = `You can't step ${direction} -- ${why}.${this.doorHint(room, cell, blockedBy)}${leap}`;
1209
1210
  // SAY IT ONCE (player screenshot 2026-09-21: twelve identical
1210
1211
  // "You can't step south -- there's a wall." filling the log).
1211
1212
  //
@@ -1728,7 +1729,7 @@ export class MoveCommand extends Command {
1728
1729
  if (drift.taken === 0)
1729
1730
  return driftRefusal(drift, direction);
1730
1731
  const stopped = drift.blockedBy === undefined ? ''
1731
- : drift.blockedBy === 'ward' ? ` A ward stops you${drift.ward ? ` at ${drift.ward}` : ''}.`
1732
+ : drift.blockedBy === 'ward' ? ` A ward stops you${drift.ward ? ` at ${drift.ward}` : ''}${hint(` -- "go ${direction}" presses through it`)}.`
1732
1733
  : drift.blockedBy === 'barrier' ? ` A mana barrier stops you${drift.ward ? ` -- ${drift.ward}'s working` : ''}.`
1733
1734
  : ' Then solid earth.';
1734
1735
  // Silent on a plain drift, like a meat step: the map moved, which
@@ -5,10 +5,11 @@ import { rollPool, formatRoll } from '../utilities/dice.js';
5
5
  import { accrueOverwatch } from '../utilities/overwatch.js';
6
6
  import { MAX_MARKS, markHackerFromDevice } from '../utilities/marks.js';
7
7
  import { deviceMaster } from '../utilities/wan.js';
8
- import { isWatched, cameraMasterHost, directConnectionBlocker, cameraWithinReach, cameraOutOfReach } from '../utilities/surveillance.js';
8
+ import { isWatched, cameraMasterHost, lensMaster, directConnectionBlocker, cameraWithinReach, cameraOutOfReach } from '../utilities/surveillance.js';
9
9
  import { hint } from '../utilities/hints.js';
10
10
  import { showsMechanics, mechanicsActorPrefix } from '../utilities/mechanics-audience.js';
11
11
  import { deviceDefensePool, bruteForceMatrixDv, freeMatrixPerceptionHits, overwatchFromDefense } from '../utilities/matrix-intrusion.js';
12
+ import { ownerInformed } from '../utilities/owner-guard.js';
12
13
  /**
13
14
  * TAP -- THE DIRECT CONNECTION (backlog items 9 and 10, Niko, session
14
15
  * 2026-08-27T02-07-12-404Z: "check the rules on this -- shouldn't I be
@@ -132,7 +133,9 @@ export class TapCommand extends Command {
132
133
  return cameraOutOfReach(lens, 'get a cable into it');
133
134
  if (lens?.destroyed)
134
135
  return `The ${lens.name} is smashed -- a cracked housing and a cut cable. Nothing left on the end of it to talk to.`;
135
- const host = cameraMasterHost(rooms, room);
136
+ // THE CABLE REACHES THIS LENS'S MASTER (surveillance.ts lensMaster):
137
+ // on a strip, the shop it is slaved to, not the strip.
138
+ const host = lens ? lensMaster(rooms, room, lens) : cameraMasterHost(rooms, room);
136
139
  if (!host) {
137
140
  return `You get the housing open and find... a wire to a box on the wall. These are dumb recorders -- no host on this site for them to answer to, nothing on the other end of your cable but tape. ${hint(`Whatever they saw, they saw locally.`)}`;
138
141
  }
@@ -202,10 +205,13 @@ export class TapCommand extends Command {
202
205
  host.host?.spotted.add(actor.name);
203
206
  actor.sneaking = false;
204
207
  this.scene.addWorldEvent(`Something forced the cameras in ${room.name} -- ${hostLabel(host)} flagged an intrusion and its ice is hunting.`);
208
+ // ...and the cameras' OWNER is told, and takes the mark (owner-guard.ts).
209
+ const toldOwner = ownerInformed(this.scene, room, actor, 'device-sleaze', `The ${room.name} cameras`);
205
210
  this.scene.updateStatus();
206
211
  return [
207
212
  `The housing's tamper line trips under your fingers.`,
208
213
  ` The camera reports itself -- and ${hostLabel(host)} believes it. Walls UP: it holds a mark on your persona now, everything guarding this place knows someone is on the wire, and you are no longer moving unnoticed.`,
214
+ ...(toldOwner ? [` ${toldOwner}`] : []),
209
215
  ...godLines,
210
216
  ].join('\n');
211
217
  }
@@ -392,7 +398,8 @@ export class TapCommand extends Command {
392
398
  actor.sneaking = false;
393
399
  // ...and it marks you down the cable (p.236), as it would on the grid.
394
400
  const onYou = markHackerFromDevice(actor, device.name, host);
395
- const trace = ` It holds ${onYou} mark${onYou === 1 ? '' : 's'} on your deck now.`;
401
+ const toldOwner = ownerInformed(this.scene, room, actor, 'device-sleaze', device.name);
402
+ const trace = ` It holds ${onYou} mark${onYou === 1 ? '' : 's'} on your deck now.${toldOwner ? ` ${toldOwner}` : ''}`;
396
403
  if (host) {
397
404
  host.hostAlert = true;
398
405
  this.scene.addWorldEvent(`${device.name} flags a bad handshake on its cable -- ${hostLabel(host, { capital: true })} is awake.`, { plane: 'matrix' });
@@ -458,6 +465,9 @@ export class TapCommand extends Command {
458
465
  if (host)
459
466
  host.hostAlert = true;
460
467
  this.scene.addWorldEvent(`${actor.name} forced ${device.name} over a cable -- the housing shows it.`);
468
+ const toldOwner = ownerInformed(this.scene, room, actor, 'attack-landed', device.name);
469
+ if (toldOwner)
470
+ lines.push(` ${toldOwner}`);
461
471
  // p.238: Brute Force burns what it forces, 1 DV per two full net
462
472
  // hits, resisted by Device Rating + Firewall.
463
473
  const dv = bruteForceMatrixDv(netHits);
@@ -3403,5 +3403,17 @@
3403
3403
  // head noun is a door (door, gate, entrance, ...) or a window keeps its
3404
3404
  // anchor but fills no cell (room-grid wallFixtureKindOf): an exit's door
3405
3405
  // is already the exit's mark, any other door and every window is prose.
3406
- export const ENGINE_VERSION = '1.203.0';
3406
+ // 1.204.0 (2026-10-06): PLAYER-BUILT RUNS. The engine side of the
3407
+ // site's /runs editor (factories/authored-run.ts): prepareAuthoredSeed,
3408
+ // previewAuthoredRun and the authored audit (cells for furniture, NPCs,
3409
+ // items, devices and cameras; the ground and masked outdoor areas; tall
3410
+ // rooms; authored doors and stairs; host IC lineups, spiders, file
3411
+ // protection and data bombs, the Matrix wire). Cameras slave lens by lens
3412
+ // and see by line of sight; ledges and "leap off <direction>" with one
3413
+ // falling rule (SR5 p.172). WARDS ARE A ROOM'S ASTRAL BARRIER (p.294,
3414
+ // p.297-298, p.315-316): they stop astral forms both ways and no body;
3415
+ // press through on Magic + Charisma [Astral] v. Force x 2, "attack ward"
3416
+ // from the astral; the ward device kind is gone and legacy ones migrate
3417
+ // onto their room.
3418
+ export const ENGINE_VERSION = '1.204.0';
3407
3419
  //# sourceMappingURL=engine-version.js.map