@adatechnology/game-test-room 0.15.0 → 0.16.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/dist/index.js CHANGED
@@ -110,7 +110,7 @@ function resolveScenery(scenery) {
110
110
  if (!position) throw new Error(`game-test-room: scenery "${id}" is new, so it needs a position`);
111
111
  merged.set(id, { ...obj, position });
112
112
  }
113
- return [...merged.entries()].map(([id, o]) => ({ id, spec: o.spec, position: o.position, rotationY: o.rotationY ?? 0, colors: o.colors, build: o.build, label: o.label, top: o.top, spout: o.spout }));
113
+ return [...merged.entries()].map(([id, o]) => ({ id, spec: o.spec, position: o.position, rotationY: o.rotationY ?? 0, colors: o.colors, build: o.build, follow: o.follow, label: o.label, top: o.top, spout: o.spout, free: o.free }));
114
114
  }
115
115
  function createArena(THREE, size, scene, scenery, tapOption) {
116
116
  const group = markKitOrigin(new THREE.Group(), { owner: "game-test-room", kind: "room" });
@@ -2346,6 +2346,9 @@ var en = {
2346
2346
  "act.strike.leg": "{weapon}: {clip} with the {leg} leg begins, impact in {seconds} s",
2347
2347
  "leg.left": "left",
2348
2348
  "leg.right": "right",
2349
+ "act.strike.hand": "{weapon}: {clip} with the {hand} hand begins, impact in {seconds} s",
2350
+ "hand.left": "left",
2351
+ "hand.right": "right",
2349
2352
  "act.flame.hit": "{weapon}: flame at {temp} \xB0C on {where}",
2350
2353
  "act.flame.air": "{weapon}: flame, nothing in range",
2351
2354
  "act.heat.hit": "{weapon}: heating {where} at {temp} \xB0C",
@@ -2377,6 +2380,7 @@ var en = {
2377
2380
  "loading.open_area": "Opening {area}\u2026",
2378
2381
  "loading.spawn": "Building {name}\u2026",
2379
2382
  "act.loosened": "{name} was heavy but free: the blast moved it",
2383
+ "act.shoved": "{name} stands free: the shots moved it",
2380
2384
  "act.impact": "{name} hit {where} at {speed} m/s: {energy} J of blunt damage",
2381
2385
  "act.use_item": "{name}: {use}",
2382
2386
  "act.tap.on": "Tap opened",
@@ -2653,6 +2657,9 @@ var ptBR = {
2653
2657
  "act.strike.leg": "{weapon}: {clip} com a perna {leg} come\xE7a, impacto em {seconds} s",
2654
2658
  "leg.left": "esquerda",
2655
2659
  "leg.right": "direita",
2660
+ "act.strike.hand": "{weapon}: {clip} com a m\xE3o {hand} come\xE7a, impacto em {seconds} s",
2661
+ "hand.left": "esquerda",
2662
+ "hand.right": "direita",
2656
2663
  "act.flame.hit": "{weapon}: chama a {temp} \xB0C em {where}",
2657
2664
  "act.flame.air": "{weapon}: chama, nada ao alcance",
2658
2665
  "act.heat.hit": "{weapon}: esquentando {where} a {temp} \xB0C",
@@ -2684,6 +2691,7 @@ var ptBR = {
2684
2691
  "loading.open_area": "Abrindo {area}\u2026",
2685
2692
  "loading.spawn": "Montando {name}\u2026",
2686
2693
  "act.loosened": "{name} \xE9 pesado mas estava solto: a explos\xE3o o moveu",
2694
+ "act.shoved": "{name} estava solto no ch\xE3o: os tiros o moveram",
2687
2695
  "act.impact": "{name} bateu em {where} a {speed} m/s: {energy} J de dano de impacto",
2688
2696
  "act.use_item": "{name}: {use}",
2689
2697
  "act.tap.on": "Abriu a torneira",
@@ -3147,7 +3155,7 @@ function createTestTablePanel(table, t) {
3147
3155
  relay.type = "button";
3148
3156
  relay.onclick = () => table.relay();
3149
3157
  trials.appendChild(relay);
3150
- element.append(head, search, found, sub, list, trials);
3158
+ element.append(head, search, found, sub, trials, list);
3151
3159
  const groups = () => {
3152
3160
  const keep = select.value;
3153
3161
  select.textContent = "";
@@ -3794,6 +3802,7 @@ function createUi(o) {
3794
3802
 
3795
3803
  // src/room.ts
3796
3804
  var FIXED_DT = 1 / 60;
3805
+ var SHOVE_SPEED = 0.04;
3797
3806
  var METRICS_INTERVAL_S = 0.25;
3798
3807
  var CARRY_NEAR = 0.62;
3799
3808
  var CARRY_PALM = 0.012;
@@ -4156,7 +4165,9 @@ function createTestRoom(options) {
4156
4165
  scene.add(root);
4157
4166
  root.updateMatrixWorld(true);
4158
4167
  world.add(structuredCloneSpec(o.spec), { id: o.id, position: o.position, ...o.rotationY ? { rotation: [0, Math.sin(o.rotationY / 2), 0, Math.cos(o.rotationY / 2)] } : {} });
4159
- registerEntry(o.id, o.id, root, o.spec, o.label ?? S.text[`arena.${o.id}`] ?? o.id, void 0, void 0, true, false);
4168
+ const e = registerEntry(o.id, o.id, root, o.spec, o.label ?? S.text[`arena.${o.id}`] ?? o.id, void 0, void 0, true, false);
4169
+ if (o.free) e.free = true;
4170
+ e.follower = o.follow?.(root, world, o.id) || null;
4160
4171
  }
4161
4172
  };
4162
4173
  addArena();
@@ -4251,6 +4262,7 @@ function createTestRoom(options) {
4251
4262
  renderer.unbind(id);
4252
4263
  } catch {
4253
4264
  }
4265
+ e.follower?.dispose?.();
4254
4266
  if (world.has(id)) world.remove(id);
4255
4267
  e.so.root.removeFromParent();
4256
4268
  letGo(e.so.root);
@@ -4285,6 +4297,7 @@ function createTestRoom(options) {
4285
4297
  for (const e of entries.values()) {
4286
4298
  world.reset(e.so.objectId);
4287
4299
  renderer.restore(e.so.objectId);
4300
+ e.follower?.restore?.();
4288
4301
  }
4289
4302
  renderer.clear();
4290
4303
  vfx.world.clear();
@@ -4306,6 +4319,7 @@ function createTestRoom(options) {
4306
4319
  if (heldEntry === e) continue;
4307
4320
  world.reset(e.so.objectId);
4308
4321
  renderer.restore(e.so.objectId);
4322
+ e.follower?.restore?.();
4309
4323
  if (e.containerId) {
4310
4324
  const c = fluids.container(e.containerId);
4311
4325
  const f = e.item?.fluid?.container;
@@ -4609,6 +4623,19 @@ function createTestRoom(options) {
4609
4623
  if (!rendererPieces.has(objectId)) return;
4610
4624
  renderer.impulse(objectId, [dir[0] * momentum, dir[1] * momentum, dir[2] * momentum], point);
4611
4625
  };
4626
+ const shoveFree = (pushes) => {
4627
+ for (const [objectId, push] of pushes) {
4628
+ const e = entries.get(objectId);
4629
+ if (!e || e.piece || !e.free) continue;
4630
+ const mass = Math.max(0.2, massOfObject(objectId));
4631
+ if (Math.hypot(...push.impulse) / mass < SHOVE_SPEED) continue;
4632
+ const piece = renderer.makePiece(objectId, { mass });
4633
+ e.piece = piece;
4634
+ rendererPieces.set(objectId, piece);
4635
+ action("loosened", t("act.shoved", { name: e.name }), { objectId, itemId: e.so.itemId });
4636
+ renderer.impulse(objectId, push.impulse, push.point);
4637
+ }
4638
+ };
4612
4639
  const fireShots = (shots, recoil) => {
4613
4640
  if (shots.length === 0) return;
4614
4641
  const w = toolName();
@@ -4618,6 +4645,7 @@ function createTestRoom(options) {
4618
4645
  let hits = 0;
4619
4646
  let first = null;
4620
4647
  let energy = 0;
4648
+ const pushes = /* @__PURE__ */ new Map();
4621
4649
  withoutHeld(() => {
4622
4650
  for (const s of shots) {
4623
4651
  energy = Math.max(energy, s.energy);
@@ -4629,11 +4657,16 @@ function createTestRoom(options) {
4629
4657
  end = r0.point;
4630
4658
  if (!first) first = { object: r0.object, part: r0.part, point: r0.point, normal: [0, 1, 0], distance: dist3(s.origin, r0.point) };
4631
4659
  const speed = Math.max(80, s.speed);
4632
- pushPiece(r0.object, s.direction, 2 * s.energy / speed, r0.point);
4660
+ const momentum = 2 * s.energy / speed;
4661
+ pushPiece(r0.object, s.direction, momentum, r0.point);
4662
+ const push = pushes.get(r0.object) ?? { impulse: [0, 0, 0], point: r0.point };
4663
+ for (let k = 0; k < 3; k++) push.impulse[k] += s.direction[k] * momentum;
4664
+ pushes.set(r0.object, push);
4633
4665
  }
4634
4666
  if (shots.length <= 3 || rnd() < 0.34) tracer(m, end);
4635
4667
  }
4636
4668
  });
4669
+ shoveFree(pushes);
4637
4670
  player.kick(recoil[0], recoil[1]);
4638
4671
  const f = first;
4639
4672
  const d = f ? num(f.distance, 1) : "";
@@ -4725,16 +4758,25 @@ function createTestRoom(options) {
4725
4758
  let strikes = [];
4726
4759
  const kickLeg = options.kickLeg ?? "alternate";
4727
4760
  let nextLeg = "right";
4761
+ const punchHand = options.punchHand ?? "alternate";
4762
+ const punchTools = new Set(options.punchTools ?? ["hand", "fists"]);
4763
+ let nextHand = "right";
4728
4764
  const strikeUse = (u, id = toolId) => {
4729
4765
  const clip = strikeClips[id];
4730
4766
  const leg = id === "kick" ? kickLeg === "alternate" ? nextLeg : kickLeg : void 0;
4731
- const seconds = clip === void 0 ? null : avatar?.strike?.(clip, leg ? { leg } : void 0) ?? null;
4767
+ const hand = punchTools.has(id) ? punchHand === "alternate" ? nextHand : punchHand : void 0;
4768
+ const side = leg ? { leg } : hand ? { hand } : void 0;
4769
+ const seconds = clip === void 0 ? null : avatar?.strike?.(clip, side) ?? null;
4732
4770
  if (leg && seconds !== null && kickLeg === "alternate") nextLeg = leg === "right" ? "left" : "right";
4771
+ if (hand && seconds !== null && punchHand === "alternate") nextHand = hand === "right" ? "left" : "right";
4733
4772
  if (clip === void 0 || seconds === null) {
4734
4773
  meleeUse(u, id);
4735
4774
  return;
4736
4775
  }
4737
- action("strike", t(leg ? "act.strike.leg" : "act.strike", { weapon: toolName(id), clip, seconds: num(seconds, 2), leg: leg ? t(`leg.${leg}`) : "" }), { data: { weapon: id, clip, impactIn: seconds, ...leg ? { leg } : {} } });
4776
+ const text = leg ? "act.strike.leg" : hand ? "act.strike.hand" : "act.strike";
4777
+ action("strike", t(text, { weapon: toolName(id), clip, seconds: num(seconds, 2), leg: leg ? t(`leg.${leg}`) : "", hand: hand ? t(`hand.${hand}`) : "" }), {
4778
+ data: { weapon: id, clip, impactIn: seconds, ...leg ? { leg } : {}, ...hand ? { hand } : {} }
4779
+ });
4738
4780
  strikes.push({
4739
4781
  key: id,
4740
4782
  remaining: seconds,