@adatechnology/game-test-room 0.14.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/README.md +17 -1
- package/dist/index.d.ts +179 -17
- package/dist/index.global.js +813 -146
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +552 -96
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
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" });
|
|
@@ -471,7 +471,7 @@ function buildFromSpec(THREE, spec, options = {}) {
|
|
|
471
471
|
}
|
|
472
472
|
|
|
473
473
|
// src/explosives.ts
|
|
474
|
-
import { backblastEffect, blastEffect, createExplosiveBody, tripwireSegment } from "@adatechnology/game-weapons";
|
|
474
|
+
import { ExplosiveBody, backblastEffect, blastEffect, createExplosiveBody, tripwireSegment } from "@adatechnology/game-weapons";
|
|
475
475
|
|
|
476
476
|
// src/segment-box.ts
|
|
477
477
|
var segmentTouchesBox = (from, to, min, max) => {
|
|
@@ -714,6 +714,14 @@ function createExplosives(context) {
|
|
|
714
714
|
...projectile.fire ? { fire: projectile.fire } : {}
|
|
715
715
|
});
|
|
716
716
|
};
|
|
717
|
+
const blastAt = (weapon, explosive, point) => {
|
|
718
|
+
const def = arsenal.explosives.get(explosive);
|
|
719
|
+
if (!def) return false;
|
|
720
|
+
const event = new ExplosiveBody({ explosive: def, origin: point, triggers: ["remote"], rules: arsenal.rules.explosives }).trigger("remote");
|
|
721
|
+
if (event?.type !== "detonate") return false;
|
|
722
|
+
detonate({ weapon }, event.detonation);
|
|
723
|
+
return true;
|
|
724
|
+
};
|
|
717
725
|
const detonateCharges = () => {
|
|
718
726
|
let count = 0;
|
|
719
727
|
for (const projectile of [...projectiles]) {
|
|
@@ -805,7 +813,172 @@ function createExplosives(context) {
|
|
|
805
813
|
}
|
|
806
814
|
}
|
|
807
815
|
};
|
|
808
|
-
return { throwUse, placeUse, backblastUse, detonateCharges, update, clear };
|
|
816
|
+
return { throwUse, placeUse, backblastUse, detonateCharges, blastAt, update, clear };
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
// src/test-table.ts
|
|
820
|
+
var TRIAL_KINDS = ["shot", "punch", "stab", "fire", "blast"];
|
|
821
|
+
var DEFAULT_TRIALS = {
|
|
822
|
+
shot: { weapon: "pistol_9mm", distance: 2.5, lift: 0.5 },
|
|
823
|
+
punch: { weapon: "fists", distance: 0.3, lift: 0.15 },
|
|
824
|
+
stab: { weapon: "knife", distance: 0.22, lift: 0.1 },
|
|
825
|
+
fire: { weapon: "flamethrower", distance: 1.6, lift: 0.4, hold: 0.8 },
|
|
826
|
+
blast: { weapon: "frag_grenade", distance: 0.3, lift: 1, watch: 6 }
|
|
827
|
+
};
|
|
828
|
+
var resolveTrials = (overrides = {}) => Object.fromEntries(TRIAL_KINDS.map((kind) => [kind, { ...DEFAULT_TRIALS[kind], ...overrides[kind] }]));
|
|
829
|
+
function fitRow(width, start, total, length, gap) {
|
|
830
|
+
let used = 0;
|
|
831
|
+
let count = 0;
|
|
832
|
+
for (let i = start; i < total; i++) {
|
|
833
|
+
const w = width(i);
|
|
834
|
+
const next = count === 0 ? w : used + gap + w;
|
|
835
|
+
if (count > 0 && next > length) break;
|
|
836
|
+
used = next;
|
|
837
|
+
count++;
|
|
838
|
+
}
|
|
839
|
+
return count;
|
|
840
|
+
}
|
|
841
|
+
function rowCentres(widths, centreX, gap) {
|
|
842
|
+
const length = widths.reduce((sum, w) => sum + w, 0) + gap * Math.max(0, widths.length - 1);
|
|
843
|
+
let x = centreX - length / 2;
|
|
844
|
+
return widths.map((w) => {
|
|
845
|
+
const centre = x + w / 2;
|
|
846
|
+
x += w + gap;
|
|
847
|
+
return centre;
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
function trialView(tool, kind, min, max) {
|
|
851
|
+
const target = [(min[0] + max[0]) / 2, (min[1] + max[1]) / 2, (min[2] + max[2]) / 2];
|
|
852
|
+
const away = kind === "blast" ? tool.watch ?? 6 : tool.distance;
|
|
853
|
+
return { eye: [target[0], target[1] + tool.lift, max[2] + away], target };
|
|
854
|
+
}
|
|
855
|
+
function createTestTable(context, options = {}) {
|
|
856
|
+
const gap = options.gap ?? 0.12;
|
|
857
|
+
const margin = options.margin ?? 0.1;
|
|
858
|
+
const trials = resolveTrials(options.trials);
|
|
859
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
860
|
+
let current = null;
|
|
861
|
+
const itemsOf = (group) => context.groups().get(group) ?? [];
|
|
862
|
+
const emit = () => {
|
|
863
|
+
const page = state();
|
|
864
|
+
for (const listener of [...listeners]) listener(page);
|
|
865
|
+
return page;
|
|
866
|
+
};
|
|
867
|
+
const state = () => {
|
|
868
|
+
if (!current) return null;
|
|
869
|
+
const total = itemsOf(current.group).length;
|
|
870
|
+
const live = current.objects.filter((o) => context.box(o.objectId));
|
|
871
|
+
return {
|
|
872
|
+
group: current.group,
|
|
873
|
+
page: current.page,
|
|
874
|
+
first: current.first,
|
|
875
|
+
total,
|
|
876
|
+
objects: live,
|
|
877
|
+
selected: current.selected,
|
|
878
|
+
hasPrev: current.page > 0,
|
|
879
|
+
hasNext: current.first + current.objects.length < total
|
|
880
|
+
};
|
|
881
|
+
};
|
|
882
|
+
const bounds = /* @__PURE__ */ new Map();
|
|
883
|
+
const widthOf = (itemId) => context.measure(itemId).w;
|
|
884
|
+
const boundsUntil = (group, length, until) => {
|
|
885
|
+
const items = itemsOf(group);
|
|
886
|
+
const known = bounds.get(group) ?? [0];
|
|
887
|
+
bounds.set(group, known);
|
|
888
|
+
while (known[known.length - 1] < items.length && !until(known)) {
|
|
889
|
+
const first = known[known.length - 1];
|
|
890
|
+
known.push(first + fitRow((i) => widthOf(items[i].id), first, items.length, length, gap));
|
|
891
|
+
}
|
|
892
|
+
return known;
|
|
893
|
+
};
|
|
894
|
+
const lengthOf = (top) => top.maxX - top.minX - 2 * margin;
|
|
895
|
+
const lay = (group, page, top) => {
|
|
896
|
+
const items = itemsOf(group);
|
|
897
|
+
const known = boundsUntil(group, lengthOf(top), (b) => b.length > page + 1);
|
|
898
|
+
const index = Math.max(0, Math.min(page, known.length - 2));
|
|
899
|
+
const first = known[index];
|
|
900
|
+
const laid = items.slice(first, known[index + 1]);
|
|
901
|
+
context.clear();
|
|
902
|
+
const sizes = laid.map((item) => context.measure(item.id));
|
|
903
|
+
const centres = rowCentres(sizes.map((size) => size.w), (top.minX + top.maxX) / 2, gap);
|
|
904
|
+
const objects = laid.map((item, i) => {
|
|
905
|
+
const d = Math.min(sizes[i].d, top.maxZ - top.minZ);
|
|
906
|
+
const { objectId } = context.spawn(item.id, [centres[i], top.top, top.maxZ - margin / 2 - d / 2]);
|
|
907
|
+
return { objectId, itemId: item.id, name: item.name };
|
|
908
|
+
});
|
|
909
|
+
current = { group, page: index, first, objects, selected: objects[0]?.objectId ?? null };
|
|
910
|
+
context.log("test_table", context.translate("act.test_table", { group, from: first + 1, to: first + laid.length, total: items.length }), { group, page: index, items: laid.map((i) => i.id) });
|
|
911
|
+
return emit();
|
|
912
|
+
};
|
|
913
|
+
const open = (group, page = 0) => {
|
|
914
|
+
const top = context.top();
|
|
915
|
+
if (!itemsOf(group).length || !top) return null;
|
|
916
|
+
return lay(group, page, top);
|
|
917
|
+
};
|
|
918
|
+
const find = (itemId) => {
|
|
919
|
+
const top = context.top();
|
|
920
|
+
const group = [...context.groups()].find(([, items]) => items.some((i) => i.id === itemId))?.[0];
|
|
921
|
+
if (group === void 0 || !top) return null;
|
|
922
|
+
const index = itemsOf(group).findIndex((i) => i.id === itemId);
|
|
923
|
+
const known = boundsUntil(group, lengthOf(top), (b) => b[b.length - 1] > index);
|
|
924
|
+
lay(group, known.findIndex((bound, i) => bound <= index && index < known[i + 1]), top);
|
|
925
|
+
const target = current?.objects.find((o) => o.itemId === itemId);
|
|
926
|
+
if (current && target) current.selected = target.objectId;
|
|
927
|
+
return emit();
|
|
928
|
+
};
|
|
929
|
+
const selected = (objectId) => {
|
|
930
|
+
const id = objectId ?? current?.selected ?? null;
|
|
931
|
+
return id && context.box(id) ? id : null;
|
|
932
|
+
};
|
|
933
|
+
const trial = (kind, objectId) => {
|
|
934
|
+
const id = selected(objectId);
|
|
935
|
+
const box2 = id ? context.box(id) : null;
|
|
936
|
+
if (!id || !box2) return false;
|
|
937
|
+
const tool = trials[kind];
|
|
938
|
+
if (!context.equip(tool.weapon)) return false;
|
|
939
|
+
const view = trialView(tool, kind, box2.min, box2.max);
|
|
940
|
+
context.look(view.eye, view.target);
|
|
941
|
+
const name = current?.objects.find((o) => o.objectId === id)?.name ?? id;
|
|
942
|
+
context.log("trial", context.translate(`act.trial.${kind}`, { name }), { kind, objectId: id, weapon: tool.weapon });
|
|
943
|
+
if (kind === "blast") {
|
|
944
|
+
const point = [view.target[0], box2.min[1] + 0.05, box2.min[2] - tool.distance];
|
|
945
|
+
return context.blastAt(tool.weapon, point);
|
|
946
|
+
}
|
|
947
|
+
context.use(tool.hold ?? 0);
|
|
948
|
+
emit();
|
|
949
|
+
return true;
|
|
950
|
+
};
|
|
951
|
+
return {
|
|
952
|
+
groups: () => [...context.groups()].filter(([, items]) => items.length > 0).map(([group]) => group),
|
|
953
|
+
items: () => [...context.groups()].flatMap(([group, items]) => items.map((item) => ({ id: item.id, name: item.name, group }))),
|
|
954
|
+
open,
|
|
955
|
+
find,
|
|
956
|
+
next: () => {
|
|
957
|
+
const page = state();
|
|
958
|
+
return page?.hasNext ? open(page.group, page.page + 1) : page;
|
|
959
|
+
},
|
|
960
|
+
prev: () => {
|
|
961
|
+
const page = state();
|
|
962
|
+
return page?.hasPrev ? open(page.group, page.page - 1) : page;
|
|
963
|
+
},
|
|
964
|
+
relay: () => {
|
|
965
|
+
if (!current) return null;
|
|
966
|
+
context.resetAll();
|
|
967
|
+
return open(current.group, current.page);
|
|
968
|
+
},
|
|
969
|
+
state,
|
|
970
|
+
select: (objectId) => {
|
|
971
|
+
if (!current || !current.objects.some((o) => o.objectId === objectId) || !context.box(objectId)) return false;
|
|
972
|
+
current.selected = objectId;
|
|
973
|
+
emit();
|
|
974
|
+
return true;
|
|
975
|
+
},
|
|
976
|
+
trial,
|
|
977
|
+
on: (listener) => {
|
|
978
|
+
listeners.add(listener);
|
|
979
|
+
return () => listeners.delete(listener);
|
|
980
|
+
}
|
|
981
|
+
};
|
|
809
982
|
}
|
|
810
983
|
|
|
811
984
|
// src/host-events.ts
|
|
@@ -2173,6 +2346,9 @@ var en = {
|
|
|
2173
2346
|
"act.strike.leg": "{weapon}: {clip} with the {leg} leg begins, impact in {seconds} s",
|
|
2174
2347
|
"leg.left": "left",
|
|
2175
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",
|
|
2176
2352
|
"act.flame.hit": "{weapon}: flame at {temp} \xB0C on {where}",
|
|
2177
2353
|
"act.flame.air": "{weapon}: flame, nothing in range",
|
|
2178
2354
|
"act.heat.hit": "{weapon}: heating {where} at {temp} \xB0C",
|
|
@@ -2204,6 +2380,7 @@ var en = {
|
|
|
2204
2380
|
"loading.open_area": "Opening {area}\u2026",
|
|
2205
2381
|
"loading.spawn": "Building {name}\u2026",
|
|
2206
2382
|
"act.loosened": "{name} was heavy but free: the blast moved it",
|
|
2383
|
+
"act.shoved": "{name} stands free: the shots moved it",
|
|
2207
2384
|
"act.impact": "{name} hit {where} at {speed} m/s: {energy} J of blunt damage",
|
|
2208
2385
|
"act.use_item": "{name}: {use}",
|
|
2209
2386
|
"act.tap.on": "Tap opened",
|
|
@@ -2237,7 +2414,7 @@ var en = {
|
|
|
2237
2414
|
"hud.throw": "throw",
|
|
2238
2415
|
"hud.tilt": "tilt (hold)",
|
|
2239
2416
|
"hud.equip": "equip {weapon}",
|
|
2240
|
-
"ui.help": "Click: look \xB7 WASD: walk \xB7 Shift: run \xB7 C: crouch \xB7 Space: jump \xB7 1-0 / wheel: tool \xB7 LMB: use \xB7 E: grab/drop \xB7 G or RMB: throw \xB7 R: reload \xB7 Q: fire mode \xB7 X: clear a jam \xB7 B: safety \xB7 Y: detonate charges set down \xB7 Tab: panels \xB7 Esc: free the mouse",
|
|
2417
|
+
"ui.help": "Click: look \xB7 WASD: walk \xB7 Shift: run \xB7 C: crouch \xB7 Space: jump \xB7 1-0 / wheel: tool \xB7 LMB: use (bare hands: punch) \xB7 E: grab/drop \xB7 G or RMB: throw \xB7 R: reload \xB7 Q: fire mode \xB7 X: clear a jam \xB7 B: safety \xB7 Y: detonate charges set down \xB7 Tab: panels \xB7 Esc: free the mouse",
|
|
2241
2418
|
"ui.help.camera": "V: 1st/3rd person (Shift+V: kick)",
|
|
2242
2419
|
"camera.first": "1st person",
|
|
2243
2420
|
"camera.third": "3rd person",
|
|
@@ -2251,6 +2428,32 @@ var en = {
|
|
|
2251
2428
|
"ui.copy_json": "Copy JSON",
|
|
2252
2429
|
"ui.download_ndjson": "Download NDJSON",
|
|
2253
2430
|
"ui.download_txt": "Download TXT",
|
|
2431
|
+
"ui.test_table": "Test table",
|
|
2432
|
+
"ui.test_table.group": "Group to lay on the table",
|
|
2433
|
+
"ui.test_table.lay": "Lay",
|
|
2434
|
+
"ui.test_table.prev": "Previous items",
|
|
2435
|
+
"ui.test_table.next": "Next items",
|
|
2436
|
+
"ui.test_table.relay": "Put back",
|
|
2437
|
+
"ui.test_table.search": "Find an item to put on the table",
|
|
2438
|
+
"ui.test_table.hint": "Pick a group and lay it on the table, then pick an item and try it.",
|
|
2439
|
+
"ui.test_table.page": "Items {from}\u2013{to} of {total}. Pick one, then a trial:",
|
|
2440
|
+
"ui.trial.shot": "Shot",
|
|
2441
|
+
"ui.trial.punch": "Punch",
|
|
2442
|
+
"ui.trial.stab": "Knife",
|
|
2443
|
+
"ui.trial.fire": "Fire",
|
|
2444
|
+
"ui.trial.blast": "Blast",
|
|
2445
|
+
"ui.trial.shot.hint": "A 9 mm round from 2.5 m",
|
|
2446
|
+
"ui.trial.punch.hint": "A punch, up close",
|
|
2447
|
+
"ui.trial.stab.hint": "A knife blow, up close",
|
|
2448
|
+
"ui.trial.fire.hint": "A flamethrower burst from 1.6 m",
|
|
2449
|
+
"ui.trial.blast.hint": "A fragmentation grenade goes off just behind it (it reaches the neighbours too)",
|
|
2450
|
+
"act.test_table": "Test table: {group}, items {from}\u2013{to} of {total}",
|
|
2451
|
+
"act.trial.shot": "Trial: shooting {name}",
|
|
2452
|
+
"act.trial.punch": "Trial: punching {name}",
|
|
2453
|
+
"act.trial.stab": "Trial: stabbing {name}",
|
|
2454
|
+
"act.trial.fire": "Trial: setting fire to {name}",
|
|
2455
|
+
"act.trial.blast": "Trial: a blast beside {name}",
|
|
2456
|
+
"arena.test_table": "Test table",
|
|
2254
2457
|
"ui.clear_log": "Clear",
|
|
2255
2458
|
"ui.catalog": "Catalogue",
|
|
2256
2459
|
"ui.clear": "Clear",
|
|
@@ -2454,6 +2657,9 @@ var ptBR = {
|
|
|
2454
2657
|
"act.strike.leg": "{weapon}: {clip} com a perna {leg} come\xE7a, impacto em {seconds} s",
|
|
2455
2658
|
"leg.left": "esquerda",
|
|
2456
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",
|
|
2457
2663
|
"act.flame.hit": "{weapon}: chama a {temp} \xB0C em {where}",
|
|
2458
2664
|
"act.flame.air": "{weapon}: chama, nada ao alcance",
|
|
2459
2665
|
"act.heat.hit": "{weapon}: esquentando {where} a {temp} \xB0C",
|
|
@@ -2485,6 +2691,7 @@ var ptBR = {
|
|
|
2485
2691
|
"loading.open_area": "Abrindo {area}\u2026",
|
|
2486
2692
|
"loading.spawn": "Montando {name}\u2026",
|
|
2487
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",
|
|
2488
2695
|
"act.impact": "{name} bateu em {where} a {speed} m/s: {energy} J de dano de impacto",
|
|
2489
2696
|
"act.use_item": "{name}: {use}",
|
|
2490
2697
|
"act.tap.on": "Abriu a torneira",
|
|
@@ -2518,7 +2725,7 @@ var ptBR = {
|
|
|
2518
2725
|
"hud.throw": "arremessar",
|
|
2519
2726
|
"hud.tilt": "inclinar (segurar)",
|
|
2520
2727
|
"hud.equip": "equipar {weapon}",
|
|
2521
|
-
"ui.help": "Clique: olhar \xB7 WASD: andar \xB7 Shift: correr \xB7 C: agachar \xB7 Espa\xE7o: pular \xB7 1-0 / roda: ferramenta \xB7 bot\xE3o esquerdo: usar \xB7 E: pegar/soltar \xB7 G ou bot\xE3o direito: arremessar \xB7 R: recarregar \xB7 Q: modo de tiro \xB7 X: destravar \xB7 B: trava \xB7 Y: detonar cargas postas \xB7 Tab: pain\xE9is \xB7 Esc: soltar o mouse",
|
|
2728
|
+
"ui.help": "Clique: olhar \xB7 WASD: andar \xB7 Shift: correr \xB7 C: agachar \xB7 Espa\xE7o: pular \xB7 1-0 / roda: ferramenta \xB7 bot\xE3o esquerdo: usar (m\xE3o livre: soco) \xB7 E: pegar/soltar \xB7 G ou bot\xE3o direito: arremessar \xB7 R: recarregar \xB7 Q: modo de tiro \xB7 X: destravar \xB7 B: trava \xB7 Y: detonar cargas postas \xB7 Tab: pain\xE9is \xB7 Esc: soltar o mouse",
|
|
2522
2729
|
"ui.help.camera": "V: 1\xAA/3\xAA pessoa (Shift+V: chute)",
|
|
2523
2730
|
"camera.first": "1\xAA pessoa",
|
|
2524
2731
|
"camera.third": "3\xAA pessoa",
|
|
@@ -2532,6 +2739,32 @@ var ptBR = {
|
|
|
2532
2739
|
"ui.copy_json": "Copiar JSON",
|
|
2533
2740
|
"ui.download_ndjson": "Baixar NDJSON",
|
|
2534
2741
|
"ui.download_txt": "Baixar TXT",
|
|
2742
|
+
"ui.test_table": "Mesa de testes",
|
|
2743
|
+
"ui.test_table.group": "Grupo para p\xF4r na mesa",
|
|
2744
|
+
"ui.test_table.lay": "P\xF4r na mesa",
|
|
2745
|
+
"ui.test_table.prev": "Itens anteriores",
|
|
2746
|
+
"ui.test_table.next": "Pr\xF3ximos itens",
|
|
2747
|
+
"ui.test_table.relay": "Repor",
|
|
2748
|
+
"ui.test_table.search": "Buscar item para p\xF4r na mesa",
|
|
2749
|
+
"ui.test_table.hint": "Escolha um grupo e ponha na mesa; depois escolha um item e teste.",
|
|
2750
|
+
"ui.test_table.page": "Itens {from}\u2013{to} de {total}. Escolha um e um teste:",
|
|
2751
|
+
"ui.trial.shot": "Tiro",
|
|
2752
|
+
"ui.trial.punch": "Soco",
|
|
2753
|
+
"ui.trial.stab": "Faca",
|
|
2754
|
+
"ui.trial.fire": "Fogo",
|
|
2755
|
+
"ui.trial.blast": "Explos\xE3o",
|
|
2756
|
+
"ui.trial.shot.hint": "Um tiro de 9 mm a 2,5 m",
|
|
2757
|
+
"ui.trial.punch.hint": "Um soco, de perto",
|
|
2758
|
+
"ui.trial.stab.hint": "Um golpe de faca, de perto",
|
|
2759
|
+
"ui.trial.fire.hint": "Uma rajada de lan\xE7a-chamas a 1,6 m",
|
|
2760
|
+
"ui.trial.blast.hint": "Uma granada de fragmenta\xE7\xE3o explode logo atr\xE1s dele (pega os vizinhos tamb\xE9m)",
|
|
2761
|
+
"act.test_table": "Mesa de testes: {group}, itens {from}\u2013{to} de {total}",
|
|
2762
|
+
"act.trial.shot": "Teste: tiro em {name}",
|
|
2763
|
+
"act.trial.punch": "Teste: soco em {name}",
|
|
2764
|
+
"act.trial.stab": "Teste: faca em {name}",
|
|
2765
|
+
"act.trial.fire": "Teste: fogo em {name}",
|
|
2766
|
+
"act.trial.blast": "Teste: explos\xE3o ao lado de {name}",
|
|
2767
|
+
"arena.test_table": "Mesa de testes",
|
|
2535
2768
|
"ui.clear_log": "Limpar",
|
|
2536
2769
|
"ui.catalog": "Cat\xE1logo",
|
|
2537
2770
|
"ui.clear": "Limpar",
|
|
@@ -2873,6 +3106,122 @@ function createBenchPanel(o) {
|
|
|
2873
3106
|
};
|
|
2874
3107
|
}
|
|
2875
3108
|
|
|
3109
|
+
// src/test-table-panel.ts
|
|
3110
|
+
var TEST_TABLE_CSS = `
|
|
3111
|
+
.tr-table{flex:0 0 auto;max-height:42%}
|
|
3112
|
+
.tr-table .sub{color:#9aa3b2;margin:4px 0}
|
|
3113
|
+
.tr-table .list{display:flex;flex-wrap:wrap;gap:3px}
|
|
3114
|
+
.tr-table .list .tr-btn{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
3115
|
+
.tr-table select{flex:1;min-width:0;max-width:55%}
|
|
3116
|
+
.tr-table .tr-search{margin:6px 0 0}
|
|
3117
|
+
.tr-root .tr-table button.tr-btn.on{background:#3b3a14;border-color:#ffd23f;color:#fff}
|
|
3118
|
+
`;
|
|
3119
|
+
var mk2 = (tag, cls, text) => {
|
|
3120
|
+
const e = document.createElement(tag);
|
|
3121
|
+
if (cls) e.className = cls;
|
|
3122
|
+
if (text !== void 0) e.textContent = text;
|
|
3123
|
+
return e;
|
|
3124
|
+
};
|
|
3125
|
+
function createTestTablePanel(table, t) {
|
|
3126
|
+
const element = mk2("div", "tr-panel tr-table");
|
|
3127
|
+
element.appendChild(mk2("h3", void 0, t("ui.test_table")));
|
|
3128
|
+
const head = mk2("div", "tr-row");
|
|
3129
|
+
const select = mk2("select");
|
|
3130
|
+
select.setAttribute("aria-label", t("ui.test_table.group"));
|
|
3131
|
+
const lay = mk2("button", "tr-btn", t("ui.test_table.lay"));
|
|
3132
|
+
const prev = mk2("button", "tr-btn", "\u25C0");
|
|
3133
|
+
const next = mk2("button", "tr-btn", "\u25B6");
|
|
3134
|
+
prev.title = t("ui.test_table.prev");
|
|
3135
|
+
next.title = t("ui.test_table.next");
|
|
3136
|
+
for (const b of [lay, prev, next]) b.type = "button";
|
|
3137
|
+
head.append(select, lay, prev, next);
|
|
3138
|
+
const search = mk2("input", "tr-search");
|
|
3139
|
+
search.type = "search";
|
|
3140
|
+
search.placeholder = t("ui.test_table.search");
|
|
3141
|
+
const found = mk2("div", "list");
|
|
3142
|
+
const sub = mk2("div", "sub", t("ui.test_table.hint"));
|
|
3143
|
+
const list = mk2("div", "list");
|
|
3144
|
+
const trials = mk2("div", "tr-row");
|
|
3145
|
+
const trialButtons = TRIAL_KINDS.map((kind) => {
|
|
3146
|
+
const b = mk2("button", "tr-btn", t(`ui.trial.${kind}`));
|
|
3147
|
+
b.type = "button";
|
|
3148
|
+
b.dataset.trial = kind;
|
|
3149
|
+
b.title = t(`ui.trial.${kind}.hint`);
|
|
3150
|
+
b.onclick = () => table.trial(kind);
|
|
3151
|
+
trials.appendChild(b);
|
|
3152
|
+
return b;
|
|
3153
|
+
});
|
|
3154
|
+
const relay = mk2("button", "tr-btn", t("ui.test_table.relay"));
|
|
3155
|
+
relay.type = "button";
|
|
3156
|
+
relay.onclick = () => table.relay();
|
|
3157
|
+
trials.appendChild(relay);
|
|
3158
|
+
element.append(head, search, found, sub, trials, list);
|
|
3159
|
+
const groups = () => {
|
|
3160
|
+
const keep = select.value;
|
|
3161
|
+
select.textContent = "";
|
|
3162
|
+
for (const group of table.groups()) {
|
|
3163
|
+
const op = mk2("option", void 0, group);
|
|
3164
|
+
op.value = group;
|
|
3165
|
+
select.appendChild(op);
|
|
3166
|
+
}
|
|
3167
|
+
if ([...select.options].some((o) => o.value === keep)) select.value = keep;
|
|
3168
|
+
};
|
|
3169
|
+
const render = (page) => {
|
|
3170
|
+
list.textContent = "";
|
|
3171
|
+
prev.disabled = !page?.hasPrev;
|
|
3172
|
+
next.disabled = !page?.hasNext;
|
|
3173
|
+
for (const b of [...trialButtons, relay]) b.disabled = !page?.selected;
|
|
3174
|
+
if (!page) {
|
|
3175
|
+
sub.textContent = t("ui.test_table.hint");
|
|
3176
|
+
return;
|
|
3177
|
+
}
|
|
3178
|
+
if (select.value !== page.group) select.value = page.group;
|
|
3179
|
+
sub.textContent = t("ui.test_table.page", { from: page.first + 1, to: page.first + page.objects.length, total: page.total });
|
|
3180
|
+
for (const o of page.objects) {
|
|
3181
|
+
const b = mk2("button", o.objectId === page.selected ? "tr-btn on" : "tr-btn", o.name);
|
|
3182
|
+
b.type = "button";
|
|
3183
|
+
b.title = o.itemId;
|
|
3184
|
+
b.onclick = () => table.select(o.objectId);
|
|
3185
|
+
list.appendChild(b);
|
|
3186
|
+
}
|
|
3187
|
+
};
|
|
3188
|
+
const fold2 = (text) => text.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase();
|
|
3189
|
+
search.oninput = () => {
|
|
3190
|
+
found.textContent = "";
|
|
3191
|
+
const term = fold2(search.value.trim());
|
|
3192
|
+
if (!term) return;
|
|
3193
|
+
const hits = table.items().filter((item) => fold2(`${item.name} ${item.id}`).includes(term)).slice(0, 8);
|
|
3194
|
+
for (const item of hits) {
|
|
3195
|
+
const b = mk2("button", "tr-btn", item.name);
|
|
3196
|
+
b.type = "button";
|
|
3197
|
+
b.title = `${item.group} \xB7 ${item.id}`;
|
|
3198
|
+
b.onclick = () => {
|
|
3199
|
+
search.value = "";
|
|
3200
|
+
found.textContent = "";
|
|
3201
|
+
table.find(item.id);
|
|
3202
|
+
};
|
|
3203
|
+
found.appendChild(b);
|
|
3204
|
+
}
|
|
3205
|
+
if (!hits.length) found.appendChild(mk2("div", "sub", t("ui.no_results")));
|
|
3206
|
+
};
|
|
3207
|
+
lay.onclick = () => table.open(select.value);
|
|
3208
|
+
prev.onclick = () => table.prev();
|
|
3209
|
+
next.onclick = () => table.next();
|
|
3210
|
+
select.onchange = () => table.open(select.value);
|
|
3211
|
+
for (const box2 of [select, search]) box2.addEventListener("keydown", (e) => e.stopPropagation());
|
|
3212
|
+
const off = table.on(render);
|
|
3213
|
+
groups();
|
|
3214
|
+
render(table.state());
|
|
3215
|
+
return {
|
|
3216
|
+
element,
|
|
3217
|
+
refresh: () => {
|
|
3218
|
+
groups();
|
|
3219
|
+
render(table.state());
|
|
3220
|
+
},
|
|
3221
|
+
dispose: off
|
|
3222
|
+
};
|
|
3223
|
+
}
|
|
3224
|
+
|
|
2876
3225
|
// src/ui.ts
|
|
2877
3226
|
var CSS = `
|
|
2878
3227
|
.tr-root{position:absolute;inset:0;pointer-events:none;font:12px/1.35 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;color:#e8eaee;overflow:hidden}
|
|
@@ -2951,7 +3300,7 @@ var CSS = `
|
|
|
2951
3300
|
@media (max-width:980px){.tr-left,.tr-right{display:none}.tr-root.open .tr-left,.tr-root.open .tr-right{display:flex}.tr-toggle{display:block;pointer-events:auto}.tr-root.open .tr-toggle{right:min(310px,34vw)}.tr-left{width:min(400px,46vw)}.tr-help{display:none}}
|
|
2952
3301
|
`;
|
|
2953
3302
|
var fold = (text) => text.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase();
|
|
2954
|
-
var
|
|
3303
|
+
var mk3 = (tag, cls, text) => {
|
|
2955
3304
|
const e = document.createElement(tag);
|
|
2956
3305
|
if (cls) e.className = cls;
|
|
2957
3306
|
if (text !== void 0) e.textContent = text;
|
|
@@ -2962,7 +3311,7 @@ var thumbSource = (thumbnail) => {
|
|
|
2962
3311
|
return source.replace(/["\\\n\r]/g, (char) => encodeURIComponent(char));
|
|
2963
3312
|
};
|
|
2964
3313
|
var thumb = (thumbnail, credit) => {
|
|
2965
|
-
const e =
|
|
3314
|
+
const e = mk3("span", "tr-thumb");
|
|
2966
3315
|
if (credit) e.title = credit;
|
|
2967
3316
|
else e.setAttribute("aria-hidden", "true");
|
|
2968
3317
|
e.style.setProperty("--tr-thumb", `url("${thumbSource(thumbnail)}")`);
|
|
@@ -2983,42 +3332,43 @@ async function toggleFullscreen() {
|
|
|
2983
3332
|
}
|
|
2984
3333
|
function createUi(o) {
|
|
2985
3334
|
const { t } = o;
|
|
2986
|
-
const style =
|
|
2987
|
-
style.textContent = CSS;
|
|
2988
|
-
const root =
|
|
3335
|
+
const style = mk3("style");
|
|
3336
|
+
style.textContent = CSS + (o.testTable ? TEST_TABLE_CSS : "");
|
|
3337
|
+
const root = mk3("div", "tr-root");
|
|
2989
3338
|
const pos = getComputedStyle?.(o.container)?.position;
|
|
2990
3339
|
if (!pos || pos === "static") o.container.style.position = "relative";
|
|
2991
3340
|
root.appendChild(style);
|
|
2992
3341
|
o.container.appendChild(root);
|
|
2993
|
-
const cross =
|
|
2994
|
-
cross.appendChild(
|
|
2995
|
-
const top =
|
|
2996
|
-
const toolBox =
|
|
2997
|
-
const status =
|
|
2998
|
-
const prog =
|
|
2999
|
-
const progLabel =
|
|
3000
|
-
const progBar =
|
|
3001
|
-
const progFill =
|
|
3342
|
+
const cross = mk3("div", "tr-cross");
|
|
3343
|
+
cross.appendChild(mk3("i"));
|
|
3344
|
+
const top = mk3("div", "tr-top");
|
|
3345
|
+
const toolBox = mk3("div", "tr-tool");
|
|
3346
|
+
const status = mk3("div", "tr-status");
|
|
3347
|
+
const prog = mk3("div", "tr-prog");
|
|
3348
|
+
const progLabel = mk3("b");
|
|
3349
|
+
const progBar = mk3("div", "tr-bar");
|
|
3350
|
+
const progFill = mk3("i");
|
|
3002
3351
|
progBar.appendChild(progFill);
|
|
3003
3352
|
prog.append(progLabel, progBar);
|
|
3004
3353
|
top.append(toolBox, status, prog);
|
|
3005
|
-
const bottom =
|
|
3006
|
-
const held =
|
|
3007
|
-
const hotbar =
|
|
3354
|
+
const bottom = mk3("div", "tr-bottom");
|
|
3355
|
+
const held = mk3("div", "tr-held");
|
|
3356
|
+
const hotbar = mk3("div", "tr-hotbar");
|
|
3008
3357
|
bottom.append(held, hotbar);
|
|
3009
|
-
const help =
|
|
3358
|
+
const help = mk3("div", "tr-help");
|
|
3010
3359
|
help.textContent = t("ui.help");
|
|
3011
|
-
const left =
|
|
3012
|
-
const insp =
|
|
3013
|
-
const logPanel =
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
const
|
|
3017
|
-
const
|
|
3360
|
+
const left = mk3("div", "tr-left");
|
|
3361
|
+
const insp = mk3("div", "tr-panel tr-insp");
|
|
3362
|
+
const logPanel = mk3("div", "tr-panel tr-log");
|
|
3363
|
+
const tablePanel = o.testTable ? createTestTablePanel(o.testTable, t) : null;
|
|
3364
|
+
left.append(insp, ...tablePanel ? [tablePanel.element] : [], logPanel);
|
|
3365
|
+
const logTitle = mk3("h3", void 0, t("ui.log"));
|
|
3366
|
+
const logBar = mk3("div", "tr-logbar");
|
|
3367
|
+
const logBody = mk3("div", "tr-logbody");
|
|
3018
3368
|
const filters = { action: true, event: true, check: true };
|
|
3019
3369
|
const filterBtns = [];
|
|
3020
3370
|
for (const ch of ["action", "event", "check"]) {
|
|
3021
|
-
const b =
|
|
3371
|
+
const b = mk3("button", "tr-btn on", t(`ui.filter.${ch}`));
|
|
3022
3372
|
b.type = "button";
|
|
3023
3373
|
b.onclick = () => {
|
|
3024
3374
|
filters[ch] = !filters[ch];
|
|
@@ -3029,8 +3379,8 @@ function createUi(o) {
|
|
|
3029
3379
|
logBar.appendChild(b);
|
|
3030
3380
|
}
|
|
3031
3381
|
let autoscroll = true;
|
|
3032
|
-
const asLabel =
|
|
3033
|
-
const asBox =
|
|
3382
|
+
const asLabel = mk3("label");
|
|
3383
|
+
const asBox = mk3("input");
|
|
3034
3384
|
asBox.type = "checkbox";
|
|
3035
3385
|
asBox.checked = true;
|
|
3036
3386
|
asBox.onchange = () => {
|
|
@@ -3039,7 +3389,7 @@ function createUi(o) {
|
|
|
3039
3389
|
asLabel.append(asBox, document.createTextNode(" " + t("ui.autoscroll")));
|
|
3040
3390
|
logBar.appendChild(asLabel);
|
|
3041
3391
|
const logBtn = (label, fn) => {
|
|
3042
|
-
const b =
|
|
3392
|
+
const b = mk3("button", "tr-btn", label);
|
|
3043
3393
|
b.type = "button";
|
|
3044
3394
|
b.onclick = fn;
|
|
3045
3395
|
logBar.appendChild(b);
|
|
@@ -3047,7 +3397,7 @@ function createUi(o) {
|
|
|
3047
3397
|
logBtn(t("ui.copy_json"), () => {
|
|
3048
3398
|
const text = o.log.toJSON();
|
|
3049
3399
|
const select = () => {
|
|
3050
|
-
const ta =
|
|
3400
|
+
const ta = mk3("textarea");
|
|
3051
3401
|
ta.value = text;
|
|
3052
3402
|
ta.setAttribute("readonly", "");
|
|
3053
3403
|
ta.style.cssText = "position:fixed;left:8px;bottom:8px;width:min(480px,80vw);height:120px;z-index:99999";
|
|
@@ -3081,12 +3431,12 @@ function createUi(o) {
|
|
|
3081
3431
|
const fill = (n, e) => {
|
|
3082
3432
|
n.className = lineClass(e);
|
|
3083
3433
|
n.textContent = "";
|
|
3084
|
-
const tm =
|
|
3434
|
+
const tm = mk3("time", void 0, fmtTime(e.t));
|
|
3085
3435
|
n.append(tm, document.createTextNode(e.text));
|
|
3086
3436
|
};
|
|
3087
3437
|
const addNode = (e) => {
|
|
3088
3438
|
if (!filters[e.channel]) return;
|
|
3089
|
-
const n =
|
|
3439
|
+
const n = mk3("div");
|
|
3090
3440
|
fill(n, e);
|
|
3091
3441
|
nodes.set(e.seq, n);
|
|
3092
3442
|
logBody.appendChild(n);
|
|
@@ -3108,18 +3458,18 @@ function createUi(o) {
|
|
|
3108
3458
|
if (n) fill(n, e);
|
|
3109
3459
|
} else addNode(e);
|
|
3110
3460
|
});
|
|
3111
|
-
const right =
|
|
3112
|
-
const cat =
|
|
3113
|
-
const anim =
|
|
3114
|
-
const tests =
|
|
3461
|
+
const right = mk3("div", "tr-right");
|
|
3462
|
+
const cat = mk3("div", "tr-panel tr-cat");
|
|
3463
|
+
const anim = mk3("div", "tr-panel tr-anim");
|
|
3464
|
+
const tests = mk3("div", "tr-panel tr-tests");
|
|
3115
3465
|
const benchPanel = createBenchPanel({ t, num: (n, d) => num(n, d), onControl: o.onControl, onLayer: o.onLayer, onAction: o.onAction });
|
|
3116
3466
|
right.append(cat, anim, benchPanel.element, tests);
|
|
3117
|
-
cat.appendChild(
|
|
3118
|
-
const itemSearch =
|
|
3467
|
+
cat.appendChild(mk3("h3", void 0, t("ui.catalog")));
|
|
3468
|
+
const itemSearch = mk3("input", "tr-search");
|
|
3119
3469
|
itemSearch.type = "search";
|
|
3120
3470
|
itemSearch.placeholder = t("ui.search_items");
|
|
3121
|
-
const tabs =
|
|
3122
|
-
const items =
|
|
3471
|
+
const tabs = mk3("div", "tr-tabs");
|
|
3472
|
+
const items = mk3("div", "tr-items");
|
|
3123
3473
|
cat.append(itemSearch, tabs, items);
|
|
3124
3474
|
let activeGroup = "";
|
|
3125
3475
|
const visibleItems = () => {
|
|
@@ -3131,18 +3481,18 @@ function createUi(o) {
|
|
|
3131
3481
|
items.textContent = "";
|
|
3132
3482
|
const searching = itemSearch.value.trim() !== "";
|
|
3133
3483
|
const found = visibleItems();
|
|
3134
|
-
if (!found.length) items.appendChild(
|
|
3484
|
+
if (!found.length) items.appendChild(mk3("div", "tr-empty", t("ui.no_results")));
|
|
3135
3485
|
for (const { item: it, group } of found) {
|
|
3136
|
-
const wrap =
|
|
3137
|
-
const b =
|
|
3138
|
-
if (it.thumbnail) b.append(thumb(it.thumbnail),
|
|
3139
|
-
if (searching) b.appendChild(
|
|
3486
|
+
const wrap = mk3("div", "tr-item");
|
|
3487
|
+
const b = mk3("button", it.thumbnail ? "tr-btn has-thumb" : "tr-btn", it.thumbnail ? void 0 : it.name);
|
|
3488
|
+
if (it.thumbnail) b.append(thumb(it.thumbnail), mk3("span", "tr-name", it.name));
|
|
3489
|
+
if (searching) b.appendChild(mk3("small", void 0, group));
|
|
3140
3490
|
b.type = "button";
|
|
3141
3491
|
b.title = it.note ?? it.name;
|
|
3142
3492
|
b.onclick = () => o.onSpawn(it.id);
|
|
3143
3493
|
wrap.appendChild(b);
|
|
3144
3494
|
if (it.weapon) {
|
|
3145
|
-
const w =
|
|
3495
|
+
const w = mk3("button", "tr-btn", "\u2694");
|
|
3146
3496
|
w.type = "button";
|
|
3147
3497
|
w.title = t("ui.equip");
|
|
3148
3498
|
w.onclick = () => o.onEquip(it.id);
|
|
@@ -3156,7 +3506,7 @@ function createUi(o) {
|
|
|
3156
3506
|
const groupNames = [...o.groups().keys()];
|
|
3157
3507
|
if (!groupNames.includes(activeGroup)) activeGroup = groupNames[0] ?? "";
|
|
3158
3508
|
for (const g of groupNames) {
|
|
3159
|
-
const b =
|
|
3509
|
+
const b = mk3("button", g === activeGroup ? "tr-btn on" : "tr-btn", g);
|
|
3160
3510
|
b.type = "button";
|
|
3161
3511
|
b.onclick = () => {
|
|
3162
3512
|
activeGroup = g;
|
|
@@ -3169,9 +3519,9 @@ function createUi(o) {
|
|
|
3169
3519
|
renderTabs();
|
|
3170
3520
|
itemSearch.oninput = renderItems;
|
|
3171
3521
|
for (const box2 of [itemSearch]) box2.addEventListener("keydown", (e) => e.stopPropagation());
|
|
3172
|
-
const controls =
|
|
3522
|
+
const controls = mk3("div", "tr-row");
|
|
3173
3523
|
const ctl = (label, fn) => {
|
|
3174
|
-
const b =
|
|
3524
|
+
const b = mk3("button", "tr-btn", label);
|
|
3175
3525
|
b.type = "button";
|
|
3176
3526
|
b.onclick = () => fn(b);
|
|
3177
3527
|
controls.appendChild(b);
|
|
@@ -3196,29 +3546,29 @@ function createUi(o) {
|
|
|
3196
3546
|
fullscreenBtn.title = t("ui.fullscreen.hint");
|
|
3197
3547
|
const blastBtns = ["shelter", "fragmentHits", "confinement"].map((key) => ({ key, b: ctl(t(`ui.blast.${key}`), () => o.onBlast(key)) }));
|
|
3198
3548
|
for (const { key, b } of blastBtns) b.title = t(`ui.blast.${key}.hint`);
|
|
3199
|
-
const qSel =
|
|
3549
|
+
const qSel = mk3("select");
|
|
3200
3550
|
for (const q of ["low", "medium", "high"]) {
|
|
3201
|
-
const op =
|
|
3551
|
+
const op = mk3("option", void 0, t(`ui.quality.${q}`));
|
|
3202
3552
|
op.value = q;
|
|
3203
3553
|
qSel.appendChild(op);
|
|
3204
3554
|
}
|
|
3205
3555
|
qSel.value = o.quality;
|
|
3206
3556
|
qSel.onchange = () => o.onQuality(qSel.value);
|
|
3207
|
-
const qLabel =
|
|
3557
|
+
const qLabel = mk3("label", void 0, t("ui.quality") + " ");
|
|
3208
3558
|
qLabel.appendChild(qSel);
|
|
3209
3559
|
controls.appendChild(qLabel);
|
|
3210
|
-
const count =
|
|
3560
|
+
const count = mk3("span");
|
|
3211
3561
|
controls.appendChild(count);
|
|
3212
3562
|
cat.appendChild(controls);
|
|
3213
|
-
tests.appendChild(
|
|
3214
|
-
const runAll =
|
|
3563
|
+
tests.appendChild(mk3("h3", void 0, t("ui.tests")));
|
|
3564
|
+
const runAll = mk3("button", "tr-btn", t("ui.run_all"));
|
|
3215
3565
|
runAll.type = "button";
|
|
3216
|
-
const summary =
|
|
3217
|
-
const testSearch =
|
|
3566
|
+
const summary = mk3("div", "tr-summary");
|
|
3567
|
+
const testSearch = mk3("input", "tr-search");
|
|
3218
3568
|
testSearch.type = "search";
|
|
3219
3569
|
testSearch.placeholder = t("ui.search_tests");
|
|
3220
3570
|
testSearch.addEventListener("keydown", (e) => e.stopPropagation());
|
|
3221
|
-
const list =
|
|
3571
|
+
const list = mk3("div", "list");
|
|
3222
3572
|
tests.append(runAll, summary, testSearch, list);
|
|
3223
3573
|
testSearch.oninput = () => {
|
|
3224
3574
|
const term = fold(testSearch.value.trim());
|
|
@@ -3241,7 +3591,7 @@ function createUi(o) {
|
|
|
3241
3591
|
list.textContent = "";
|
|
3242
3592
|
scBtns.clear();
|
|
3243
3593
|
for (const s of o.scenarios()) {
|
|
3244
|
-
const b =
|
|
3594
|
+
const b = mk3("button", "tr-btn", s.name);
|
|
3245
3595
|
b.type = "button";
|
|
3246
3596
|
b.onclick = async () => {
|
|
3247
3597
|
if (busy) return;
|
|
@@ -3267,7 +3617,7 @@ function createUi(o) {
|
|
|
3267
3617
|
busy = false;
|
|
3268
3618
|
}
|
|
3269
3619
|
};
|
|
3270
|
-
const toggle =
|
|
3620
|
+
const toggle = mk3("button", "tr-btn tr-toggle", t("ui.panel"));
|
|
3271
3621
|
toggle.type = "button";
|
|
3272
3622
|
const togglePanels = () => {
|
|
3273
3623
|
root.classList.toggle("open");
|
|
@@ -3276,15 +3626,15 @@ function createUi(o) {
|
|
|
3276
3626
|
toggle.onclick = togglePanels;
|
|
3277
3627
|
root.append(cross, top, bottom, help, left, right, toggle);
|
|
3278
3628
|
const bar = (value, max, cls) => {
|
|
3279
|
-
const b =
|
|
3280
|
-
const i =
|
|
3629
|
+
const b = mk3("div", `tr-bar ${cls}`);
|
|
3630
|
+
const i = mk3("i");
|
|
3281
3631
|
i.style.width = `${Math.max(0, Math.min(100, value / Math.max(1e-9, max) * 100))}%`;
|
|
3282
3632
|
b.appendChild(i);
|
|
3283
3633
|
return b;
|
|
3284
3634
|
};
|
|
3285
3635
|
const row = (k, v) => {
|
|
3286
|
-
const r =
|
|
3287
|
-
r.append(
|
|
3636
|
+
const r = mk3("div", "r");
|
|
3637
|
+
r.append(mk3("span", void 0, k), mk3("span", void 0, v));
|
|
3288
3638
|
return r;
|
|
3289
3639
|
};
|
|
3290
3640
|
const num = (n, d = 1) => {
|
|
@@ -3293,13 +3643,13 @@ function createUi(o) {
|
|
|
3293
3643
|
};
|
|
3294
3644
|
const renderInspector = (i) => {
|
|
3295
3645
|
insp.textContent = "";
|
|
3296
|
-
insp.appendChild(
|
|
3646
|
+
insp.appendChild(mk3("h3", void 0, t("ui.inspector")));
|
|
3297
3647
|
if (!i) {
|
|
3298
|
-
insp.appendChild(
|
|
3648
|
+
insp.appendChild(mk3("div", void 0, t("ui.aim_at_something")));
|
|
3299
3649
|
return;
|
|
3300
3650
|
}
|
|
3301
3651
|
if (i.thumbnail) insp.appendChild(thumb(i.thumbnail, i.thumbnailCredit));
|
|
3302
|
-
insp.appendChild(
|
|
3652
|
+
insp.appendChild(mk3("div", "t", `${i.object} \u203A ${i.part}`));
|
|
3303
3653
|
insp.appendChild(row(t("ins.material"), i.material));
|
|
3304
3654
|
insp.appendChild(row(t("ins.status"), i.status + (i.burning ? ` \xB7 ${t("ins.burning")}` : "")));
|
|
3305
3655
|
insp.appendChild(row(t("ins.hp"), `${num(i.hp, 0)} / ${num(i.maxHp, 0)}`));
|
|
@@ -3318,30 +3668,30 @@ function createUi(o) {
|
|
|
3318
3668
|
insp.appendChild(bar(Math.min(i.stress, 1.2), 1.2, i.stress > 1 ? "bad" : i.stress > 0.7 ? "warn" : "hp"));
|
|
3319
3669
|
}
|
|
3320
3670
|
if (i.joints.length) {
|
|
3321
|
-
insp.appendChild(
|
|
3671
|
+
insp.appendChild(mk3("div", void 0, t("ins.joints") + ":"));
|
|
3322
3672
|
for (const j of i.joints) {
|
|
3323
3673
|
const tools = j.tools.length ? j.tools.join(", ") : t("tool.none");
|
|
3324
|
-
insp.appendChild(
|
|
3674
|
+
insp.appendChild(mk3("div", void 0, `\u2022 ${j.kind} (${j.id})${j.open ? ` \xB7 ${t("ins.open")}` : ` \u2192 ${tools}`}`));
|
|
3325
3675
|
}
|
|
3326
3676
|
}
|
|
3327
|
-
if (i.note) insp.appendChild(
|
|
3677
|
+
if (i.note) insp.appendChild(mk3("div", void 0, i.note));
|
|
3328
3678
|
};
|
|
3329
3679
|
let lastAnim = "";
|
|
3330
3680
|
const renderAnimations = (a) => {
|
|
3331
3681
|
anim.textContent = "";
|
|
3332
|
-
anim.appendChild(
|
|
3682
|
+
anim.appendChild(mk3("h3", void 0, t("ui.animations")));
|
|
3333
3683
|
if (!a) {
|
|
3334
|
-
anim.appendChild(
|
|
3684
|
+
anim.appendChild(mk3("div", "sub", t("ui.animations_aim")));
|
|
3335
3685
|
return;
|
|
3336
3686
|
}
|
|
3337
|
-
anim.appendChild(
|
|
3687
|
+
anim.appendChild(mk3("div", "sub", a.name));
|
|
3338
3688
|
if (a.clips.length === 0) {
|
|
3339
|
-
anim.appendChild(
|
|
3689
|
+
anim.appendChild(mk3("div", "sub", t("ui.animations_none")));
|
|
3340
3690
|
return;
|
|
3341
3691
|
}
|
|
3342
|
-
const l =
|
|
3692
|
+
const l = mk3("div", "list");
|
|
3343
3693
|
for (const c of a.clips) {
|
|
3344
|
-
const b =
|
|
3694
|
+
const b = mk3("button", a.playing === c.id ? "tr-btn on" : "tr-btn", `\u25B6 ${t(`anim.${c.id}`) === `anim.${c.id}` ? c.id : t(`anim.${c.id}`)} (${num(c.duration, 1)} s)`);
|
|
3345
3695
|
b.type = "button";
|
|
3346
3696
|
b.onclick = () => o.onPlay(a.objectId, c.id);
|
|
3347
3697
|
l.appendChild(b);
|
|
@@ -3358,8 +3708,8 @@ function createUi(o) {
|
|
|
3358
3708
|
hud(s) {
|
|
3359
3709
|
toolBox.textContent = "";
|
|
3360
3710
|
toolBox.append(document.createTextNode(s.toolName));
|
|
3361
|
-
if (s.ammo) toolBox.append(
|
|
3362
|
-
if (s.camera) toolBox.append(
|
|
3711
|
+
if (s.ammo) toolBox.append(mk3("small", void 0, s.ammo));
|
|
3712
|
+
if (s.camera) toolBox.append(mk3("small", void 0, t(`camera.${s.camera}`)));
|
|
3363
3713
|
const helpText = s.camera ? `${t("ui.help")} \xB7 ${t("ui.help.camera")}` : t("ui.help");
|
|
3364
3714
|
if (help.textContent !== helpText) help.textContent = helpText;
|
|
3365
3715
|
if (s.status) status.textContent = s.status;
|
|
@@ -3382,7 +3732,7 @@ function createUi(o) {
|
|
|
3382
3732
|
];
|
|
3383
3733
|
if (s.held.weapon) keys.push(["H", t("hud.equip", { weapon: s.held.weapon })]);
|
|
3384
3734
|
for (const [k, label] of keys) {
|
|
3385
|
-
held.append(
|
|
3735
|
+
held.append(mk3("kbd", void 0, k), document.createTextNode(` ${label} `));
|
|
3386
3736
|
}
|
|
3387
3737
|
} else held.style.display = "none";
|
|
3388
3738
|
const key = s.slots.join("|") + s.page;
|
|
@@ -3392,9 +3742,9 @@ function createUi(o) {
|
|
|
3392
3742
|
slotsEl.length = 0;
|
|
3393
3743
|
hudPage = s.page - 1;
|
|
3394
3744
|
s.slots.forEach((name, i) => {
|
|
3395
|
-
const b =
|
|
3745
|
+
const b = mk3("button", "tr-slot");
|
|
3396
3746
|
b.type = "button";
|
|
3397
|
-
b.append(
|
|
3747
|
+
b.append(mk3("b", void 0, String((i + 1) % 10)), document.createTextNode(name));
|
|
3398
3748
|
b.title = name;
|
|
3399
3749
|
b.onclick = () => o.onTool(hudPage * 10 + i);
|
|
3400
3750
|
hotbar.appendChild(b);
|
|
@@ -3426,6 +3776,7 @@ function createUi(o) {
|
|
|
3426
3776
|
refresh() {
|
|
3427
3777
|
renderTabs();
|
|
3428
3778
|
renderScenarios();
|
|
3779
|
+
tablePanel?.refresh();
|
|
3429
3780
|
},
|
|
3430
3781
|
showGroup(group) {
|
|
3431
3782
|
activeGroup = group;
|
|
@@ -3440,6 +3791,7 @@ function createUi(o) {
|
|
|
3440
3791
|
},
|
|
3441
3792
|
dispose() {
|
|
3442
3793
|
offLog();
|
|
3794
|
+
tablePanel?.dispose();
|
|
3443
3795
|
if (toastTimer) clearTimeout(toastTimer);
|
|
3444
3796
|
root.remove();
|
|
3445
3797
|
}
|
|
@@ -3450,6 +3802,7 @@ function createUi(o) {
|
|
|
3450
3802
|
|
|
3451
3803
|
// src/room.ts
|
|
3452
3804
|
var FIXED_DT = 1 / 60;
|
|
3805
|
+
var SHOVE_SPEED = 0.04;
|
|
3453
3806
|
var METRICS_INTERVAL_S = 0.25;
|
|
3454
3807
|
var CARRY_NEAR = 0.62;
|
|
3455
3808
|
var CARRY_PALM = 0.012;
|
|
@@ -3812,7 +4165,9 @@ function createTestRoom(options) {
|
|
|
3812
4165
|
scene.add(root);
|
|
3813
4166
|
root.updateMatrixWorld(true);
|
|
3814
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)] } : {} });
|
|
3815
|
-
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;
|
|
3816
4171
|
}
|
|
3817
4172
|
};
|
|
3818
4173
|
addArena();
|
|
@@ -3907,6 +4262,7 @@ function createTestRoom(options) {
|
|
|
3907
4262
|
renderer.unbind(id);
|
|
3908
4263
|
} catch {
|
|
3909
4264
|
}
|
|
4265
|
+
e.follower?.dispose?.();
|
|
3910
4266
|
if (world.has(id)) world.remove(id);
|
|
3911
4267
|
e.so.root.removeFromParent();
|
|
3912
4268
|
letGo(e.so.root);
|
|
@@ -3941,6 +4297,7 @@ function createTestRoom(options) {
|
|
|
3941
4297
|
for (const e of entries.values()) {
|
|
3942
4298
|
world.reset(e.so.objectId);
|
|
3943
4299
|
renderer.restore(e.so.objectId);
|
|
4300
|
+
e.follower?.restore?.();
|
|
3944
4301
|
}
|
|
3945
4302
|
renderer.clear();
|
|
3946
4303
|
vfx.world.clear();
|
|
@@ -3962,6 +4319,7 @@ function createTestRoom(options) {
|
|
|
3962
4319
|
if (heldEntry === e) continue;
|
|
3963
4320
|
world.reset(e.so.objectId);
|
|
3964
4321
|
renderer.restore(e.so.objectId);
|
|
4322
|
+
e.follower?.restore?.();
|
|
3965
4323
|
if (e.containerId) {
|
|
3966
4324
|
const c = fluids.container(e.containerId);
|
|
3967
4325
|
const f = e.item?.fluid?.container;
|
|
@@ -4265,6 +4623,19 @@ function createTestRoom(options) {
|
|
|
4265
4623
|
if (!rendererPieces.has(objectId)) return;
|
|
4266
4624
|
renderer.impulse(objectId, [dir[0] * momentum, dir[1] * momentum, dir[2] * momentum], point);
|
|
4267
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
|
+
};
|
|
4268
4639
|
const fireShots = (shots, recoil) => {
|
|
4269
4640
|
if (shots.length === 0) return;
|
|
4270
4641
|
const w = toolName();
|
|
@@ -4274,6 +4645,7 @@ function createTestRoom(options) {
|
|
|
4274
4645
|
let hits = 0;
|
|
4275
4646
|
let first = null;
|
|
4276
4647
|
let energy = 0;
|
|
4648
|
+
const pushes = /* @__PURE__ */ new Map();
|
|
4277
4649
|
withoutHeld(() => {
|
|
4278
4650
|
for (const s of shots) {
|
|
4279
4651
|
energy = Math.max(energy, s.energy);
|
|
@@ -4285,11 +4657,16 @@ function createTestRoom(options) {
|
|
|
4285
4657
|
end = r0.point;
|
|
4286
4658
|
if (!first) first = { object: r0.object, part: r0.part, point: r0.point, normal: [0, 1, 0], distance: dist3(s.origin, r0.point) };
|
|
4287
4659
|
const speed = Math.max(80, s.speed);
|
|
4288
|
-
|
|
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);
|
|
4289
4665
|
}
|
|
4290
4666
|
if (shots.length <= 3 || rnd() < 0.34) tracer(m, end);
|
|
4291
4667
|
}
|
|
4292
4668
|
});
|
|
4669
|
+
shoveFree(pushes);
|
|
4293
4670
|
player.kick(recoil[0], recoil[1]);
|
|
4294
4671
|
const f = first;
|
|
4295
4672
|
const d = f ? num(f.distance, 1) : "";
|
|
@@ -4381,16 +4758,25 @@ function createTestRoom(options) {
|
|
|
4381
4758
|
let strikes = [];
|
|
4382
4759
|
const kickLeg = options.kickLeg ?? "alternate";
|
|
4383
4760
|
let nextLeg = "right";
|
|
4761
|
+
const punchHand = options.punchHand ?? "alternate";
|
|
4762
|
+
const punchTools = new Set(options.punchTools ?? ["hand", "fists"]);
|
|
4763
|
+
let nextHand = "right";
|
|
4384
4764
|
const strikeUse = (u, id = toolId) => {
|
|
4385
4765
|
const clip = strikeClips[id];
|
|
4386
4766
|
const leg = id === "kick" ? kickLeg === "alternate" ? nextLeg : kickLeg : void 0;
|
|
4387
|
-
const
|
|
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;
|
|
4388
4770
|
if (leg && seconds !== null && kickLeg === "alternate") nextLeg = leg === "right" ? "left" : "right";
|
|
4771
|
+
if (hand && seconds !== null && punchHand === "alternate") nextHand = hand === "right" ? "left" : "right";
|
|
4389
4772
|
if (clip === void 0 || seconds === null) {
|
|
4390
4773
|
meleeUse(u, id);
|
|
4391
4774
|
return;
|
|
4392
4775
|
}
|
|
4393
|
-
|
|
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
|
+
});
|
|
4394
4780
|
strikes.push({
|
|
4395
4781
|
key: id,
|
|
4396
4782
|
remaining: seconds,
|
|
@@ -4629,6 +5015,10 @@ function createTestRoom(options) {
|
|
|
4629
5015
|
heldPiece = null;
|
|
4630
5016
|
heldTilt = 0;
|
|
4631
5017
|
};
|
|
5018
|
+
const handUse = () => {
|
|
5019
|
+
if (heldPiece) grab();
|
|
5020
|
+
else useTool(FIXED_DT, false);
|
|
5021
|
+
};
|
|
4632
5022
|
const grab = () => {
|
|
4633
5023
|
if (heldPiece) {
|
|
4634
5024
|
const name = heldName;
|
|
@@ -5097,10 +5487,10 @@ function createTestRoom(options) {
|
|
|
5097
5487
|
if (tiltKey || heldTilt > 0) {
|
|
5098
5488
|
heldTilt = Math.max(0, Math.min(2.4, heldTilt + (tiltKey ? 2.2 : -3) * dt));
|
|
5099
5489
|
}
|
|
5100
|
-
if (useHeld && !paused) {
|
|
5490
|
+
if ((useHeld || useFirst) && !paused) {
|
|
5101
5491
|
if (tool.def.category === "hand") {
|
|
5102
|
-
if (useFirst)
|
|
5103
|
-
} else useTool(dt, !useFirst);
|
|
5492
|
+
if (useFirst) handUse();
|
|
5493
|
+
} else if (useHeld) useTool(dt, !useFirst);
|
|
5104
5494
|
useFirst = false;
|
|
5105
5495
|
}
|
|
5106
5496
|
if (!paused) followHeld(dt);
|
|
@@ -5655,6 +6045,63 @@ function createTestRoom(options) {
|
|
|
5655
6045
|
const row = (list, gap, z) => list.map((item, index) => spawn(item.id, [(index - (list.length - 1) / 2) * gap, 0, z], 0));
|
|
5656
6046
|
return [...row(front, 1.6, 1.5), ...row(back, 4.5, -4)];
|
|
5657
6047
|
};
|
|
6048
|
+
const catalogGroups = () => {
|
|
6049
|
+
const m = /* @__PURE__ */ new Map();
|
|
6050
|
+
for (const i of catalog) {
|
|
6051
|
+
const g = m.get(i.group) ?? [];
|
|
6052
|
+
g.push(i);
|
|
6053
|
+
m.set(i.group, g);
|
|
6054
|
+
}
|
|
6055
|
+
return m;
|
|
6056
|
+
};
|
|
6057
|
+
const tableOptions = options.testTable === false ? {} : options.testTable ?? {};
|
|
6058
|
+
const tableScenery = tableOptions.scenery ?? "test_table";
|
|
6059
|
+
const measured = /* @__PURE__ */ new Map();
|
|
6060
|
+
const testTable = createTestTable(
|
|
6061
|
+
{
|
|
6062
|
+
groups: catalogGroups,
|
|
6063
|
+
top: () => {
|
|
6064
|
+
const top = arena.tops.find((x) => x.id === tableScenery);
|
|
6065
|
+
return top && topOk(top) ? top : null;
|
|
6066
|
+
},
|
|
6067
|
+
measure: (itemId) => {
|
|
6068
|
+
let size = measured.get(itemId);
|
|
6069
|
+
if (!size) {
|
|
6070
|
+
const item = catalogMap.get(itemId);
|
|
6071
|
+
const box2 = item ? new THREE.Box3().setFromObject(buildRoot(item)) : null;
|
|
6072
|
+
size = box2 && !box2.isEmpty() ? { w: box2.max.x - box2.min.x, d: box2.max.z - box2.min.z } : { w: 0.3, d: 0.3 };
|
|
6073
|
+
measured.set(itemId, size);
|
|
6074
|
+
}
|
|
6075
|
+
return size;
|
|
6076
|
+
},
|
|
6077
|
+
spawn: (itemId, position) => spawn(itemId, position, 0),
|
|
6078
|
+
clear,
|
|
6079
|
+
resetAll,
|
|
6080
|
+
box: (objectId) => {
|
|
6081
|
+
const e = entries.get(objectId);
|
|
6082
|
+
if (!e || !world.has(objectId)) return null;
|
|
6083
|
+
const box2 = new THREE.Box3().setFromObject(e.so.root);
|
|
6084
|
+
return box2.isEmpty() ? null : { min: [box2.min.x, box2.min.y, box2.min.z], max: [box2.max.x, box2.max.y, box2.max.z] };
|
|
6085
|
+
},
|
|
6086
|
+
equip: (weapon) => {
|
|
6087
|
+
if (!arsenal.weapons.has(weapon)) return false;
|
|
6088
|
+
if (heldEntry) releaseHeld();
|
|
6089
|
+
equip(weapon);
|
|
6090
|
+
room.waitUntilReady();
|
|
6091
|
+
return true;
|
|
6092
|
+
},
|
|
6093
|
+
look: (eye, target) => player.look(eye, target),
|
|
6094
|
+
use: (hold) => room.use(hold),
|
|
6095
|
+
blastAt: (weapon, point) => {
|
|
6096
|
+
const def = arsenal.weapons.get(weapon);
|
|
6097
|
+
const explosive = def?.action.kind === "throwable" ? def.action.explosive : def?.action.kind === "launcher" ? def.action.projectile : void 0;
|
|
6098
|
+
return explosive !== void 0 && explosives.blastAt(weapon, explosive, point);
|
|
6099
|
+
},
|
|
6100
|
+
log: (type, text, data) => action(type, text, { data }),
|
|
6101
|
+
translate: t
|
|
6102
|
+
},
|
|
6103
|
+
tableOptions
|
|
6104
|
+
);
|
|
5658
6105
|
const room = {
|
|
5659
6106
|
world,
|
|
5660
6107
|
renderer,
|
|
@@ -5674,6 +6121,7 @@ function createTestRoom(options) {
|
|
|
5674
6121
|
get scenarios() {
|
|
5675
6122
|
return allScenarios();
|
|
5676
6123
|
},
|
|
6124
|
+
testTable,
|
|
5677
6125
|
spawn,
|
|
5678
6126
|
clear,
|
|
5679
6127
|
resetAll,
|
|
@@ -5681,7 +6129,8 @@ function createTestRoom(options) {
|
|
|
5681
6129
|
useItem,
|
|
5682
6130
|
use(hold = 0) {
|
|
5683
6131
|
if (tool.def.category === "hand") {
|
|
5684
|
-
|
|
6132
|
+
handUse();
|
|
6133
|
+
flush();
|
|
5685
6134
|
return;
|
|
5686
6135
|
}
|
|
5687
6136
|
useTool(FIXED_DT, false);
|
|
@@ -5914,7 +6363,8 @@ function createTestRoom(options) {
|
|
|
5914
6363
|
},
|
|
5915
6364
|
onAction: (id) => {
|
|
5916
6365
|
if (activeBench) slowly(activeBench, id, () => benches.get(activeBench)?.act(id));
|
|
5917
|
-
}
|
|
6366
|
+
},
|
|
6367
|
+
...options.testTable !== false && arena.tops.some((x) => x.id === tableScenery) ? { testTable } : {}
|
|
5918
6368
|
});
|
|
5919
6369
|
ui.hud(hudState());
|
|
5920
6370
|
showBench();
|
|
@@ -5967,19 +6417,25 @@ function structuredCloneSpec(spec) {
|
|
|
5967
6417
|
export {
|
|
5968
6418
|
DEFAULT_HAND_STANCES,
|
|
5969
6419
|
DEFAULT_STRIKE_CLIPS,
|
|
6420
|
+
DEFAULT_TRIALS,
|
|
5970
6421
|
LOADING_CLASS,
|
|
5971
6422
|
LOADING_CSS,
|
|
5972
6423
|
MATERIAL_COLORS,
|
|
6424
|
+
TRIAL_KINDS,
|
|
5973
6425
|
brickWallSpec,
|
|
5974
6426
|
buildFromSpec,
|
|
5975
6427
|
createLoading,
|
|
5976
6428
|
createLog,
|
|
5977
6429
|
createTestRoom,
|
|
6430
|
+
createTestTable,
|
|
5978
6431
|
decodeBenchState,
|
|
5979
6432
|
encodeBenchState,
|
|
6433
|
+
fitRow,
|
|
5980
6434
|
loadingMarkup,
|
|
5981
6435
|
locales,
|
|
5982
6436
|
nextPaint,
|
|
5983
|
-
resolveStrings
|
|
6437
|
+
resolveStrings,
|
|
6438
|
+
rowCentres,
|
|
6439
|
+
trialView
|
|
5984
6440
|
};
|
|
5985
6441
|
//# sourceMappingURL=index.js.map
|