@maka/maka-cli 5.132.0 → 5.133.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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maka/maka-cli",
3
- "version": "5.132.0",
3
+ "version": "5.133.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.",
@@ -38,10 +38,23 @@ export class JumpCommand extends Command {
38
38
  // (utilities/owned-drones.ts): a frame parked at home jumps from
39
39
  // home and stays parked while you ride it.
40
40
  const owned = ownedDrones(actor, this.game?.homeRoom, { reach: 'here' });
41
- const drones = owned.map(d => d.item);
41
+ // ...AND EVERY DEPLOYED FRAME, WHEREVER IT FLIES (transcript
42
+ // 2026-09-06: a Direktionssekretar deployed from the garage could
43
+ // not be jumped into once the rigger left the hideout -- "Nothing
44
+ // to jump into -- no drone in your pack" -- while this verb's own
45
+ // description promised seizure "wherever it flies"). Jumping in
46
+ // rides the link, not your hands: the hands rule above is for
47
+ // frames still stowed; a frame already out is in reach by definition.
48
+ const deployed = (this.game?.companions ?? [])
49
+ .filter(c => c.kind === 'drone' && c.boundDevice && !owned.some(d => d.item === c.boundDevice));
50
+ const drones = [...owned.map(d => d.item), ...deployed.map(c => c.boundDevice)];
51
+ const listing = [
52
+ ...droneListLines(owned),
53
+ ...deployed.map(c => ` • ${c.boundDevice.name.padEnd(26)} deployed -- ${c.npc.currentLocation.name}${c.boundDevice.maxDroneBoxes > 0 ? ` hull ${c.boundDevice.droneSummary()}` : ''}`),
54
+ ];
42
55
  const atHome = this.game?.homeRoom !== undefined && actor.currentLocation === this.game.homeRoom;
43
56
  if (drones.length === 0) {
44
- return `Nothing to jump into -- no drone in your pack${atHome ? ' or your garage' : ''}.${hint(` (Ratchet's Circuit Bazaar stocks airframes.)`)}`;
57
+ return `Nothing to jump into -- no drone in your pack${atHome ? ' or your garage' : ''}, none deployed.${hint(` (Ratchet's Circuit Bazaar stocks airframes.)`)}`;
45
58
  }
46
59
  // "jump hot" / "jump <drone> hot": strip the mode word, pick the frame.
47
60
  const words = args.map(w => w.toLowerCase());
@@ -52,11 +65,11 @@ export class JumpCommand extends Command {
52
65
  const picked = fuzzyPickName(nameWords.join(' '), drones.map(d => d.name));
53
66
  drone = picked ? drones.find(d => d.name === picked) : undefined;
54
67
  if (!drone) {
55
- return [`No drone by that name in reach. Yours:`, ...droneListLines(owned)].join('\n');
68
+ return [`No drone by that name in reach. Yours:`, ...listing].join('\n');
56
69
  }
57
70
  }
58
71
  if (!drone) {
59
- return [`Which airframe? ("jump <name>", add "hot" for hot-sim)`, ...droneListLines(owned)].join('\n');
72
+ return [`Which airframe? ("jump <name>", add "hot" for hot-sim)`, ...listing].join('\n');
60
73
  }
61
74
  if (drone.isWrecked) {
62
75
  return `The ${drone.name} is a wreck -- ${droneWreckFragment(drone)} -- and a wreck jumps nowhere. It repairs while you rest somewhere safe.`;
@@ -7,7 +7,7 @@ import { Direction } from '../types/shared/direction-enum.js';
7
7
  import { Door } from '../models/door.js';
8
8
  import { fuzzyPickName } from '../utilities/fuzzy-match.js';
9
9
  import { heldBy, holding, physicalLimit } from '../utilities/grapple.js';
10
- import { spotsActive, resolveSpot, spotOf, describeSpotRoster, OPEN_FLOOR, pathBetweenSpots, spotDistanceMeters, spotClimbSteps, blockingRegion, terrainRefusal, reseatOpenFloor, routeForMove, stepFrom, spotForCell, actorCell, standingRoomNear, furnitureCells, approachCellFor, exitSpot, concealedFrom, revealActor, onTheFloor } from '../utilities/spots.js';
10
+ import { spotsActive, resolveSpot, spotOf, describeSpotRoster, OPEN_FLOOR, pathBetweenSpots, spotDistanceMeters, spotClimbSteps, blockingRegion, terrainRefusal, reseatOpenFloor, routeForMove, stepFrom, spotForCell, actorCell, standingRoomNear, yieldSquareToMaster, furnitureCells, approachCellFor, exitSpot, concealedFrom, revealActor, onTheFloor } from '../utilities/spots.js';
11
11
  // fallDamageDVMeters, not fallDamageDV: a climb that fell short drops
12
12
  // you from where you GOT to, which is a distance in metres, not a whole
13
13
  // storey. The storey-based wrapper still exists for callers that really
@@ -759,6 +759,8 @@ export class MoveCommand extends Command {
759
759
  const wasAt = actor.atSpot;
760
760
  actor.atCell = cell;
761
761
  actor.atSpot = spotForCell(room, cell);
762
+ // A shell of yours on that square steps aside (spots.ts heelsTo).
763
+ yieldSquareToMaster(room, actor);
762
764
  actor.performAction('steps', `${taken} ${taken === 1 ? 'pace' : 'paces'} ${direction}`);
763
765
  this.scene.updateStatus();
764
766
  this.scene.updateExits(room);
@@ -345,5 +345,13 @@
345
345
  // while "order <drone> fold/stow" packs. A frame you jump out of HOLDS
346
346
  // its position (Game.companions.holding) instead of teleporting to your
347
347
  // heel on your next step; recall clears the hold. HUD shows "holding at".
348
- export const ENGINE_VERSION = '1.37.0';
348
+ // 1.38.0 (2026-09-06): YOUR OWN SHELL IS NEVER IN YOUR WAY. COMMAND SEMANTICS
349
+ // in shared scenes: a companion shell (drone, spirit, sprite, agent) at its
350
+ // master's heel no longer blocks the master's "move <direction>" -- it
351
+ // yields the square (spots.ts heelsTo / yieldSquareToMaster); hired crew
352
+ // still hold theirs. "jump" reaches every DEPLOYED frame wherever it flies,
353
+ // garage-born or not (it used to answer "no drone in your pack" away from
354
+ // the hideout). An NPC with no dialogue and no AI no longer greets you
355
+ // with "<name>: undefined".
356
+ export const ENGINE_VERSION = '1.38.0';
349
357
  //# sourceMappingURL=engine-version.js.map
@@ -1546,7 +1546,13 @@ ${worldEventsSummary}
1546
1546
  this._triedThisStimulus = [];
1547
1547
  if (!AI.isConfigured()) {
1548
1548
  this.logger.write(`No AI available`);
1549
- await actor.hear(this, this.speak());
1549
+ // A shell with no dialogue -- every companion is built with
1550
+ // `dialog: []` -- has nothing to say, and used to say so as
1551
+ // "<name>: undefined" (transcript 2026-09-06: a drone waking as
1552
+ // its rigger walked in). Silence is the right line.
1553
+ const line = this.speak();
1554
+ if (line)
1555
+ await actor.hear(this, line);
1550
1556
  return;
1551
1557
  }
1552
1558
  // ---------- helpers ----------
@@ -2679,6 +2679,10 @@ export class Player extends AbstractPlayer {
2679
2679
  const overLink = opts?.viaLink || this.activeCallPartner === actor;
2680
2680
  if (!overLink && !this.canPerceive(actor))
2681
2681
  return;
2682
+ // Nothing said is nothing heard: a caller passing an empty line
2683
+ // (an NPC with no dialogue, AI off) must not print "<name>: undefined".
2684
+ if (!message)
2685
+ return;
2682
2686
  this.logger.write(`${this.name} heard ${actor.name}`);
2683
2687
  // A voice arriving over an active CALL from someone who isn't in the
2684
2688
  // room wears the comm dressing (player note: Mr. Johnson -- who lives
@@ -858,6 +858,15 @@ export function standingOccupants(room, mover) {
858
858
  const offPlane = new Set(room.getActors()
859
859
  .filter(a => !onTheFloor(a) && a.bodyRoom !== room)
860
860
  .map(a => a.name));
861
+ // YOUR OWN SHELL IS NEVER IN YOUR WAY (transcript 2026-09-06: a drone
862
+ // at heel sat on its master's next square -- "You can't step east --
863
+ // S-K Direktionssekretar (autopilot)'s in the way", a dozen times --
864
+ // and read as the frame refusing to follow). A companion shell heels
865
+ // AT its master's spot by construction (go.ts), so of course it is
866
+ // standing where the master wants to go next; it yields instead
867
+ // (yieldSquareToMaster, called by the step). Hired crew are people
868
+ // (ruling 2026-08-25) and still hold their square.
869
+ const heels = new Set(mover ? room.getActors().filter(a => heelsTo(a, mover)).map(a => a.name) : []);
861
870
  for (const [name, c] of seatingIn(room).entries()) {
862
871
  if (mover && name === mover.name)
863
872
  continue;
@@ -865,10 +874,40 @@ export function standingOccupants(room, mover) {
865
874
  continue;
866
875
  if (offPlane.has(name))
867
876
  continue;
877
+ if (heels.has(name))
878
+ continue;
868
879
  out.set(key(c), name);
869
880
  }
870
881
  return out;
871
882
  }
883
+ /** Is `a` a companion SHELL of `master` -- a drone, spirit, sprite or
884
+ * agent riding their bond? Hired crew (kind 'ally') are people and
885
+ * answer no. */
886
+ export function heelsTo(a, master) {
887
+ const shell = a;
888
+ return shell.allyOf === master.name && shell.companionKind !== undefined && shell.companionKind !== 'ally';
889
+ }
890
+ /**
891
+ * After `master` steps onto a square one of their own shells was
892
+ * holding, the shell gives it up: its cell is released so seatingIn
893
+ * finds it the nearest free square at the master's spot. Returns the
894
+ * shells that moved. */
895
+ export function yieldSquareToMaster(room, master) {
896
+ const here = master.atCell ? key(master.atCell) : undefined;
897
+ if (!here)
898
+ return [];
899
+ const moved = [];
900
+ for (const a of room.getActors()) {
901
+ if (!heelsTo(a, master))
902
+ continue;
903
+ if (!a.atCell || key(a.atCell) !== here)
904
+ continue;
905
+ a.atCell = undefined;
906
+ a.atSpot = master.atSpot;
907
+ moved.push(a);
908
+ }
909
+ return moved;
910
+ }
872
911
  /** The cell `mover` would end up in on arriving at `spotName` -- their
873
912
  * seat around that fixture, with everyone else's seats already taken.
874
913
  * This, not the fixture's anchor, is where movement actually paths to:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maka/maka-cli",
3
- "version": "5.132.0",
3
+ "version": "5.133.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.",