@maka/maka-cli 5.7.0 → 5.8.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/deploy/ubuntu.sub.cmd.js +16 -31
- package/bundle/typescript/src/commands/deploy/ubuntu.sub.cmd.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/archetypes.js +2 -2
- package/bundle/typescript/src/commands/game/sideQuest/archetypes.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/ask.js +5 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/ask.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js +11 -8
- package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js +32 -14
- package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/companions.d.ts +33 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/companions.js +137 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/companions.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.d.ts +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js +53 -12
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js +12 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/jump.js +23 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/jump.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/look.js +7 -6
- package/bundle/typescript/src/commands/game/sideQuest/commands/look.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/order.d.ts +19 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/order.js +151 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/order.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/search.js +9 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/search.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/summon.d.ts +19 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/summon.js +112 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/summon.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +81 -0
- package/bundle/typescript/src/commands/game/sideQuest/game.js +367 -9
- package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.d.ts +33 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +162 -3
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +2 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js +9 -2
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/room.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/room.js +6 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/room.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.js +7 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/ui.js +32 -5
- package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/auto-fight.js +3 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/auto-fight.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.d.ts +15 -3
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js +111 -28
- 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 +7 -4
- package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.js +8 -5
- package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/log-style.d.ts +14 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/log-style.js +15 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/log-style.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/logger.d.ts +16 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/logger.js +49 -4
- package/bundle/typescript/src/commands/game/sideQuest/utilities/logger.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js +23 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js.map +1 -1
- package/bundle/typescript/src/commands/ssl.js +10 -15
- package/bundle/typescript/src/commands/ssl.js.map +1 -1
- package/bundle/typescript/src/templates/react/kit/mui/auth/password-reset/basic-password-reset-page.js.tsx +3 -4
- package/bundle/typescript/src/tools/ssl/ssl.class.d.ts +8 -0
- package/bundle/typescript/src/tools/ssl/ssl.class.js +53 -0
- package/bundle/typescript/src/tools/ssl/ssl.class.js.map +1 -1
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ import { NPC } from '../models/npc.js';
|
|
|
3
3
|
import { Category } from '../types/shared/item-enum.js';
|
|
4
4
|
import { Command } from './command.js';
|
|
5
5
|
import { shellsInRoom, canReachHost } from '../utilities/planes.js';
|
|
6
|
+
import { BULLET } from '../utilities/log-style.js';
|
|
6
7
|
export class LookCommand extends Command {
|
|
7
8
|
static verb = 'look';
|
|
8
9
|
static description = 'Examine your surroundings';
|
|
@@ -80,7 +81,7 @@ export class LookCommand extends Command {
|
|
|
80
81
|
if (otherActors.length > 0) {
|
|
81
82
|
const actorList = otherActors.map(a => {
|
|
82
83
|
const aura = this.actor.plane === 'astral' && a.plane === 'meat' ? ' (an aura, dim and physical)' : '';
|
|
83
|
-
return
|
|
84
|
+
return `${BULLET}${a.name}${aura}`;
|
|
84
85
|
}).join('\n');
|
|
85
86
|
description += `\n\nYou see:\n${actorList}`;
|
|
86
87
|
}
|
|
@@ -89,7 +90,7 @@ export class LookCommand extends Command {
|
|
|
89
90
|
if (this.actor.plane !== 'matrix') {
|
|
90
91
|
const shells = shellsInRoom(this.scene, room).filter(s => s !== this.actor);
|
|
91
92
|
if (shells.length > 0) {
|
|
92
|
-
const shellList = shells.map(s =>
|
|
93
|
+
const shellList = shells.map(s => `${BULLET}${s.name}'s body -- slumped and vacant, nobody home`).join('\n');
|
|
93
94
|
description += `\n\n${shellList}`;
|
|
94
95
|
}
|
|
95
96
|
}
|
|
@@ -97,15 +98,15 @@ export class LookCommand extends Command {
|
|
|
97
98
|
const exits = Array.from(room.exits.entries())
|
|
98
99
|
.map(([direction, exit]) => {
|
|
99
100
|
if (typeof exit === 'string') {
|
|
100
|
-
return
|
|
101
|
+
return `${BULLET}${direction}: ${exit}`;
|
|
101
102
|
}
|
|
102
103
|
else if (exit instanceof Door) {
|
|
103
104
|
const targetRoom = exit.getOtherSideToName(room);
|
|
104
105
|
const lockedStr = exit.checkIfLocked() ? ' (locked)' : '';
|
|
105
|
-
return
|
|
106
|
+
return `${BULLET}${direction}: ${targetRoom}${lockedStr}`;
|
|
106
107
|
}
|
|
107
108
|
else {
|
|
108
|
-
return
|
|
109
|
+
return `${BULLET}${direction}: Unknown`;
|
|
109
110
|
}
|
|
110
111
|
});
|
|
111
112
|
if (exits.length > 0) {
|
|
@@ -167,7 +168,7 @@ export class LookCommand extends Command {
|
|
|
167
168
|
for (const slotKey of Object.keys(group)) {
|
|
168
169
|
const item = group[slotKey];
|
|
169
170
|
if (item) {
|
|
170
|
-
lines.push(
|
|
171
|
+
lines.push(`${BULLET}${groupKey}.${slotKey}: ${item.name}`);
|
|
171
172
|
}
|
|
172
173
|
}
|
|
173
174
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"look.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/look.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAExD,OAAO,EAAE,OAAO,EAAY,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"look.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/look.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Command, ICommand } from './command.js';
|
|
2
|
+
/**
|
|
3
|
+
* Deterministic companion control: "order <companion> <command...>" runs
|
|
4
|
+
* the command AS the companion, through its own scene-bound registry
|
|
5
|
+
* (NPC.runCommand -- no AI round trip, no reflect chain: an order is an
|
|
6
|
+
* order). The companion's AI still acts on its own between orders (its
|
|
7
|
+
* prompt carries the allegiance block); this verb is for the moments
|
|
8
|
+
* that must happen NOW -- "order spirit attack krow". A spirit charges
|
|
9
|
+
* one service for an ordered physical task (fights bill separately in
|
|
10
|
+
* combat-exchange, one per fight).
|
|
11
|
+
*/
|
|
12
|
+
export declare class OrderCommand extends Command implements ICommand {
|
|
13
|
+
protected static verb: string;
|
|
14
|
+
protected static description: string;
|
|
15
|
+
execute(args?: string[]): Promise<string>;
|
|
16
|
+
/** Per-kind feed styling -- matches the HUD's plane color language. */
|
|
17
|
+
private static readonly FEED;
|
|
18
|
+
private static readonly ATOMIC_REFUSAL;
|
|
19
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { Command } from './command.js';
|
|
2
|
+
import { fuzzyPickName } from '../utilities/fuzzy-match.js';
|
|
3
|
+
import { AI } from '../../../../tools/ai/ai.class.js';
|
|
4
|
+
/**
|
|
5
|
+
* Deterministic companion control: "order <companion> <command...>" runs
|
|
6
|
+
* the command AS the companion, through its own scene-bound registry
|
|
7
|
+
* (NPC.runCommand -- no AI round trip, no reflect chain: an order is an
|
|
8
|
+
* order). The companion's AI still acts on its own between orders (its
|
|
9
|
+
* prompt carries the allegiance block); this verb is for the moments
|
|
10
|
+
* that must happen NOW -- "order spirit attack krow". A spirit charges
|
|
11
|
+
* one service for an ordered physical task (fights bill separately in
|
|
12
|
+
* combat-exchange, one per fight).
|
|
13
|
+
*/
|
|
14
|
+
export class OrderCommand extends Command {
|
|
15
|
+
static verb = 'order';
|
|
16
|
+
static description = 'Command a companion: exact commands run instantly ("order spirit attack Krow"); anything else becomes a standing DIRECTIVE its AI pursues ("order agent to find Mr. Krow"). Spirit tasks cost a service.';
|
|
17
|
+
async execute(args = []) {
|
|
18
|
+
const game = this.game;
|
|
19
|
+
if (!game || game.companions.length === 0) {
|
|
20
|
+
return `You have no one to order -- no spirit bound, no agent running, no drone deployed.`;
|
|
21
|
+
}
|
|
22
|
+
if (!args || args.length < 2) {
|
|
23
|
+
const roster = game.companions.map(c => c.npc.name).join(', ');
|
|
24
|
+
return `Order WHO to do WHAT? With you: ${roster}. ("order <name> <command>")`;
|
|
25
|
+
}
|
|
26
|
+
// Longest-prefix companion match, remainder is the command.
|
|
27
|
+
let entry;
|
|
28
|
+
let commandWords = [];
|
|
29
|
+
for (let i = args.length - 1; i >= 1; i--) {
|
|
30
|
+
const picked = fuzzyPickName(args.slice(0, i).join(' '), game.companions.map(c => c.npc.name));
|
|
31
|
+
if (picked) {
|
|
32
|
+
entry = game.companions.find(c => c.npc.name === picked);
|
|
33
|
+
commandWords = args.slice(i);
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (!entry) {
|
|
38
|
+
return `None of yours answers to that. With you: ${game.companions.map(c => c.npc.name).join(', ')}.`;
|
|
39
|
+
}
|
|
40
|
+
if (commandWords.length === 0) {
|
|
41
|
+
return `Order ${entry.npc.name} to do WHAT?`;
|
|
42
|
+
}
|
|
43
|
+
if (entry.npc.isIncapacitated()) {
|
|
44
|
+
return `${entry.npc.name} is past taking orders.`;
|
|
45
|
+
}
|
|
46
|
+
// "order agent to find krow" reads naturally -- strip the connective
|
|
47
|
+
// FIRST, so every check below sees the bare command ("to attack krow"
|
|
48
|
+
// must read as the attack it is).
|
|
49
|
+
if (commandWords[0]?.toLowerCase() === 'to')
|
|
50
|
+
commandWords = commandWords.slice(1);
|
|
51
|
+
const cmd = commandWords.join(' ');
|
|
52
|
+
// The feed wears its plane's colors (player request: what the
|
|
53
|
+
// companion SEES should read as coming through its senses) -- the
|
|
54
|
+
// same visual language the HUD already speaks: yellow ✈ for a
|
|
55
|
+
// drone's sensor feed, magenta ✧ for a spirit's otherworldly report,
|
|
56
|
+
// cyan ▣ for an agent on the grid.
|
|
57
|
+
const feed = OrderCommand.FEED[entry.kind] ?? OrderCommand.FEED.ally;
|
|
58
|
+
this.actor.performAction('orders', `${entry.npc.name}: "${cmd}"`);
|
|
59
|
+
this.logger.logWithColor(`${feed.icon} [order] ${entry.npc.name}: ${cmd}`, feed.color);
|
|
60
|
+
this.logger.write(`OrderCommand: ${this.actor.name} -> ${entry.npc.name}: ${cmd}`);
|
|
61
|
+
// RECALL intent folds the companion deterministically and FREE --
|
|
62
|
+
// it must never reach the registry, where the astral "return" verb
|
|
63
|
+
// would run as the companion and answer "You're already in your
|
|
64
|
+
// body." (a real session's agent couldn't be brought home by any
|
|
65
|
+
// natural phrasing: "order agent return", "return to deck"...).
|
|
66
|
+
// ("return fire" is exempt -- that's a shooting order, not a fold.)
|
|
67
|
+
if (entry.kind !== 'ally'
|
|
68
|
+
&& /^(return(?!\s+fire)|recall|come\s+(back|home)|fold|dismiss|stand\s+down|go\s+home)\b/i.test(cmd)) {
|
|
69
|
+
const foldLine = entry.kind === 'spirit'
|
|
70
|
+
? `${feed.icon} You speak the release. The spirit inclines its head -- the bargain closes${(entry.services ?? 0) > 0 ? `, ${entry.services} unspent service${entry.services === 1 ? '' : 's'} forfeit` : ''} -- and it thins back to its own plane.`
|
|
71
|
+
: entry.kind === 'drone'
|
|
72
|
+
? `${feed.icon} The ${entry.boundDevice?.name ?? entry.npc.name} banks once and settles back onto your hand, rotors folding.${entry.boundDevice && entry.boundDevice.droneDamage > 0 ? ` The airframe carries its dents (${entry.boundDevice.droneSummary()}) -- rest repairs it.` : ''}`
|
|
73
|
+
: this.actor.plane === 'matrix'
|
|
74
|
+
? `${feed.icon} Your agent's icon collapses back into your persona -- folded into the deck.`
|
|
75
|
+
: `${feed.icon} The deck spins its agent down -- the DECK IN AR light dies as the icon folds home.`;
|
|
76
|
+
game.dismissCompanion(entry, `ordered home: "${cmd}"`);
|
|
77
|
+
this.scene.updateStatus();
|
|
78
|
+
return `{${feed.color}-fg}${foldLine}{/${feed.color}-fg}`;
|
|
79
|
+
}
|
|
80
|
+
// Spirits bill non-combat tasks a service (combat bills per-fight in
|
|
81
|
+
// combat-exchange, so attack orders aren't double-charged). The
|
|
82
|
+
// CHARGE lands on the success paths below -- a refused order (AI-off
|
|
83
|
+
// directive, unknown target) costs nothing; a spent bargain refuses
|
|
84
|
+
// up front.
|
|
85
|
+
// Anywhere in the phrase, not just the start: "find Mr. Krow and
|
|
86
|
+
// kill him" is an attack order too -- a real session billed it as a
|
|
87
|
+
// task, then the fight's own per-fight charge found the bargain
|
|
88
|
+
// already at zero and dismissed the spirit mid-lunge.
|
|
89
|
+
const isAttackOrder = /\b(attack|kill|subdue|fight|slay|destroy)\b/i.test(cmd);
|
|
90
|
+
const billsService = entry.kind === 'spirit' && !isAttackOrder;
|
|
91
|
+
if (billsService && (entry.services ?? 0) <= 0) {
|
|
92
|
+
return `${entry.npc.name} regards you flatly. The bargain is spent -- no services remain.`;
|
|
93
|
+
}
|
|
94
|
+
const chargeService = () => {
|
|
95
|
+
if (!billsService)
|
|
96
|
+
return;
|
|
97
|
+
entry.services = (entry.services ?? 0) - 1;
|
|
98
|
+
// Resource arithmetic -- Mechanics ticker (readability pass).
|
|
99
|
+
this.logger.meta(`👥 One service spent (${entry.services} left).`, 'green');
|
|
100
|
+
};
|
|
101
|
+
// Tier 1 -- ATOMIC: a known command runs deterministically, no AI.
|
|
102
|
+
// A parsed command whose RESULT is a refusal is NOT obedience: a real
|
|
103
|
+
// session's "go kill Mr. Krow" parsed as go("kill"), answered "That
|
|
104
|
+
// is not a way to go" -- and billed a service for it; "kill Mr.
|
|
105
|
+
// Krow" with Krow two rooms off shrugged instead of hunting. Refused
|
|
106
|
+
// atomics cost nothing and escalate to the directive tier.
|
|
107
|
+
const direct = await entry.npc.tryRunCommand(cmd);
|
|
108
|
+
const atomicRefused = direct !== null && OrderCommand.ATOMIC_REFUSAL.test(direct);
|
|
109
|
+
if (direct !== null && !atomicRefused) {
|
|
110
|
+
chargeService();
|
|
111
|
+
this.scene.updateStatus();
|
|
112
|
+
const report = direct || `${entry.npc.name} moves to obey.`;
|
|
113
|
+
return `{${feed.color}-fg}${feed.icon} ${report}{/${feed.color}-fg}`;
|
|
114
|
+
}
|
|
115
|
+
// Tier 2 -- DIRECTIVE (player request: "order agent to find mr.
|
|
116
|
+
// krow"): not a command (or a refused one), a GOAL. Set it as the
|
|
117
|
+
// companion's standing objective (surfaced in every future prompt)
|
|
118
|
+
// and spur its AI now -- the reflect chain lets it move rooms,
|
|
119
|
+
// search, and act several steps on its own, then keep pursuing on
|
|
120
|
+
// later stimuli.
|
|
121
|
+
if (!AI.isConfigured()) {
|
|
122
|
+
if (direct !== null) {
|
|
123
|
+
// No AI to escalate to -- at least show the refusal, unbilled.
|
|
124
|
+
return `{${feed.color}-fg}${feed.icon} ${direct}{/${feed.color}-fg}`;
|
|
125
|
+
}
|
|
126
|
+
return `{${feed.color}-fg}${feed.icon} ${entry.npc.name} needs exact commands without an AI brain -- try "order ${entry.npc.name.toLowerCase()} go north" or "... attack <name>".{/${feed.color}-fg}`;
|
|
127
|
+
}
|
|
128
|
+
chargeService();
|
|
129
|
+
entry.npc.setObjective(`ORDERED by ${this.actor.name}: ${cmd}. Pursue this until done or countermanded.`);
|
|
130
|
+
// viaLink: the order rides the bond (deck/rigger/summoning), so it
|
|
131
|
+
// reaches the companion across rooms and planes -- a meat-side
|
|
132
|
+
// master in AR must still reach their agent on the grid.
|
|
133
|
+
void Promise.resolve(entry.npc.hear(this.actor, `${cmd} [System note: this is a direct ORDER from ${this.actor.name}, your master. Acknowledge in ONE short line in your own voice, then PURSUE it immediately with [COMMAND] actions -- move rooms ("go <direction>"), search, act; several steps now if needed. Keep pursuing it on future turns until it's done.]`, { viaLink: true })).catch(err => {
|
|
134
|
+
this.logger.error(`${entry.npc.name} failed to take the directive: ${err}`);
|
|
135
|
+
});
|
|
136
|
+
this.scene.updateStatus();
|
|
137
|
+
return `{${feed.color}-fg}${feed.icon} ${entry.npc.name} takes the directive -- "${cmd}" -- and moves on it.{/${feed.color}-fg}`;
|
|
138
|
+
}
|
|
139
|
+
/** Per-kind feed styling -- matches the HUD's plane color language. */
|
|
140
|
+
static FEED = {
|
|
141
|
+
spirit: { color: 'magenta', icon: '✧' },
|
|
142
|
+
drone: { color: 'yellow', icon: '✈' },
|
|
143
|
+
agent: { color: 'cyan', icon: '▣' },
|
|
144
|
+
ally: { color: 'white', icon: '👥' },
|
|
145
|
+
};
|
|
146
|
+
// Result strings that mean the atomic tier bounced -- collected from
|
|
147
|
+
// real refusals (go/attack/talk/take across sessions). The ’ variant
|
|
148
|
+
// covers commands that answer with a smart quote.
|
|
149
|
+
static ATOMIC_REFUSAL = /not a way to go|can['’]t go that way|isn['’]t here|don['’]t see|there is no item|too heavy|doesn['’]t know how|not valid|doesn['’]t seem to have/i;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=order.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/order.ts"],"names":[],"mappings":"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"}
|
|
@@ -28,7 +28,7 @@ export class PickCommand extends BypassCommand {
|
|
|
28
28
|
const pool = Math.max(1, this.actor.agility + (skill > 0 ? skill : -1) + this.actor.woundModifier - this.actor.sustainingPenalty);
|
|
29
29
|
const roll = rollPool(pool);
|
|
30
30
|
if (this.actor === this.scene.getPlayer()) {
|
|
31
|
-
this.logger.
|
|
31
|
+
this.logger.meta(`Locksmith: ${formatRoll(roll)} (2+ to open)`);
|
|
32
32
|
}
|
|
33
33
|
return roll.hits >= 2;
|
|
34
34
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pick.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/pick.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE5D,MAAM,OAAO,WAAY,SAAQ,aAAa;IAClC,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC;IACrB,MAAM,CAAC,WAAW,GAAG,uNAAuN,CAAC;IAC7O,UAAU,GAAqB,UAAU,CAAC;IAC1C,eAAe,GAAG,+BAA+B,CAAC;IAE5D,KAAK,CAAC,OAAO,CAAC,IAAc;QAC1B,sEAAsE;QACtE,qEAAqE;QACrE,gCAAgC;QAChC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,2DAA2D,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,IAAI,cAAc,6DAA6D,CAAC;QAC7K,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,+FAA+F,CAAC;QACzG,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;YACjC,OAAO,yFAAyF,CAAC;QACnG,CAAC;QACD,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAES,KAAK,CAAC,gBAAgB;QAC9B,uEAAuE;QACvE,uEAAuE;QACvE,kEAAkE;QAClE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAClI,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"pick.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/pick.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE5D,MAAM,OAAO,WAAY,SAAQ,aAAa;IAClC,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC;IACrB,MAAM,CAAC,WAAW,GAAG,uNAAuN,CAAC;IAC7O,UAAU,GAAqB,UAAU,CAAC;IAC1C,eAAe,GAAG,+BAA+B,CAAC;IAE5D,KAAK,CAAC,OAAO,CAAC,IAAc;QAC1B,sEAAsE;QACtE,qEAAqE;QACrE,gCAAgC;QAChC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,2DAA2D,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,IAAI,cAAc,6DAA6D,CAAC;QAC7K,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,+FAA+F,CAAC;QACzG,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;YACjC,OAAO,yFAAyF,CAAC;QACnG,CAAC;QACD,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAES,KAAK,CAAC,gBAAgB;QAC9B,uEAAuE;QACvE,uEAAuE;QACvE,kEAAkE;QAClE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAClI,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;IACxB,CAAC"}
|
|
@@ -15,8 +15,15 @@ export class SearchCommand extends Command {
|
|
|
15
15
|
const perception = this.actor.skillRating('perception');
|
|
16
16
|
const pool = Math.max(1, this.actor.intuition + (perception > 0 ? perception : -1) + this.actor.augBonus('perception') + this.actor.woundModifier - this.actor.sustainingPenalty);
|
|
17
17
|
const roll = rollPool(pool);
|
|
18
|
+
// Roll anatomy to the Mechanics ticker for the player; an NPC's
|
|
19
|
+
// return string is its AI history, so IT keeps the roll inline
|
|
20
|
+
// (readability pass).
|
|
21
|
+
const isPlayer = this.actor === this.scene.getPlayer();
|
|
22
|
+
if (isPlayer)
|
|
23
|
+
this.logger.meta(`Perception: ${formatRoll(roll)}`);
|
|
24
|
+
const rollPrefix = isPlayer ? '' : `Perception: ${formatRoll(roll)}\n`;
|
|
18
25
|
if (roll.hits === 0) {
|
|
19
|
-
let missed =
|
|
26
|
+
let missed = `${rollPrefix}You sweep the room and come up empty... you think.`;
|
|
20
27
|
for (const target of room.getPuzzleTargets()) {
|
|
21
28
|
const directionNote = target.direction ? ` (blocking the way ${target.direction})` : '';
|
|
22
29
|
missed += `\n\n${target.puzzle.riddle}${directionNote}`;
|
|
@@ -38,7 +45,7 @@ export class SearchCommand extends Command {
|
|
|
38
45
|
// (looking is free; taking still needs hands, see take.ts).
|
|
39
46
|
|| (this.actor.plane === 'drone' && i.plane === 'meat'))
|
|
40
47
|
.filter(i => !(i.plane === 'matrix' && room.hasNode && !hostReachable));
|
|
41
|
-
let description =
|
|
48
|
+
let description = rollPrefix;
|
|
42
49
|
if (found.length === 0) {
|
|
43
50
|
description += "You search the area thoroughly, but don't find any items.";
|
|
44
51
|
}
|
|
@@ -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,iBAAiB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE5D,MAAM,OAAO,aAAc,SAAQ,OAAO;IAC9B,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;IACvB,MAAM,CAAC,WAAW,GAAG,+BAA+B,CAAC;IAE/D,KAAK,CAAC,OAAO,CAAC,KAAe;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC;QAExC,oEAAoE;QACpE,qEAAqE;QACrE,oEAAoE;QACpE,sEAAsE;QACtE,qEAAqE;QACrE,6BAA6B;QAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAClL,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAE5B,
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Command, ICommand } from './command.js';
|
|
2
|
+
/**
|
|
3
|
+
* Conjuring (SR5e p.300-303): "summon <force>" calls a spirit -- an
|
|
4
|
+
* opposed Magic + conjuring test against the spirit's Force dice. NET
|
|
5
|
+
* hits become SERVICES (zero and the astral doesn't answer); the spirit
|
|
6
|
+
* materializes beside you as a companion shell (see Game.companions):
|
|
7
|
+
* it follows, it fights (one service per fight, ticked in
|
|
8
|
+
* combat-exchange), it obeys "order", and it departs when the bargain
|
|
9
|
+
* is spent, when dismissed ("summon" again), or when you travel (RAW:
|
|
10
|
+
* the summons doesn't outlast the ride). Drain is the summoner's toll:
|
|
11
|
+
* 2 x the spirit's hits, minimum 2 -- PHYSICAL when Force exceeds your
|
|
12
|
+
* Magic, same overcast law as spellcasting. Force past twice your Magic
|
|
13
|
+
* is refused: some bargains end the summoner.
|
|
14
|
+
*/
|
|
15
|
+
export declare class SummonCommand extends Command implements ICommand {
|
|
16
|
+
protected static verb: string;
|
|
17
|
+
protected static description: string;
|
|
18
|
+
execute(args?: string[]): Promise<string>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Command } from './command.js';
|
|
2
|
+
import { rollPool, formatRoll } from '../utilities/dice.js';
|
|
3
|
+
/**
|
|
4
|
+
* Conjuring (SR5e p.300-303): "summon <force>" calls a spirit -- an
|
|
5
|
+
* opposed Magic + conjuring test against the spirit's Force dice. NET
|
|
6
|
+
* hits become SERVICES (zero and the astral doesn't answer); the spirit
|
|
7
|
+
* materializes beside you as a companion shell (see Game.companions):
|
|
8
|
+
* it follows, it fights (one service per fight, ticked in
|
|
9
|
+
* combat-exchange), it obeys "order", and it departs when the bargain
|
|
10
|
+
* is spent, when dismissed ("summon" again), or when you travel (RAW:
|
|
11
|
+
* the summons doesn't outlast the ride). Drain is the summoner's toll:
|
|
12
|
+
* 2 x the spirit's hits, minimum 2 -- PHYSICAL when Force exceeds your
|
|
13
|
+
* Magic, same overcast law as spellcasting. Force past twice your Magic
|
|
14
|
+
* is refused: some bargains end the summoner.
|
|
15
|
+
*/
|
|
16
|
+
export class SummonCommand extends Command {
|
|
17
|
+
static verb = 'summon';
|
|
18
|
+
static description = 'Summon a spirit (Awakened casters): "summon <force>" -- Magic + conjuring vs its Force; net hits are its services. Drain 2x its hits (PHYSICAL past your Magic). "summon" again dismisses.';
|
|
19
|
+
async execute(args = []) {
|
|
20
|
+
const actor = this.actor;
|
|
21
|
+
const game = this.game;
|
|
22
|
+
// A standing spirit: bare "summon" (or any re-summon) releases it.
|
|
23
|
+
const standing = game?.companions.find(c => c.kind === 'spirit');
|
|
24
|
+
if (standing) {
|
|
25
|
+
game.dismissCompanion(standing, 'released by summoner');
|
|
26
|
+
this.scene.updateStatus();
|
|
27
|
+
return `You open the hand that held the binding. ${standing.npc.name} inclines its head and thins into nothing -- the bargain closed early, no offense taken.`;
|
|
28
|
+
}
|
|
29
|
+
if (!actor.isAwakened() || actor.adept) {
|
|
30
|
+
return actor.adept
|
|
31
|
+
? `Your magic flows inward -- the body, not the summons. Spirits answer magicians.`
|
|
32
|
+
: `The astral doesn't know your voice. Summoning takes the Awakened gift.`;
|
|
33
|
+
}
|
|
34
|
+
if (actor.plane === 'matrix' || actor.plane === 'drone') {
|
|
35
|
+
return `No spirit answers a machine. Come back to the flesh first.`;
|
|
36
|
+
}
|
|
37
|
+
if (actor.inExchange) {
|
|
38
|
+
return `The chant takes longer than the fight will give you.`;
|
|
39
|
+
}
|
|
40
|
+
const force = /^\d+$/.test(args[0] ?? '') ? parseInt(args[0], 10) : Math.max(1, actor.magic);
|
|
41
|
+
if (force < 1)
|
|
42
|
+
return `Force below 1 summons nothing but embarrassment.`;
|
|
43
|
+
if (force > actor.magic * 2) {
|
|
44
|
+
return `A Force ${force} spirit would wear YOU as the vessel -- twice your Magic (${actor.magic * 2}) is the hard ceiling.`;
|
|
45
|
+
}
|
|
46
|
+
const overcast = force > actor.magic;
|
|
47
|
+
// The opposed test (p.300): Magic + conjuring vs the spirit's Force.
|
|
48
|
+
const conjuring = actor.skillRating('conjuring');
|
|
49
|
+
const mine = rollPool(Math.max(1, actor.magic + (conjuring > 0 ? conjuring : -1) + actor.woundModifier - actor.sustainingPenalty));
|
|
50
|
+
const spirit = rollPool(force);
|
|
51
|
+
const services = Math.max(0, mine.hits - spirit.hits);
|
|
52
|
+
// Drain: 2x the SPIRIT's hits, min 2 (p.300), resisted with
|
|
53
|
+
// Willpower (+ Centering, p.325) -- physical when overcast.
|
|
54
|
+
const drainValue = Math.max(2, spirit.hits * 2);
|
|
55
|
+
const resist = rollPool(actor.willpower + (actor.hasMetamagic('centering') ? actor.initiationGrade : 0));
|
|
56
|
+
const drainTaken = Math.max(0, drainValue - resist.hits);
|
|
57
|
+
actor.performAction('chants a summoning', `the air pressure changing around them`);
|
|
58
|
+
this.scene.addWorldEvent(`${actor.name} performed a summoning in ${actor.currentLocation.name}.`);
|
|
59
|
+
this.logger.write(`SummonCommand: ${actor.name} force ${force} -- ${mine.hits} vs ${spirit.hits}, services ${services}, drain ${drainValue} (took ${drainTaken}${overcast ? ' physical' : ''}).`);
|
|
60
|
+
// Show the pool's anatomy -- a real session's summoner watched their
|
|
61
|
+
// dice shrink 10 -> 9 -> 8 across attempts with no hint that drain
|
|
62
|
+
// stun (wound modifiers) was the reason, and read it as a bug. The
|
|
63
|
+
// anatomy is Mechanics-ticker material (readability pass); the world
|
|
64
|
+
// keeps the call and what answers.
|
|
65
|
+
const poolParts = [`Magic ${actor.magic}`, conjuring > 0 ? `conjuring ${conjuring}` : `no conjuring -1`];
|
|
66
|
+
if (actor.woundModifier < 0)
|
|
67
|
+
poolParts.push(`wounds ${actor.woundModifier}`);
|
|
68
|
+
if (actor.sustainingPenalty > 0)
|
|
69
|
+
poolParts.push(`sustaining -${actor.sustainingPenalty}`);
|
|
70
|
+
this.logger.meta(`Summoning (${poolParts.join(', ')}): ${formatRoll(mine)}`);
|
|
71
|
+
this.logger.meta(` the spirit resists: ${formatRoll(spirit)}`);
|
|
72
|
+
const lines = [
|
|
73
|
+
`You reach into the astral and CALL, at Force ${force}${overcast ? ' (past your Magic -- the drain will be PHYSICAL)' : ''}:`,
|
|
74
|
+
];
|
|
75
|
+
if (services === 0) {
|
|
76
|
+
lines.push(` The astral considers you... and declines. Nothing crosses.`);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const shell = this.game?.spawnCompanionShell({
|
|
80
|
+
name: `Bound Spirit (Force ${force})`,
|
|
81
|
+
description: `A spirit ${actor.name} summoned and bound -- a shape of pressure and intent that reads wrong in every light. It serves until its ${services} service${services === 1 ? '' : 's'} are spent.`,
|
|
82
|
+
kind: 'spirit',
|
|
83
|
+
combat: { body: force, agility: force, reaction: force, strength: force, willpower: force, intuition: force, logic: 1, charisma: 1, magic: force, skills: { unarmed: Math.ceil(force / 2), perception: Math.ceil(force / 2) } },
|
|
84
|
+
room: actor.currentLocation,
|
|
85
|
+
plane: 'meat',
|
|
86
|
+
force,
|
|
87
|
+
services,
|
|
88
|
+
});
|
|
89
|
+
lines.push(shell
|
|
90
|
+
? ` Something crosses over and takes shape beside you -- materialized, patient, OWED. ${services} service${services === 1 ? '' : 's'} on the bargain. (It follows; it fights -- one service per fight; "order" it; "summon" again to release it.)`
|
|
91
|
+
: ` Something crosses -- and snags on a name already taken. The summons collapses.`);
|
|
92
|
+
}
|
|
93
|
+
this.logger.meta(`Drain (${drainValue}${overcast ? ', OVERCAST -- physical' : ''}): resist ${formatRoll(resist)}`);
|
|
94
|
+
if (drainTaken === 0) {
|
|
95
|
+
lines.push(` You shake the drain off.`);
|
|
96
|
+
}
|
|
97
|
+
else if (overcast) {
|
|
98
|
+
actor.takeDamage(drainTaken);
|
|
99
|
+
lines.push(` The binding tears something on the way through -- ${drainTaken} PHYSICAL: ${actor.conditionSummary()}`);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
const { stun, overflow } = actor.takeStun(drainTaken);
|
|
103
|
+
lines.push(` The drain bites -- ${stun} stun: ${actor.stunSummary()}`);
|
|
104
|
+
if (overflow > 0) {
|
|
105
|
+
lines.push(` It's more than your mind can hold -- ${overflow} box${overflow === 1 ? '' : 'es'} spill into your body: ${actor.conditionSummary()}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
this.scene.updateStatus();
|
|
109
|
+
return lines.join('\n');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=summon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summon.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/summon.ts"],"names":[],"mappings":"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"}
|
|
@@ -329,7 +329,7 @@ For EVERY npc in the skeleton, expand its "concept":
|
|
|
329
329
|
{ "body", "agility", "reaction", "combatSkill", "strength"?, "willpower"?, "logic"?,
|
|
330
330
|
"intuition"?, "charisma"?, "magic"?, "resonance"?, "adept"?,
|
|
331
331
|
"skills"?: { "firearms"?, "blades"?, "unarmed"?, "sneaking"?, "perception"?, "hacking"?,
|
|
332
|
-
"locksmith"?, "negotiation"?, "con"?, "intimidation"?, "assensing"? } }
|
|
332
|
+
"locksmith"?, "negotiation"?, "con"?, "intimidation"?, "assensing"?, "conjuring"? } }
|
|
333
333
|
"magic" 3-6 ONLY for a genuinely Awakened concept; "plane":"matrix" ice fights with
|
|
334
334
|
logic 4-7; give combat blocks to anyone the story expects in a firefight. "skills" is
|
|
335
335
|
optional flavor for defined concepts (a sharpshooter's "firearms": 6).
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import blessed from 'blessed';
|
|
2
2
|
import { ISceneSeedJson } from './types/seed/scene-seed.js';
|
|
3
|
+
import { Item } from './models/item.js';
|
|
3
4
|
import { Player, Inventory, Room, Scene } from './models/_index.js';
|
|
4
5
|
import { ILifestyleTier } from './utilities/commerce.js';
|
|
6
|
+
import { NPC } from './models/npc.js';
|
|
5
7
|
import { AutoFight } from './utilities/auto-fight.js';
|
|
6
8
|
import { IMainGameConfig } from './ui.js';
|
|
7
9
|
import { PlayerEquipment } from './types/player-equipment.js';
|
|
@@ -14,6 +16,7 @@ export default class Game {
|
|
|
14
16
|
autoFight: AutoFight;
|
|
15
17
|
private _screen;
|
|
16
18
|
private _logBox;
|
|
19
|
+
private _metaBox;
|
|
17
20
|
private _statusBox;
|
|
18
21
|
private _inputBox;
|
|
19
22
|
private _useAi;
|
|
@@ -47,6 +50,64 @@ export default class Game {
|
|
|
47
50
|
* spirits don't do noodles: non-meat actors stay off the roster.
|
|
48
51
|
*/
|
|
49
52
|
private seedHomeTurfContacts;
|
|
53
|
+
companions: {
|
|
54
|
+
npc: NPC;
|
|
55
|
+
kind: 'spirit' | 'agent' | 'drone' | 'ally';
|
|
56
|
+
services?: number;
|
|
57
|
+
force: number;
|
|
58
|
+
boundDevice?: Item;
|
|
59
|
+
}[];
|
|
60
|
+
private _pendingRedeploys;
|
|
61
|
+
/**
|
|
62
|
+
* The one correct runtime NPC spawn (mirrors scene-factory's seed
|
|
63
|
+
* path): construct with a scene-bound registry, add to the scene
|
|
64
|
+
* (names must be unique -- addActor throws), place via
|
|
65
|
+
* setCharacterLocation (the ONLY path that binds room observers), and
|
|
66
|
+
* hand it the scene for its AI context.
|
|
67
|
+
*/
|
|
68
|
+
spawnCompanionShell(opts: {
|
|
69
|
+
name: string;
|
|
70
|
+
description: string;
|
|
71
|
+
kind: 'spirit' | 'agent' | 'drone' | 'ally';
|
|
72
|
+
combat: Partial<import('./models/player.js').ICombatAttributes>;
|
|
73
|
+
room: Room;
|
|
74
|
+
plane: 'meat' | 'matrix' | 'astral';
|
|
75
|
+
force: number;
|
|
76
|
+
services?: number;
|
|
77
|
+
boundDevice?: Item;
|
|
78
|
+
}): NPC | null;
|
|
79
|
+
/**
|
|
80
|
+
* The autonomous-drone shell, shared by the deploy command and
|
|
81
|
+
* arrival re-shelling: the frame's dog-brain (Pilot = 2 + quality)
|
|
82
|
+
* stands in for every attribute it lacks (RAW p.269-271).
|
|
83
|
+
*/
|
|
84
|
+
private static readonly DRONE_CARGO_KG;
|
|
85
|
+
deployDroneShell(item: Item, room: Room): NPC | null;
|
|
86
|
+
/** Drops a companion's shell and its roster entry. */
|
|
87
|
+
dismissCompanion(entry: (typeof this.companions)[number], reason: string): void;
|
|
88
|
+
/**
|
|
89
|
+
* An actor left the world (Scene.removeActor). For a companion shell
|
|
90
|
+
* that DIED (not a deliberate dismissal -- those set deathClaimed
|
|
91
|
+
* first and prune themselves), settle the wreckage: a drone's frame is
|
|
92
|
+
* wrecked where it fell, an agent derezzes (the deck already ate the
|
|
93
|
+
* damage), a spirit is banished outright.
|
|
94
|
+
*/
|
|
95
|
+
onActorRemoved(name: string): void;
|
|
96
|
+
/**
|
|
97
|
+
* Spirits with no services left depart once no exchange holds them
|
|
98
|
+
* (called from CombatExchange.finishExchange): the bargain is spent.
|
|
99
|
+
*/
|
|
100
|
+
settleSpiritServices(): void;
|
|
101
|
+
private _pursuitTimer?;
|
|
102
|
+
private readonly _pursuitInFlight;
|
|
103
|
+
private static readonly PURSUIT_TICK_MS;
|
|
104
|
+
private startPursuitHeartbeat;
|
|
105
|
+
stopPursuitHeartbeat(): void;
|
|
106
|
+
spurCompanionPursuits(): void;
|
|
107
|
+
/** Pre-travel: every shell folds, each with its own goodbye. */
|
|
108
|
+
foldCompanionsForTravel(): string[];
|
|
109
|
+
/** Post-arrival: re-shell what was deployed when you left (drones). */
|
|
110
|
+
unfoldCompanionsOnArrival(): string[];
|
|
50
111
|
/**
|
|
51
112
|
* Records a real transaction with a hub NPC: first contact opens the
|
|
52
113
|
* relationship at Loyalty 1 (a safeguard -- the hub cast is pre-seeded
|
|
@@ -164,6 +225,7 @@ export default class Game {
|
|
|
164
225
|
*/
|
|
165
226
|
private connectHomeRoom;
|
|
166
227
|
get logBox(): blessed.Widgets.BoxElement;
|
|
228
|
+
get metaBox(): blessed.Widgets.BoxElement;
|
|
167
229
|
get inputBox(): blessed.Widgets.TextboxElement;
|
|
168
230
|
init(options: IMainGameConfig, screen: blessed.Widgets.Screen): Promise<string>;
|
|
169
231
|
/**
|
|
@@ -241,6 +303,25 @@ export default class Game {
|
|
|
241
303
|
close(): Promise<void>;
|
|
242
304
|
private initInputBox;
|
|
243
305
|
private initLogBox;
|
|
306
|
+
/**
|
|
307
|
+
* Scroll the log to its tail -- unless the player has paged up to read
|
|
308
|
+
* history (followBottom off), in which case their place is left alone.
|
|
309
|
+
* Every "new line arrived" site goes through here.
|
|
310
|
+
*/
|
|
311
|
+
followLog(): void;
|
|
312
|
+
/**
|
|
313
|
+
* The MECHANICS column (readability pass, player request: the log was
|
|
314
|
+
* a "wall of text"): dice anatomy and resource arithmetic land here
|
|
315
|
+
* (via Logger.meta) instead of the world log, so the narrative stays
|
|
316
|
+
* prose. A full-height COLUMN beside the world log, not a bottom
|
|
317
|
+
* strip -- the first playtest's 3-row ticker scrolled combat rolls
|
|
318
|
+
* away faster than they could be read. De-emphasis is the BLUE border
|
|
319
|
+
* -- gray is banned (ANSI bright-black, illegible on stock dark
|
|
320
|
+
* palettes). Follow-only (no keys); the full interleaved record lives
|
|
321
|
+
* in session.log. Roll lines wrap at the column width -- fine in a
|
|
322
|
+
* tall column. NO mouse (see initInputBox): never arm mouse tracking.
|
|
323
|
+
*/
|
|
324
|
+
private initMetaBox;
|
|
244
325
|
/**
|
|
245
326
|
* The HUD: a fixed strip between the log and the input box for the
|
|
246
327
|
* important real-time state -- condition tracks, armed/link status,
|