@maka/maka-cli 5.133.0 → 5.134.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/move.js +14 -0
- package/bundle/typescript/src/commands/game/sideQuest/engine-version.js +7 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/companion-heel.js +67 -9
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maka/maka-cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.134.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"summary": "A command line tool for scaffolding Meteor 3.x applications using either React.",
|
|
6
6
|
"description": "A command line tool for scaffolding Meteor 3.x applications using React.",
|
|
@@ -14,6 +14,7 @@ import { spotsActive, resolveSpot, spotOf, describeSpotRoster, OPEN_FLOOR, pathB
|
|
|
14
14
|
// do fall a level.
|
|
15
15
|
import { fallDamageDVMeters, climbHitsFor, climbMetersFrom, climbSurfaceModifier, METERS_PER_CELL, METERS_PER_LEVEL, key, distanceMeters } from '../utilities/room-grid.js';
|
|
16
16
|
import { rollPool, formatRoll } from '../utilities/dice.js';
|
|
17
|
+
import { trailMaster } from '../utilities/companion-heel.js';
|
|
17
18
|
/**
|
|
18
19
|
* "walk to <spot>" / "run to <spot>" / "sprint to <spot>" -- crossing
|
|
19
20
|
* the CURRENT room to one of its "at" spots (see utilities/spots.ts;
|
|
@@ -101,6 +102,15 @@ export class MoveCommand extends Command {
|
|
|
101
102
|
}
|
|
102
103
|
return `Spots are a meat-world concern -- on the grid there is no distance at all, so "go <room>" puts your persona anywhere by name.`;
|
|
103
104
|
}
|
|
105
|
+
/** Your shells trail you across the room (companion-heel.ts
|
|
106
|
+
* trailMaster): after every in-room move they re-place themselves
|
|
107
|
+
* beside you. An NPC mover has no Game in its context and drags
|
|
108
|
+
* nobody. */
|
|
109
|
+
trailCompanions() {
|
|
110
|
+
if (!this.game)
|
|
111
|
+
return;
|
|
112
|
+
trailMaster(this.actor, this.game.companions);
|
|
113
|
+
}
|
|
104
114
|
async execute(args = []) {
|
|
105
115
|
const actor = this.actor;
|
|
106
116
|
const room = actor.currentLocation;
|
|
@@ -633,6 +643,7 @@ export class MoveCommand extends Command {
|
|
|
633
643
|
// an NPC's own spot is a social event for them (the bartender greets
|
|
634
644
|
// you when you reach the bar).
|
|
635
645
|
actor.performAction('moves to', `the ${spot.name}`);
|
|
646
|
+
this.trailCompanions();
|
|
636
647
|
this.logger.write(`MoveCommand: ${actor.name} ${this.mode()}s to ${spot.name} in ${room.name}.`);
|
|
637
648
|
// Companions drift along with their master (go.ts follow precedent).
|
|
638
649
|
if (actor === this.scene.getPlayer() && this.game) {
|
|
@@ -762,6 +773,7 @@ export class MoveCommand extends Command {
|
|
|
762
773
|
// A shell of yours on that square steps aside (spots.ts heelsTo).
|
|
763
774
|
yieldSquareToMaster(room, actor);
|
|
764
775
|
actor.performAction('steps', `${taken} ${taken === 1 ? 'pace' : 'paces'} ${direction}`);
|
|
776
|
+
this.trailCompanions();
|
|
765
777
|
this.scene.updateStatus();
|
|
766
778
|
this.scene.updateExits(room);
|
|
767
779
|
// QUIET STEPS (user, 2026-09-01: "You step 1 pace east" is spammy now
|
|
@@ -867,6 +879,7 @@ export class MoveCommand extends Command {
|
|
|
867
879
|
actor.atCell = cell;
|
|
868
880
|
actor.atSpot = spotForCell(room, cell);
|
|
869
881
|
actor.performAction('steps up beside', target.name);
|
|
882
|
+
this.trailCompanions();
|
|
870
883
|
this.scene.updateStatus();
|
|
871
884
|
this.scene.updateExits(room);
|
|
872
885
|
const pace = actor.isRunningThisTurn ? ` You're running now -- everything else this turn is at -2.` : '';
|
|
@@ -1016,6 +1029,7 @@ export class MoveCommand extends Command {
|
|
|
1016
1029
|
actor.atCell = cell;
|
|
1017
1030
|
actor.atSpot = spotForCell(room, cell);
|
|
1018
1031
|
actor.performAction('moves to', `the ${direction} doorway`);
|
|
1032
|
+
this.trailCompanions();
|
|
1019
1033
|
this.scene.updateStatus();
|
|
1020
1034
|
this.scene.updateExits(room);
|
|
1021
1035
|
return `You cross to the ${direction} way out.${hint(` ("go ${direction}" to step through.)`)}`;
|
|
@@ -353,5 +353,11 @@
|
|
|
353
353
|
// garage-born or not (it used to answer "no drone in your pack" away from
|
|
354
354
|
// the hideout). An NPC with no dialogue and no AI no longer greets you
|
|
355
355
|
// with "<name>: undefined".
|
|
356
|
-
|
|
356
|
+
// 1.39.0 (2026-09-06): COMPANIONS TRAIL YOU ACROSS THE ROOM. COMMAND SEMANTICS
|
|
357
|
+
// in shared scenes: every in-room move ("move <direction>", "move to
|
|
358
|
+
// <spot>", the doorway) re-places your shells on the nearest free square
|
|
359
|
+
// beside you (companion-heel.ts trailMaster) -- they used to heel only on
|
|
360
|
+
// a room change and sat in the doorway while you paced. "recall" judges
|
|
361
|
+
// "already at your side" by cells, not spot names.
|
|
362
|
+
export const ENGINE_VERSION = '1.39.0';
|
|
357
363
|
//# sourceMappingURL=engine-version.js.map
|
|
@@ -1,22 +1,80 @@
|
|
|
1
|
+
import { actorCell, standingRoomNear, onTheFloor, heelsTo } from './spots.js';
|
|
2
|
+
/** Chebyshev distance in cells, or undefined when either has no cell. */
|
|
3
|
+
function cellGap(room, a, b) {
|
|
4
|
+
const ca = actorCell(room, a);
|
|
5
|
+
const cb = actorCell(room, b);
|
|
6
|
+
if (!ca || !cb)
|
|
7
|
+
return undefined;
|
|
8
|
+
return Math.max(Math.abs(ca.x - cb.x), Math.abs(ca.y - cb.y), Math.abs(ca.z - cb.z));
|
|
9
|
+
}
|
|
10
|
+
/** Is the shell beside its master -- same room, same spot, and at most
|
|
11
|
+
* one square away (or on a room with no grid to measure)? */
|
|
12
|
+
export function atMastersSide(entry, master) {
|
|
13
|
+
const room = master.currentLocation;
|
|
14
|
+
if (entry.npc.currentLocation !== room || entry.npc.atSpot !== master.atSpot)
|
|
15
|
+
return false;
|
|
16
|
+
const gap = cellGap(room, entry.npc, master);
|
|
17
|
+
return gap === undefined || gap <= 1;
|
|
18
|
+
}
|
|
19
|
+
/** Put the shell on the nearest free square beside its master, at the
|
|
20
|
+
* master's spot. */
|
|
21
|
+
export function placeBeside(entry, master) {
|
|
22
|
+
const room = master.currentLocation;
|
|
23
|
+
if (entry.npc.currentLocation !== room)
|
|
24
|
+
entry.npc.currentLocation = room;
|
|
25
|
+
entry.npc.atSpot = master.atSpot;
|
|
26
|
+
const here = actorCell(room, master);
|
|
27
|
+
entry.npc.atCell = here ? standingRoomNear(room, here, entry.npc) : undefined;
|
|
28
|
+
}
|
|
1
29
|
/**
|
|
2
30
|
* BRING A COMPANION TO HEEL (player ruling 2026-09-06: "recall" is
|
|
3
31
|
* "return to me" -- the frame comes to your side and follows again;
|
|
4
32
|
* putting it away is "stow"). The shell crosses to the master's room
|
|
5
|
-
* and spot,
|
|
6
|
-
*
|
|
7
|
-
*
|
|
33
|
+
* and spot, takes the nearest free square beside them, and any HOLDING
|
|
34
|
+
* flag clears so the next move drags it along like any companion.
|
|
35
|
+
* Returns whether it had anywhere to come from -- judged by CELLS, not
|
|
36
|
+
* spot names: a frame eight squares off on the same open floor shares
|
|
37
|
+
* the spot name and is not "at your side" (transcript 2026-09-06).
|
|
8
38
|
*
|
|
9
39
|
* One function, used by Game.heelCompanion and by the tests that pin
|
|
10
40
|
* recall, so a mock Game and the real one cannot disagree about it.
|
|
11
41
|
*/
|
|
12
42
|
export function bringToHeel(entry, master) {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
if (entry.npc.currentLocation !== here)
|
|
16
|
-
entry.npc.currentLocation = here;
|
|
17
|
-
entry.npc.atSpot = master.atSpot;
|
|
18
|
-
entry.npc.atCell = undefined;
|
|
43
|
+
const moved = !!entry.holding || !atMastersSide(entry, master);
|
|
44
|
+
placeBeside(entry, master);
|
|
19
45
|
entry.holding = false;
|
|
20
46
|
return { moved };
|
|
21
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* COMPANIONS TRAIL THEIR MASTER ACROSS THE ROOM (playtest 2026-09-06:
|
|
50
|
+
* "It will follow to another room, but then just sit at the door").
|
|
51
|
+
* go.ts heels every shell on a ROOM change; nothing did on an in-room
|
|
52
|
+
* move, so a rigger who paced eight squares across the Neon Strip left
|
|
53
|
+
* the frame parked in the doorway. Called after every successful
|
|
54
|
+
* in-room move (move.ts): each shell of the mover's that is on the
|
|
55
|
+
* floor here, not HOLDING and not hired crew, is re-placed beside them.
|
|
56
|
+
* The frame answers to the meat body only (go.ts HEELS_ON): a rigger
|
|
57
|
+
* flying one frame does not drag the others around.
|
|
58
|
+
*/
|
|
59
|
+
export function trailMaster(master, entries) {
|
|
60
|
+
if (master.plane !== 'meat')
|
|
61
|
+
return [];
|
|
62
|
+
const room = master.currentLocation;
|
|
63
|
+
const moved = [];
|
|
64
|
+
for (const entry of entries) {
|
|
65
|
+
if (entry.holding || entry.kind === 'ally')
|
|
66
|
+
continue;
|
|
67
|
+
if (!heelsTo(entry.npc, master))
|
|
68
|
+
continue;
|
|
69
|
+
if (entry.npc.currentLocation !== room || !onTheFloor(entry.npc))
|
|
70
|
+
continue;
|
|
71
|
+
if (entry.npc.isIncapacitated() || entry.npc.inExchange)
|
|
72
|
+
continue;
|
|
73
|
+
if (atMastersSide(entry, master))
|
|
74
|
+
continue;
|
|
75
|
+
placeBeside(entry, master);
|
|
76
|
+
moved.push(entry.npc);
|
|
77
|
+
}
|
|
78
|
+
return moved;
|
|
79
|
+
}
|
|
22
80
|
//# sourceMappingURL=companion-heel.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maka/maka-cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.134.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"summary": "A command line tool for scaffolding Meteor 3.x applications using either React.",
|
|
6
6
|
"description": "A command line tool for scaffolding Meteor 3.x applications using React.",
|