@maka/maka-cli 5.117.0 → 5.119.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/typescript/package.json +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js +6 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js +9 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/compile.js +3 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/compile.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/deck.d.ts +14 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/deck.js +73 -38
- package/bundle/typescript/src/commands/game/sideQuest/commands/deck.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/decompile.js +3 -6
- package/bundle/typescript/src/commands/game/sideQuest/commands/decompile.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/docwagon.js +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/docwagon.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/download.js +4 -3
- package/bundle/typescript/src/commands/game/sideQuest/commands/download.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/enter-host.d.ts +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/enter-host.js +10 -8
- package/bundle/typescript/src/commands/game/sideQuest/commands/enter-host.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/equip.js +17 -7
- package/bundle/typescript/src/commands/game/sideQuest/commands/equip.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.d.ts +10 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.js +72 -20
- package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js +8 -3
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js +30 -14
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/haggle.js +14 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/haggle.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/hop.d.ts +16 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/hop.js +95 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/hop.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/inv.js +6 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/inv.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/jack.js +3 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/jack.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/jackpoint.js +5 -7
- package/bundle/typescript/src/commands/game/sideQuest/commands/jackpoint.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/look.js +24 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/look.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/map.js +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/map.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/mark.js +20 -6
- package/bundle/typescript/src/commands/game/sideQuest/commands/mark.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/reboot.js +7 -6
- package/bundle/typescript/src/commands/game/sideQuest/commands/reboot.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/reload.js +6 -3
- package/bundle/typescript/src/commands/game/sideQuest/commands/reload.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/rest.js +3 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/rest.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/say.js +8 -5
- package/bundle/typescript/src/commands/game/sideQuest/commands/say.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js +4 -3
- package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/sin.js +11 -3
- package/bundle/typescript/src/commands/game/sideQuest/commands/sin.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/stance.js +5 -3
- package/bundle/typescript/src/commands/game/sideQuest/commands/stance.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/take.js +20 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/take.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/tap.js +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/tap.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/thread.js +2 -5
- package/bundle/typescript/src/commands/game/sideQuest/commands/thread.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/chargen-factory.d.ts +6 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/chargen-factory.js +17 -4
- package/bundle/typescript/src/commands/game/sideQuest/factories/chargen-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +1 -0
- 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 +2 -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 +22 -0
- package/bundle/typescript/src/commands/game/sideQuest/game.js +132 -29
- package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/host.d.ts +80 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/host.js +98 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/host.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/item.d.ts +50 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/item.js +78 -2
- package/bundle/typescript/src/commands/game/sideQuest/models/item.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +133 -3
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js +381 -85
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/room.d.ts +40 -9
- package/bundle/typescript/src/commands/game/sideQuest/models/room.js +73 -12
- package/bundle/typescript/src/commands/game/sideQuest/models/room.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.d.ts +3 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.js +3 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/qualities.d.ts +34 -1
- package/bundle/typescript/src/commands/game/sideQuest/qualities.js +58 -26
- package/bundle/typescript/src/commands/game/sideQuest/qualities.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/types/player-equipment.d.ts +8 -12
- package/bundle/typescript/src/commands/game/sideQuest/types/save-file.d.ts +14 -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 +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/shared/equipment-enum.d.ts +22 -16
- package/bundle/typescript/src/commands/game/sideQuest/types/shared/equipment-enum.js +22 -16
- package/bundle/typescript/src/commands/game/sideQuest/types/shared/equipment-enum.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/ui.js +2 -2
- package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/auto-fight.js +13 -8
- package/bundle/typescript/src/commands/game/sideQuest/utilities/auto-fight.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog-data.d.ts +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog-data.js +8 -7
- package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog-data.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js +61 -16
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/condition-report.d.ts +23 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/condition-report.js +111 -11
- package/bundle/typescript/src/commands/game/sideQuest/utilities/condition-report.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.d.ts +5 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.js +5 -27
- package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-reach.js +2 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-reach.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-view.d.ts +11 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-view.js +56 -8
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-view.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grids.d.ts +72 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grids.js +100 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grids.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/harm-note.d.ts +25 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/harm-note.js +10 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/harm-note.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/harm-settlement.d.ts +29 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/harm-settlement.js +64 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/harm-settlement.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/ic-actors.d.ts +9 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/ic-actors.js +98 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/ic-actors.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/ic.d.ts +3 -2
- package/bundle/typescript/src/commands/game/sideQuest/utilities/ic.js +34 -6
- package/bundle/typescript/src/commands/game/sideQuest/utilities/ic.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/marks.d.ts +42 -2
- package/bundle/typescript/src/commands/game/sideQuest/utilities/marks.js +75 -4
- package/bundle/typescript/src/commands/game/sideQuest/utilities/marks.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/matrix-roster.d.ts +62 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/matrix-roster.js +97 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/matrix-roster.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/overwatch.js +3 -3
- package/bundle/typescript/src/commands/game/sideQuest/utilities/overwatch.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.d.ts +1 -3
- package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js +85 -7
- package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.d.ts +10 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js +39 -23
- package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/programs.d.ts +16 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/programs.js +12 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/programs.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/sin.d.ts +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/sin.js +23 -4
- package/bundle/typescript/src/commands/game/sideQuest/utilities/sin.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
import { agentRatingFromName } from './utilities/programs.js';
|
|
1
2
|
import blessed from 'blessed';
|
|
3
|
+
import { hostLabel } from './utilities/grid-names.js';
|
|
4
|
+
import { marksPlaced, marksOnYou } from './utilities/marks.js';
|
|
5
|
+
import { settleUnresolvedHarm } from './utilities/harm-settlement.js';
|
|
6
|
+
import { hostInteriorPanel } from './utilities/grid-view.js';
|
|
7
|
+
import { DEFAULT_GRID_PROVIDER, PUBLIC_GRID, globalGrid } from './utilities/grids.js';
|
|
2
8
|
import { hostsInReach, hostDockLine, gridVicinity } from './utilities/grid-reach.js';
|
|
3
9
|
import { nameThem, scrubHandles } from './utilities/identity.js';
|
|
4
10
|
import { dirname } from 'path';
|
|
@@ -27,7 +33,7 @@ import { rollPool, formatRoll } from './utilities/dice.js';
|
|
|
27
33
|
import { Direction } from './types/shared/direction-enum.js';
|
|
28
34
|
import { Logger } from './utilities/logger.js';
|
|
29
35
|
import { runHostTurn } from './utilities/ic.js';
|
|
30
|
-
import { leaveMatrix } from './utilities/planes.js';
|
|
36
|
+
import { leaveMatrix, endPersona } from './utilities/planes.js';
|
|
31
37
|
import { CommandQueue } from './utilities/command-queue.js';
|
|
32
38
|
import { currentSession } from './utilities/session-context.js';
|
|
33
39
|
import { PlayersCommand } from './commands/players.js';
|
|
@@ -66,6 +72,7 @@ import { EquipmentCommand } from './commands/equipment.js';
|
|
|
66
72
|
import { MapCommand } from './commands/map.js';
|
|
67
73
|
import { SilentCommand } from './commands/silent.js';
|
|
68
74
|
import { EnterHostCommand, ExitHostCommand } from './commands/enter-host.js';
|
|
75
|
+
import { HopCommand } from './commands/hop.js';
|
|
69
76
|
import { RestCommand } from './commands/rest.js';
|
|
70
77
|
import { ReloadCommand } from './commands/reload.js';
|
|
71
78
|
import { SubdueCommand } from './commands/subdue.js';
|
|
@@ -1295,6 +1302,55 @@ export default class Game {
|
|
|
1295
1302
|
return npc;
|
|
1296
1303
|
}
|
|
1297
1304
|
_remoteFixer;
|
|
1305
|
+
/**
|
|
1306
|
+
* The live-sheet read of everything this runner has out (contract
|
|
1307
|
+
* 2026-09-02): the ledger's companions plus the drone they are jumped
|
|
1308
|
+
* into. `where` is the room, or the host/grid for a construct;
|
|
1309
|
+
* `damage` is the thing's OWN track -- a drone's hull, an agent's deck
|
|
1310
|
+
* (shared monitor, p.246), a spirit's or sprite's shell.
|
|
1311
|
+
*/
|
|
1312
|
+
companionsForBeat(player) {
|
|
1313
|
+
const whereOf = (a) => a.plane === 'matrix'
|
|
1314
|
+
? (a.hostInside ? hostLabel(a.hostInside.over, { capital: true }) : (a.currentGrid?.name ?? 'the grid'))
|
|
1315
|
+
: a.currentLocation?.name;
|
|
1316
|
+
const out = [];
|
|
1317
|
+
for (const c of this.companions) {
|
|
1318
|
+
const dev = c.boundDevice;
|
|
1319
|
+
const services = typeof c.services === 'number' ? `, ${c.services} service${c.services === 1 ? '' : 's'}` : '';
|
|
1320
|
+
const line = c.kind === 'drone' && dev ? `Pilot ${2 + dev.qualityBonus}, hull ${dev.droneSummary()}`
|
|
1321
|
+
: c.kind === 'agent' && dev ? `rating ${c.force} on ${dev.name} ${dev.deckSummary()}`
|
|
1322
|
+
: c.kind === 'sprite' ? `${c.spriteType ?? 'sprite'} level ${c.force}${services}${c.registered ? ', registered' : ''}`
|
|
1323
|
+
: c.kind === 'spirit' ? `Force ${c.force}${services}`
|
|
1324
|
+
: c.npc.archetypeName ?? undefined;
|
|
1325
|
+
const damage = c.kind === 'drone' && dev ? { taken: dev.droneDamage, max: dev.maxDroneBoxes }
|
|
1326
|
+
: c.kind === 'agent' && dev ? { taken: dev.deckDamage, max: dev.maxDeckBoxes }
|
|
1327
|
+
: { taken: c.npc.damageTaken, max: c.npc.maxConditionBoxes };
|
|
1328
|
+
out.push({ name: dev?.name ?? c.npc.name, kind: c.kind, deployed: true, where: whereOf(c.npc), line, damage });
|
|
1329
|
+
}
|
|
1330
|
+
if (player.riggedDrone) {
|
|
1331
|
+
const d = player.riggedDrone;
|
|
1332
|
+
out.push({ name: d.name, kind: 'drone', deployed: true, where: `jumped in${player.bodyRoom ? ` from ${player.bodyRoom.name}` : ''}`, line: `hull ${d.droneSummary()}`, damage: { taken: d.droneDamage, max: d.maxDroneBoxes } });
|
|
1333
|
+
}
|
|
1334
|
+
// STOWED (addendum 2026-09-02: "and when they are deployed or not"): the
|
|
1335
|
+
// roster the runner OWNS and has not sent out -- drones in the bag, the
|
|
1336
|
+
// deck's agent, registered sprites waiting in the Resonance. Spirits
|
|
1337
|
+
// exist only while summoned, so none is ever stowed.
|
|
1338
|
+
for (const d of player.inventory.getAllItems().filter(i => i.isDrone())) {
|
|
1339
|
+
if (out.some(o => o.name === d.name))
|
|
1340
|
+
continue;
|
|
1341
|
+
out.push({ name: d.name, kind: 'drone', deployed: false, line: `Pilot ${2 + d.qualityBonus}, hull ${d.droneSummary()}${d.isWrecked ? ' -- WRECKED' : ''}`, damage: { taken: d.droneDamage, max: d.maxDroneBoxes } });
|
|
1342
|
+
}
|
|
1343
|
+
const deck = player.getAnyCyberdeck();
|
|
1344
|
+
if (deck && !this.companions.some(c => c.kind === 'agent')) {
|
|
1345
|
+
const chips = player.inventory.getAllItems().map(i => agentRatingFromName(i.name)).filter((r) => r !== undefined);
|
|
1346
|
+
const rating = Math.max(3 + deck.qualityBonus, ...(chips.length ? chips : [0]));
|
|
1347
|
+
out.push({ name: `Agent (${deck.name})`, kind: 'agent', deployed: false, line: `rating ${rating} on ${deck.name} ${deck.deckSummary()}`, damage: { taken: deck.deckDamage, max: deck.maxDeckBoxes } });
|
|
1348
|
+
}
|
|
1349
|
+
for (const sp of this.registeredSpritesWaiting()) {
|
|
1350
|
+
out.push({ name: sp.name, kind: 'sprite', deployed: false, line: `${sp.spriteType} level ${sp.level}, ${sp.tasks} task${sp.tasks === 1 ? '' : 's'}, registered` });
|
|
1351
|
+
}
|
|
1352
|
+
return out;
|
|
1353
|
+
}
|
|
1298
1354
|
spawnCompanionShell(opts) {
|
|
1299
1355
|
if (this.scene.getActor(opts.name)) {
|
|
1300
1356
|
Logger.getInstance().write(`spawnCompanionShell: name "${opts.name}" already in scene -- refusing.`);
|
|
@@ -1312,6 +1368,7 @@ export default class Game {
|
|
|
1312
1368
|
this.scene.addActor(npc);
|
|
1313
1369
|
this.scene.setCharacterLocation(npc, opts.room.name);
|
|
1314
1370
|
npc.scene = this.scene;
|
|
1371
|
+
this.player.noteConditionChanged(); // the crew rides the beat (companions)
|
|
1315
1372
|
this.companions.push({ npc, kind: opts.kind, services: opts.services, force: opts.force, boundDevice: opts.boundDevice });
|
|
1316
1373
|
Logger.getInstance().write(`Companion spawned: ${opts.name} (${opts.kind}, force ${opts.force}) in ${opts.room.name}.`);
|
|
1317
1374
|
return npc;
|
|
@@ -1364,6 +1421,7 @@ export default class Game {
|
|
|
1364
1421
|
const idx = this.companions.indexOf(entry);
|
|
1365
1422
|
if (idx >= 0)
|
|
1366
1423
|
this.companions.splice(idx, 1);
|
|
1424
|
+
this.player.noteConditionChanged(); // the crew rides the beat (companions)
|
|
1367
1425
|
Logger.getInstance().write(`Companion dismissed: ${entry.npc.name} -- ${reason}`);
|
|
1368
1426
|
}
|
|
1369
1427
|
/**
|
|
@@ -1425,6 +1483,7 @@ export default class Game {
|
|
|
1425
1483
|
const idx = this.companions.indexOf(entry);
|
|
1426
1484
|
if (idx >= 0)
|
|
1427
1485
|
this.companions.splice(idx, 1);
|
|
1486
|
+
this.player.noteConditionChanged(); // the crew rides the beat (companions)
|
|
1428
1487
|
if (entry.kind === 'drone' && entry.boundDevice && !entry.npc.deathClaimed) {
|
|
1429
1488
|
entry.boundDevice.takeDroneDamage(entry.boundDevice.maxDroneBoxes);
|
|
1430
1489
|
Logger.getInstance().logWithColor(`👥 The ${entry.boundDevice.name} is WRECKED where it fell -- rest to repair the frame.`, 'yellow');
|
|
@@ -1659,6 +1718,8 @@ export default class Game {
|
|
|
1659
1718
|
// and while the tab stands, rest at the hideout recovers half (rest.ts;
|
|
1660
1719
|
// "pay" squares it, pay.ts; "lifestyle" views and moves tiers).
|
|
1661
1720
|
lifestyleTier = 'Squatter';
|
|
1721
|
+
/** The Big Ten grid a High lifestyle rides (SR5 p.222). A placeholder default until chargen offers the pick (grids.ts). */
|
|
1722
|
+
gridProvider = DEFAULT_GRID_PROVIDER;
|
|
1662
1723
|
rentDebt = 0;
|
|
1663
1724
|
/** The active lifestyle tier's row (falls back to Squatter). */
|
|
1664
1725
|
get lifestyle() {
|
|
@@ -2213,19 +2274,26 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
2213
2274
|
// The one-word role on the live sheet's actor entries: the contact
|
|
2214
2275
|
// ledger's word, else "fence" when the room's fence stands here,
|
|
2215
2276
|
// else nothing (utilities/condition-report.ts setActorRoleResolver).
|
|
2216
|
-
void import('./utilities/condition-report.js').then(m =>
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2277
|
+
void import('./utilities/condition-report.js').then(m => {
|
|
2278
|
+
// The marks this persona HOLDS (contract 2026-09-02, web accepted first):
|
|
2279
|
+
// the same names the "marks" listing prints.
|
|
2280
|
+
m.setMarksPlacedResolver(p => marksPlaced(this.scene, p.name));
|
|
2281
|
+
m.setMarksOnYouResolver(p => marksOnYou(this.scene, p));
|
|
2282
|
+
m.setCompanionsResolver(p => this.companionsForBeat(p));
|
|
2283
|
+
return m.setActorRoleResolver(a => {
|
|
2284
|
+
const contact = this.contacts.get(a.name)?.role;
|
|
2285
|
+
if (contact)
|
|
2286
|
+
return contact;
|
|
2287
|
+
// The same classifier the ledger uses, on anyone -- minus its
|
|
2288
|
+
// "Street Contact" default, which is a ledger word, not a role: an
|
|
2289
|
+
// extra it cannot place carries nothing rather than a wrong word.
|
|
2290
|
+
const classified = Game.roleOf(a);
|
|
2291
|
+
if (classified !== 'Street Contact')
|
|
2292
|
+
return classified;
|
|
2293
|
+
const room = a.currentLocation;
|
|
2294
|
+
return room && isFence(a, room) ? 'Fence' : undefined;
|
|
2295
|
+
});
|
|
2296
|
+
}).catch(() => undefined);
|
|
2229
2297
|
}
|
|
2230
2298
|
registerCommands() {
|
|
2231
2299
|
CommandFactory.registerCommand('look', LookCommand);
|
|
@@ -2287,6 +2355,7 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
2287
2355
|
// branch ROUTES a bare "exit" to this command while the persona is
|
|
2288
2356
|
// inside a host, and 'exit-host' is the always-reachable name.
|
|
2289
2357
|
CommandFactory.registerCommand('enter', EnterHostCommand);
|
|
2358
|
+
CommandFactory.registerCommand('hop', HopCommand);
|
|
2290
2359
|
CommandFactory.registerCommand('exit-host', ExitHostCommand);
|
|
2291
2360
|
CommandFactory.registerCommand('rest', RestCommand);
|
|
2292
2361
|
CommandFactory.registerCommand('reload', ReloadCommand);
|
|
@@ -2662,6 +2731,7 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
2662
2731
|
throw new Error(`Scene generation failed: ${err.message}`);
|
|
2663
2732
|
}
|
|
2664
2733
|
this.scene.initialize(this);
|
|
2734
|
+
this.resolveHostGrids();
|
|
2665
2735
|
this.player.currentLocation = this.determineStartRoom();
|
|
2666
2736
|
this.applySeedStartSpot(this.sceneSeed);
|
|
2667
2737
|
this.registerCommands();
|
|
@@ -2862,6 +2932,16 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
2862
2932
|
this._resumedAt = room;
|
|
2863
2933
|
}
|
|
2864
2934
|
/** The location a save carries: the current hub room and spot. */
|
|
2935
|
+
/** Each host's seeded grid word ('public' | 'local' | 'global:<corp>') against this scene's local grid. */
|
|
2936
|
+
resolveHostGrids() {
|
|
2937
|
+
for (const room of Object.values(this.scene.getRooms())) {
|
|
2938
|
+
const host = room.host;
|
|
2939
|
+
if (!host?.gridSeed)
|
|
2940
|
+
continue;
|
|
2941
|
+
const w = host.gridSeed.trim().toLowerCase();
|
|
2942
|
+
host.grid = w === 'public' ? PUBLIC_GRID : w === 'local' ? this.scene.localGrid : w.startsWith('global:') ? globalGrid(host.gridSeed.slice('global:'.length)) : undefined;
|
|
2943
|
+
}
|
|
2944
|
+
}
|
|
2865
2945
|
hubLocationSnapshot() {
|
|
2866
2946
|
// The BODY's room, never the persona's: jacked in, currentLocation is
|
|
2867
2947
|
// wherever the persona stands (a host's room inside one), and a resume
|
|
@@ -2903,6 +2983,8 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
2903
2983
|
// local file never knew -- that is the cloud repair's job, and the
|
|
2904
2984
|
// sync protocol's, see the repair-visibility ruling in cloud-saves.)
|
|
2905
2985
|
this.lifestyleTier = canonicalLifestyleTier(save.game.lifestyleTier) ?? 'Street';
|
|
2986
|
+
if (typeof save.game.gridProvider === 'string' && save.game.gridProvider.trim())
|
|
2987
|
+
this.gridProvider = save.game.gridProvider;
|
|
2906
2988
|
this.rentDebt = save.game.rentDebt;
|
|
2907
2989
|
this.syncHomeToLifestyle();
|
|
2908
2990
|
this.player.lifestyleEdgeBonus = this.lifestyle.edgeBonus;
|
|
@@ -3169,6 +3251,7 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
3169
3251
|
player: serializePlayer(this.player),
|
|
3170
3252
|
game: {
|
|
3171
3253
|
location: this.hubLocationSnapshot(),
|
|
3254
|
+
gridProvider: this.gridProvider,
|
|
3172
3255
|
lifestyleTier: this.lifestyleTier,
|
|
3173
3256
|
rentDebt: this.rentDebt,
|
|
3174
3257
|
tier: this._tier,
|
|
@@ -3417,7 +3500,7 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
3417
3500
|
this.player.linkLockedBy.clear();
|
|
3418
3501
|
// Same enumeration, same reason: insideHost is persona state and these
|
|
3419
3502
|
// paths end the persona without passing through planes.leaveMatrix.
|
|
3420
|
-
this.player
|
|
3503
|
+
endPersona(this.player);
|
|
3421
3504
|
this.player.astralTicks = 0;
|
|
3422
3505
|
this.player.activeDeck = undefined;
|
|
3423
3506
|
this.player.riggedDrone = undefined;
|
|
@@ -3521,7 +3604,7 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
3521
3604
|
this.player.linkLockedBy.clear();
|
|
3522
3605
|
// Same enumeration, same reason: insideHost is persona state and these
|
|
3523
3606
|
// paths end the persona without passing through planes.leaveMatrix.
|
|
3524
|
-
this.player
|
|
3607
|
+
endPersona(this.player);
|
|
3525
3608
|
this.player.astralTicks = 0;
|
|
3526
3609
|
this.player.activeDeck = undefined;
|
|
3527
3610
|
this.player.riggedDrone = undefined;
|
|
@@ -3973,7 +4056,11 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
3973
4056
|
// forward), and no blocking AI-redressing pass either -- the chunked
|
|
3974
4057
|
// rooms pass already wrote this scene's prose.
|
|
3975
4058
|
this.scene = await SceneSynthesizer.synthesizeFromJson(seed, this.player, false, false);
|
|
4059
|
+
// A run happens in the same metroplex: it rides the hub's local grid.
|
|
4060
|
+
if (this._hubScene)
|
|
4061
|
+
this.scene.localGrid = this._hubScene.localGrid;
|
|
3976
4062
|
this.scene.initialize(this);
|
|
4063
|
+
this.resolveHostGrids();
|
|
3977
4064
|
this.player.currentLocation = this.determineStartRoom();
|
|
3978
4065
|
this.applySeedStartSpot(seed);
|
|
3979
4066
|
// New job -- and the needs come due at the door (see
|
|
@@ -4842,7 +4929,7 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
4842
4929
|
// each under the picture it belongs to, so the HUD stops repeating
|
|
4843
4930
|
// what two panels already show. The breadcrumb went with it -- the
|
|
4844
4931
|
// district map draws the way you came far better than a text trail.
|
|
4845
|
-
const stanceColor = player.autoStance === '
|
|
4932
|
+
const stanceColor = player.autoStance === 'lethal' ? 'red' : player.autoStance === 'non-lethal' ? 'yellow' : 'white';
|
|
4846
4933
|
// WHAT'S IN YOUR HANDS rides alongside the stance (player ruling
|
|
4847
4934
|
// 2026-08-25). The two answer the same question -- how ready are you
|
|
4848
4935
|
// -- and the stance line was left short and lonely once the location
|
|
@@ -5128,12 +5215,19 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
5128
5215
|
this.setRoomOverlay(logoPanelLines(Game.MAP_DOCK_ROWS - 2, boxWidth ?? 16));
|
|
5129
5216
|
return;
|
|
5130
5217
|
}
|
|
5218
|
+
// INSIDE A HOST there is no floor to draw (p.219, p.246): the dock
|
|
5219
|
+
// shows the interior's icons, not the room the body sits in.
|
|
5220
|
+
const inside = this.player.hostInside;
|
|
5221
|
+
if (inside) {
|
|
5222
|
+
this.setRoomOverlay(hostInteriorPanel(this.scene, this.player, inside, Game.MAP_DOCK_ROWS - 2, boxWidth ?? 16));
|
|
5223
|
+
return;
|
|
5224
|
+
}
|
|
5131
5225
|
}
|
|
5132
5226
|
else {
|
|
5133
5227
|
const mapInner = mapWidth ?? 15;
|
|
5134
5228
|
const mapView = Math.max(7, mapInner % 2 === 0 ? mapInner - 1 : mapInner);
|
|
5135
5229
|
const mapLines = renderMapViewport(this.scene.getRooms(), here, (r, d) => this.scene.barrierSealing(r, d), {
|
|
5136
|
-
visited: this.player.visitedRooms,
|
|
5230
|
+
visited: this.player.hasSoft('mapsoft') ? undefined /* Mapsoft (p.442): the district drawn and named */ : this.player.visitedRooms,
|
|
5137
5231
|
arEyes: this.player.hasMatrixEyes(),
|
|
5138
5232
|
}, mapView, tallestRoomRows());
|
|
5139
5233
|
// The captions the HUD used to carry: where you are under the
|
|
@@ -5316,6 +5410,13 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
5316
5410
|
if (actor.isUnconscious() && this.scene.getKnockout(actor.name)) {
|
|
5317
5411
|
return out(`You're out cold -- the world moves without you.`);
|
|
5318
5412
|
}
|
|
5413
|
+
// HARM NOBODY SETTLED (user report 2026-09-02: killed by ice, still
|
|
5414
|
+
// walking): a track that filled outside an exchange -- IC biofeedback,
|
|
5415
|
+
// dumpshock, a blow to the empty body -- is judged before the next
|
|
5416
|
+
// command runs, and again after it (utilities/harm-settlement.ts).
|
|
5417
|
+
const settledBefore = await settleUnresolvedHarm(this.scene, actor);
|
|
5418
|
+
if (settledBefore.length > 0)
|
|
5419
|
+
return out(settledBefore.join('\n'));
|
|
5319
5420
|
if (verb === 'maka') {
|
|
5320
5421
|
return out('You are still in the game, type "quit" to exit');
|
|
5321
5422
|
}
|
|
@@ -5341,7 +5442,13 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
5341
5442
|
const command = CommandFactory.createCommand(verb, context);
|
|
5342
5443
|
if (command) {
|
|
5343
5444
|
const result = await command.execute(args);
|
|
5344
|
-
|
|
5445
|
+
const wrapped = this.withEphemeralTurn(actor, this.withAlarmTurn(actor, this.withICTurn(actor, result)));
|
|
5446
|
+
// The IC turn above may have filled a track -- settle it now, not
|
|
5447
|
+
// on the next keystroke.
|
|
5448
|
+
const settled = await settleUnresolvedHarm(this.scene, actor);
|
|
5449
|
+
if (settled.length === 0)
|
|
5450
|
+
return out(wrapped);
|
|
5451
|
+
return out([wrapped ?? '', ...settled].filter((l, i) => i > 0 || l.length > 0).join('\n'));
|
|
5345
5452
|
}
|
|
5346
5453
|
// Typo tolerance: two straight sessions bounced on slips like "searh"
|
|
5347
5454
|
// and "maop". Reuse the same fuzzy matcher item/NPC names go through
|
|
@@ -5455,16 +5562,12 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
5455
5562
|
withICTurn(actor, result) {
|
|
5456
5563
|
if (result === null)
|
|
5457
5564
|
return null;
|
|
5458
|
-
|
|
5459
|
-
//
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
// twelve runs, twelve cracked hosts, zero sightings. A host with a
|
|
5463
|
-
// node gets its turn whenever a persona is standing in it, and
|
|
5464
|
-
// ic.ts decides whether that turn is eyes or ice.
|
|
5465
|
-
if (!room || actor.plane !== 'matrix' || !room.hasNode)
|
|
5565
|
+
// The host's turn happens INSIDE it (p.246-247): the ice acts on what
|
|
5566
|
+
// is in the host, and the persona's position says whether it is.
|
|
5567
|
+
const host = actor.hostInside;
|
|
5568
|
+
if (!host || actor.plane !== 'matrix')
|
|
5466
5569
|
return result;
|
|
5467
|
-
const turn = runHostTurn(
|
|
5570
|
+
const turn = runHostTurn(host.over, actor, this.scene);
|
|
5468
5571
|
if (turn.lines.length === 0 && turn.meta.length === 0)
|
|
5469
5572
|
return result;
|
|
5470
5573
|
// Dice to the Mechanics pane, and only for a human -- the same gate
|
|
@@ -5545,7 +5648,7 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
|
|
|
5545
5648
|
// players" / "crew street"); the bare verb still answers quietly.
|
|
5546
5649
|
{ title: 'party', entries: [['crew', 'party'], ['hire'], ['dismiss'], ['train'], ['order'], ['lead'], ['command'], ['deploy'], ['recall']] },
|
|
5547
5650
|
{ title: 'magic', entries: [['spells'], ['cast'], ['summon', 'conjure'], ['project', 'astral'], ['return'], ['assense']] },
|
|
5548
|
-
{ title: 'matrix', entries: [['jack'], ['jackpoint'], ['deck'], ['load'], ['unload'], ['hack'], ['mark'], ['download'], ['enter'], ['exit-host'], ['tap', 'splice'], ['snoop'], ['overwatch', 'os'], ['pan'], ['ar'], ['aros'], ['silent'], ['reboot'], ['agent'], ['drone'], ['jump', 'rig']] },
|
|
5651
|
+
{ title: 'matrix', entries: [['jack'], ['jackpoint'], ['deck'], ['load'], ['unload'], ['hack'], ['mark'], ['download'], ['enter'], ['exit-host'], ['hop'], ['tap', 'splice'], ['snoop'], ['overwatch', 'os'], ['pan'], ['ar'], ['aros'], ['silent'], ['reboot'], ['agent'], ['drone'], ['jump', 'rig']] },
|
|
5549
5652
|
// The Emerged get their own shelf (player request: "there MUST be
|
|
5550
5653
|
// resonance" -- matrix is the place, Resonance is the talent).
|
|
5551
5654
|
// `sustain` shelves here and not under magic: the command is
|