@adatechnology/game-weapons-three 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.
@@ -14856,7 +14856,7 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
14856
14856
  shade: () => shade
14857
14857
  });
14858
14858
 
14859
- // ../game-shapes/dist/chunk-M5N2SHNL.js
14859
+ // ../game-shapes/dist/chunk-FZQTELDQ.js
14860
14860
  function canonicalJson(value) {
14861
14861
  if (value === null) return "null";
14862
14862
  if (typeof value === "number") return Object.is(value, -0) ? "-0" : Number.isFinite(value) ? String(value) : JSON.stringify(String(value));
@@ -15768,17 +15768,19 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
15768
15768
  if (p.prevZ) p.prevZ.nextZ = p.nextZ;
15769
15769
  if (p.nextZ) p.nextZ.prevZ = p.prevZ;
15770
15770
  }
15771
- function Node(i, x, y) {
15772
- this.i = i;
15773
- this.x = x;
15774
- this.y = y;
15775
- this.prev = null;
15776
- this.next = null;
15777
- this.z = 0;
15778
- this.prevZ = null;
15779
- this.nextZ = null;
15780
- this.steiner = false;
15781
- }
15771
+ var Node = class {
15772
+ constructor(i, x, y) {
15773
+ this.i = i;
15774
+ this.x = x;
15775
+ this.y = y;
15776
+ this.prev = null;
15777
+ this.next = null;
15778
+ this.z = 0;
15779
+ this.prevZ = null;
15780
+ this.nextZ = null;
15781
+ this.steiner = false;
15782
+ }
15783
+ };
15782
15784
  function signedArea(data, start, end3, dim) {
15783
15785
  let sum2 = 0;
15784
15786
  for (let i = start, j = end3 - dim; i < end3; i += dim) {
@@ -16622,6 +16624,9 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
16622
16624
  }
16623
16625
  return releaseObject3D(list2, { keep });
16624
16626
  }
16627
+ function isMesh(o) {
16628
+ return !!o && o.isMesh === true;
16629
+ }
16625
16630
 
16626
16631
  // ../game-props3d/dist/index.js
16627
16632
  function rng(seed) {
@@ -21699,6 +21704,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
21699
21704
  floor: 60
21700
21705
  }
21701
21706
  },
21707
+ ricochetDeg: 12,
21702
21708
  hitDebris: "chips",
21703
21709
  breakDebris: "dust",
21704
21710
  visual: { innerColor: 10197652 },
@@ -21730,6 +21736,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
21730
21736
  0.04,
21731
21737
  0.12
21732
21738
  ],
21739
+ ricochetDeg: 10,
21733
21740
  hitDebris: "chips",
21734
21741
  breakDebris: "dust",
21735
21742
  visual: { innerColor: 12085567 },
@@ -21787,6 +21794,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
21787
21794
  0.06,
21788
21795
  0.3
21789
21796
  ],
21797
+ ricochetDeg: 15,
21790
21798
  hitDebris: "chips",
21791
21799
  breakDebris: "dust",
21792
21800
  visual: { innerColor: 9407364 },
@@ -22215,6 +22223,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22215
22223
  0.03,
22216
22224
  0.15
22217
22225
  ],
22226
+ ricochetDeg: 8,
22218
22227
  hitDebris: "chips",
22219
22228
  breakDebris: "dust",
22220
22229
  thermal: {
@@ -22314,6 +22323,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22314
22323
  0.02,
22315
22324
  0.08
22316
22325
  ],
22326
+ ricochetDeg: 8,
22317
22327
  hitDebris: "chips",
22318
22328
  breakDebris: "dust",
22319
22329
  thermal: {
@@ -22408,6 +22418,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22408
22418
  0.05,
22409
22419
  0.15
22410
22420
  ],
22421
+ ricochetDeg: 15,
22411
22422
  hitDebris: "chips",
22412
22423
  breakDebris: "chips",
22413
22424
  thermal: {
@@ -22433,6 +22444,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22433
22444
  0.04,
22434
22445
  0.12
22435
22446
  ],
22447
+ ricochetDeg: 12,
22436
22448
  hitDebris: "chips",
22437
22449
  breakDebris: "chips",
22438
22450
  thermal: {
@@ -27923,7 +27935,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
27923
27935
  }
27924
27936
  var towerLocales = { en: { labels: en_default.labels }, "pt-BR": { labels: pt_BR_default.labels } };
27925
27937
 
27926
- // ../game-floorplan-three/dist/chunk-7XVCZF6H.js
27938
+ // ../game-floorplan-three/dist/chunk-Y3Y7NYOL.js
27939
+ var __defProp3 = Object.defineProperty;
27940
+ var __defNormalProp2 = (obj, key2, value) => key2 in obj ? __defProp3(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
27941
+ var __publicField2 = (obj, key2, value) => __defNormalProp2(obj, typeof key2 !== "symbol" ? key2 + "" : key2, value);
27927
27942
  var en2 = {
27928
27943
  "prompt.open": "E: open {what}",
27929
27944
  "prompt.close": "E: close {what}",
@@ -28007,6 +28022,20 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28007
28022
  const WITH_MAP = { roughcast: 1, block: 1 };
28008
28023
  class Accumulator {
28009
28024
  constructor() {
28025
+ __publicField2(this, "cv");
28026
+ __publicField2(this, "ci");
28027
+ __publicField2(this, "p");
28028
+ __publicField2(this, "n");
28029
+ __publicField2(this, "c");
28030
+ __publicField2(this, "u");
28031
+ __publicField2(this, "i");
28032
+ __publicField2(this, "nv");
28033
+ __publicField2(this, "ni");
28034
+ __publicField2(this, "lim");
28035
+ __publicField2(this, "cur");
28036
+ __publicField2(this, "piece0");
28037
+ __publicField2(this, "mat", "");
28038
+ __publicField2(this, "group", "");
28010
28039
  this.cv = 2048;
28011
28040
  this.ci = 3072;
28012
28041
  this.p = new Float32Array(this.cv * 3);
@@ -28069,7 +28098,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28069
28098
  g.position.copy(u.pose0.p);
28070
28099
  g.quaternion.copy(u.pose0.q);
28071
28100
  g.scale.copy(u.pose0.s);
28072
- const e = new THREE.Vector3(...a.axis || [0, 1, 0]);
28101
+ const [ax, ay, az] = a.axis || [0, 1, 0];
28102
+ const e = new THREE.Vector3(ax, ay, az);
28073
28103
  if (a.type === "swing" || a.type === "toggle") g.rotateOnAxis(e, (a.angle || 0) * t);
28074
28104
  else if (a.type === "slide") g.translateOnAxis(e, (a.dist || 0) * t);
28075
28105
  else if (a.type === "scale") {
@@ -28164,7 +28194,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28164
28194
  }
28165
28195
  if (uvr) {
28166
28196
  let gu = G.u[k * 2], gv = G.u[k * 2 + 1];
28167
- for (let r = uvr.rot | 0; r > 0; r--) {
28197
+ for (let r = (uvr.rot ?? 0) | 0; r > 0; r--) {
28168
28198
  const t = gu;
28169
28199
  gu = gv;
28170
28200
  gv = 1 - t;
@@ -28262,14 +28292,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28262
28292
  A.nv += n;
28263
28293
  }
28264
28294
  let bxImpl = bxBase;
28265
- function bx(...a) {
28266
- return bxImpl(...a);
28267
- }
28268
- K.getBx = () => bxImpl;
28269
- K.setBx = (f) => {
28295
+ const bx = (...a) => bxImpl(...a);
28296
+ const getBx = () => bxImpl;
28297
+ const setBx = (f) => {
28270
28298
  bxImpl = f;
28271
28299
  };
28272
- Object.assign(K, { GEO, UV_SCALE, WITH_MAP, Accumulator, cursor, PARTS, MIRRORS, part, applyPart, _Y, _qa, _qb, pieceRecord, structurePiece, accFor, _q, _e, _col, rgbOf, put, boxC, bx, cylBase, polyFace });
28300
+ const defined = { GEO, UV_SCALE, WITH_MAP, Accumulator, cursor, PARTS, MIRRORS, part, applyPart, _Y, _qa, _qb, pieceRecord, structurePiece, accFor, _q, _e, _col, rgbOf, put, boxC, bx, getBx, setBx, cylBase, polyFace };
28301
+ Object.assign(K, defined);
28273
28302
  }
28274
28303
  function installKernelNoise(K, _shared) {
28275
28304
  const _h2 = (x, z) => {
@@ -28285,15 +28314,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28285
28314
  const n = 0.5 * vnoise(x / 5.5, z / 5.5) + 0.32 * vnoise(x / 1.9 + 31, z / 1.9) + 0.18 * vnoise(x / 0.8 + 7, z / 0.8), m = vnoise(x / 9 + 100, z / 9 + 50) - 0.5, f = 0.76 + 0.5 * n;
28286
28315
  return type === "dirt" ? [f * (1 + 0.14 * m), f * (1 + 0.03 * m), f * (1 - 0.18 * m)] : [f * (1 + 0.1 * m), f * (1 + 0.05 * m), f * (1 - 0.1 * m)];
28287
28316
  }
28288
- Object.assign(K, { _h2, vnoise, macroGround });
28317
+ const defined = { _h2, vnoise, macroGround };
28318
+ Object.assign(K, defined);
28289
28319
  }
28290
28320
  function installMaterialsTextures(K, _shared) {
28291
28321
  const { DOC, THREE, cfg } = K;
28292
28322
  function texture(n, f, rep = true, rx = 1, ry = 1) {
28323
+ if (!DOC) throw new Error("game-floorplan-three: the procedural textures need a document (options.document)");
28293
28324
  const c = DOC.createElement("canvas");
28294
28325
  c.width = n;
28295
28326
  c.height = n;
28296
28327
  const g = c.getContext("2d");
28328
+ if (!g) throw new Error("game-floorplan-three: no 2d canvas context");
28297
28329
  f(g, n);
28298
28330
  const t = new THREE.CanvasTexture(c);
28299
28331
  t.colorSpace = THREE.SRGBColorSpace;
@@ -28412,7 +28444,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28412
28444
  const TEX = {};
28413
28445
  for (const k of Object.keys(TEXGEN)) TEX[k] = cfg.textures && cfg.textures[k] || TEXGEN[k]();
28414
28446
  const ATLAS = {};
28415
- Object.assign(K, { texture, rngTexture, TEXGEN, TEX, ATLAS });
28447
+ const defined = { texture, rngTexture, TEXGEN, TEX, ATLAS };
28448
+ Object.assign(K, defined);
28449
+ }
28450
+ function context2d(c) {
28451
+ const g = c.getContext("2d");
28452
+ if (!g) throw new Error("game-floorplan-three: no 2d canvas context");
28453
+ return g;
28416
28454
  }
28417
28455
  function installMaterialsMaterials(K, _shared) {
28418
28456
  const { THREE, cfg, ATLAS, TEX, rngTexture } = K;
@@ -28425,7 +28463,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28425
28463
  return t;
28426
28464
  };
28427
28465
  if (!(cfg.atlas && cfg.atlas.floorKind)) {
28428
- const pc = props.atlas("floor").canvas, g = pc.getContext("2d");
28466
+ const pc = props.atlas("floor").canvas, g = context2d(pc);
28429
28467
  for (const c of [0, 1]) {
28430
28468
  g.save();
28431
28469
  g.globalCompositeOperation = "screen";
@@ -28440,7 +28478,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28440
28478
  g.restore();
28441
28479
  }
28442
28480
  if (!(cfg.atlas && cfg.atlas.floorKind)) {
28443
- const pc = props.atlas("floor").canvas, g = pc.getContext("2d");
28481
+ const pc = props.atlas("floor").canvas, g = context2d(pc);
28444
28482
  g.save();
28445
28483
  g.fillStyle = "rgba(128,92,62,0.52)";
28446
28484
  g.fillRect(256, 256, 256, 256);
@@ -28537,7 +28575,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28537
28575
  }
28538
28576
  const ORDER2 = { glass: 3, water: 2, screen: 3, building: 4 };
28539
28577
  const NO_SHADOW = /* @__PURE__ */ new Set(["dirt", "glass", "water", "screen", "building", "picture", "floor", "emissive"]);
28540
- Object.assign(K, { createMaterials: createMaterials2, antiTile, dirtMaterial, CLOTHES_UNIFORMS, clothesMaterial, ORDER: ORDER2, NO_SHADOW });
28578
+ const defined = { createMaterials: createMaterials2, antiTile, dirtMaterial, CLOTHES_UNIFORMS, clothesMaterial, ORDER: ORDER2, NO_SHADOW };
28579
+ Object.assign(K, defined);
28541
28580
  }
28542
28581
  function installKernelCloseScene(K, shared2) {
28543
28582
  const { THREE, NO_SHADOW, ORDER: ORDER2, PARTS, applyPart, cursor } = K;
@@ -28546,15 +28585,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28546
28585
  const assembleVegetation = (...a) => K.assembleVegetation(...a);
28547
28586
  function markMesh(m, A) {
28548
28587
  const L = A.lim, fx = [];
28588
+ const pieces = shared2.ctx.pieces;
28549
28589
  for (let k = 0; k < L.length; k++) {
28550
- if (!L[k].pc) continue;
28551
- const v1 = k + 1 < L.length ? L[k + 1].v : A.nv, i1 = k + 1 < L.length ? L[k + 1].i : A.ni;
28552
- if (v1 > L[k].v) fx.push({ id: L[k].pc.id, v0: L[k].v, v1, i0: L[k].i, i1 });
28590
+ const lim = L[k], pc = lim.pc;
28591
+ if (!pc) continue;
28592
+ const next = L[k + 1];
28593
+ const v1 = next ? next.v : A.nv, i1 = next ? next.i : A.ni;
28594
+ if (v1 > lim.v) fx.push({ id: pc.id, v0: lim.v, v1, i0: lim.i, i1 });
28553
28595
  }
28554
28596
  if (!fx.length) return;
28555
28597
  const u = m.userData, ids = [...new Set(fx.map((f) => f.id))], weight = {};
28556
28598
  for (const f of fx) {
28557
- const mt = shared2.ctx.pieces.get(f.id).mat;
28599
+ const mt = pieces.get(f.id).mat;
28558
28600
  weight[mt] = (weight[mt] || 0) + f.v1 - f.v0;
28559
28601
  }
28560
28602
  u.ranges = fx;
@@ -28562,7 +28604,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28562
28604
  u.destructionMaterial = Object.keys(weight).sort((a, b) => weight[b] - weight[a])[0];
28563
28605
  if (ids.length === 1) {
28564
28606
  u.destructionPart = ids[0];
28565
- const pc = shared2.ctx.pieces.get(ids[0]);
28607
+ const pc = pieces.get(ids[0]);
28566
28608
  if (pc.role) u.structuralRole = pc.role;
28567
28609
  }
28568
28610
  }
@@ -28613,7 +28655,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28613
28655
  assembleVegetation(groups);
28614
28656
  return groups;
28615
28657
  }
28616
- Object.assign(K, { markMesh, closeScene });
28658
+ const defined = { markMesh, closeScene };
28659
+ Object.assign(K, defined);
28617
28660
  }
28618
28661
  function installHouseHelpers(K, shared2) {
28619
28662
  shared2.ctx = {};
@@ -28649,8 +28692,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28649
28692
  for (const h of holes) L = L.flatMap((r) => subRect(r, h));
28650
28693
  return L;
28651
28694
  }
28652
- const wallColor = (c) => c && c.color && colorOf(c.color.wall) != null ? colorOf(c.color.wall) : 14999768;
28653
- const floorColor = (c) => c && c.color && colorOf(c.color.floor) != null ? colorOf(c.color.floor) : 11577496;
28695
+ const wallColor = (c) => {
28696
+ const k = c && c.color ? colorOf(c.color.wall) : null;
28697
+ return k != null ? k : 14999768;
28698
+ };
28699
+ const floorColor = (c) => {
28700
+ const k = c && c.color ? colorOf(c.color.floor) : null;
28701
+ return k != null ? k : 11577496;
28702
+ };
28654
28703
  function stairFootprint(m) {
28655
28704
  const c = Math.cos(m.ry), s = Math.sin(m.ry), pts = [[-m.w / 2, -m.d / 2], [m.w / 2, -m.d / 2], [m.w / 2, m.d / 2], [-m.w / 2, m.d / 2]].map(([a, b]) => [m.x + a * c + b * s, m.z - a * s + b * c]);
28656
28705
  return [Math.min(...pts.map((p) => p[0])), Math.min(...pts.map((p) => p[1])), Math.max(...pts.map((p) => p[0])), Math.max(...pts.map((p) => p[1]))];
@@ -28661,11 +28710,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28661
28710
  const pitch = A[f + 1].y0 - A[f].y0;
28662
28711
  return h > pitch && h - pitch <= 0.45 ? pitch : h;
28663
28712
  }
28664
- Object.assign(K, { OPEN_ROOM_TYPES: OPEN_ROOM_TYPES22, NO_CEILING, OPEN_AREA, EPS: EPS6, Y0, colorOf, rectsOf: rectsOf2, roomAt, subRect, subRects, wallColor, floorColor, stairFootprint, effectiveHeight });
28713
+ const defined = { OPEN_ROOM_TYPES: OPEN_ROOM_TYPES22, NO_CEILING, OPEN_AREA, EPS: EPS6, Y0, colorOf, rectsOf: rectsOf2, roomAt, subRect, subRects, wallColor, floorColor, stairFootprint, effectiveHeight };
28714
+ Object.assign(K, defined);
28665
28715
  }
28666
28716
  function installHouseWalls(K, shared2) {
28667
28717
  const { EPS: EPS6, Y0, boxC, bx, cursor, effectiveHeight, pieceRecord, structurePiece, wallColor } = K;
28668
- const sh = (color2, factor) => K.sh(color2, factor);
28718
+ const sh = (...a) => K.sh(...a);
28669
28719
  function wallBox(alongU, L, a, b, ya, yb, th, cL, cH, mL, mH) {
28670
28720
  if (yb - ya < 1e-4 || b - a < 1e-4) return;
28671
28721
  if (alongU) {
@@ -28711,7 +28761,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28711
28761
  const corners = /* @__PURE__ */ new Map();
28712
28762
  const looks = /* @__PURE__ */ new Map();
28713
28763
  for (const w of R.walls) {
28714
- const f = w.floor;
28764
+ const f = w.floor, colliders = shared2.ctx.colliders;
28715
28765
  cursor.group = "f" + f;
28716
28766
  cursor.pc = pieceOf(w);
28717
28767
  const y0 = Y0(f), pitch = f + 1 < nA ? Y0(f + 1) - y0 : Infinity, th = w.thickness || 0.15, alongU = w.axis === "u";
@@ -28723,7 +28773,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28723
28773
  const face = sideL.exterior ? sideL : sideH;
28724
28774
  looks.set(w.id, { mat: face.mat, color: face.color, top: y0 + hh });
28725
28775
  }
28726
- shared2.ctx.colliders.push({ type: "wall", piece: w.id, f, x0: alongU ? s0 : L - th / 2, z0: alongU ? L - th / 2 : s0, x1: alongU ? s1 : L + th / 2, z1: alongU ? L + th / 2 : s1 });
28776
+ colliders.push({ type: "wall", piece: w.id, f, x0: alongU ? s0 : L - th / 2, z0: alongU ? L - th / 2 : s0, x1: alongU ? s1 : L + th / 2, z1: alongU ? L + th / 2 : s1 });
28727
28777
  if (w.type === "railing") {
28728
28778
  const c0 = shared2.ctx.colors.metal != null ? shared2.ctx.colors.metal : 9080466;
28729
28779
  const sx = alongU ? 1 : 0, sz = alongU ? 0 : 1, len = s1 - s0, n = Math.max(1, Math.round(len / 1.4));
@@ -28789,7 +28839,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28789
28839
  }
28790
28840
  cursor.pc = null;
28791
28841
  }
28792
- Object.assign(K, { wallBox, sideOf, pieceOf, nearestWall, walls, wallPillars });
28842
+ const defined = { wallBox, sideOf, pieceOf, nearestWall, walls, wallPillars };
28843
+ Object.assign(K, defined);
28793
28844
  }
28794
28845
  function installHouseDoors(K, shared2) {
28795
28846
  const seedKey = (id) => K.seedKey(id);
@@ -28806,7 +28857,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28806
28857
  }
28807
28858
  shared2.doorState = /* @__PURE__ */ new Map();
28808
28859
  function doors() {
28809
- shared2.ctx.leaves = [];
28860
+ const leaves = shared2.ctx.leaves = [], doorState = shared2.doorState, colliders = shared2.ctx.colliders;
28810
28861
  const R = shared2.ctx.r, cut = shared2.ctx.cut, C = shared2.ctx.colors, wood = C.wood != null ? C.wood : 8016948, frame2 = sh(wood, 0.55);
28811
28862
  for (const p of R.doors) {
28812
28863
  const f = p.floor;
@@ -28837,21 +28888,21 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28837
28888
  }
28838
28889
  const leaf = (u0, u1, y_0, y_1, tt, color2, mat = "wood") => alongU ? bx(mat, u0, y0 + y_0, L - tt / 2, u1, y0 + y_1, L + tt / 2, color2) : bx(mat, L - tt / 2, y0 + y_0, u0, L + tt / 2, y0 + y_1, u1, color2);
28839
28890
  const extC = wood;
28840
- const open0 = p.blocked ? false : shared2.doorState.has(p.id) ? shared2.doorState.get(p.id) : !!p.open;
28841
- shared2.doorState.set(p.id, open0);
28891
+ const open0 = p.blocked ? false : doorState.has(p.id) ? doorState.get(p.id) === true : !!p.open;
28892
+ doorState.set(p.id, open0);
28842
28893
  const dc = alongU ? [p.at, L] : [L, p.at];
28843
- const fo = { id: p.id, floor: f, type: p.model === "steel" ? "steel" : "swing", open: open0, t: open0 ? 1 : 0, blockedFlag: !!p.blocked, locked: R.state === "fortified" && !!p.exterior, handleNames: [], hT: 0, cx: dc[0], cz: dc[1], visH, groups: [], col: null };
28894
+ const fo = { id: p.id, floor: f, type: p.model === "steel" ? "steel" : "swing", open: open0, t: open0 ? 1 : 0, blockedFlag: !!p.blocked, locked: R.state === "fortified" && !!p.exterior, handleNames: [], hT: 0, cx: dc[0], cz: dc[1], visH, groups: [], gs: [], col: null };
28844
28895
  const colR = { type: "door", f, x0: alongU ? a : L - th / 2, z0: alongU ? L - th / 2 : a, x1: alongU ? b : L + th / 2, z1: alongU ? L + th / 2 : b, off: open0 };
28845
- shared2.ctx.colliders.push(colR);
28896
+ colliders.push(colR);
28846
28897
  fo.col = colR;
28847
28898
  const leafBox = (hu, d0, d1, y_0, y_1, tt, color2, mat) => alongU ? bx(mat, d0, y_0, -tt / 2, d1, y_1, tt / 2, color2) : bx(mat, -tt / 2, y_0, d0, tt / 2, y_1, d1, color2);
28848
- const newGroup = (k, hu, topY) => {
28899
+ const newGroup2 = (k, hu, topY) => {
28849
28900
  cursor.group = "dyn:" + p.id + ":" + k;
28850
28901
  fo.groups.push({ name: cursor.group, pos: alongU ? [hu, topY != null ? y0 + topY : y0, L] : [L, topY != null ? y0 + topY : y0, hu] });
28851
28902
  };
28852
28903
  if (p.model === "steel") {
28853
- const light = [14276044, 13223615, 14999766], pal = ((R.seed | 0) + p.id.length * 7) % 4, color2 = pal === 3 ? wood : light[pal], mid = (a + b) / 2;
28854
- newGroup(0, mid, visH);
28904
+ const light = [14276044, 13223615, 14999766], pal = ((Number(R.seed) | 0) + p.id.length * 7) % 4, color2 = pal === 3 ? wood : light[pal], mid = (a + b) / 2;
28905
+ newGroup2(0, mid, visH);
28855
28906
  const la = a + jw - mid, lb = b - jw - mid, nSec = Math.max(4, Math.round(visH / 0.5)), hs = visH / nSec, grv = sh(color2, 0.55);
28856
28907
  leafBox(0, la, lb, -visH, 0, 0.05, color2, "metal");
28857
28908
  for (let k = 1; k < nSec; k++) leafBox(0, la, lb, -k * hs - 0.012, -k * hs + 0.012, 0.07, grv, "metal");
@@ -28866,7 +28917,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28866
28917
  for (let k = 0; k < nf; k++) {
28867
28918
  const u0 = nf === 2 ? k ? (aa + bb) / 2 : aa : aa, u1 = nf === 2 ? k ? bb : (aa + bb) / 2 : bb, color2 = p.exterior ? extC : wood;
28868
28919
  const hingeAt = nf === 2 ? k ? u1 : u0 : p.hinge === "end" ? u1 : u0, dir = hingeAt === u0 ? 1 : -1, len = u1 - u0;
28869
- newGroup(k, hingeAt);
28920
+ newGroup2(k, hingeAt);
28870
28921
  const d0 = dir > 0 ? 5e-3 : -len + 5e-3, d1 = dir > 0 ? len - 5e-3 : -5e-3;
28871
28922
  leafBox(hingeAt, d0, d1, 0, visH, 0.04, color2, PMAT);
28872
28923
  {
@@ -28902,7 +28953,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28902
28953
  fo.rot = Math.atan2(n[0] * A[1] - n[1] * A[0], A[0] * n[0] + A[1] * n[1]);
28903
28954
  }
28904
28955
  }
28905
- shared2.ctx.leaves.push(fo);
28956
+ leaves.push(fo);
28906
28957
  cursor.group = "f" + f;
28907
28958
  if (p.blocked) {
28908
28959
  part("window_boards", [0, 0, 0], () => {
@@ -28930,11 +28981,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28930
28981
  }
28931
28982
  }
28932
28983
  }, { id: "boards:" + p.id }, "f" + f);
28933
- shared2.ctx.colliders.push({ type: "board", f, x0: alongU ? a : L - th / 2, z0: alongU ? L - th / 2 : a, x1: alongU ? b : L + th / 2, z1: alongU ? L + th / 2 : b });
28984
+ colliders.push({ type: "board", f, x0: alongU ? a : L - th / 2, z0: alongU ? L - th / 2 : a, x1: alongU ? b : L + th / 2, z1: alongU ? L + th / 2 : b });
28934
28985
  }
28935
28986
  }
28936
28987
  }
28937
- Object.assign(K, { doorLineSides, doors });
28988
+ const defined = { doorLineSides, doors };
28989
+ Object.assign(K, defined);
28938
28990
  }
28939
28991
  function installHouseWindows(K, shared2) {
28940
28992
  const { EPS: EPS6, Y0, boxC, bx, cursor, pieceRecord, roomAt } = K;
@@ -28992,7 +29044,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28992
29044
  }
28993
29045
  }
28994
29046
  }
28995
- Object.assign(K, { FRAME_COLORS, SILL_COLORS, windows });
29047
+ const defined = { FRAME_COLORS, SILL_COLORS, windows };
29048
+ Object.assign(K, defined);
28996
29049
  }
28997
29050
  function installHouseFloors(K, shared2) {
28998
29051
  const { rectsOf: rectsOf2, EPS: EPS6, OPEN_AREA, Y0, bx, cursor, floorColor, stairFootprint, structurePiece, subRects } = K;
@@ -29000,7 +29053,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29000
29053
  if (shared2.ctx._flights && shared2.ctx._flights.r === shared2.ctx.r) return shared2.ctx._flights.l;
29001
29054
  const R = shared2.ctx.r, mp = /* @__PURE__ */ new Map();
29002
29055
  for (const m of R.items) {
29003
- if (m.type !== "stairs" || !m.link) continue;
29056
+ if (m.type !== "stairs" || !m.link || typeof m.link !== "object") continue;
29004
29057
  const k = [m.link.from, m.link.to, m.x.toFixed(2), m.z.toFixed(2), (m.ry || 0).toFixed(2)].join("|");
29005
29058
  if (!mp.has(k)) mp.set(k, { m, from: m.link.from, to: m.link.to, rect: stairFootprint(m) });
29006
29059
  }
@@ -29019,7 +29072,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29019
29072
  }
29020
29073
  const panelRects = (p) => p.footprint && p.footprint.length ? p.footprint : [p.aabb];
29021
29074
  function tilesOf(parent, rc) {
29022
- const ps = parent && shared2.ctx.panelsOf && shared2.ctx.panelsOf.get(parent);
29075
+ const ps = parent ? shared2.ctx.panelsOf && shared2.ctx.panelsOf.get(parent) : void 0;
29023
29076
  if (!ps) return [[parent ? structurePiece(parent) : null, rc]];
29024
29077
  const out = [], taken = [];
29025
29078
  for (const p of ps) for (const q of panelRects(p)) {
@@ -29081,13 +29134,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29081
29134
  const { rectsOf: rectsOf2, Y0, boxC, bx, cursor, flights, stairFootprint, structurePiece } = K;
29082
29135
  const sh = (...a) => K.sh(...a);
29083
29136
  function buildStairs() {
29084
- const R = shared2.ctx.r;
29085
- shared2.ctx.stairs = [];
29137
+ const R = shared2.ctx.r, stairs = shared2.ctx.stairs = [];
29086
29138
  for (const vo of flights()) {
29087
29139
  const m = vo.m, f = vo.from, Dr = m.d - (vo.LP || 0);
29088
29140
  cursor.group = "f" + f;
29089
29141
  cursor.pc = structurePiece("stairs_" + vo.from + "_" + vo.to);
29090
- const y0 = Y0(f), H = Y0(m.link.to) - y0, n = Math.max(8, Math.round(H / 0.18)), c = Math.cos(m.ry), s = Math.sin(m.ry);
29142
+ const y0 = Y0(f), H = Y0(vo.to) - y0, n = Math.max(8, Math.round(H / 0.18)), c = Math.cos(m.ry), s = Math.sin(m.ry);
29091
29143
  const wood = shared2.ctx.colors.wood != null ? shared2.ctx.colors.wood : 9071176, under = sh(wood, 0.7);
29092
29144
  const P = (lx, lz) => [m.x + lx * c + lz * s, m.z - lx * s + lz * c];
29093
29145
  const boxL = (mat, lx, y, lz, w, h, d, color2, rx = 0) => {
@@ -29110,7 +29162,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29110
29162
  }
29111
29163
  }
29112
29164
  cursor.pc = null;
29113
- shared2.ctx.stairs.push({ m, f, to: vo.to, y0, H, rect: stairFootprint(m), landingPoint: (vo.LP || 0) / m.d });
29165
+ stairs.push({ m, f, to: vo.to, y0, H, rect: stairFootprint(m), landingPoint: (vo.LP || 0) / m.d });
29114
29166
  }
29115
29167
  }
29116
29168
  function elevator() {
@@ -29127,7 +29179,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29127
29179
  }
29128
29180
  }
29129
29181
  }
29130
- Object.assign(K, { buildStairs, elevator });
29182
+ const defined = { buildStairs, elevator };
29183
+ Object.assign(K, defined);
29131
29184
  }
29132
29185
  function installLightsFixtures(K, shared2) {
29133
29186
  const seedKey = (id) => K.seedKey(id);
@@ -29165,14 +29218,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29165
29218
  c: (mat, x, y, z, r, h, color2, seg2) => api.cylinder(M, mat, x, y0 + y, z, r, h, color2, 0, 0, seg2),
29166
29219
  e: (mat, x, y, z, r, h, color2) => api.cylinder(M, mat, x, y0 + y - h / 2, z, r, h, color2, 0, 0, "sphere"),
29167
29220
  t(mat, p, q, r, color2, seg2) {
29221
+ const tc = color2 ?? NaN;
29168
29222
  const dx = q[0] - p[0], dy = q[1] - p[1], dz = q[2] - p[2], L = Math.hypot(dx, dy, dz);
29169
29223
  if (L < 1e-5) return;
29170
29224
  const nx = dx / L, ny = dy / L, nz = dz / L;
29171
29225
  if (Math.abs(nx) < 1e-4 && Math.abs(nz) < 1e-4) {
29172
- api.cylinder(M, mat, p[0], y0 + Math.min(p[1], q[1]), p[2], r, L, color2, 0, 0, seg2);
29226
+ api.cylinder(M, mat, p[0], y0 + Math.min(p[1], q[1]), p[2], r, L, tc, 0, 0, seg2);
29173
29227
  return;
29174
29228
  }
29175
- api.cylinder(M, mat, (p[0] + q[0]) / 2, y0 + (p[1] + q[1]) / 2, (p[2] + q[2]) / 2, r, L, color2, Math.atan2(nz, ny), -Math.asin(nx), seg2);
29229
+ api.cylinder(M, mat, (p[0] + q[0]) / 2, y0 + (p[1] + q[1]) / 2, (p[2] + q[2]) / 2, r, L, tc, Math.atan2(nz, ny), -Math.asin(nx), seg2);
29176
29230
  },
29177
29231
  polyFace: (mat, pts, color2, hint) => polyFace(mat, pts.map((p) => W(p[0], p[1], p[2])), color2, hint && [hint[0] * c + hint[2] * s, hint[1], -hint[0] * s + hint[2] * c]),
29178
29232
  part(type, lx, ly, lz, fn, meta) {
@@ -29351,7 +29405,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29351
29405
  K2.part("light_switch", x, 0, 0.011, () => K2.b("plain", x, -0.018, 0.0125, two ? 0.03 : 0.036, 0.034, 8e-3, 16513782, 0, -0.12), { id: "sw_" + M.seed + "_" + i, room: M.room, target: M.target || M.room, opens: { type: "toggle", axis: [1, 0, 0], angle: 0.24 }, on: !!M.on, t0: M.on ? 1 : 0 });
29352
29406
  }
29353
29407
  }
29354
- Object.assign(K, { hashString, rngString, SEED, STYLE, kit2, arcPoints, TEMP_WARM, TEMP_NEUTRAL, TEMP_COOL, colorTemperature, lightStyle, ceilingLamp, tableLamp, floorLamp, sconce, outdoorLamp, lightSwitch });
29408
+ const defined = { hashString, rngString, SEED, STYLE, kit2, arcPoints, TEMP_WARM, TEMP_NEUTRAL, TEMP_COOL, colorTemperature, lightStyle, ceilingLamp, tableLamp, floorLamp, sconce, outdoorLamp, lightSwitch };
29409
+ Object.assign(K, defined);
29355
29410
  }
29356
29411
  function installLightsDecor(K, shared2) {
29357
29412
  const { EPS: EPS6, OPEN_AREA, SEED, Y0, cursor, rngString, roomAt, stairFootprint } = K;
@@ -29416,7 +29471,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29416
29471
  void sd;
29417
29472
  }
29418
29473
  }
29419
- Object.assign(K, { decorLights });
29474
+ const defined = { decorLights };
29475
+ Object.assign(K, defined);
29420
29476
  }
29421
29477
  function installLotTerrain(K, shared2) {
29422
29478
  const { rectsOf: rectsOf2, MIRRORS, PARTS, bx, cursor } = K;
@@ -29467,7 +29523,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29467
29523
  if (x < b) out.push([x, b]);
29468
29524
  return out.filter((q) => q[1] - q[0] > 0.3);
29469
29525
  }
29470
- Object.assign(K, { terrain, freeSpans });
29526
+ const defined = { terrain, freeSpans };
29527
+ Object.assign(K, defined);
29471
29528
  }
29472
29529
  function installLotPerimeter(K, shared2) {
29473
29530
  const { EPS: EPS6, boxC, bx, colorOf, cursor, freeSpans, pieceRecord } = K;
@@ -29485,7 +29542,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29485
29542
  for (const s of lt2.perimeter) {
29486
29543
  const alongU = Math.abs(s.v1 - s.v0) < EPS6, L = alongU ? s.v0 : s.u0, a = Math.min(alongU ? s.u0 : s.v0, alongU ? s.u1 : s.v1), b = Math.max(alongU ? s.u0 : s.v0, alongU ? s.u1 : s.v1);
29487
29544
  cursor.pc = pieceRecord("lot_wall:" + s.id, s.type === "wall" ? "brick" : s.type === "fence" ? "wood_soft" : "steel", null, { tags: ["wall"] });
29488
- const th = s.thickness || 0.15, h = s.height, color2 = colorOf(s.color) != null ? colorOf(s.color) : C.wall || 12104874, len = b - a;
29545
+ const th = s.thickness || 0.15, h = s.height, color2 = colorOf(s.color) ?? (C.wall || 12104874), len = b - a;
29489
29546
  const B = (mat, u0, y0, u1, y1, t, c, off = 0) => alongU ? bx(mat, u0, y0, L + off - t / 2, u1, y1, L + off + t / 2, c) : bx(mat, L + off - t / 2, y0, u0, L + off + t / 2, y1, u1, c);
29490
29547
  const col = { type: "lot_wall", f: -1, x0: alongU ? a : L - th / 2, z0: alongU ? L - th / 2 : a, x1: alongU ? b : L + th / 2, z1: alongU ? L + th / 2 : b };
29491
29548
  shared2.ctx.colliders.push(col);
@@ -29559,7 +29616,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29559
29616
  }
29560
29617
  }
29561
29618
  }
29562
- Object.assign(K, { perimeter, paths });
29619
+ const defined = { perimeter, paths };
29620
+ Object.assign(K, defined);
29563
29621
  }
29564
29622
  function installLotGates(K, shared2) {
29565
29623
  const { bx, colorOf, cursor, cylBase } = K;
@@ -29573,7 +29631,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29573
29631
  cursor.group = "lot";
29574
29632
  const structure = R.style, auto = structure !== "budget", wall = colorOf("wall") || 12104874, cu = (lt2.rect[0] + lt2.rect[2]) / 2, cz = (lt2.rect[1] + lt2.rect[3]) / 2;
29575
29633
  for (const g of lt2.gates) {
29576
- const gc = colorOf(g.color) != null ? colorOf(g.color) : C.gate != null ? C.gate : 2763310, a = g.u - g.width / 2, b = g.u + g.width / 2, v = g.v, h = g.height, t = 0.05, ped = g.model === "pedestrian", tilt = g.model === "tilting";
29634
+ const gc = colorOf(g.color) ?? (C.gate != null ? C.gate : 2763310), a = g.u - g.width / 2, b = g.u + g.width / 2, v = g.v, h = g.height, t = 0.05, ped = g.model === "pedestrian", tilt = g.model === "tilting";
29577
29635
  const sd = cz - v >= 0 ? 1 : -1;
29578
29636
  const pil = (x0, x1, high) => {
29579
29637
  bx("plaster", x0, 0, v - 0.13, x1, high, v + 0.13, wall);
@@ -29645,7 +29703,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29645
29703
  if (!g.open || ped) shared2.ctx.colliders.push({ type: "gate", f: -1, x0: a, z0: v - 0.1, x1: b, z1: v + 0.1 });
29646
29704
  }
29647
29705
  }
29648
- Object.assign(K, { slideDirection, gates });
29706
+ const defined = { slideDirection, gates };
29707
+ Object.assign(K, defined);
29649
29708
  }
29650
29709
  function installRoofRoofs(K, shared2) {
29651
29710
  const { rectsOf: rectsOf2, EPS: EPS6, OPEN_AREA, Y0, bx, cursor } = K;
@@ -29657,13 +29716,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29657
29716
  function roofs() {
29658
29717
  const R = shared2.ctx.r, F = R.facade, C = shared2.ctx.colors, nA = R.floors.length, type = F.roof;
29659
29718
  cursor.group = "roof";
29660
- shared2.ctx.roofRects = [];
29661
- shared2.ctx.gutter = gutterConfig();
29662
- shared2.ctx.gutter.ncond = 0;
29663
- shared2.ctx.gutter.nbuz = 0;
29664
- shared2.ctx.gutter.bz = /* @__PURE__ */ new Set();
29719
+ const roofRects = shared2.ctx.roofRects = [];
29720
+ const G = shared2.ctx.gutter = gutterConfig();
29721
+ G.ncond = 0;
29722
+ G.nbuz = 0;
29723
+ G.bz = /* @__PURE__ */ new Set();
29665
29724
  shared2.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] };
29666
- const roofColor = C.roof != null ? C.roof : 11031610, gable = (R.seed | 0) % 2 === 0;
29725
+ const roofColor = C.roof != null ? C.roof : 11031610, gable = (Number(R.seed) | 0) % 2 === 0;
29667
29726
  for (let f = 0; f < nA; f++) {
29668
29727
  const rs = R.rooms.filter((c) => c.floor === f && c.type !== "void" && !c.outbuilding && !OPEN_AREA(c)).flatMap(rectsOf2), up = R.rooms.filter((c) => c.floor === f + 1 && c.type !== "void").flatMap(rectsOf2);
29669
29728
  if (!rs.length) continue;
@@ -29685,7 +29744,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29685
29744
  return Y0(f) + Math.max(...cs.map((c) => c.ceiling)) + 0.2;
29686
29745
  };
29687
29746
  if (type === "slab") {
29688
- for (let j = 0; j < nz; j++) for (let i = 0; i < nx; i++) if (O(j, i)) shared2.ctx.roofRects.push({ f, r: [xs[i], zs[j], xs[i + 1], zs[j + 1]], slab: true, yb: pe(xs[i], zs[j], xs[i + 1], zs[j + 1]) + 0.03 });
29747
+ for (let j = 0; j < nz; j++) for (let i = 0; i < nx; i++) if (O(j, i)) roofRects.push({ f, r: [xs[i], zs[j], xs[i + 1], zs[j + 1]], slab: true, yb: pe(xs[i], zs[j], xs[i + 1], zs[j + 1]) + 0.03 });
29689
29748
  slabs(f, xs, zs, O, U, nx, nz, full, pe, C);
29690
29749
  cursor.pc = null;
29691
29750
  continue;
@@ -29708,16 +29767,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29708
29767
  if (U(q.j0 - 1, i)) touchesU[1] = 1;
29709
29768
  if (U(q.j1 + 1, i)) touchesU[3] = 1;
29710
29769
  }
29711
- shared2.ctx.roofRects.push({ f, r: [x0, z0, x1, z1], touchesU });
29770
+ roofRects.push({ f, r: [x0, z0, x1, z1], touchesU });
29712
29771
  const ybq = pe(x0, z0, x1, z1);
29713
29772
  roofRect(type, x0, z0, x1, z1, ybq, roofColor, gable && single, F, touchesU);
29714
29773
  cursor.pc = null;
29715
- if (shared2.ctx.gutter.on) gutter(type, f, x0, z0, x1, z1, ybq, touchesU);
29774
+ if (G.on) gutter(type, f, x0, z0, x1, z1, ybq, touchesU);
29716
29775
  }
29717
29776
  }
29718
29777
  for (const e of shared2.ctx.outbuildingList || []) {
29719
29778
  const [x0, z0, x1, z1] = e.aabb, yb = Y0(0) + (e.ceiling || 2.6) + 0.2;
29720
- shared2.ctx.roofRects.push({ f: 0, r: [x0, z0, x1, z1], outbuilding: e.id });
29779
+ roofRects.push({ f: 0, r: [x0, z0, x1, z1], outbuilding: e.id });
29721
29780
  if (type === "slab") {
29722
29781
  const c = C.facade != null ? C.facade : 14209216;
29723
29782
  bx("plaster", x0 - 0.08, yb, z0 - 0.08, x1 + 0.08, yb + 0.03, z1 + 0.08, sh(C.ceiling != null ? C.ceiling : 12104876, 0.85));
@@ -29728,11 +29787,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29728
29787
  roofRect(type, x0, z0, x1, z1, yb, roofColor, true, F, [0, 0, 0, 0]);
29729
29788
  cursor.pc = null;
29730
29789
  shared2.ctx.noPiece = false;
29731
- if (shared2.ctx.gutter.on) gutter(type, 0, x0, z0, x1, z1, yb, [0, 0, 0, 0]);
29790
+ if (G.on) gutter(type, 0, x0, z0, x1, z1, yb, [0, 0, 0, 0]);
29732
29791
  }
29733
29792
  }
29734
- Object.assign(K, { roofs });
29793
+ const defined = { roofs };
29794
+ Object.assign(K, defined);
29735
29795
  }
29796
+ var paletteMeta = (colors) => colors.meta;
29736
29797
  function installRoofGutters(K, shared2) {
29737
29798
  const { boxC, bx, cursor, roomAt } = K;
29738
29799
  const sh = (...a) => K.sh(...a);
@@ -29749,7 +29810,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29749
29810
  const draw2 = rnd2() < p, light = rnd2() < 0.6;
29750
29811
  void draw2;
29751
29812
  const on = true;
29752
- return { on, rnd: rnd2, color: high ? 3816770 : light ? 15527921 : 10857392, bad: (shared2.ctx.colors.meta && shared2.ctx.colors.meta.state) === "abandoned" || R.state === "abandoned", fallback: false };
29813
+ return { on, rnd: rnd2, color: high ? 3816770 : light ? 15527921 : 10857392, bad: paletteMeta(shared2.ctx.colors)?.state === "abandoned" || R.state === "abandoned", fallback: false };
29753
29814
  }
29754
29815
  function gutter(type, f, X0, Z0, X1, Z1, yb, touchesU) {
29755
29816
  const G = shared2.ctx.gutter, o = type === "fiber_cement" ? 0.3 : 0.45, x0 = X0 - (touchesU[0] ? 0 : o), x1 = X1 + (touchesU[2] ? 0 : o), z0 = Z0 - (touchesU[1] ? 0 : o), z1 = Z1 + (touchesU[3] ? 0 : o), c = G.color, y = yb - 0.05;
@@ -29791,7 +29852,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29791
29852
  const px = cx + sx * 0.06, pz = cz + sz * 0.06;
29792
29853
  if (!freeAt(px, pz, sx, sz)) return false;
29793
29854
  const floats = G.bad && G.ncond === 1, yt = yb - 0.1, ybx = floats ? 0.7 : 0.04;
29794
- G.ncond++;
29855
+ G.ncond = (G.ncond ?? 0) + 1;
29795
29856
  if (run2 >= 2) boxC("plain", (sides[run2][4] + px) / 2, yt, pz, Math.abs(sides[run2][4] - px), 0.07, 0.07, c);
29796
29857
  else boxC("plain", px, yt, (sides[run2][4] + pz) / 2, 0.07, 0.07, Math.abs(sides[run2][4] - pz), c);
29797
29858
  boxC("plain", px, (ybx + yt) / 2, pz, 0.08, yt - ybx, 0.08, c);
@@ -29825,7 +29886,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29825
29886
  function drain(x, z, px, pz, c) {
29826
29887
  const g0 = cursor.group;
29827
29888
  cursor.group = "f0";
29828
- if (px != null) boxC("plain", (px + x) / 2, 0.075, (pz + z) / 2, Math.abs(x - px) + 0.05, 0.05, Math.abs(z - pz) + 0.05, sh(c, 0.85));
29889
+ if (px != null && pz != null && c != null) boxC("plain", (px + x) / 2, 0.075, (pz + z) / 2, Math.abs(x - px) + 0.05, 0.05, Math.abs(z - pz) + 0.05, sh(c, 0.85));
29829
29890
  const t = 0.045;
29830
29891
  bx("plain", x - 0.12, 0, z - 0.12, x + 0.12, t - 6e-3, z + 0.12, 12170668);
29831
29892
  bx("metal", x - 0.11, t, z - 0.11, x + 0.11, t + 0.012, z + 0.11, 5922145);
@@ -29836,7 +29897,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29836
29897
  bx("metal", x - 0.085, t + 0.012, z - 6e-3, x + 0.085, t + 0.02, z + 6e-3, 9080466);
29837
29898
  cursor.group = g0;
29838
29899
  }
29839
- Object.assign(K, { gutterConfig, gutter, drain });
29900
+ const defined = { gutterConfig, gutter, drain };
29901
+ Object.assign(K, defined);
29840
29902
  }
29841
29903
  function installRoofSlabs(K, shared2) {
29842
29904
  const { boxC, bx, cursor, drain, roomAt, structurePiece } = K;
@@ -29868,15 +29930,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29868
29930
  side(free(j, i + 1), x1 + o - t, z0 - ez0, x1 + o, z1 + ez1);
29869
29931
  side(free(j - 1, i), x0 - ex0, z0 - o, x1 + ex1, z0 - o + t);
29870
29932
  side(free(j + 1, i), x0 - ex0, z1 + o - t, x1 + ex1, z1 + o);
29871
- if (shared2.ctx.gutter && shared2.ctx.gutter.on) for (const [ok, dx, dz] of [[free(j - 1, i), 0, -1], [free(j + 1, i), 0, 1], [free(j, i - 1), -1, 0], [free(j, i + 1), 1, 0]]) {
29933
+ const G = shared2.ctx.gutter;
29934
+ if (G && G.on && G.bz) for (const [ok, dx, dz] of [[free(j - 1, i), 0, -1], [free(j + 1, i), 0, 1], [free(j, i - 1), -1, 0], [free(j, i + 1), 1, 0]]) {
29872
29935
  const kd = f + ":" + dx + ":" + dz;
29873
- if (!ok || shared2.ctx.gutter.bz.has(kd)) continue;
29874
- shared2.ctx.gutter.bz.add(kd);
29875
- shared2.ctx.gutter.nbuz++;
29876
- const mx = (x0 + x1) / 2, mz = (z0 + z1) / 2, ex = dx ? dx < 0 ? x0 - o : x1 + o : mx, ez = dz ? dz < 0 ? z0 - o : z1 + o : mz, cc = shared2.ctx.gutter.color;
29936
+ if (!ok || G.bz.has(kd)) continue;
29937
+ G.bz.add(kd);
29938
+ G.nbuz = (G.nbuz ?? 0) + 1;
29939
+ const mx = (x0 + x1) / 2, mz = (z0 + z1) / 2, ex = dx ? dx < 0 ? x0 - o : x1 + o : mx, ez = dz ? dz < 0 ? z0 - o : z1 + o : mz, cc = G.color;
29877
29940
  boxC("plain", ex + dx * 0.15, yb + 0.1, ez + dz * 0.15, dx ? 0.42 : 0.14, 0.1, dz ? 0.42 : 0.14, cc);
29878
29941
  boxC("plain", ex + dx * 0.36, yb + 0.1, ez + dz * 0.36, dx ? 0.04 : 0.18, 0.14, dz ? 0.04 : 0.18, sh(cc, 0.8));
29879
- if (shared2.ctx.gutter.bad) boxC("plain", ex + dx * 0.05, yb + 0.5 * 0, ez + dz * 0.05, dx ? 0.06 : 0.3, 0.02, dz ? 0.06 : 0.3, 4868674);
29942
+ if (G.bad) boxC("plain", ex + dx * 0.05, yb + 0.5 * 0, ez + dz * 0.05, dx ? 0.06 : 0.3, 0.02, dz ? 0.06 : 0.3, 4868674);
29880
29943
  {
29881
29944
  const tx = ex + dx * 0.38, tz = ez + dz * 0.38;
29882
29945
  let lv = true;
@@ -29896,7 +29959,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29896
29959
  }
29897
29960
  }
29898
29961
  }
29899
- Object.assign(K, { slabs });
29962
+ const defined = { slabs };
29963
+ Object.assign(K, defined);
29900
29964
  }
29901
29965
  function installRoofTiles(K, shared2) {
29902
29966
  const { UV_SCALE, _Y, _h2, _q, accFor, cursor, put, rgbOf, structurePiece } = K;
@@ -30027,7 +30091,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30027
30091
  }
30028
30092
  return m ? structurePiece(m.id) : null;
30029
30093
  }
30030
- Object.assign(K, { R_STYLE, tileRelief, ridge, pieceOfPane });
30094
+ const defined = { R_STYLE, tileRelief, ridge, pieceOfPane };
30095
+ Object.assign(K, defined);
30031
30096
  }
30032
30097
  function installRoofRect(K, shared2) {
30033
30098
  const { R_STYLE, bx, cursor, pieceOfPane, polyFace, ridge, tileRelief } = K;
@@ -30071,7 +30136,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30071
30136
  }
30072
30137
  const rm = alongX ? dz / 2 : dx / 2;
30073
30138
  {
30074
- const rr = shared2.ctx.roofRects[shared2.ctx.roofRects.length - 1];
30139
+ const roofRects = shared2.ctx.roofRects, rr = roofRects[roofRects.length - 1];
30075
30140
  if (rr && !rr.yb) Object.assign(rr, { yb, tp, gable: !!gable, alongX, exterior: [x0, z0, x1, z1], rm });
30076
30141
  }
30077
30142
  if (gable) {
@@ -30108,7 +30173,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30108
30173
  }
30109
30174
  }
30110
30175
  }
30111
- Object.assign(K, { roofRect });
30176
+ const defined = { roofRect };
30177
+ Object.assign(K, defined);
30112
30178
  }
30113
30179
  function installMirrors(K, shared2) {
30114
30180
  const { DOC, THREE, Reflector, MIRRORS, Y0, _Y, roomAt } = K;
@@ -30117,9 +30183,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30117
30183
  function mirrorEnv() {
30118
30184
  if (shared2.mirrorEnv) return shared2.mirrorEnv;
30119
30185
  const mk = (f) => {
30186
+ if (!DOC) throw new Error("game-floorplan-three: the mirrors need a document (options.document)");
30120
30187
  const c = DOC.createElement("canvas");
30121
30188
  c.width = c.height = 64;
30122
30189
  const g = c.getContext("2d");
30190
+ if (!g) throw new Error("game-floorplan-three: no 2d canvas context");
30123
30191
  f(g);
30124
30192
  return c;
30125
30193
  };
@@ -30178,7 +30246,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30178
30246
  B.N.push(v.x, v.y, v.z);
30179
30247
  B.U.push(ua.getX(i), ua.getY(i));
30180
30248
  }
30181
- for (const k of geo.index.array) B.I.push(B.nv + k);
30249
+ for (const k of geo.index?.array ?? []) B.I.push(B.nv + k);
30182
30250
  B.nv += pa.count;
30183
30251
  geo.dispose();
30184
30252
  }
@@ -30256,7 +30324,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30256
30324
  m.fake.visible = !on;
30257
30325
  }
30258
30326
  }
30259
- Object.assign(K, { mirrorEnv, newMirrorState, assembleMirrors, floorAtY, chooseMirror });
30327
+ const defined = { mirrorEnv, newMirrorState, assembleMirrors, floorAtY, chooseMirror };
30328
+ Object.assign(K, defined);
30260
30329
  }
30261
30330
  function installCars(K, shared2) {
30262
30331
  const { THREE, FLEET, _Y } = K;
@@ -30267,13 +30336,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30267
30336
  high: ["electric_hatch", "hybrid_suv", "midsize_suv", "v8_coupe", "large_suv", "midsize_pickup", "crossover_pickup", "fastback_sedan"]
30268
30337
  }, K.cfg.carKinds);
30269
30338
  const CAR_CACHE = /* @__PURE__ */ new Map();
30270
- function materialSignature(m) {
30339
+ function materialSignature(material) {
30340
+ const m = material;
30271
30341
  const f = (v) => v == null ? "" : typeof v === "number" ? v.toFixed(3) : v.isColor ? v.getHexString() : v.uuid || String(v);
30272
30342
  return [m.type, f(m.color), f(m.roughness), f(m.metalness), f(m.opacity), m.transparent ? 1 : 0, m.side, f(m.map), f(m.emissive), f(m.emissiveIntensity), m.vertexColors ? 1 : 0, m.flatShading ? 1 : 0, f(m.envMapIntensity), f(m.alphaTest)].join("|");
30273
30343
  }
30274
30344
  const BUCKETS = /* @__PURE__ */ new Map();
30275
- function bucketMaterial(m) {
30276
- if (m.type !== "MeshStandardMaterial" || m.map || m.alphaTest || m.vertexColors || !m.color) return null;
30345
+ function bucketMaterial(material) {
30346
+ if (material.type !== "MeshStandardMaterial") return null;
30347
+ const m = material;
30348
+ if (m.map || m.alphaTest || m.vertexColors || !m.color) return null;
30277
30349
  const mt = m.metalness > 0.5 ? 2 : m.metalness > 0.2 ? 1 : 0, rg = m.roughness < 0.3 ? 0 : m.roughness < 0.6 ? 1 : 2, tr = m.transparent || m.opacity < 1, op = tr ? Math.max(0.2, Math.min(0.9, Math.round(m.opacity * 5) / 5)) : 1, sig = "bucket" + mt + rg + "s" + m.side + (tr ? "t" + op : "");
30278
30350
  let b = BUCKETS.get(sig);
30279
30351
  if (!b) {
@@ -30285,7 +30357,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30285
30357
  }
30286
30358
  function carModel(k, seed) {
30287
30359
  const kc = k + "|" + shared2.quality + "|" + (seed || 0);
30288
- if (CAR_CACHE.has(kc)) return CAR_CACHE.get(kc);
30360
+ if (CAR_CACHE.has(kc)) return CAR_CACHE.get(kc) ?? null;
30289
30361
  if (!FLEET) return null;
30290
30362
  let res = null;
30291
30363
  try {
@@ -30293,8 +30365,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30293
30365
  c.root.updateMatrixWorld(true);
30294
30366
  const inv = new THREE.Matrix4();
30295
30367
  const byMaterial = /* @__PURE__ */ new Map(), tmp = new THREE.Matrix4(), v = new THREE.Vector3(), nm = new THREE.Matrix3(), bb = new THREE.Box3();
30296
- c.g.traverse((o) => {
30297
- if (!o.isMesh || o.isInstancedMesh || o.isSkinnedMesh || !o.geometry || !o.geometry.attributes.position) return;
30368
+ c.g.traverse((node) => {
30369
+ if (!isMesh(node)) return;
30370
+ const o = node;
30371
+ if (o.isInstancedMesh || o.isSkinnedMesh || !o.geometry || !o.geometry.attributes.position) return;
30298
30372
  for (let p = o; p; p = p.parent) if (p.visible === false) return;
30299
30373
  const mats = Array.isArray(o.material) ? o.material : [o.material];
30300
30374
  let geo = o.geometry;
@@ -30308,7 +30382,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30308
30382
  const pa = geo.attributes.position, na = geo.attributes.normal, ua = geo.attributes.uv, total = pa.count;
30309
30383
  const grs = Array.isArray(o.material) && o.geometry.groups.length ? o.geometry.groups : [{ start: 0, count: total, materialIndex: 0 }];
30310
30384
  for (const gr of grs) {
30311
- const m = mats[gr.materialIndex] || mats[0];
30385
+ const m = (gr.materialIndex != null ? mats[gr.materialIndex] : void 0) || mats[0];
30312
30386
  if (!m) continue;
30313
30387
  const a0 = Math.min(gr.start, total), n0 = Math.min(gr.count, total - a0) - Math.min(gr.count, total - a0) % 3;
30314
30388
  if (n0 < 3) continue;
@@ -30409,7 +30483,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30409
30483
  return g;
30410
30484
  }
30411
30485
  function assembleCars(groups) {
30412
- if (shared2.quality === "game") return assembleMergedCars(groups);
30486
+ if (shared2.quality === "game") {
30487
+ assembleMergedCars(groups);
30488
+ return;
30489
+ }
30413
30490
  for (const C of CARS) {
30414
30491
  const g = carGroup(C.k, C.w, C.d, C.seed);
30415
30492
  if (!g) continue;
@@ -30460,7 +30537,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30460
30537
  (groups[B.parent] || (groups[B.parent] = new THREE.Group())).add(m);
30461
30538
  }
30462
30539
  }
30463
- Object.assign(K, { CARS, CAR_BY_STYLE, CAR_CACHE, materialSignature, BUCKETS, bucketMaterial, carModel, carGroup, assembleCars, assembleMergedCars });
30540
+ const defined = { CARS, CAR_BY_STYLE, CAR_CACHE, materialSignature, BUCKETS, bucketMaterial, carModel, carGroup, assembleCars, assembleMergedCars };
30541
+ Object.assign(K, defined);
30464
30542
  }
30465
30543
  function installHouseBuilding(K, shared2) {
30466
30544
  const { bx, cursor } = K;
@@ -30514,12 +30592,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30514
30592
  bx("plaster", Math.min(hall[0] - 3, color2[0]), ytop, Math.min(un[1] ? unitBox(un[1])[1] : 0, el[1]), Math.max(color2[2], un0[2]), ytop + 0.2, Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0), 11841704);
30515
30593
  shared2.ctx.limits = { x0: Math.min(hall[0] - 3, color2[0]), z0: Math.min(el[1], un[1] ? unitBox(un[1])[1] : 0), x1: Math.max(color2[2], un0[2]), z1: Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0) };
30516
30594
  }
30517
- Object.assign(K, { building });
30595
+ const defined = { building };
30596
+ Object.assign(K, defined);
30518
30597
  }
30519
30598
  function installUtilitiesWater(K, shared2) {
30520
30599
  const { THREE, _Y, _q, cursor, cylBase, part, pieceRecord, put } = K;
30521
30600
  function createWater(r, state) {
30522
- const H = r.utilities.plumbing, cap = H ? +H.capacityL || 0 : 0, ls = { dry: [], full: [] }, points = {}, itemPoint = {};
30601
+ const H = r.utilities?.plumbing, cap = H ? +H.capacityL || 0 : 0, ls = { dry: [], full: [] }, points = {}, itemPoint = {};
30523
30602
  if (H) for (const p of H.points) {
30524
30603
  points[p.id] = p;
30525
30604
  itemPoint[p.item] = p.id;
@@ -30608,14 +30687,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30608
30687
  }
30609
30688
  const _v3 = new THREE.Vector3();
30610
30689
  function waterPipes() {
30611
- const H = shared2.ctx.r.utilities.plumbing;
30690
+ const H = shared2.ctx.r.utilities?.plumbing;
30612
30691
  if (!H || !H.visibleRuns) return;
30613
30692
  const nA = shared2.ctx.r.floors.length;
30614
30693
  const groupOf = (c) => c && c.floor >= 0 ? "f" + Math.min(c.floor, nA - 1) : "lot", xyz = (p) => [p[0], p[2], p[1]];
30615
30694
  for (const tr of H.visibleRuns) {
30616
30695
  const pts = tr.points.map(xyz), d = tr.diameter || 0.025;
30617
30696
  if (tr.exposed === "wall") {
30618
- const pt = H.points.find((p) => p.run === tr.id), com = shared2.ctx.roomById[tr.to], g2 = groupOf(com || pt && { floor: pt.floor });
30697
+ const pt = H.points.find((p) => p.run === tr.id), com = tr.to != null ? shared2.ctx.roomById[tr.to] : void 0, g2 = groupOf(com || pt && { floor: pt.floor });
30619
30698
  part("wall_pipe", [0, 0, 0], () => {
30620
30699
  for (let i = 0; i + 1 < pts.length; i++) pipe(pts[i], pts[i + 1], d, PIPE_COLOR);
30621
30700
  for (const p of pts) cylBase("plain", p[0], p[1] - d, p[2], d * 0.7, d * 2, PIPE_COLOR);
@@ -30637,16 +30716,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30637
30716
  cursor.pc = null;
30638
30717
  }
30639
30718
  }
30640
- Object.assign(K, { createWater, PIPE_COLOR, pipe, _v3, waterPipes });
30719
+ const defined = { createWater, PIPE_COLOR, pipe, _v3, waterPipes };
30720
+ Object.assign(K, defined);
30641
30721
  }
30642
30722
  function installUtilitiesElectrical(K, shared2) {
30643
30723
  const { _Y, _q, _v3, bx, cursor, cylBase, pieceRecord, put } = K;
30644
30724
  const sh = (...a) => K.sh(...a);
30645
30725
  function electricalStructure() {
30646
- const E = shared2.ctx.r.utilities.electrical;
30726
+ const R = shared2.ctx.r, E = R.utilities?.electrical;
30647
30727
  shared2.ctx.electricalInfo = null;
30648
30728
  if (!E) return;
30649
- const R = shared2.ctx.r, nA = R.floors.length, lotGroup = R.lot ? "lot" : "f0", concreteColor = 11973547, iron = 4869200, wireRun = 1842206, info = { pole: null, meter: null, panel: null, conduits: [], outlets: [], switches: [], circuits: E.circuits || [], exposed: !!E.exposed };
30729
+ const nA = R.floors.length, lotGroup = R.lot ? "lot" : "f0", concreteColor = 11973547, iron = 4869200, wireRun = 1842206, info = { pole: null, meter: null, panel: null, conduits: [], outlets: [], switches: [], circuits: E.circuits || [], exposed: !!E.exposed };
30650
30730
  const en22 = E.serviceEntrance, KV = shared2.ctx.iv ? shared2.ctx.iv.plane : null;
30651
30731
  const wireL = (a, b, r_ = 8e-3) => {
30652
30732
  const L = Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]);
@@ -30751,7 +30831,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30751
30831
  _q.setFromUnitVectors(_Y, _v3.set(dx / L, dy / L, dz / L));
30752
30832
  put("plain", "cyl", (a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2, _q, diameter, L, diameter, color2);
30753
30833
  }
30754
- Object.assign(K, { electricalStructure, pipe2 });
30834
+ const defined = { electricalStructure, pipe2 };
30835
+ Object.assign(K, defined);
30755
30836
  }
30756
30837
  function installHouseBaseboard(K, shared2) {
30757
30838
  const { Y0, bx, cursor, sideOf } = K;
@@ -30787,7 +30868,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30787
30868
  strip(W, y0, y0 + 0.045, 0, W, "sidewalk", cal);
30788
30869
  }
30789
30870
  }
30790
- Object.assign(K, { baseboardAndSidewalk });
30871
+ const defined = { baseboardAndSidewalk };
30872
+ Object.assign(K, defined);
30791
30873
  }
30792
30874
  function installUtilitiesSolar(K, shared2) {
30793
30875
  const { Y0, boxC, bx, cursor, cylBase } = K;
@@ -30800,6 +30882,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30800
30882
  if (u >= a - 0.05 && u <= c + 0.05 && v >= b - 0.05 && v <= d + 0.05) y = Math.max(y == null ? -1e9 : y, rr.yb);
30801
30883
  continue;
30802
30884
  }
30885
+ if (!rr.exterior || rr.tp == null || rr.rm == null) continue;
30803
30886
  const [x0, z0, x1, z1] = rr.exterior;
30804
30887
  if (u < x0 || u > x1 || v < z0 || v > z1) continue;
30805
30888
  const dz = Math.min(v - z0, z1 - v), dx = Math.min(u - x0, x1 - u), dd = rr.gable ? rr.alongX ? dz : dx : Math.min(dx, dz), h = rr.yb + rr.tp * Math.min(dd, rr.rm);
@@ -30808,7 +30891,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30808
30891
  return y;
30809
30892
  }
30810
30893
  function solar() {
30811
- const R = shared2.ctx.r, S = R.utilities.solar;
30894
+ const R = shared2.ctx.r, S = R.utilities?.solar;
30812
30895
  shared2.ctx.solarInfo = null;
30813
30896
  if (!S || !S.panels || !S.panels.length) return;
30814
30897
  cursor.group = "roof";
@@ -30851,13 +30934,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30851
30934
  bx("plain", iv.u - W * 0.6, y0 + 0.05, iv.v + fa0, iv.u + W * 0.6, y0 + 0.17, iv.v + fa1, 2106924);
30852
30935
  bx("emissive", iv.u - 0.03, y0 - 0.12, iv.v + fa0, iv.u + 0.03, y0 - 0.09, iv.v + fa1, 6479994);
30853
30936
  }
30854
- const top = Math.max(...(shared2.ctx.roofRects || []).filter((t2) => t2.yb != null).map((t2) => t2.yb), Y0(fa) + 2.8);
30937
+ const top = Math.max(...(shared2.ctx.roofRects || []).flatMap((t2) => t2.yb != null ? [t2.yb] : []), Y0(fa) + 2.8);
30855
30938
  cylBase("plain", iv.u, y0 + h / 2, iv.v, 0.016, Math.max(0.2, top - 0.2 - (y0 + h / 2)), 15262936);
30856
30939
  info.inverter = { id: iv.id, pos: [iv.u, y0, iv.v], side: iv.side, link: iv.link };
30857
30940
  }
30858
30941
  shared2.ctx.solarInfo = info;
30859
30942
  }
30860
- Object.assign(K, { roofHeightAt, solar });
30943
+ const defined = { roofHeightAt, solar };
30944
+ Object.assign(K, defined);
30861
30945
  }
30862
30946
  function installHouseOutbuildings(K, shared2) {
30863
30947
  const { t, bx, cursor, floorColor } = K;
@@ -30870,7 +30954,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30870
30954
  counts.set(w.floor, i + 1);
30871
30955
  return w.id ? w : Object.assign({}, w, { id: `wall_${w.floor}_${i}` });
30872
30956
  }) });
30873
- const E = (r.outbuildings || []).filter((e) => e && e.walls && e.walls.length && e.interior && e.interior.length);
30957
+ const E = (r.outbuildings || []).filter((e) => !!(e && e.walls && e.walls.length && e.interior && e.interior.length));
30874
30958
  if (!E.length) return r;
30875
30959
  const rooms = r.rooms.slice(), walls = r.walls.slice(), doors = r.doors.slice(), windows = r.windows.slice(), items = r.items.filter((m) => m.type !== "outbuilding");
30876
30960
  for (const e of E) {
@@ -30884,7 +30968,22 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30884
30968
  const alongU = p.axis === "u", below = p.pos < (alongU ? cz : cx);
30885
30969
  doors.push({ id: p.id, floor: 0, u: p.u, v: p.v, axis: p.axis, pos: p.pos, at: p.at, width: p.width, a: below ? "outside" : e.id, b: below ? e.id : "outside", opensTo: e.id, exterior: true, side: p.side, leaves: 1, model: "single", hinge: "start", zones: [], blocked: false, outbuilding: e.id });
30886
30970
  }
30887
- for (const j of e.windows || []) windows.push({ id: j.id, floor: 0, u: j.u, v: j.v, axis: j.axis, pos: j.pos, at: j.at, width: j.width, y0: j.y0, y1: j.y1, room: e.id, side: j.side, outbuilding: e.id });
30971
+ for (const j of e.windows || []) windows.push({
30972
+ id: j.id,
30973
+ floor: 0,
30974
+ u: j.u,
30975
+ v: j.v,
30976
+ axis: j.axis,
30977
+ pos: j.pos,
30978
+ at: j.at,
30979
+ width: j.width,
30980
+ y0: j.y0 ?? 1,
30981
+ y1: j.y1 ?? 2,
30982
+ /* the structure always gives a window its sill and head (1.0, 2.0) */
30983
+ room: e.id,
30984
+ side: j.side,
30985
+ outbuilding: e.id
30986
+ });
30888
30987
  (e.items || []).forEach((m, i) => items.push({ id: e.id + "." + m.type + i, type: m.type, category: m.category, x: m.u, z: m.v, ry: m.ry || 0, w: m.w, d: m.d, h: m.h, y: 0.04, frontU: m.frontU, frontV: m.frontV, room: e.id, floor: 0, outdoor: false, aabb: m.aabb, color: "wood" }));
30889
30988
  items.push({ id: e.id + ".ceiling_light", type: "ceiling_light", category: "ceiling_light", x: cx, z: cz, ry: 0, w: 0.35, d: 0.35, h: 0.1, y: pe - 0.1, room: e.id, floor: 0, outdoor: false, assembly: "ceiling", color: "metal", decor: true });
30890
30989
  }
@@ -30905,7 +31004,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30905
31004
  }
30906
31005
  }
30907
31006
  }
30908
- Object.assign(K, { OUTBUILDING_USE, applyOutbuildings, outbuildings });
31007
+ const defined = { OUTBUILDING_USE, applyOutbuildings, outbuildings };
31008
+ Object.assign(K, defined);
30909
31009
  }
30910
31010
  function installFurnitureApi(K, _shared) {
30911
31011
  const { _e, _h2, _q, boxC, cursor, macroGround, polyFace, put } = K;
@@ -30968,7 +31068,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30968
31068
  return { b: (mat, x, y, z, w, h, d, color2, ry, rx, rz) => A.box(M, mat, x, y0 + y, z, w, h, d, color2, ry || 0, rx || 0, rz || 0), c: (mat, x, y, z, r, h, color2, rx, rz, seg2) => A.cylinder(M, mat, x, y0 + y, z, r, h, color2, rx || 0, rz || 0, seg2), rnd: rngOf(M), wood: paletteColor(M, "wood", 8016948), met: paletteColor(M, "metal", 10133154) };
30969
31069
  }
30970
31070
  const PE = Math.PI / 2;
30971
- Object.assign(K, { MATERIAL_MAP: MATERIAL_MAP2, mm, LIGHTS, makeApi, sh, paletteColor, rngOf, kk, PE });
31071
+ const defined = { MATERIAL_MAP: MATERIAL_MAP2, mm, LIGHTS, makeApi, sh, paletteColor, rngOf, kk, PE };
31072
+ Object.assign(K, defined);
30972
31073
  }
30973
31074
  function installFurnitureBuilders(K, _shared) {
30974
31075
  const { PE, _q, kit2, kk, paletteColor, put, rngOf, sh } = K;
@@ -31094,7 +31195,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31094
31195
  for (let s = 0; s < np; s++) lb("fabric", np === 1 ? 0 : (s ? 1 : -1) * w * 0.23, 0.5, -d / 2 + 0.3, w * (np === 1 ? 0.6 : 0.4), 0.12, 0.34, 15789798, (s ? 1 : -1) * 0.08);
31095
31196
  },
31096
31197
  wardrobe(M, A) {
31097
- const { b: lb } = kk(M, A), w = M.w, d = M.d, h = M.h, wood = M.color != null && false ? M.color : paletteColor(M, "wood", 5980208), np = Math.max(2, Math.round(w / 0.7));
31198
+ const { b: lb } = kk(M, A), w = M.w, d = M.d, h = M.h, wood = paletteColor(M, "wood", 5980208), np = Math.max(2, Math.round(w / 0.7));
31098
31199
  lb("wood", 0, 0.06, 0, w, h - 0.06, d, wood);
31099
31200
  lb("wood", 0, h, 0, w + 0.04, 0.04, d + 0.04, sh(wood, 0.8));
31100
31201
  lb("wood", 0, 0, 0, w - 0.04, 0.06, d - 0.04, sh(wood, 0.4));
@@ -31486,7 +31587,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31486
31587
  lb("metal", 0, h - 0.04, d / 2, w, 0.03, 0.03, 3815994);
31487
31588
  }
31488
31589
  };
31489
- Object.assign(K, { FURNITURE });
31590
+ const defined = { FURNITURE };
31591
+ Object.assign(K, defined);
31490
31592
  }
31491
31593
  function installFurnitureTypeTable(K, _shared) {
31492
31594
  const { FURNITURE, kk, paletteColor } = K;
@@ -31494,7 +31596,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31494
31596
  function typeTable(props) {
31495
31597
  const B = props.builders, T2 = {};
31496
31598
  const mv = (type, id) => {
31497
- if (B[id || type]) T2[type] = { f: B[id || type], source: "props3d" };
31599
+ const f = B[id || type];
31600
+ if (f) T2[type] = { f, source: "props3d" };
31498
31601
  };
31499
31602
  const mine = (type, f, source = "game") => {
31500
31603
  T2[type] = { f, source };
@@ -31633,7 +31736,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31633
31736
  extraTypes(T2, props);
31634
31737
  return T2;
31635
31738
  }
31636
- Object.assign(K, { typeTable });
31739
+ const defined = { typeTable };
31740
+ Object.assign(K, defined);
31637
31741
  }
31638
31742
  function installFurnitureTaps(K, shared2) {
31639
31743
  shared2.tapCount = 0;
@@ -31695,7 +31799,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31695
31799
  }, { id: id + "_a", target: id, hidden: true, fluid: "water" });
31696
31800
  return id;
31697
31801
  }
31698
- Object.assign(K, { counterTap, wallTap });
31802
+ const defined = { counterTap, wallTap };
31803
+ Object.assign(K, defined);
31699
31804
  }
31700
31805
  function installFurnitureFixtures(K, _shared) {
31701
31806
  const seedKey = (id) => K.seedKey(id);
@@ -31804,7 +31909,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31804
31909
  const a = rnd2() * 6.283, u = Math.sqrt(rnd2()), ph = (rnd2() - 0.2) * 1.2, dx = Math.cos(a) * u * R * 0.75, dz = Math.sin(a) * u * R * 0.75, dy = (o.flatten ? 0.35 : 0.55) * R * (Math.sin(ph) * 0.5 + 0.5) * 1.5 - R * 0.15;
31805
31910
  const r = R * (0.34 + rnd2() * 0.22) * (1 - u * 0.25), alt = r * 2 * (o.flatten ? 0.75 : 0.95), f = 0.72 + Math.min(1, (dy + R * 0.2) / (R * 1.2)) * 0.32 + rnd2() * 0.12;
31806
31911
  K2.e("plant", cx + dx, cy + dy + r * 0.5, cz + dz, r, alt, sh(green2, f));
31807
- if (o.flower && rnd2() < o.flower) {
31912
+ if (o.flower && o.flowers && rnd2() < o.flower) {
31808
31913
  const fa = rnd2() * 6.283;
31809
31914
  K2.e("plain", cx + dx + Math.cos(fa) * r * 0.78, cy + dy + r * 0.5 + rnd2() * r * 0.5, cz + dz + Math.sin(fa) * r * 0.78, 0.028 + rnd2() * 0.012, 0.05, o.flowers[rnd2() * o.flowers.length | 0]);
31810
31915
  }
@@ -31917,7 +32022,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31917
32022
  else blobs(K2, x, bh - 0.05, z, 0.24 + rnd2() * 0.08, 6, green2, rnd2, { flatten: true, flower: tp === "flower" ? 0.9 : 0.25, flowers: FLOWERS.slice(i % 3, i % 3 + 3) });
31918
32023
  }
31919
32024
  }
31920
- Object.assign(K, { GREENS: GREENS2, FLOWERS, blobs, potModel, arcLeaf, tuft, palm_tree, treeModel, shrubModel, potPlant, tablePot, planterModel });
32025
+ const defined = { GREENS: GREENS2, FLOWERS, blobs, potModel, arcLeaf, tuft, palm_tree, treeModel, shrubModel, potPlant, tablePot, planterModel };
32026
+ Object.assign(K, defined);
31921
32027
  }
31922
32028
  function installFurnitureYard(K, shared2) {
31923
32029
  const seedKey = (id) => K.seedKey(id);
@@ -32071,7 +32177,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32071
32177
  };
32072
32178
  FURNITURE.mailbox = function(M, A) {
32073
32179
  const K2 = kit2(M, A, 0), w = M.w || 0.3, d = M.d || 0.22, h = M.h || 0.3, y = M.y != null && M.y > 0 ? M.y : 1, structure = STYLE(), pc = structure === "high" ? 2763824 : structure === "mid" ? 13676640 : 13126202, rnd2 = rngString(SEED() + "|" + seedKey(M.seed) + "|correio");
32074
- if (M.pole !== false && !(M.y > 0)) {
32180
+ if (M.pole !== false && !(M.y != null && M.y > 0)) {
32075
32181
  K2.b("plain", 0, 0, -d / 2 - 0.1, 0.12, y, 0.12, 12104874);
32076
32182
  }
32077
32183
  K2.b("metal", 0, y, 0, w, h * 0.78, d, pc);
@@ -32091,7 +32197,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32091
32197
  );
32092
32198
  K2.b("plain", 0, y + h * 0.62, d / 2 + 4e-3, 0.08, 0.05, 4e-3, 15921386);
32093
32199
  };
32094
- Object.assign(K, { CLOTHES_COLORS, strip, garment: garment2 });
32200
+ const defined = { CLOTHES_COLORS, strip, garment: garment2 };
32201
+ Object.assign(K, defined);
32095
32202
  }
32096
32203
  function installFurnitureExtraTypes(K, _shared) {
32097
32204
  const seedKey = (id) => K.seedKey(id);
@@ -32149,7 +32256,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32149
32256
  tuft(K2, 0, 0, 0, Math.max(0.2, (M.w || 0.4) / 2), 16, 5212738, rnd2);
32150
32257
  });
32151
32258
  }
32152
- Object.assign(K, { extraTypes });
32259
+ const defined = { extraTypes };
32260
+ Object.assign(K, defined);
32153
32261
  }
32154
32262
  function installFurniturePlaceItems(K, shared2) {
32155
32263
  const { THREE, Y0, _col, boxC, colorOf, cursor, decorLights, makeApi, structurePiece } = K;
@@ -32169,8 +32277,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32169
32277
  if (m.type === "stairs") continue;
32170
32278
  const exterior = m.outdoor || m.floor < 0, f = exterior ? -1 : Math.min(m.floor, R.floors.length - 1);
32171
32279
  cursor.group = exterior ? "lot" : "f" + f;
32172
- const com = shared2.ctx.roomById[m.room], base = exterior ? 0 : Y0(f);
32173
- const M = { x: m.x, z: m.z, ry: m.ry || 0, w: m.w, d: m.d, h: m.h, y: m.y || 0, base, floor: exterior ? -1 : f, palette: shared2.ctx.colors, color: m.category === "ground_cover" ? void 0 : colorOf(m.color) != null ? colorOf(m.color) : void 0, seed: m.id, room: m.room, typeWith: com ? com.type : null, ceiling: com ? com.ceiling : 2.9, on: shared2.ctx.night, light: shared2.ctx.night, lit: shared2.ctx.night, open: !!m.doorOpen, overhead: m.overhead, assembly: m.assembly, hose: m.hose };
32280
+ const com = m.room != null ? shared2.ctx.roomById[m.room] : void 0, base = exterior ? 0 : Y0(f);
32281
+ const M = { x: m.x, z: m.z, ry: m.ry || 0, w: m.w, d: m.d, h: m.h, y: m.y || 0, base, floor: exterior ? -1 : f, palette: shared2.ctx.colors, color: m.category === "ground_cover" ? void 0 : colorOf(m.color) ?? void 0, seed: m.id, room: m.room, typeWith: com ? com.type : null, ceiling: com ? com.ceiling : 2.9, on: shared2.ctx.night, light: shared2.ctx.night, lit: shared2.ctx.night, open: !!m.doorOpen, overhead: m.overhead, assembly: m.assembly, hose: m.hose };
32174
32282
  if (m.category === "ground_cover" && m.polygon) {
32175
32283
  const xs = m.polygon.map((p) => p[0]), zs = m.polygon.map((p) => p[1]);
32176
32284
  M.x = (Math.min(...xs) + Math.max(...xs)) / 2;
@@ -32247,7 +32355,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32247
32355
  boxC("plain", m.x, M.base + (m.y || 0) + h / 2, m.z, m.w, h, m.d, color2, 0, m.ry || 0, 0);
32248
32356
  shared2.ctx.labels.push({ pos: new THREE.Vector3(m.x, M.base + (m.y || 0) + h + 0.15, m.z), text: m.type, group, type: "no_model" });
32249
32357
  }
32250
- Object.assign(K, { houseItems, waterTankOfHouse, hashColor, labeledBox });
32358
+ const defined = { houseItems, waterTankOfHouse, hashColor, labeledBox };
32359
+ Object.assign(K, defined);
32251
32360
  }
32252
32361
  function installVegetationBridge(K, shared2) {
32253
32362
  const seedKey = (id) => K.seedKey(id);
@@ -32280,7 +32389,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32280
32389
  const ids = VEG_MAP[m.type], can2 = VEG_PLANTER[m.type];
32281
32390
  if (!ids && !can2) return false;
32282
32391
  const rnd2 = rngString(SEED() + "|" + seedKey(m.id) + "|veg"), pick3 = (l) => l[Math.min(l.length - 1, rnd2() * l.length | 0)], ok = (id) => {
32283
- if (V3.ok.has(id)) return V3.ok.get(id);
32392
+ if (V3.ok.has(id)) return V3.ok.get(id) === true;
32284
32393
  let r = true;
32285
32394
  try {
32286
32395
  V3.S.toSpec(id);
@@ -32326,7 +32435,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32326
32435
  obj.position.y = G.y;
32327
32436
  obj.name = "vegetation";
32328
32437
  obj.traverse((o) => {
32329
- if (o.isMesh) {
32438
+ if (isMesh(o)) {
32330
32439
  o.castShadow = true;
32331
32440
  o.receiveShadow = true;
32332
32441
  o.name = "veg/" + o.name;
@@ -32341,7 +32450,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32341
32450
  }
32342
32451
  shared2.ctx.vegInfo = { plants: pl, triangles: tri, colliders: col, lodCounts: lod, materials: mats };
32343
32452
  }
32344
- Object.assign(K, { VEG_POT, VEG_CACTUS, VEG_MAP, VEG_PLANTER, vegItem, assembleVegetation });
32453
+ const defined = { VEG_POT, VEG_CACTUS, VEG_MAP, VEG_PLANTER, vegItem, assembleVegetation };
32454
+ Object.assign(K, defined);
32345
32455
  }
32346
32456
  function installInteractionState(K, shared2) {
32347
32457
  const { THREE, cfg, colliderChanged, invalidateShadow, invalidate, UV_SCALE, applyPart, texture } = K;
@@ -32407,12 +32517,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32407
32517
  shared2.inter.msg = { text, until: performance.now() + MESSAGE_MS };
32408
32518
  if (cfg.onMessage) cfg.onMessage(text);
32409
32519
  };
32410
- function definePiece(name, def) {
32520
+ const I = () => shared2.inter;
32521
+ function definePiece(name, definition) {
32522
+ const def = definition;
32411
32523
  def.name = name;
32412
32524
  def.meshes = [];
32413
32525
  def.t = def.target = shared2.partState.has(name) ? shared2.partState.get(name) : def.t0 || 0;
32414
- shared2.inter.defs.set(name, def);
32415
- shared2.inter.pieces.push(def);
32526
+ I().defs.set(name, def);
32527
+ I().pieces.push(def);
32416
32528
  return def;
32417
32529
  }
32418
32530
  const localOf = (M, lx, lz) => {
@@ -32424,17 +32536,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32424
32536
  return true;
32425
32537
  }
32426
32538
  function assembleInteractive(gs) {
32427
- for (const [name, def] of shared2.inter.defs) {
32539
+ const inter = I();
32540
+ for (const [name, def] of inter.defs) {
32428
32541
  const g = gs[name];
32429
32542
  if (!g) continue;
32430
32543
  delete gs[name];
32431
32544
  const outer = new THREE.Group();
32432
- outer.position.set(...def.pivot);
32545
+ outer.position.fromArray(def.pivot);
32433
32546
  outer.rotation.y = def.ry || 0;
32434
32547
  outer.updateMatrix();
32435
- const inv = new THREE.Matrix4().compose(new THREE.Vector3(...def.pivot), new THREE.Quaternion().setFromAxisAngle(_EY, def.ry || 0), _UM3).invert();
32548
+ const inv = new THREE.Matrix4().compose(new THREE.Vector3().fromArray(def.pivot), new THREE.Quaternion().setFromAxisAngle(_EY, def.ry || 0), _UM3).invert();
32436
32549
  g.traverse((o) => {
32437
- if (o.isMesh) {
32550
+ if (isMesh(o)) {
32438
32551
  o.geometry.applyMatrix4(inv);
32439
32552
  o.userData.piece = def;
32440
32553
  def.meshes.push(o);
@@ -32446,13 +32559,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32446
32559
  const parent = def.leaf ? def.leaf.gs[def.k] : gs[def.parent] || (gs[def.parent] = new THREE.Group());
32447
32560
  if (parent) parent.add(outer);
32448
32561
  if (def.roomId) {
32449
- if (!shared2.inter.lights.has(def.roomId)) shared2.inter.lights.set(def.roomId, []);
32450
- shared2.inter.lights.get(def.roomId).push(def);
32562
+ let lamps = inter.lights.get(def.roomId);
32563
+ if (!lamps) inter.lights.set(def.roomId, lamps = []);
32564
+ lamps.push(def);
32451
32565
  }
32452
32566
  applyPiece(def);
32453
32567
  }
32454
- for (const roomId of shared2.inter.litRooms) applyLight(roomId);
32455
- shared2.inter.defs.forEach((d) => {
32568
+ for (const roomId of inter.litRooms) applyLight(roomId);
32569
+ inter.defs.forEach((d) => {
32456
32570
  if (d.col) d.col.off = d.t > 0.5;
32457
32571
  });
32458
32572
  }
@@ -32460,6 +32574,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32460
32574
  const n = p.inner;
32461
32575
  if (!n) return;
32462
32576
  switch (p.kind) {
32577
+ /* each kind always sets its dimensions (sgn, angle, travel, k, axis) */
32463
32578
  case "swing":
32464
32579
  n.rotation.y = p.sgn * p.t * p.angle;
32465
32580
  break;
@@ -32492,8 +32607,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32492
32607
  }
32493
32608
  const DURATION = { swing: 0.55, drawer: 0.4, curtain: 0.9, gate_swing: 0.9, gate_tilt: 1.4, gate_slide: 1.6, lightSwitch: 0.12, part: 0.4 };
32494
32609
  function animateInteractive(dt) {
32495
- if (!shared2.inter.anim.size) return;
32496
- for (const p of shared2.inter.anim) {
32610
+ const inter = I();
32611
+ if (!inter.anim.size) return;
32612
+ for (const p of inter.anim) {
32497
32613
  const step = dt / (DURATION[p.kind] || 0.5), d = p.target - p.t;
32498
32614
  p.t = Math.abs(d) <= step ? p.target : p.t + Math.sign(d) * step;
32499
32615
  applyPiece(p);
@@ -32501,7 +32617,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32501
32617
  p.col.off = p.target > 0.5;
32502
32618
  colliderChanged(p.col);
32503
32619
  }
32504
- if (p.t === p.target) shared2.inter.anim.delete(p);
32620
+ if (p.t === p.target) inter.anim.delete(p);
32505
32621
  }
32506
32622
  invalidateShadow();
32507
32623
  }
@@ -32512,7 +32628,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32512
32628
  p.col.off = p.target > 0.5;
32513
32629
  colliderChanged(p.col);
32514
32630
  }
32515
- shared2.inter.anim.add(p);
32631
+ I().anim.add(p);
32516
32632
  }
32517
32633
  const lightBase = (roomId) => roomId == null ? true : shared2.partState.has("light:" + roomId) ? !!shared2.partState.get("light:" + roomId) : !!shared2.ctx.night;
32518
32634
  const lightOn = (roomId) => {
@@ -32520,20 +32636,21 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32520
32636
  return S ? S.ef : lightBase(roomId);
32521
32637
  };
32522
32638
  function applyLight(roomId) {
32523
- const on = lightOn(roomId);
32524
- for (const d of shared2.inter.lights.get(roomId) || []) for (const m of d.meshes) if (m.name.endsWith("/emissive")) m.material = on ? shared2.mats.emissive : shared2.mats.off;
32525
- const sw = shared2.inter.defs.get("ix:int:" + roomId);
32639
+ const on = lightOn(roomId), inter = I(), mats = shared2.mats;
32640
+ for (const d of inter.lights.get(roomId) || []) for (const m of d.meshes) if (m.name.endsWith("/emissive")) m.material = on ? mats.emissive : mats.off;
32641
+ const sw = inter.defs.get("ix:int:" + roomId);
32526
32642
  if (sw) {
32527
32643
  sw.target = on ? 1 : 0;
32528
- if (sw.t !== sw.target) shared2.inter.anim.add(sw);
32644
+ if (sw.t !== sw.target) inter.anim.add(sw);
32529
32645
  }
32530
32646
  invalidate();
32531
32647
  }
32532
32648
  function toggleLight(roomId) {
32533
32649
  const S = shared2.ctx.iv && shared2.ctx.iv.roomStates.get(roomId);
32534
32650
  if (S) {
32535
- ivRoomLight(shared2.ctx.iv, roomId, !S.ef);
32536
- const ef = ivRoomEffective(shared2.ctx.iv, S);
32651
+ const IV = shared2.ctx.iv;
32652
+ ivRoomLight(IV, roomId, !S.ef);
32653
+ const ef = ivRoomEffective(IV, S);
32537
32654
  if (ef !== S.ef) {
32538
32655
  S.ef = ef;
32539
32656
  applyLight(roomId);
@@ -32545,9 +32662,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32545
32662
  applyLight(roomId);
32546
32663
  if (cfg.onLight) cfg.onLight(roomId, lightOn(roomId));
32547
32664
  }
32548
- Object.assign(K, { newInteractiveState, MESSAGE_MS, createInteractiveMaterials, _EY, _UM3, hudMessage, definePiece, localOf, visibleChain, assembleInteractive, applyPiece, DURATION, animateInteractive, togglePiece, lightBase, lightOn, applyLight, toggleLight });
32665
+ const defined = { newInteractiveState, MESSAGE_MS, createInteractiveMaterials, _EY, _UM3, hudMessage, definePiece, localOf, visibleChain, assembleInteractive, applyPiece, DURATION, animateInteractive, togglePiece, lightBase, lightOn, applyLight, toggleLight };
32666
+ Object.assign(K, defined);
32549
32667
  }
32550
32668
  function installInteractionCollision(K, shared2) {
32669
+ const inter = () => shared2.inter;
32551
32670
  const NO_COLLIDE = /(^|_)(rug|floor|concrete|dirt|lawn|deck|ceiling_light|pendant|chandelier|spot|picture|curtain|blinds|wall_shelving|plank_shelf|wall_ac|ac_condenser|pool|soaking_tub|pergola|stairs|mirror)/;
32552
32671
  function registerCollision(m, M) {
32553
32672
  const h = m.h || 0, y = M.y || 0;
@@ -32557,7 +32676,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32557
32676
  w = Math.min(w, 0.5);
32558
32677
  d = Math.min(d, 0.5);
32559
32678
  }
32560
- shared2.inter.objs.push({ f: M.floor, cx: m.x, cz: m.z, c: Math.cos(M.ry), s: Math.sin(M.ry), hw: w / 2, hd: d / 2, type: m.type });
32679
+ inter().objs.push({ f: M.floor, cx: m.x, cz: m.z, c: Math.cos(M.ry), s: Math.sin(M.ry), hw: w / 2, hd: d / 2, type: m.type });
32561
32680
  }
32562
32681
  function objectDistance(o, x, z) {
32563
32682
  const dx = x - o.cx, dz = z - o.cz, lx = dx * o.c - dz * o.s, lz = dx * o.s + dz * o.c, ex = Math.abs(lx) - o.hw, ez = Math.abs(lz) - o.hd;
@@ -32565,7 +32684,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32565
32684
  }
32566
32685
  function collideObject(x, z, fx, fz, floor2) {
32567
32686
  const R = 0.2;
32568
- for (const o of shared2.inter.objs) {
32687
+ for (const o of inter().objs) {
32569
32688
  if (o.f !== -1 ? o.f !== floor2 : floor2 !== 0) continue;
32570
32689
  const d1 = objectDistance(o, x, z);
32571
32690
  if (d1 < R && d1 < objectDistance(o, fx, fz) - 1e-6) return true;
@@ -32585,13 +32704,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32585
32704
  const de = opt.from || [x + 1e4, z + 1e4];
32586
32705
  return collideObject(x, z, de[0], de[1], floor2);
32587
32706
  }
32588
- Object.assign(K, { NO_COLLIDE, registerCollision, objectDistance, collideObject, collideAt });
32707
+ const defined = { NO_COLLIDE, registerCollision, objectDistance, collideObject, collideAt };
32708
+ Object.assign(K, defined);
32589
32709
  }
32590
32710
  function installInteractionItems(K, shared2) {
32591
32711
  const { t, LIGHTS, cursor, definePiece, localOf, registerCollision, togglePiece } = K;
32592
32712
  const DOOR_ITEM = /^(tv_unit|tv_unit_small|tv_unit_large|sideboard|china_cabinet|filing_cabinet|pantry|laundry_cabinet|wardrobe|wardrobe_small|wardrobe_large|closet_wardrobe|kitchen_cabinet|kitchen_cabinet_large|kitchen_cabinet_small|fridge|fridge_large|display_fridge_medium|display_fridge)$/;
32593
32713
  const DRAWER_ITEM = /^(console_table|dresser|nightstand|vanity_table)$/;
32594
32714
  const LIGHT_TYPES = /* @__PURE__ */ new Set(["ceiling_light", "pendant", "chandelier", "track_spot", "hanging_plant"]);
32715
+ const I = () => shared2.inter;
32595
32716
  function objectName(type, drawer) {
32596
32717
  return drawer ? "drawer" : /^wardrobe/.test(type) ? "wardrobe" : /fridge|refrig|freezer/.test(type) ? "fridge" : /pantry/.test(type) ? "pantry" : "cabinet";
32597
32718
  }
@@ -32620,8 +32741,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32620
32741
  cursor.group = parent;
32621
32742
  }
32622
32743
  for (let i = n0; i < LIGHTS.length; i++) LIGHTS[i].roomId = m.room;
32623
- if (!shared2.inter.defs.has(name)) definePiece(name, { kind: "light", pivot: [0, 0, 0], ry: 0, parent, roomId: m.room });
32624
- shared2.inter.litRooms.add(m.room);
32744
+ if (!I().defs.has(name)) definePiece(name, { kind: "light", pivot: [0, 0, 0], ry: 0, parent, roomId: m.room });
32745
+ I().litRooms.add(m.room);
32625
32746
  }
32626
32747
  function curtainItem(m, M, ent, api, parent) {
32627
32748
  M.open = false;
@@ -32649,12 +32770,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32649
32770
  for (const c of body) api[c[0]](M, ...c[1]);
32650
32771
  if (!parts.length) return;
32651
32772
  const [ax, az] = localOf(M, 0, 0.2);
32652
- shared2.inter.items.push({ type: "curtain", id: m.id, floor: M.floor, anchor: [ax, M.base + (M.y || 0) + (m.h || 2) * 0.5, az], range: 2.4, angle: 1, pieces: parts, text: () => t(parts[0].target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what.curtain") }), action: () => {
32653
- const al = parts[0].target > 0.5 ? 0 : 1;
32773
+ const first = parts[0];
32774
+ I().items.push({ type: "curtain", id: m.id, floor: M.floor, anchor: [ax, M.base + (M.y || 0) + (m.h || 2) * 0.5, az], range: 2.4, angle: 1, pieces: parts, text: () => t(first.target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what.curtain") }), action: () => {
32775
+ const al = first.target > 0.5 ? 0 : 1;
32654
32776
  for (const p of parts) {
32655
32777
  p.target = al;
32656
32778
  shared2.partState.set(p.name, al);
32657
- shared2.inter.anim.add(p);
32779
+ I().anim.add(p);
32658
32780
  }
32659
32781
  } });
32660
32782
  }
@@ -32675,7 +32797,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32675
32797
  calls.forEach((c, i) => {
32676
32798
  if (owner.has(i)) return;
32677
32799
  const a = c[1];
32678
- let x0, x1, y0, y1, ok = false, grip = 0, wide2 = false;
32800
+ let x0 = 0, x1 = 0, y0 = 0, y1 = 0, ok = false, grip = 0, wide2 = false;
32679
32801
  if (c[0] === "box") {
32680
32802
  const [mat, x, y, z, w, h, d, , ry, rx, rz] = a;
32681
32803
  if (ry || rx || rz || d > 0.05 || z + d / 2 < front - 5e-3 || w > M.w * 1.01) return;
@@ -32707,8 +32829,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32707
32829
  return;
32708
32830
  }
32709
32831
  candidate.sort((p, q) => overlap(x0, x1, q.x0, q.x1) - overlap(x0, x1, p.x0, p.x1));
32710
- owner.set(i, candidate[0]);
32711
- if (grip) candidate[0].grip = grip;
32832
+ const best = candidate[0];
32833
+ owner.set(i, best);
32834
+ if (grip) best.grip = grip;
32712
32835
  });
32713
32836
  const name = objectName(m.type, drawer), parts = [];
32714
32837
  panels.forEach((p, k) => {
@@ -32724,8 +32847,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32724
32847
  p.def = def;
32725
32848
  parts.push(def);
32726
32849
  const [ax, az] = localOf(M, cx, front + 0.08);
32727
- shared2.inter.items.push({ type: drawer ? "drawer" : "cabinet", id: m.id, floor: M.floor, anchor: [ax, M.base + (M.y || 0) + (p.y0 + p.y1) / 2, az], range: 1.6, angle: 0.4, pieces: [def], text: () => t(def.target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what." + name) }), action: () => togglePiece(def) });
32728
- def.item = shared2.inter.items[shared2.inter.items.length - 1];
32850
+ I().items.push({ type: drawer ? "drawer" : "cabinet", id: m.id, floor: M.floor, anchor: [ax, M.base + (M.y || 0) + (p.y0 + p.y1) / 2, az], range: 1.6, angle: 0.4, pieces: [def], text: () => t(def.target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what." + name) }), action: () => togglePiece(def) });
32851
+ def.item = I().items[I().items.length - 1];
32729
32852
  });
32730
32853
  calls.forEach((c, i) => {
32731
32854
  const p = owner.get(i);
@@ -32739,12 +32862,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32739
32862
  }
32740
32863
  cursor.group = parent;
32741
32864
  }
32742
- Object.assign(K, { DOOR_ITEM, DRAWER_ITEM, LIGHT_TYPES, objectName, recordApi, buildItem: buildItem2, lightItem, curtainItem, furnitureItem });
32865
+ const defined = { DOOR_ITEM, DRAWER_ITEM, LIGHT_TYPES, objectName, recordApi, buildItem: buildItem2, lightItem, curtainItem, furnitureItem };
32866
+ Object.assign(K, defined);
32743
32867
  }
32744
32868
  function installInteractionFittings(K, shared2) {
32745
32869
  const { t, EPS: EPS6, OPEN_AREA, Y0, applyPiece, bx, cursor, definePiece, gates, lightOn, roomAt, slideDirection, toggleLight, togglePiece } = K;
32870
+ const I = () => shared2.inter;
32871
+ const house = () => shared2.ctx.r;
32746
32872
  function gatesInteractive() {
32747
- const lt2 = shared2.ctx.r.lot;
32873
+ const lt2 = house().lot;
32748
32874
  if (!lt2) return;
32749
32875
  const cz0 = (lt2.rect[1] + lt2.rect[3]) / 2;
32750
32876
  const orig = K.getBx(), gs = lt2.gates, opening = gs.map((g) => g.open), reg = gs.map((g) => {
@@ -32764,9 +32890,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32764
32890
  return;
32765
32891
  }
32766
32892
  }
32767
- return orig(mat, x0, y0, z0, x1, y1, z1, color2);
32893
+ orig(mat, x0, y0, z0, x1, y1, z1, color2);
32768
32894
  });
32769
- const n0 = shared2.ctx.colliders.length;
32895
+ const colliders = shared2.ctx.colliders, n0 = colliders.length;
32770
32896
  try {
32771
32897
  gs.forEach((g) => {
32772
32898
  g.open = false;
@@ -32778,7 +32904,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32778
32904
  g.open = opening[i];
32779
32905
  });
32780
32906
  }
32781
- const cols = shared2.ctx.colliders.slice(n0), cz = (lt2.rect[1] + lt2.rect[3]) / 2, cu = (lt2.rect[0] + lt2.rect[2]) / 2;
32907
+ const cols = colliders.slice(n0), cz = (lt2.rect[1] + lt2.rect[3]) / 2, cu = (lt2.rect[0] + lt2.rect[2]) / 2;
32782
32908
  reg.forEach((r, i) => {
32783
32909
  const g = r.g;
32784
32910
  if (!isFinite(r.x0)) return;
@@ -32787,25 +32913,25 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32787
32913
  const p = ped ? definePiece(name, Object.assign(base, { kind: "gate_swing", pivot: [r.x0, 0, g.v], angle: -sd * 1.65 })) : tilt ? definePiece(name, Object.assign(base, { kind: "gate_tilting", pivot: [(r.x0 + r.x1) / 2, r.y1, g.v], angle: -sd * 1.45 })) : definePiece(name, Object.assign(base, { kind: "gate_sliding", pivot: [r.x0, 0, r.zm], travel: r.dx * g.width }));
32788
32914
  if (p.col) p.col.off = p.target > 0.5;
32789
32915
  const text = () => t(p.target > 0.5 ? "prompt.close" : "prompt.open", { what: t(ped ? "what.pedestrianGate" : "what.garageGate") });
32790
- shared2.inter.items.push({ type: "gate", id: g.id, floor: -1, anchor: [g.u, 1, g.v + sd * 0.4], range: 2.8, angle: 0.9, pieces: [p], text, action: () => togglePiece(p), noWall: true });
32916
+ I().items.push({ type: "gate", id: g.id, floor: -1, anchor: [g.u, 1, g.v + sd * 0.4], range: 2.8, angle: 0.9, pieces: [p], text, action: () => togglePiece(p), noWall: true });
32791
32917
  });
32792
32918
  }
32793
32919
  function mailboxInteractive() {
32794
- for (const m of shared2.ctx.r.items) {
32920
+ for (const m of house().items) {
32795
32921
  if (m.type !== "mailbox") continue;
32796
32922
  const g = shared2.ctx.parts && shared2.ctx.parts["mailbox_" + m.id];
32797
32923
  if (!g) continue;
32798
32924
  const name = "ix:correio:" + m.id, def = definePiece(name, { kind: "part", pivot: [0, 0, 0], ry: 0, parent: "lot" });
32799
32925
  def.inner = g;
32800
32926
  const fx = Math.sin(m.ry || 0), fz = Math.cos(m.ry || 0), ay = (m.y || 1) + (m.h || 0.3) * 0.4;
32801
- shared2.inter.items.push({ type: "mailbox", id: m.id, floor: -1, anchor: [m.x + fx * 0.2, ay, m.z + fz * 0.2], range: 2.2, angle: 0.7, pieces: [def], text: () => t(def.target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what.mailbox") }), action: () => togglePiece(def), noWall: true });
32927
+ I().items.push({ type: "mailbox", id: m.id, floor: -1, anchor: [m.x + fx * 0.2, ay, m.z + fz * 0.2], range: 2.2, angle: 0.7, pieces: [def], text: () => t(def.target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what.mailbox") }), action: () => togglePiece(def), noWall: true });
32802
32928
  applyPiece(def);
32803
32929
  }
32804
32930
  }
32805
32931
  function placeSwitches() {
32806
- const R = shared2.ctx.r, used = /* @__PURE__ */ new Set();
32932
+ const R = house(), used = /* @__PURE__ */ new Set();
32807
32933
  for (const c of R.rooms) {
32808
- if (c.type === "void" || OPEN_AREA(c) || !shared2.inter.litRooms.has(c.id) || used.has(c.id) || shared2.ctx.iv && shared2.ctx.iv.switchRooms.has(c.id)) continue;
32934
+ if (c.type === "void" || OPEN_AREA(c) || !I().litRooms.has(c.id) || used.has(c.id) || shared2.ctx.iv && shared2.ctx.iv.switchRooms.has(c.id)) continue;
32809
32935
  const doors = R.doors.filter((p) => p.floor === c.floor && (p.a === c.id || p.b === c.id));
32810
32936
  doors.sort((p, q) => ((q.exterior ? 1 : 0) - (p.exterior ? 1 : 0)) * (c.type === "living" ? 1 : -1));
32811
32937
  for (const p of doors) if (putSwitch(c, p)) {
@@ -32815,11 +32941,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32815
32941
  }
32816
32942
  }
32817
32943
  function putSwitch(c, p) {
32818
- const R = shared2.ctx.r, f = p.floor, alongU = p.axis === "u", L = p.pos, a = p.at - p.width / 2, b = p.at + p.width / 2;
32944
+ const R = house(), f = p.floor, alongU = p.axis === "u", L = p.pos, a = p.at - p.width / 2, b = p.at + p.width / 2;
32819
32945
  const wref = R.walls.find((w) => w.floor === f && w.axis === p.axis && Math.abs((alongU ? w.v0 : w.u0) - L) < EPS6), th = wref ? wref.thickness || 0.15 : 0.15;
32820
32946
  const inside2 = (sd2) => {
32821
32947
  const cc = roomAt(f, alongU ? p.at : L + sd2 * 0.4, alongU ? L + sd2 * 0.4 : p.at);
32822
- return cc && cc.id === c.id;
32948
+ return !!cc && cc.id === c.id;
32823
32949
  };
32824
32950
  const sd = inside2(1) ? 1 : inside2(-1) ? -1 : 0;
32825
32951
  if (!sd) return false;
@@ -32842,17 +32968,20 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32842
32968
  const piece2 = definePiece("ix:int:" + roomId, { kind: "light_switch", pivot: pv, ry: 0, parent: "f" + f, axis: alongU ? "x" : "z", sgn: alongU ? sd : -sd, t0: lightOn(roomId) ? 1 : 0 });
32843
32969
  piece2.t = piece2.target = lightOn(roomId) ? 1 : 0;
32844
32970
  const an = alongU ? [u, yc, face + sd * 0.12] : [face + sd * 0.12, yc, u];
32845
- shared2.inter.items.push({ type: "light_switch", id: roomId, floor: f, anchor: an, range: 1.5, angle: 0.45, pieces: [piece2], text: () => t(lightOn(roomId) ? "prompt.lightOff" : "prompt.lightOn"), action: () => toggleLight(roomId) });
32971
+ I().items.push({ type: "light_switch", id: roomId, floor: f, anchor: an, range: 1.5, angle: 0.45, pieces: [piece2], text: () => t(lightOn(roomId) ? "prompt.lightOff" : "prompt.lightOn"), action: () => toggleLight(roomId) });
32846
32972
  return true;
32847
32973
  }
32848
32974
  return false;
32849
32975
  }
32850
- Object.assign(K, { gatesInteractive, mailboxInteractive, placeSwitches, putSwitch });
32976
+ const defined = { gatesInteractive, mailboxInteractive, placeSwitches, putSwitch };
32977
+ Object.assign(K, defined);
32851
32978
  }
32852
32979
  function installInteractionDoors(K, shared2) {
32853
32980
  const { t, colliderChanged, invalidateShadow, applyPiece, hudMessage } = K;
32981
+ const leaves = () => shared2.ctx.leaves;
32854
32982
  function linkDoorLeaves() {
32855
- for (const fo of shared2.ctx.leaves) fo.handles = (fo.handleNames || []).map((n) => shared2.inter.defs.get(n)).filter(Boolean);
32983
+ const I = shared2.inter;
32984
+ for (const fo of leaves()) fo.handles = (fo.handleNames || []).map((n) => I.defs.get(n)).filter((d) => !!d);
32856
32985
  }
32857
32986
  function handleApply(fo) {
32858
32987
  for (const mc of fo.handles || []) {
@@ -32862,11 +32991,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32862
32991
  }
32863
32992
  function toggleDoor(fo) {
32864
32993
  if (fo.phase === "rattle") return;
32994
+ const col = fo.col;
32865
32995
  if (fo.phase === "handle" || fo.phase === "swing") {
32866
32996
  fo.open = !fo.open;
32867
32997
  shared2.doorState.set(fo.id, fo.open);
32868
- fo.col.off = fo.open;
32869
- colliderChanged(fo.col);
32998
+ col.off = fo.open;
32999
+ colliderChanged(col);
32870
33000
  fo.anim = true;
32871
33001
  fo.phase = "swing";
32872
33002
  return;
@@ -32880,8 +33010,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32880
33010
  }
32881
33011
  fo.open = !fo.open;
32882
33012
  shared2.doorState.set(fo.id, fo.open);
32883
- fo.col.off = fo.open;
32884
- colliderChanged(fo.col);
33013
+ col.off = fo.open;
33014
+ colliderChanged(col);
32885
33015
  fo.anim = true;
32886
33016
  shared2.ctx.animateDoorsOn = true;
32887
33017
  if (fo.handles && fo.handles.length) {
@@ -32892,7 +33022,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32892
33022
  function animateDoors(dt) {
32893
33023
  if (!shared2.ctx.animateDoorsOn) return;
32894
33024
  let active = false;
32895
- for (const fo of shared2.ctx.leaves) {
33025
+ for (const fo of leaves()) {
32896
33026
  if (!fo.phase) continue;
32897
33027
  active = true;
32898
33028
  if (fo.phase === "handle") {
@@ -32912,7 +33042,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32912
33042
  handleApply(fo);
32913
33043
  if (fo.hT <= 0) fo.phase = null;
32914
33044
  } else if (fo.phase === "rattle") {
32915
- fo.jig -= dt;
33045
+ fo.jig = (fo.jig ?? 0) - dt;
32916
33046
  fo.hT = fo.jig > 0 ? 0.55 * Math.abs(Math.sin(fo.jig * 26)) : 0;
32917
33047
  handleApply(fo);
32918
33048
  if (fo.jig <= 0) {
@@ -32926,9 +33056,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32926
33056
  invalidateShadow();
32927
33057
  }
32928
33058
  function wallBlocks(ex, ez, ax, az, floor2) {
32929
- const n = shared2.ctx.wallColliders != null ? shared2.ctx.wallColliders : 0;
33059
+ const n = shared2.ctx.wallColliders != null ? shared2.ctx.wallColliders : 0, colliders = shared2.ctx.colliders;
32930
33060
  for (let i = 0; i < n; i++) {
32931
- const c = shared2.ctx.colliders[i];
33061
+ const c = colliders[i];
32932
33062
  if (c.f !== floor2 && !(c.f === -1 && floor2 === 0)) continue;
32933
33063
  let t0 = 0, t1 = 1;
32934
33064
  const dx = ax - ex, dz = az - ez;
@@ -32958,7 +33088,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32958
33088
  g.updateMatrix();
32959
33089
  }
32960
33090
  }
32961
- Object.assign(K, { linkDoorLeaves, handleApply, toggleDoor, animateDoors, wallBlocks, doorText, applyLeaf });
33091
+ const defined = { linkDoorLeaves, handleApply, toggleDoor, animateDoors, wallBlocks, doorText, applyLeaf };
33092
+ Object.assign(K, defined);
32962
33093
  }
32963
33094
  function installInteractionTarget(K, shared2) {
32964
33095
  const { doorText, toggleDoor, visibleChain, wallBlocks } = K;
@@ -32966,6 +33097,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32966
33097
  function targetOf(o, opt) {
32967
33098
  if (!o) return null;
32968
33099
  opt = opt || {};
33100
+ const I = shared2.inter;
32969
33101
  const ex = o.x, ey = o.y, ez = o.z, floor2 = o.floor, cp = Math.cos(o.pitch || 0), vx2 = Math.sin(o.yaw) * cp, vy2 = Math.sin(o.pitch || 0), vz2 = Math.cos(o.yaw) * cp;
32970
33102
  let best = null;
32971
33103
  const tries = (score, text, action, target) => {
@@ -32979,16 +33111,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32979
33111
  if (angle > 1.35 && d > 0.9) continue;
32980
33112
  tries(angle * 1.6 + d * 0.5 + (angle < 0.25 ? 0 : 0.6), doorText(fo), () => toggleDoor(fo), fo);
32981
33113
  }
32982
- const vis = shared2.inter.pieces.flatMap((p) => p.meshes).filter(visibleChain), hit = vis.length && opt.strike ? opt.strike(vis) : null;
33114
+ const vis = I.pieces.flatMap((p) => p.meshes).filter(visibleChain), hit = vis.length && opt.strike ? opt.strike(vis) : null;
32983
33115
  const kitA = shared2.ctx.iv ? ivTarget(shared2.ctx.iv, o, opt && opt.interactives) : null;
32984
33116
  const nearKit = kitA && hit && Math.hypot(kitA.target.pos[0] - ex, kitA.target.pos[1] - ey, kitA.target.pos[2] - ez) < hit.distance + 0.1;
32985
33117
  const pieceHit = hit && !nearKit && hit.object.userData.piece;
32986
- for (const it of shared2.inter.items) {
33118
+ for (const it of I.items) {
32987
33119
  if (it.floor !== floor2 && !(it.floor === -1 && floor2 === 0)) continue;
32988
33120
  const [ax, ay, az] = it.anchor, dx = ax - ex, dy = ay - ey, dz = az - ez, d = Math.hypot(dx, dy, dz), dh = Math.hypot(dx, dz);
32989
33121
  if (dh > it.range + 0.4) continue;
32990
33122
  const angle = Math.acos(Math.max(-1, Math.min(1, (dx * vx2 + dy * vy2 + dz * vz2) / (d || 1))));
32991
- const byRay = pieceHit && it.pieces.includes(pieceHit) && hit.distance <= it.range + 0.5;
33123
+ const byRay = !!hit && pieceHit && it.pieces.includes(pieceHit) && hit.distance <= it.range + 0.5;
32992
33124
  if (!byRay && !(dh <= it.range && angle <= it.angle)) continue;
32993
33125
  if (!it.noWall && wallBlocks(ex, ez, ax, az, it.floor < 0 ? 0 : it.floor)) continue;
32994
33126
  tries((byRay ? 0 : angle * 2) + d * 0.3 - (byRay ? 1.5 : 0), it.text(), it.action, it);
@@ -32996,7 +33128,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32996
33128
  if (kitA) tries(kitA.score - (nearKit ? 0.5 : 0), kitA.text, kitA.action, kitA.target);
32997
33129
  return best;
32998
33130
  }
32999
- Object.assign(K, { targetOf });
33131
+ const defined = { targetOf };
33132
+ Object.assign(K, defined);
33000
33133
  }
33001
33134
  function installInteractablesBridge(K, shared2) {
33002
33135
  const { t, THREE, invalidate, invalidateShadow, cfg, DOC, LIGHT_TYPES, _Y, _q, _v3, accFor, applyLight, cursor, hashString, hudMessage, lightBase, pieceRecord, put, rgbOf, sh, wallBlocks } = K;
@@ -33051,7 +33184,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33051
33184
  function ivBuild(h, water) {
33052
33185
  const ik = K.IVK, r = shared2.ctx.r, A = ik.A, world0 = null;
33053
33186
  void world0;
33054
- const plane2 = A.plan(r, { seed: r.seed });
33187
+ const source = r;
33188
+ const plane2 = A.plan(source, { seed: r.seed });
33055
33189
  const IV = { k: ik, plane: plane2, world: null, water, entries: /* @__PURE__ */ new Map(), roots: [], replace: /* @__PURE__ */ new Set(), roomStates: /* @__PURE__ */ new Map(), lampRoom: /* @__PURE__ */ new Map(), anim: /* @__PURE__ */ new Map(), screens: /* @__PURE__ */ new Map(), efx: null, items: null, itemsDirty: true, itemsT: 0, dirty: true, list: null, listT: 0, t: 0, circuits: [], switchRooms: /* @__PURE__ */ new Set(), warnings: [], tBuild: 0 };
33056
33190
  h.IV = IV;
33057
33191
  const t0 = performance.now();
@@ -33070,9 +33204,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33070
33204
  const wants = (roomId) => lightBase(roomId);
33071
33205
  const entById = new Map(plane2.items.map((e) => [e.id, e]));
33072
33206
  const entByItem = new Map(plane2.items.map((e) => [e.item, e]));
33073
- IV.mats = { plain: shared2.mats.plain, metal: shared2.mats.metal, wood: shared2.mats.wood, glass: shared2.mats.glass, fabric: shared2.mats.fabric, plant: shared2.mats.plant, water: shared2.mats.water, emissive: shared2.mats.emissive, atlas_picture: shared2.mats.picture, atlas_floor: shared2.mats.floor };
33207
+ const mats = shared2.mats;
33208
+ IV.mats = { plain: mats.plain, metal: shared2.mats.metal, wood: shared2.mats.wood, glass: shared2.mats.glass, fabric: shared2.mats.fabric, plant: shared2.mats.plant, water: shared2.mats.water, emissive: shared2.mats.emissive, atlas_picture: shared2.mats.picture, atlas_floor: shared2.mats.floor };
33074
33209
  const ev = (e) => ivEvent(h, e);
33075
- const world = IV.world = A.createWorld(r, { water, seed: r.seed, onEvent: ev });
33210
+ const world = IV.world = A.createWorld(source, { water, seed: r.seed, onEvent: ev });
33076
33211
  const add0 = world.add;
33077
33212
  world.add = (id, spec, tr) => {
33078
33213
  const e = entById.get(id);
@@ -33089,7 +33224,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33089
33224
  }
33090
33225
  return add0(id, spec, tr);
33091
33226
  };
33092
- const added = A.add(world, plane2, { isBlocked: A.blockedOf(r), build: (type, item) => ivDraw(IV, entByItem.get(item), type, item) });
33227
+ const added = A.add(world, plane2, { isBlocked: A.blockedOf(source), build: (type, item) => ivDraw(IV, entByItem.get(item), type, item) });
33093
33228
  world.add = add0;
33094
33229
  IV.warnings = added.warnings;
33095
33230
  IV.added = added;
@@ -33136,14 +33271,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33136
33271
  }
33137
33272
  function ivDraw(IV, ent, type, item) {
33138
33273
  const ik = IV.k, loc = Object.assign({}, item, { x: 0, z: 0, ry: 0 });
33274
+ const ix = item.x, iz = item.z, iry = item.ry;
33139
33275
  const mesh3 = ik.gfx.createMeshApi({ quality: "game", materials: IV.mats, shadows: true, mergeParts: true, swayAmplitude: 0.03 });
33140
33276
  const spec = ik.A.household.build(type, loc, mesh3.api);
33141
33277
  const out = mesh3.finish(spec);
33142
33278
  for (const l of out.lights) l.removeFromParent();
33143
33279
  const group = ivGroup(ent), g0 = cursor.group, root = new THREE.Group();
33144
33280
  root.name = "iv:" + ent.id;
33145
- root.position.set(item.x, ent.floorY, item.z);
33146
- root.rotation.y = item.ry;
33281
+ root.position.set(ix, ent.floorY, iz);
33282
+ root.rotation.y = iry;
33147
33283
  root.userData.iv = ent.id;
33148
33284
  const screen2 = spec.devices && spec.devices.some((d) => d.kind === "screen");
33149
33285
  let body = null;
@@ -33152,7 +33288,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33152
33288
  if (type === "gas_bottle") {
33153
33289
  cursor.pc = pieceRecord("gas_cylinder:" + ent.id, "steel", null, { floor: ent.floor, mass: 11, form: "cyl", thickness: 3e-3, fill: 0.03, contains: { fluid: "gas", liters: 13, pressurized: true }, explodes: { energy: 12e4, radius: 5, atC: 300 }, tags: ["gas_bottle"] });
33154
33290
  for (const m of out.group.children) if (!m.name.startsWith("static:")) m.traverse((o) => {
33155
- if (o.isMesh) {
33291
+ if (isMesh(o)) {
33156
33292
  o.userData.destructionPart = cursor.pc.id;
33157
33293
  o.userData.destructionMaterial = "steel";
33158
33294
  }
@@ -33160,13 +33296,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33160
33296
  }
33161
33297
  try {
33162
33298
  for (const m of out.group.children.slice()) {
33163
- if (m.isMesh && m.name.startsWith("static:")) {
33299
+ if (isMesh(m) && m.name.startsWith("static:")) {
33164
33300
  if (screen2 && m.userData.material === "emissive") {
33165
33301
  body = m;
33166
33302
  root.add(m);
33167
33303
  continue;
33168
33304
  }
33169
- ivAccumulate(IV_MATERIAL[m.userData.material] || "plain", m.geometry, item.x, ent.floorY, item.z, item.ry, null);
33305
+ ivAccumulate(IV_MATERIAL[m.userData.material] || "plain", m.geometry, ix, ent.floorY, iz, iry, null);
33170
33306
  m.geometry.dispose();
33171
33307
  } else root.add(m);
33172
33308
  }
@@ -33176,7 +33312,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33176
33312
  }
33177
33313
  const base = new Set(Object.values(IV.mats));
33178
33314
  root.traverse((o) => {
33179
- if (!o.isMesh) return;
33315
+ if (!isMesh(o)) return;
33180
33316
  o.userData.iv = ent.id;
33181
33317
  if (o.castShadow) {
33182
33318
  if (!o.geometry.boundingSphere) o.geometry.computeBoundingSphere();
@@ -33187,7 +33323,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33187
33323
  roomLightMask(m);
33188
33324
  }
33189
33325
  });
33190
- const E = { id: ent.id, type, entry: ent, floor: ent.floor, group, root, parts: out.parts, spec, screen: body, pos: [item.x, ent.floorY, item.z], ry: item.ry, origin: ent.origin };
33326
+ const E = { id: ent.id, type, entry: ent, floor: ent.floor, group, root, parts: out.parts, spec, screen: body, pos: [ix, ent.floorY, iz], ry: iry, origin: ent.origin };
33191
33327
  IV.entries.set(ent.id, E);
33192
33328
  if (root.children.length) IV.roots.push(E);
33193
33329
  return spec;
@@ -33215,7 +33351,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33215
33351
  const wire = (spec.wires || []).find((x) => x.id === d.id + "_cord"), pts = (wire ? wire.points : [d.plug]).map((p) => wl(o, p));
33216
33352
  const sid = w.power.pluggedInto(E.id, d.id);
33217
33353
  if (sid) {
33218
- const cut = sid.indexOf(":"), so = w.get(sid.slice(0, cut)), sk = so && so.spec.sockets.find((s) => s.id === sid.slice(cut + 1));
33354
+ const cut = sid.indexOf(":"), so = w.get(sid.slice(0, cut)), sk = so && (so.spec.sockets || []).find((s) => s.id === sid.slice(cut + 1));
33219
33355
  if (so && sk) {
33220
33356
  const sp = wl(so, sk.pos), dir = [Math.sin(so.transform.ry), Math.cos(so.transform.ry)], last = pts[pts.length - 1];
33221
33357
  if (last[1] < 0.3 + E.pos[1]) {
@@ -33250,9 +33386,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33250
33386
  roomLightMask(sc.material);
33251
33387
  IV.screens.set(E.id, sc);
33252
33388
  }
33253
- E.screen.material = sc.material;
33254
- E.screen.castShadow = false;
33255
- E.screen.receiveShadow = false;
33389
+ const mesh3 = E.screen;
33390
+ mesh3.material = sc.material;
33391
+ mesh3.castShadow = false;
33392
+ mesh3.receiveShadow = false;
33256
33393
  }
33257
33394
  function ivEvent(h, e) {
33258
33395
  const IV = h.IV;
@@ -33288,16 +33425,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33288
33425
  IV.itemsDirty = true;
33289
33426
  break;
33290
33427
  }
33291
- if (K.IVK.onEvent) {
33428
+ const ik = K.IVK;
33429
+ if (ik.onEvent) {
33292
33430
  try {
33293
- K.IVK.onEvent(e, h.IV.pub);
33431
+ ik.onEvent(e, IV.pub);
33294
33432
  } catch (err) {
33295
33433
  console.warn("interactables.onEvent", err);
33296
33434
  }
33297
33435
  }
33298
- if (e.type === "seat" && K.IVK.onSeat && e.actor === "player") {
33436
+ if (e.type === "seat" && ik.onSeat && e.actor === "player") {
33299
33437
  try {
33300
- K.IVK.onSeat(e.seated ? ivSeat(IV) : null, e);
33438
+ ik.onSeat(e.seated ? ivSeat(IV) : null, e);
33301
33439
  } catch (err) {
33302
33440
  console.warn("interactables.onSeat", err);
33303
33441
  }
@@ -33306,7 +33444,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33306
33444
  function ivSeat(IV) {
33307
33445
  const w = IV.world, s = w.seatOf("player");
33308
33446
  if (!s) return null;
33309
- const o = w.get(s.object), seat2 = o.spec.seats.find((q) => q.id === s.seat), L = IV.k.GI.localToWorld, tr = o.transform, E = IV.entries.get(s.object);
33447
+ const o = w.get(s.object), seat2 = (o.spec.seats || []).find((q) => q.id === s.seat), L = IV.k.GI.localToWorld, tr = o.transform, E = IV.entries.get(s.object);
33310
33448
  const eye = L(tr, [seat2.pos[0], seat2.pos[1] + (seat2.eye === void 0 ? seat2.pose === "lie" ? 0.18 : 0.62 : seat2.eye), seat2.pos[2]]);
33311
33449
  return { object: s.object, seatInfo: s.seat, pose: seat2.pose, eye, yaw: tr.ry + seat2.ry, pitch: seat2.pose === "lie" ? 0.55 : -0.08, exitPoint: L(tr, seat2.exit), floor: E ? E.floor : 0, type: E ? E.type : null };
33312
33450
  }
@@ -33348,18 +33486,19 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33348
33486
  }
33349
33487
  }
33350
33488
  const em = w.emitters();
33351
- if (em.length && !IV.efx && K.IVK.effects) {
33489
+ const ivk = K.IVK;
33490
+ if (em.length && !IV.efx && ivk.effects) {
33352
33491
  const g = h.houseGroup;
33353
- IV.efx = ik.gfx.createEffects(g, { maxParticles: 1400, seed: 11, document: DOC, ...K.IVK.effectSink ? { effects: K.IVK.effectSink } : {} });
33492
+ IV.efx = ik.gfx.createEffects(g, { maxParticles: 1400, seed: 11, document: DOC, ...ivk.effectSink ? { effects: ivk.effectSink } : {} });
33354
33493
  }
33355
33494
  if (IV.efx) {
33356
33495
  const alive = IV.efx.stats().alive;
33357
33496
  if (em.length || alive) {
33358
- IV.efx.update(dt, em, K.IVK.camera ? typeof K.IVK.camera === "function" ? K.IVK.camera() : K.IVK.camera : void 0);
33497
+ IV.efx.update(dt, em, ivk.camera ? typeof ivk.camera === "function" ? ivk.camera() : ivk.camera : void 0);
33359
33498
  invalidate();
33360
33499
  }
33361
33500
  }
33362
- if (K.IVK.items && IV.itemsDirty && IV.t - IV.itemsT > 0.1 && !IV.anim.size) ivItems(IV, h);
33501
+ if (ivk.items && IV.itemsDirty && IV.t - IV.itemsT > 0.1 && !IV.anim.size) ivItems(IV, h);
33363
33502
  }
33364
33503
  const IV_SHAPE = {
33365
33504
  can: [["cyl", 1, 1, 1, 0, 1]],
@@ -33394,7 +33533,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33394
33533
  if (c.access && w.partT(E.id, c.access) < 0.02) continue;
33395
33534
  const st = w.contents(E.id, c.id);
33396
33535
  for (let i = 0; i < st.length; i++) {
33397
- if (st[i] && items[st[i].type]) list2.push([E, c.id, i, items[st[i].type]]);
33536
+ const stack = st[i];
33537
+ if (stack && items[stack.type]) list2.push([E, c.id, i, items[stack.type]]);
33398
33538
  }
33399
33539
  }
33400
33540
  }
@@ -33423,12 +33563,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33423
33563
  gm.setIndex(new THREE.BufferAttribute(A.i.slice(0, A.ni), 1));
33424
33564
  gm.computeBoundingSphere();
33425
33565
  if (!IV.items) {
33426
- IV.items = new THREE.Mesh(gm, shared2.mats.plain);
33427
- IV.items.name = "iv-items";
33428
- IV.items.castShadow = false;
33429
- IV.items.receiveShadow = true;
33430
- IV.items.frustumCulled = false;
33431
- h.houseGroup.add(IV.items);
33566
+ const mesh3 = new THREE.Mesh(gm, shared2.mats.plain);
33567
+ IV.items = mesh3;
33568
+ mesh3.name = "iv-items";
33569
+ mesh3.castShadow = false;
33570
+ mesh3.receiveShadow = true;
33571
+ mesh3.frustumCulled = false;
33572
+ h.houseGroup.add(mesh3);
33432
33573
  } else {
33433
33574
  IV.items.geometry.dispose();
33434
33575
  IV.items.geometry = gm;
@@ -33562,7 +33703,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33562
33703
  };
33563
33704
  return IV.pub;
33564
33705
  }
33565
- Object.assign(K, { IV_MATERIAL, IV_WIRE, IV_DOOR, ivGroup, ivAccumulate, ivBuild, ivRoomEffective, ivDraw, ivCords, ivAssemble, ivScreen, ivEvent, ivSeat, ivUpdate, IV_SHAPE, ivItems, ivTarget, ivRoomLight, ivParts, ivDispose, ivPublish });
33706
+ const defined = { IV_MATERIAL, IV_WIRE, IV_DOOR, ivGroup, ivAccumulate, ivBuild, ivRoomEffective, ivDraw, ivCords, ivAssemble, ivScreen, ivEvent, ivSeat, ivUpdate, IV_SHAPE, ivItems, ivTarget, ivRoomLight, ivParts, ivDispose, ivPublish };
33707
+ Object.assign(K, defined);
33566
33708
  }
33567
33709
  function installAnimationClotheslines(K, shared2) {
33568
33710
  const { invalidate, CLOTHES_UNIFORMS } = K;
@@ -33585,7 +33727,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33585
33727
  }
33586
33728
  invalidate();
33587
33729
  }
33588
- Object.assign(K, { WIND, animateClotheslines });
33730
+ const defined = { WIND, animateClotheslines };
33731
+ Object.assign(K, defined);
33589
33732
  }
33590
33733
  function installBuildInstance(K, shared2) {
33591
33734
  const { PROPS, THREE, DOC, cfg, HP, createInteractiveMaterials, createMaterials: createMaterials2, typeTable } = K;
@@ -33608,7 +33751,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33608
33751
  shared2.quality = h.quality;
33609
33752
  }
33610
33753
  const tagDamage = (type) => ({ type, hp: HP[type], hpMax: HP[type] });
33611
- Object.assign(K, { props, TYPES, newState, enter, tagDamage });
33754
+ const defined = { props, TYPES, newState, enter, tagDamage };
33755
+ Object.assign(K, defined);
33612
33756
  }
33613
33757
  function installInteractablesKit(K, shared2) {
33614
33758
  const { t, THREE, DOC, cfg, Reflector } = K;
@@ -33634,15 +33778,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33634
33778
  for (const k of ["wood", "foliage", "flowers", "fruit", "spines"]) roomLightMask(m[k]);
33635
33779
  return m;
33636
33780
  })());
33637
- Object.assign(K, { IVK, VEG, vegMaterials });
33781
+ const defined = { IVK, VEG, vegMaterials };
33782
+ Object.assign(K, defined);
33638
33783
  }
33784
+ var newGroup = (k, house, exterior) => ({ k, house, ls: [], exterior, pos: [0, 0, 0], color: 0, n: 0, range: 0, rects: [], y: [0, 0], exclusion: null, lumens: 0, dist: 0, decay: 0, floor: 0, roomId: null, dm: 0, d: 0 });
33639
33785
  function installLightsRoomLight(K, shared2) {
33640
33786
  const { THREE, rectsOf: rectsOf2, cfg } = K;
33641
33787
  const MAX_LIGHTS = 12, EMPTY = [1e9, 1e9, -1e9, -1e9];
33642
33788
  const LZU = { uRB0: { value: new Float32Array(MAX_LIGHTS * 4) }, uRB1: { value: new Float32Array(MAX_LIGHTS * 4) }, uRB2: { value: new Float32Array(MAX_LIGHTS * 4) }, uRBY: { value: new Float32Array(MAX_LIGHTS * 2) }, uREx: { value: new Float32Array(MAX_LIGHTS * 4) }, uIndK: { value: 0.06 } };
33643
33789
  for (let i = 0; i < MAX_LIGHTS; i++) for (const k of ["uRB0", "uRB1", "uRB2", "uREx"]) LZU[k].value.set(EMPTY, i * 4);
33644
- function roomLightMask(m) {
33645
- if (!m || m.userData && m.userData.roomLightMask || !(m.isMeshLambertMaterial || m.isMeshPhongMaterial || m.isMeshStandardMaterial || m.isMeshPhysicalMaterial)) return m;
33790
+ function roomLightMask(material) {
33791
+ const m = material;
33792
+ if (!m || m.userData && m.userData.roomLightMask || !(m.isMeshLambertMaterial || m.isMeshPhongMaterial || m.isMeshStandardMaterial || m.isMeshPhysicalMaterial)) return material;
33646
33793
  m.userData = m.userData || {};
33647
33794
  m.userData.roomLightMask = true;
33648
33795
  const prev = m.onBeforeCompile, pk = m.customProgramCacheKey;
@@ -33670,12 +33817,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33670
33817
  return (pk ? pk.call(this) : "") + "|rm1";
33671
33818
  };
33672
33819
  m.needsUpdate = true;
33673
- return m;
33820
+ return material;
33674
33821
  }
33675
- function lighting(o) {
33676
- o = o || {};
33822
+ function lighting(options) {
33823
+ const o = options || {};
33677
33824
  const scene = o.scene, N = Math.max(1, Math.min(MAX_LIGHTS, o.n || 6)), NS = Math.max(0, Math.min(N, o.shadows != null ? o.shadows : 2)), size = o.shadowSize || 512, MAX_EXTERNAL = o.external != null ? o.external : 2;
33678
- for (const k of Object.keys(shared2.mats)) roomLightMask(shared2.mats[k]);
33825
+ const mats = shared2.mats;
33826
+ for (const k of Object.keys(mats)) roomLightMask(mats[k]);
33679
33827
  const budget = o.budget, lease = budget ? budget.lease({ owner: "floorplan.rooms", point: N, shadows: NS }) : null;
33680
33828
  if (budget && !lease) throw new Error("lighting: the LightBudget has no " + N + " free point slots (" + NS + " with shadow) for the rooms");
33681
33829
  if (budget) for (const [key2, width] of [["uRB0", 4], ["uRB1", 4], ["uRB2", 4], ["uRBY", 2], ["uREx", 4]]) {
@@ -33726,9 +33874,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33726
33874
  }
33727
33875
  for (let i = 0; i < NS; i++) PL[i].shadow.needsUpdate = true;
33728
33876
  };
33729
- A.update = function(houses, focus, op) {
33730
- op = op || {};
33731
- houses = (Array.isArray(houses) ? houses : [houses]).filter(Boolean);
33877
+ A.update = function(houseOrList, focus, options2) {
33878
+ const op = options2 || {}, houses = (Array.isArray(houseOrList) ? houseOrList : [houseOrList]).filter((h) => !!h);
33732
33879
  _f.set(focus.x, focus.y, focus.z);
33733
33880
  const rooms = [], exterior = [];
33734
33881
  for (const house of houses) {
@@ -33740,7 +33887,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33740
33887
  if (!house.lightOn(l.roomId)) continue;
33741
33888
  const k = l.type === "outdoor" ? "ext:" + (l.id || exterior.length) : l.roomId != null ? l.roomId : l.room;
33742
33889
  let g = by.get(k);
33743
- if (!g) by.set(k, g = { k, house, ls: [], exterior: l.type === "outdoor" });
33890
+ if (!g) by.set(k, g = newGroup(k, house, l.type === "outdoor"));
33744
33891
  g.ls.push(l);
33745
33892
  }
33746
33893
  for (const g of by.values()) {
@@ -33775,9 +33922,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33775
33922
  }
33776
33923
  }
33777
33924
  g.exclusion = [x0 + 0.03, z0 + 0.03, x1 - 0.03, z1 - 0.03];
33778
- g.lumens = ls[0].lumens != null ? ls[0].lumens : 3.2;
33779
- g.dist = ls[0].dist != null ? ls[0].dist : 5.5;
33780
- g.decay = ls[0].decay != null ? ls[0].decay : 2;
33925
+ const l0 = ls[0];
33926
+ g.lumens = l0.lumens != null ? l0.lumens : 3.2;
33927
+ g.dist = l0.dist != null ? l0.dist : 5.5;
33928
+ g.decay = l0.decay != null ? l0.decay : 2;
33781
33929
  } else {
33782
33930
  const c = house.r.rooms.find((q) => q.id === g.k);
33783
33931
  if (!c) continue;
@@ -33878,8 +34026,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33878
34026
  }
33879
34027
  const effectsByBudget = /* @__PURE__ */ new WeakMap();
33880
34028
  const OPENING_REACH = 2.5, OPENING_SIDE = 0.6;
33881
- function effectLights(o) {
33882
- o = o || {};
34029
+ function effectLights(options) {
34030
+ const o = options || {};
33883
34031
  const budget = o.budget;
33884
34032
  if (!budget) throw new Error("effectLights: a LightBudget is required");
33885
34033
  const known = effectsByBudget.get(budget);
@@ -33957,7 +34105,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33957
34105
  const A = {
33958
34106
  /** Once per frame, after the budget's `present`: points the mask of every lit slot that is not the house's at the rooms its light reaches. */
33959
34107
  update(houses) {
33960
- const indoors = cfg.effectLightsIndoors !== false, list2 = (Array.isArray(houses) ? houses : [houses]).filter(Boolean), cache2 = /* @__PURE__ */ new Map();
34108
+ const indoors = cfg.effectLightsIndoors !== false, list2 = (Array.isArray(houses) ? houses : [houses]).filter((h) => !!h), cache2 = /* @__PURE__ */ new Map();
33961
34109
  for (let at3 = 0; at3 < size; at3++) {
33962
34110
  if (ours.has(at3)) continue;
33963
34111
  const light = budget.group.children[at3];
@@ -33985,7 +34133,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33985
34133
  if (!o.ours) effectsByBudget.set(budget, A);
33986
34134
  return A;
33987
34135
  }
33988
- Object.assign(K, { MAX_LIGHTS, EMPTY, LZU, roomLightMask, lighting, effectLights });
34136
+ const defined = { MAX_LIGHTS, EMPTY, LZU, roomLightMask, lighting, effectLights };
34137
+ Object.assign(K, defined);
33989
34138
  }
33990
34139
  var NONE = { panels: [], replaced: [], supports: [] };
33991
34140
  var MEMO = /* @__PURE__ */ new WeakMap();
@@ -35162,8 +35311,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35162
35311
  }
35163
35312
  function installBuildBuild(K, shared2) {
35164
35313
  const { THREE, cfg, rectsOf: rectsOf2, invalidateShadow, colliderChanged, VERSION: VERSION2, CARS, EPS: EPS6, LIGHTS, MIRRORS, Y0, animateClotheslines, animateDoors, animateInteractive, applyLeaf, applyOutbuildings, applyPart, applyPiece, assembleInteractive, baseboardAndSidewalk, buildStairs, building, carModel, chooseMirror, closeScene, collideAt, createWater, cursor, doorText, doors, electricalStructure, elevator, floorsAndSlabs, gatesInteractive, houseItems, ivAssemble, ivBuild, ivDispose, ivParts, ivPublish, ivUpdate, lightOn, linkDoorLeaves, mailboxInteractive, newInteractiveState, newMirrorState, outbuildings, paths, perimeter, placeSwitches, roofs, roomAt, solar, targetOf, terrain, toggleDoor, toggleLight, walls, waterPipes, windows, props, TYPES, IVK, VEG, vegMaterials, markGroups, assembleStructure, createHouseDestruction, newState, enter, tagDamage } = K;
35165
- function build(r0, opts) {
35166
- opts = opts || {};
35314
+ function build(r0, options) {
35315
+ const opts = options || {};
35167
35316
  const r = applyOutbuildings(r0);
35168
35317
  const t0 = performance.now();
35169
35318
  const h = { ctx: { mv: props, types: TYPES }, inter: newInteractiveState(), state: opts.state || newState(), mirrors: newMirrorState(), quality: opts.quality === "game" || opts.quality === "high" ? opts.quality : cfg.quality === "game" ? "game" : "high", lodCurrent: 0, lodMin: 0 };
@@ -35184,7 +35333,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35184
35333
  shared2.ctx.pieces = /* @__PURE__ */ new Map();
35185
35334
  shared2.ctx.pieceObjects = /* @__PURE__ */ new Map();
35186
35335
  shared2.ctx.structureIndex = {};
35187
- for (const e of r0.structure && r0.structure.parts || []) shared2.ctx.structureIndex[e.id] = e;
35336
+ for (const e of r0.structure?.parts || []) shared2.ctx.structureIndex[e.id] = e;
35188
35337
  {
35189
35338
  const view = shared2.ctx.panelView = panelViewOf(r0.structure, !!cfg.destruction);
35190
35339
  shared2.ctx.panelsOf = /* @__PURE__ */ new Map();
@@ -35196,7 +35345,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35196
35345
  else shared2.ctx.panelsOf.set(e.slab, [e]);
35197
35346
  }
35198
35347
  }
35199
- shared2.ctx.panes = r0.roof && r0.roof.panes || [];
35348
+ shared2.ctx.panes = r0.roof?.panes || [];
35200
35349
  shared2.ctx.noPiece = false;
35201
35350
  cursor.separate = opts.pieces === "meshes";
35202
35351
  cursor.pc = null;
@@ -35207,7 +35356,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35207
35356
  shared2.ctx.pu = Math.max(0, pr.unit != null ? pr.unit : 0);
35208
35357
  shared2.ctx.showBuilding = shared2.ctx.apartment && (pr.showIt == null ? true : !!pr.showIt);
35209
35358
  shared2.ctx.limits = { x0: -2, z0: -2, x1: r.w + 2, z1: r.d + 2 };
35210
- shared2.ctx.veg = VEG ? { G: VEG.G, S: VEG.S, mats: vegMaterials, groups: /* @__PURE__ */ new Map(), ok: /* @__PURE__ */ new Map(), opts: shared2.quality === "game" ? { quality: "game" } : { lod: 0, triangleBudget: 6e4 } } : null;
35359
+ shared2.ctx.veg = VEG ? { G: VEG.G, S: VEG.S, mats: vegMaterials, groups: /* @__PURE__ */ new Map(), ok: /* @__PURE__ */ new Map(), opts: shared2.quality === "game" ? { quality: "game" } : { quality: "high", lod: 0, triangleBudget: 6e4 } } : null;
35211
35360
  shared2.ctx.vegInfo = null;
35212
35361
  terrain();
35213
35362
  if (r.lot) {
@@ -35257,7 +35406,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35257
35406
  const g = gs[gd.name];
35258
35407
  if (!g) continue;
35259
35408
  delete gs[gd.name];
35260
- g.position.set(...gd.pos);
35409
+ g.position.fromArray(gd.pos);
35261
35410
  parent.add(g);
35262
35411
  fo.gs.push(g);
35263
35412
  }
@@ -35272,7 +35421,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35272
35421
  root.add(house);
35273
35422
  shared2.mirrors.house = house;
35274
35423
  if (shared2.ctx.apartment) {
35275
- const u = r.building.units[Math.min(shared2.ctx.pu, r.building.units.length - 1)];
35424
+ const units = r.building.units, u = units[Math.min(shared2.ctx.pu, units.length - 1)];
35276
35425
  house.position.set(u.u, shared2.ctx.showBuilding ? 0 : -r.floors[0].y0, u.v);
35277
35426
  house.rotation.y = u.ry;
35278
35427
  shared2.ctx.unitRy = u.ry;
@@ -35388,7 +35537,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35388
35537
  const wallAt = (f, axis2, L) => r.walls.find((w) => w.floor === f && w.axis === axis2 && Math.abs((axis2 === "u" ? w.v0 : w.u0) - L) < EPS6);
35389
35538
  for (const j of r.windows) {
35390
35539
  const alongU = j.axis === "u", y0 = Y0(j.floor), a = j.at - j.width / 2, b = j.at + j.width / 2, w = wallAt(j.floor, j.axis, j.pos), th = w ? w.thickness || 0.15 : 0.15, L = j.pos, id = "window:" + j.id;
35391
- parts[id] = { id, type: "window", group: null, virtual: true, floor: j.floor, aabb: alongU ? [a, y0 + j.y0, L - th / 2, b, y0 + j.y1, L + th / 2] : [L - th / 2, y0 + j.y0, a, L + th / 2, y0 + j.y1, b], damageable: tagDamage("glass"), opens: () => {
35540
+ const jy0 = j.y0, jy1 = j.y1;
35541
+ parts[id] = { id, type: "window", group: null, virtual: true, floor: j.floor, aabb: alongU ? [a, y0 + jy0, L - th / 2, b, y0 + jy1, L + th / 2] : [L - th / 2, y0 + jy0, a, L + th / 2, y0 + jy1, b], damageable: tagDamage("glass"), opens: () => {
35392
35542
  }, t: 0 };
35393
35543
  }
35394
35544
  for (const E of mirrorsCopy) {
@@ -35431,7 +35581,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35431
35581
  const countDraw = () => {
35432
35582
  let n = 0, t = 0;
35433
35583
  root.traverseVisible((o) => {
35434
- if (o.isMesh) {
35584
+ if (isMesh(o)) {
35435
35585
  n++;
35436
35586
  t += (o.geometry.index ? o.geometry.index.count : o.geometry.attributes.position.count) / 3;
35437
35587
  }
@@ -35445,8 +35595,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35445
35595
  const budget = opts.drawCallBudget != null ? opts.drawCallBudget : cfg.drawCallBudget;
35446
35596
  const stats2 = { quality: h.quality, drawCalls: s0.n, drawCallsLOD1: s1.n, triangles: s0.t, trianglesLod1: s1.t, budget: budget || null, overBudget: !!budget && s0.n > budget, tBuild: performance.now() - t0 };
35447
35597
  shared2.ctx.tBuild = stats2.tBuild;
35448
- const applyLod = (n) => {
35449
- n = Math.max(0, Math.min(2, n | 0));
35598
+ const applyLod = (level) => {
35599
+ const n = Math.max(0, Math.min(2, level | 0));
35450
35600
  if (n === h.lodCurrent) return;
35451
35601
  h.lodCurrent = n;
35452
35602
  for (const o of lodObjects) o.visible = n < 1;
@@ -35523,7 +35673,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35523
35673
  lights: (() => {
35524
35674
  const by = {};
35525
35675
  for (const l of shared2.ctx.lights) {
35526
- const k = l.roomId != null ? l.roomId : l.room;
35676
+ const k = String(l.roomId != null ? l.roomId : l.room);
35527
35677
  (by[k] || (by[k] = [])).push(l);
35528
35678
  }
35529
35679
  return { list: shared2.ctx.lights, byRoom: by };
@@ -35563,9 +35713,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35563
35713
  applyLod(Math.max(n, h.lodMin));
35564
35714
  }
35565
35715
  },
35566
- show(o) {
35716
+ show(options2) {
35567
35717
  enter(h);
35568
- o = o || {};
35718
+ const o = options2 || {};
35569
35719
  const rr = shared2.ctx.r, nA = rr.floors.length, a = o.floor == null ? -1 : o.floor, sel = a >= nA ? -1 : a, cut = !!o.cut;
35570
35720
  for (const [k, g] of Object.entries(gs)) {
35571
35721
  let v = true;
@@ -35585,7 +35735,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35585
35735
  enter(h);
35586
35736
  const a = targetOf(o, opt);
35587
35737
  if (!a) return false;
35588
- return actOn(a.target && a.target.pub ? a.target.pub : { id: a.target && a.target.id || a.text, type: a.target && a.target.kit ? a.target.type : "door", label: a.text, ref: a.target, _action: a.action }, a);
35738
+ return actOn(a.target && a.target.pub ? a.target.pub : { id: a.target && a.target.id || a.text, type: a.target && a.target.kit ? a.target.type : "door", label: a.text, ref: a.target, _action: a.action, floor: 0, pos: [], radius: 0 }, a);
35589
35739
  },
35590
35740
  message() {
35591
35741
  return shared2.inter.msg && performance.now() < shared2.inter.msg.until ? shared2.inter.msg.text : null;
@@ -35642,13 +35792,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35642
35792
  }
35643
35793
  return null;
35644
35794
  },
35645
- partAt(p, tol) {
35646
- tol = tol || 0.05;
35795
+ partAt(p, tolerance) {
35796
+ const tol = tolerance || 0.05;
35647
35797
  let m = null;
35648
35798
  for (const k in parts) {
35649
- const a = parts[k].aabb;
35799
+ const part = parts[k], a = part.aabb;
35650
35800
  if (a && p.x >= a[0] - tol && p.x <= a[3] + tol && p.y >= a[1] - tol && p.y <= a[4] + tol && p.z >= a[2] - tol && p.z <= a[5] + tol) {
35651
- m = parts[k];
35801
+ m = part;
35652
35802
  break;
35653
35803
  }
35654
35804
  }
@@ -35659,8 +35809,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35659
35809
  destruction.deactivate();
35660
35810
  if (h.IV) ivDispose(h);
35661
35811
  root.traverse((o) => {
35662
- if (o.isMesh && o.geometry && !o.geometry.userData.shared) o.geometry.dispose();
35663
- if (o.type === "Reflector" && o.dispose) o.dispose();
35812
+ if (isMesh(o) && o.geometry && !o.geometry.userData.shared) o.geometry.dispose();
35813
+ if (o.type === "Reflector" && "dispose" in o && typeof o.dispose === "function") o.dispose();
35664
35814
  });
35665
35815
  root.removeFromParent();
35666
35816
  },
@@ -35668,7 +35818,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35668
35818
  };
35669
35819
  return res;
35670
35820
  }
35671
- Object.assign(K, { build });
35821
+ const defined = { build };
35822
+ Object.assign(K, defined);
35672
35823
  }
35673
35824
  function buildApi(K, shared2) {
35674
35825
  const { cfg, VERSION: VERSION2, ATLAS, TEX, applyPart, carGroup, carModel, props, TYPES, roomLightMask, lighting, effectLights, newState, build } = K;
@@ -35688,11 +35839,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35688
35839
  lighting,
35689
35840
  effectLights,
35690
35841
  setNight(n) {
35691
- shared2.mats.glass.emissive.set(n ? 9067040 : 0);
35692
- shared2.mats.glass.opacity = n ? 0.4 : 0.24;
35842
+ const glass = shared2.mats.glass;
35843
+ glass.emissive.set(n ? 9067040 : 0);
35844
+ glass.opacity = n ? 0.4 : 0.24;
35693
35845
  },
35694
35846
  /** The chipped-plaster painting of every house of this renderer as a `DeferredQueue` for a frame budget (id `floorplan.breach-paint`); asking for it changes nothing. */
35695
35847
  deferredQueue: () => K.breachPaintQueue,
35848
+ /* the destruction side is typed with the breach */
35696
35849
  cars: { model: carModel, group: carGroup, info: (k, seed) => {
35697
35850
  const m = carModel(k, seed);
35698
35851
  return m && { parts: m.parts.length, tris: m.tris, L: m.L, W: m.W, H: m.H };
@@ -35794,10 +35947,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35794
35947
  }
35795
35948
 
35796
35949
  // ../game-floorplan-residential/dist/index.js
35797
- var __defProp3 = Object.defineProperty;
35950
+ var __defProp4 = Object.defineProperty;
35798
35951
  var __export2 = (target, all) => {
35799
35952
  for (var name in all)
35800
- __defProp3(target, name, { get: all[name], enumerable: true });
35953
+ __defProp4(target, name, { get: all[name], enumerable: true });
35801
35954
  };
35802
35955
  var residentialItems = [
35803
35956
  { type: "sofa_3seat", category: "sofa", w: 2.1, d: 0.9, h: 0.85, color: { role: "fabric_main" } },
@@ -37542,7 +37695,63 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37542
37695
  };
37543
37696
  var accessoryTextOf = (locale) => ACCESSORY_TEXT[locale] ?? ACCESSORY_TEXT.en;
37544
37697
 
37545
- // ../game-audio/dist/chunk-C2K7XN2K.js
37698
+ // ../game-audio/dist/chunk-JV5XXCQE.js
37699
+ var SFX_TIERS = { light: 0, medium: 0.34, heavy: 0.67 };
37700
+ function splitTier(id) {
37701
+ const match = /^(.*)_(light|medium|heavy)$/.exec(id);
37702
+ return match ? { base: match[1], tier: match[2] } : { base: id };
37703
+ }
37704
+ var refsOf = (entries2, baseUrl) => (entries2 ?? []).map((entry2) => ({ url: `${baseUrl}${entry2.file}` }));
37705
+ function sampleBankFromManifest(manifest, options) {
37706
+ const baseUrl = options.baseUrl ?? "";
37707
+ const samples = [];
37708
+ const tiersOf = /* @__PURE__ */ new Map();
37709
+ for (const sound3 of manifest.sounds) {
37710
+ const { base, tier } = splitTier(sound3.id);
37711
+ if (tier) tiersOf.set(base, [...tiersOf.get(base) ?? [], sound3]);
37712
+ }
37713
+ const bases = /* @__PURE__ */ new Map();
37714
+ for (const sound3 of manifest.sounds) {
37715
+ if (!splitTier(sound3.id).tier) bases.set(sound3.id, sound3);
37716
+ }
37717
+ for (const [base, tiers] of tiersOf) {
37718
+ if (!bases.has(base)) bases.set(base, { id: base, category: tiers[0]?.category ?? "", layers: { close: tiers[0]?.layers.close ?? [] } });
37719
+ }
37720
+ for (const sound3 of bases.values()) {
37721
+ const numbers = options.sounds?.[sound3.id] ?? options.defaults?.(sound3);
37722
+ const close = refsOf(sound3.layers.close, baseUrl);
37723
+ if (!numbers || close.length === 0) continue;
37724
+ const tiers = (tiersOf.get(sound3.id) ?? []).map((tier) => {
37725
+ const name = splitTier(tier.id).tier;
37726
+ const tierFar = refsOf(tier.layers.far, baseUrl);
37727
+ return { name, from: SFX_TIERS[name] ?? 0, close: refsOf(tier.layers.close, baseUrl), ...tierFar.length > 0 ? { far: tierFar } : {} };
37728
+ }).sort((a, b) => a.from - b.from);
37729
+ const far = refsOf(sound3.layers.far, baseUrl);
37730
+ const indoor = refsOf(sound3.layers.tail_in, baseUrl);
37731
+ const outdoor = refsOf(sound3.layers.tail_out, baseUrl);
37732
+ const files = [sound3, ...tiersOf.get(sound3.id) ?? []].flatMap((entry2) => Object.values(entry2.layers).flatMap((entries2) => entries2 ?? []));
37733
+ samples.push({
37734
+ id: sound3.id,
37735
+ bus: numbers.bus,
37736
+ close,
37737
+ ...far.length > 0 ? { far } : {},
37738
+ ...tiers.length > 0 ? { tiers } : {},
37739
+ ...numbers.crossover ? { crossover: numbers.crossover } : {},
37740
+ ...indoor.length > 0 || outdoor.length > 0 ? { tail: { ...indoor.length > 0 ? { indoor } : {}, ...outdoor.length > 0 ? { outdoor } : {}, ...numbers.tailGain === void 0 ? {} : { gain: numbers.tailGain } } } : {},
37741
+ ...numbers.pitch === void 0 ? {} : { pitch: numbers.pitch },
37742
+ ...numbers.gain === void 0 ? {} : { gain: numbers.gain },
37743
+ ...numbers.falloff ? { falloff: numbers.falloff } : {},
37744
+ ...numbers.cutoffK === void 0 ? {} : { cutoffK: numbers.cutoffK },
37745
+ ...numbers.group ? { group: numbers.group } : {},
37746
+ ...numbers.priority === void 0 ? {} : { priority: numbers.priority },
37747
+ ...numbers.fallback ? { fallback: numbers.fallback } : {},
37748
+ sources: files.map((file) => `${file.file}: ${file.source} ${file.author} ${file.license}`)
37749
+ });
37750
+ }
37751
+ return { id: options.id, samples };
37752
+ }
37753
+
37754
+ // ../game-audio/dist/chunk-UUWKSG4J.js
37546
37755
  var DISTANCE_CURVES = {
37547
37756
  /** The game's `sfx`: `vol / (1 + d² × 0.004)`, cutoff `/ (1 + d × 0.01)`, silent below 0.01 (jogo L62091–62092, L62101). */
37548
37757
  game_sfx: { model: "inverse_square", k: 4e-3, cutoffK: 0.01, minGain: 0.01 },
@@ -37717,6 +37926,20 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37717
37926
  sources: [
37718
37927
  "sdk: the crackles of every fire share four voices"
37719
37928
  ]
37929
+ },
37930
+ debris_knock: {
37931
+ maxConcurrent: 3,
37932
+ cooldown: 0.04,
37933
+ sources: [
37934
+ "sdk: forty parts coming loose in one blast are a few knocks, not forty (room log: thunk x34 in under a second when a molotov broke)"
37935
+ ]
37936
+ },
37937
+ sizzle: {
37938
+ maxConcurrent: 1,
37939
+ cooldown: 0.5,
37940
+ sources: [
37941
+ "sdk: every melting part of a burning bin is one sizzle at a time (room log: hiss x34 in 1.6 s on a plastic bin)"
37942
+ ]
37720
37943
  }
37721
37944
  };
37722
37945
  var VOICE_GROUPS = voice_groups_default;
@@ -37804,17 +38027,19 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37804
38027
  }
37805
38028
  return merged2;
37806
38029
  }
37807
- var trimmed = (refs, alias) => refs.map((ref) => ({
38030
+ var trimmed = (refs, alias) => refs.filter((ref) => alias.only === void 0 || ref.url.includes(alias.only)).map((ref) => ({
37808
38031
  ...ref,
37809
38032
  ...alias.offset === void 0 ? {} : { offset: alias.offset },
37810
38033
  ...alias.duration === void 0 ? {} : { duration: alias.duration }
37811
38034
  }));
37812
38035
  function aliasSample(alias, file) {
38036
+ const close = trimmed(file.close, alias);
38037
+ if (close.length === 0) return void 0;
37813
38038
  const { tiers: _tiers, fallback: _fallback, choke: _choke, ...rest2 } = file;
37814
38039
  return {
37815
38040
  ...rest2,
37816
38041
  id: alias.id,
37817
- close: trimmed(file.close, alias),
38042
+ close,
37818
38043
  ...file.far ? { far: trimmed(file.far, alias) } : {},
37819
38044
  ...alias.loop === void 0 ? {} : { loop: alias.loop },
37820
38045
  ...alias.baseFrequency === void 0 ? {} : { baseFrequency: alias.baseFrequency },
@@ -37841,7 +38066,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37841
38066
  const file = samples.get(alias.file);
37842
38067
  if (!file) return void 0;
37843
38068
  const sample = aliasSample(alias, file);
37844
- derived.set(id, sample);
38069
+ if (sample) derived.set(id, sample);
37845
38070
  return sample;
37846
38071
  };
37847
38072
  const registry = {
@@ -39585,6 +39810,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39585
39810
  const set2 = registry.set(id);
39586
39811
  return set2 ? chooser.pick(set2, random) : { id, rate: 1 };
39587
39812
  };
39813
+ const wanted = /* @__PURE__ */ new Set();
39588
39814
  const loadSounds = (sounds) => {
39589
39815
  const audio = ready();
39590
39816
  if (!audio) return Promise.resolve({ loaded: [], failed: sounds.flatMap(sampleUrls).map((url2) => ({ url: url2, error: "no audio context" })) });
@@ -39709,13 +39935,20 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39709
39935
  };
39710
39936
  return {
39711
39937
  registry,
39712
- register: (bank) => registry.register(bank),
39938
+ register: (bank) => {
39939
+ registry.register(bank);
39940
+ if (wanted.size === 0) return;
39941
+ const now = [...wanted].map((id) => registry.sample(id)).filter((sample) => sample !== void 0);
39942
+ for (const sample of now) wanted.delete(sample.id);
39943
+ if (now.length > 0) void loadSounds(now).catch(() => void 0);
39944
+ },
39713
39945
  plan: (id, playOptions = {}) => planWith(id, playOptions, createRng3(playOptions.seed ?? seed)),
39714
39946
  planSample(id, playOptions = {}) {
39715
39947
  const sample = registry.sample(id);
39716
39948
  return sample ? planSample(sample, sampleInput(playOptions, createRng3(playOptions.seed ?? seed), false)) : null;
39717
39949
  },
39718
39950
  loadSamples(ids) {
39951
+ for (const id of ids ?? []) if (!registry.sample(id)) wanted.add(id);
39719
39952
  const chosen = (ids ?? registry.sampleIds()).map((id) => registry.sample(id)).filter((sample) => sample !== void 0);
39720
39953
  return loadSounds(chosen);
39721
39954
  },
@@ -40170,60 +40403,6 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
40170
40403
  burst: 20,
40171
40404
  burstSpacing: 0.06
40172
40405
  };
40173
- var SFX_TIERS = { light: 0, medium: 0.34, heavy: 0.67 };
40174
- function splitTier(id) {
40175
- const match = /^(.*)_(light|medium|heavy)$/.exec(id);
40176
- return match ? { base: match[1], tier: match[2] } : { base: id };
40177
- }
40178
- var refsOf = (entries2, baseUrl) => (entries2 ?? []).map((entry2) => ({ url: `${baseUrl}${entry2.file}` }));
40179
- function sampleBankFromManifest(manifest, options) {
40180
- const baseUrl = options.baseUrl ?? "";
40181
- const samples = [];
40182
- const tiersOf = /* @__PURE__ */ new Map();
40183
- for (const sound3 of manifest.sounds) {
40184
- const { base, tier } = splitTier(sound3.id);
40185
- if (tier) tiersOf.set(base, [...tiersOf.get(base) ?? [], sound3]);
40186
- }
40187
- const bases = /* @__PURE__ */ new Map();
40188
- for (const sound3 of manifest.sounds) {
40189
- if (!splitTier(sound3.id).tier) bases.set(sound3.id, sound3);
40190
- }
40191
- for (const [base, tiers] of tiersOf) {
40192
- if (!bases.has(base)) bases.set(base, { id: base, category: tiers[0]?.category ?? "", layers: { close: tiers[0]?.layers.close ?? [] } });
40193
- }
40194
- for (const sound3 of bases.values()) {
40195
- const numbers = options.sounds?.[sound3.id] ?? options.defaults?.(sound3);
40196
- const close = refsOf(sound3.layers.close, baseUrl);
40197
- if (!numbers || close.length === 0) continue;
40198
- const tiers = (tiersOf.get(sound3.id) ?? []).map((tier) => {
40199
- const name = splitTier(tier.id).tier;
40200
- const tierFar = refsOf(tier.layers.far, baseUrl);
40201
- return { name, from: SFX_TIERS[name] ?? 0, close: refsOf(tier.layers.close, baseUrl), ...tierFar.length > 0 ? { far: tierFar } : {} };
40202
- }).sort((a, b) => a.from - b.from);
40203
- const far = refsOf(sound3.layers.far, baseUrl);
40204
- const indoor = refsOf(sound3.layers.tail_in, baseUrl);
40205
- const outdoor = refsOf(sound3.layers.tail_out, baseUrl);
40206
- const files = [sound3, ...tiersOf.get(sound3.id) ?? []].flatMap((entry2) => Object.values(entry2.layers).flatMap((entries2) => entries2 ?? []));
40207
- samples.push({
40208
- id: sound3.id,
40209
- bus: numbers.bus,
40210
- close,
40211
- ...far.length > 0 ? { far } : {},
40212
- ...tiers.length > 0 ? { tiers } : {},
40213
- ...numbers.crossover ? { crossover: numbers.crossover } : {},
40214
- ...indoor.length > 0 || outdoor.length > 0 ? { tail: { ...indoor.length > 0 ? { indoor } : {}, ...outdoor.length > 0 ? { outdoor } : {}, ...numbers.tailGain === void 0 ? {} : { gain: numbers.tailGain } } } : {},
40215
- ...numbers.pitch === void 0 ? {} : { pitch: numbers.pitch },
40216
- ...numbers.gain === void 0 ? {} : { gain: numbers.gain },
40217
- ...numbers.falloff ? { falloff: numbers.falloff } : {},
40218
- ...numbers.cutoffK === void 0 ? {} : { cutoffK: numbers.cutoffK },
40219
- ...numbers.group ? { group: numbers.group } : {},
40220
- ...numbers.priority === void 0 ? {} : { priority: numbers.priority },
40221
- ...numbers.fallback ? { fallback: numbers.fallback } : {},
40222
- sources: files.map((file) => `${file.file}: ${file.source} ${file.author} ${file.license}`)
40223
- });
40224
- }
40225
- return { id: options.id, samples };
40226
- }
40227
40406
  var CATALOG = new Map([...SFX_CATALOG, ...SFX_IMPACTS].map((entry2) => [entry2.id, entry2]));
40228
40407
  var PT = {
40229
40408
  group: "Som",
@@ -42308,6 +42487,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
42308
42487
  const surfaceName = surface === "hard" ? "concreto" : surface === "soft" ? "terra" : surface === "wood" ? "madeira" : "metal";
42309
42488
  return { surface, kind, sample: `casing_drop_${surfaceName}_${kind}`, voices };
42310
42489
  }
42490
+ function magazineDropId(material) {
42491
+ const surface = casingSurfaceOf(material);
42492
+ return `mag_drop_${surface === "hard" ? "concreto" : surface === "soft" ? "terra" : surface === "wood" ? "madeira" : "metal"}`;
42493
+ }
42311
42494
 
42312
42495
  // src/audio/flyby.ts
42313
42496
  function computeFlyby(input) {
@@ -43109,7 +43292,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43109
43292
  var isGunshot = (id) => GUNSHOT_SAMPLE_IDS.includes(id);
43110
43293
  function weaponSampleDefaults(sound3, overrides = {}) {
43111
43294
  if (sound3.category !== "armas") return void 0;
43112
- const base = sound3.id.startsWith("suppressed_") ? SUPPRESSED_SAMPLE : isGunshot(sound3.id) ? GUNSHOT_SAMPLE : sound3.id.startsWith("casing_drop_") ? CASING_SAMPLE : RELOAD_SAMPLE;
43295
+ const base = sound3.id.startsWith("suppressed_") ? SUPPRESSED_SAMPLE : isGunshot(sound3.id) ? GUNSHOT_SAMPLE : sound3.id.startsWith("casing_drop_") || sound3.id.startsWith("mag_drop_") ? CASING_SAMPLE : RELOAD_SAMPLE;
43113
43296
  return { ...base, ...overrides[sound3.id] };
43114
43297
  }
43115
43298
  function weaponSampleBank(options) {
@@ -43160,6 +43343,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43160
43343
  void loadSamples();
43161
43344
  return false;
43162
43345
  };
43346
+ const fittedReady = (id) => sampleIds.has(id) && engine.registry.sound(id) === void 0 && engine.registry.set(id) !== void 0;
43347
+ const hostReady = (id) => sampleReady(id) || engine.registry.sound(id) === void 0 && engine.registry.set(id) !== void 0;
43163
43348
  const burst2 = (config) => {
43164
43349
  const id = config.filter === "highpass" ? BURST_IDS.highpass : BURST_IDS.lowpass;
43165
43350
  const params = { frequency: config.frequency, q: config.q ?? 0.8, gain: Math.max(config.gain, 2e-4), seconds: config.seconds };
@@ -43214,6 +43399,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43214
43399
  options.onCasing?.(sound3, "sample");
43215
43400
  return;
43216
43401
  }
43402
+ if (recorded && fittedReady(recorded)) {
43403
+ if ((input.bounce ?? 0) === 0) channel.play(recorded, { volume: Math.min(1, Math.max(0.2, (input.speed ?? 1.5) / 2.5)) });
43404
+ options.onCasing?.(sound3, "fitted");
43405
+ return;
43406
+ }
43217
43407
  for (const voice2 of sound3.voices) playCasingVoice(voice2);
43218
43408
  options.onCasing?.(sound3, "synth");
43219
43409
  };
@@ -43238,7 +43428,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43238
43428
  const pitch = 1 + (channel.random() * 2 - 1) * pitchSpread;
43239
43429
  const shot = computeGunshot({ ...base, take, pitch }, options.gunshot);
43240
43430
  const recorded = shot.samples.close;
43241
- if (shot.audible && sampleReady(recorded)) {
43431
+ const sample = shot.audible && sampleReady(recorded);
43432
+ const fitted = shot.audible && !sample && fittedReady(recorded);
43433
+ if (sample || fitted) {
43242
43434
  const occlusion = Math.min(1, Math.max(0, extras.occlusion ?? 0));
43243
43435
  const handle = channel.play(recorded, {
43244
43436
  volume: (extras.volume ?? 1) * (1 - 0.5 * occlusion),
@@ -43251,7 +43443,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43251
43443
  for (const voice2 of shot.voices) if (voice2.group === "tail") playGunshotVoice(voice2, extras);
43252
43444
  }
43253
43445
  const layers = handle?.kind === "sample" ? handle.plan.layers.map((layer3) => ({ role: layer3.role, take: layer3.take, rate: layer3.rate })) : [];
43254
- options.onGunshot?.(shot, { ...base, take, pitch }, { kind: "sample", id: recorded, layers });
43446
+ options.onGunshot?.(shot, { ...base, take, pitch }, fitted ? { kind: "fitted", id: recorded } : { kind: "sample", id: recorded, layers });
43255
43447
  return;
43256
43448
  }
43257
43449
  for (const voice2 of shot.voices) playGunshotVoice(voice2, extras);
@@ -43272,10 +43464,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43272
43464
  mechanical,
43273
43465
  cue(id, profile, lead = 0) {
43274
43466
  const carriedBy = CUES_IN_SAMPLE[id];
43275
- if (carriedBy && sampleReady(carriedBy)) return "carried";
43276
- if (sampleReady(id)) {
43467
+ if (carriedBy && (sampleReady(carriedBy) || fittedReady(carriedBy))) return "carried";
43468
+ const recorded = sampleReady(id);
43469
+ if (recorded || fittedReady(id)) {
43277
43470
  channel.play(id, { intensity: WEIGHT_INTENSITY[(profile ?? DEFAULT_SOUND_PROFILE).weight] });
43278
- return "sample";
43471
+ return recorded ? "sample" : "fitted";
43279
43472
  }
43280
43473
  for (const entry2 of reloadCueSteps(id, profile, cueTable)) step(lead > 0 ? { ...entry2, at: entry2.at + lead } : entry2);
43281
43474
  return "synth";
@@ -43302,7 +43495,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43302
43495
  casing: casing2,
43303
43496
  flyby(input) {
43304
43497
  const sound3 = computeFlyby({ ...input, pitch: input.pitch ?? 1 + (channel.random() * 2 - 1) * 0.05 });
43305
- for (const voice2 of sound3?.voices ?? []) playCasingVoice(voice2, input.position);
43498
+ if (!sound3) return;
43499
+ if (hostReady(sound3.sample)) {
43500
+ channel.play(sound3.sample, { volume: Math.min(1, 1 / (1 + input.miss / 1.5)), ...input.position ? { position: [input.position[0], input.position[1], input.position[2]] } : {} });
43501
+ return;
43502
+ }
43503
+ for (const voice2 of sound3.voices) playCasingVoice(voice2, input.position);
43306
43504
  },
43307
43505
  clink() {
43308
43506
  if (options.shotModel !== "game") {
@@ -43313,8 +43511,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43313
43511
  const at3 = 0.25 + channel.random() * 0.2;
43314
43512
  sceneTone2({ layer: "scene_tone", at: at3, wave: "sine", f, f2: 3800, d: 0.06, vol: 0.06 });
43315
43513
  },
43316
- thud() {
43317
- burst2({ seconds: 0.09, gain: 0.35, filter: "lowpass", frequency: 380 });
43514
+ thud(input = {}) {
43515
+ const id = magazineDropId(input.surface);
43516
+ if (hostReady(id)) {
43517
+ if ((input.bounce ?? 0) === 0) channel.play(id, { volume: Math.min(1, Math.max(0.2, (input.speed ?? 1.5) / 2.5)) });
43518
+ return;
43519
+ }
43520
+ burst2({ seconds: 0.09, gain: 0.35 * (input.speed === void 0 ? 1 : Math.min(1, Math.max(0.3, input.speed / 2.5))) * ((input.bounce ?? 0) === 0 ? 1 : 0.5), filter: "lowpass", frequency: 380 });
43318
43521
  },
43319
43522
  setVolume(next) {
43320
43523
  const level = Math.max(0, Math.min(1, next));
@@ -44274,7 +44477,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
44274
44477
  rules: { dropCapacity: 400, curbCatch: false, guardBehindWall: false, clipRoadEnd: false, dripStyle: "workshop" }
44275
44478
  });
44276
44479
 
44277
- // ../game-items-three/dist/chunk-WGFTVYO3.js
44480
+ // ../game-items-three/dist/chunk-76GT7V27.js
44278
44481
  var destruction_default = {
44279
44482
  families: {
44280
44483
  drink_can: {
@@ -55206,9 +55409,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
55206
55409
  }
55207
55410
 
55208
55411
  // ../game-vfx/dist/index.js
55209
- var __defProp4 = Object.defineProperty;
55210
- var __defNormalProp2 = (obj, key2, value) => key2 in obj ? __defProp4(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
55211
- var __publicField2 = (obj, key2, value) => __defNormalProp2(obj, typeof key2 !== "symbol" ? key2 + "" : key2, value);
55412
+ var __defProp5 = Object.defineProperty;
55413
+ var __defNormalProp3 = (obj, key2, value) => key2 in obj ? __defProp5(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
55414
+ var __publicField3 = (obj, key2, value) => __defNormalProp3(obj, typeof key2 !== "symbol" ? key2 + "" : key2, value);
55212
55415
  var AREA_CAP_GAME = { radius: 40, window: 4, count: 6, excessScale: 0.3 };
55213
55416
  function createAreaCap(cap) {
55214
55417
  const recent = [];
@@ -56256,11 +56459,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
56256
56459
  var DEFAULT_WIND = { x: 0.55, y: 0, z: 0.2 };
56257
56460
  var OrderedPool = class {
56258
56461
  constructor(capacity, create4, release) {
56259
- __publicField2(this, "capacity", capacity);
56260
- __publicField2(this, "create", create4);
56261
- __publicField2(this, "release", release);
56262
- __publicField2(this, "items", []);
56263
- __publicField2(this, "spare", []);
56462
+ __publicField3(this, "capacity", capacity);
56463
+ __publicField3(this, "create", create4);
56464
+ __publicField3(this, "release", release);
56465
+ __publicField3(this, "items", []);
56466
+ __publicField3(this, "spare", []);
56264
56467
  }
56265
56468
  get count() {
56266
56469
  return this.items.length;
@@ -56555,13 +56758,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
56555
56758
  }
56556
56759
  var Enclosures = class {
56557
56760
  constructor(seed = 20973) {
56558
- __publicField2(this, "spaces", /* @__PURE__ */ new Map());
56559
- __publicField2(this, "list", []);
56560
- __publicField2(this, "random");
56561
- __publicField2(this, "out", { x: 0, y: 0, z: 0, nx: 0, ny: 0, nz: 0 });
56562
- __publicField2(this, "l0", new Float64Array(3));
56563
- __publicField2(this, "l1", new Float64Array(3));
56564
- __publicField2(this, "q", new Float64Array(3));
56761
+ __publicField3(this, "spaces", /* @__PURE__ */ new Map());
56762
+ __publicField3(this, "list", []);
56763
+ __publicField3(this, "random");
56764
+ __publicField3(this, "out", { x: 0, y: 0, z: 0, nx: 0, ny: 0, nz: 0 });
56765
+ __publicField3(this, "l0", new Float64Array(3));
56766
+ __publicField3(this, "l1", new Float64Array(3));
56767
+ __publicField3(this, "q", new Float64Array(3));
56565
56768
  this.random = lehmer(seed);
56566
56769
  }
56567
56770
  get empty() {
@@ -58183,15 +58386,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
58183
58386
  var inPuddle = (puddles, x, z) => puddles.some((p) => ((x - p[0]) / p[2]) ** 2 + ((z - p[1]) / p[3]) ** 2 < 1);
58184
58387
  var RainField = class {
58185
58388
  constructor(engine) {
58186
- __publicField2(this, "engine", engine);
58187
- __publicField2(this, "positions", new Float32Array(RAIN_CAPACITY * 6));
58188
- __publicField2(this, "count", 0);
58189
- __publicField2(this, "wind", 1);
58190
- __publicField2(this, "on", false);
58191
- __publicField2(this, "centerX", 0);
58192
- __publicField2(this, "centerZ", 0);
58193
- __publicField2(this, "puddles", WORKSHOP_PUDDLES);
58194
- __publicField2(this, "puddleAt");
58389
+ __publicField3(this, "engine", engine);
58390
+ __publicField3(this, "positions", new Float32Array(RAIN_CAPACITY * 6));
58391
+ __publicField3(this, "count", 0);
58392
+ __publicField3(this, "wind", 1);
58393
+ __publicField3(this, "on", false);
58394
+ __publicField3(this, "centerX", 0);
58395
+ __publicField3(this, "centerZ", 0);
58396
+ __publicField3(this, "puddles", WORKSHOP_PUDDLES);
58397
+ __publicField3(this, "puddleAt");
58195
58398
  }
58196
58399
  /** `initRain` (W321): `count` streaks (thinned by the quality), each drawn at a random place in the box. */
58197
58400
  init(count, wind) {
@@ -59875,19 +60078,19 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
59875
60078
  };
59876
60079
  var EffectInstance = class {
59877
60080
  constructor(deps) {
59878
- __publicField2(this, "deps", deps);
59879
- __publicField2(this, "variables", /* @__PURE__ */ new Map());
59880
- __publicField2(this, "def");
59881
- __publicField2(this, "param", 0);
59882
- __publicField2(this, "fresh", false);
59883
- __publicField2(this, "time", 0);
59884
- __publicField2(this, "elapsed", 0);
59885
- __publicField2(this, "setup", {});
59886
- __publicField2(this, "dt", 0);
59887
- __publicField2(this, "index", 0);
59888
- __publicField2(this, "schedule", createSchedule());
59889
- __publicField2(this, "host");
59890
- __publicField2(this, "context");
60081
+ __publicField3(this, "deps", deps);
60082
+ __publicField3(this, "variables", /* @__PURE__ */ new Map());
60083
+ __publicField3(this, "def");
60084
+ __publicField3(this, "param", 0);
60085
+ __publicField3(this, "fresh", false);
60086
+ __publicField3(this, "time", 0);
60087
+ __publicField3(this, "elapsed", 0);
60088
+ __publicField3(this, "setup", {});
60089
+ __publicField3(this, "dt", 0);
60090
+ __publicField3(this, "index", 0);
60091
+ __publicField3(this, "schedule", createSchedule());
60092
+ __publicField3(this, "host");
60093
+ __publicField3(this, "context");
59891
60094
  const instance = () => this;
59892
60095
  this.host = {
59893
60096
  engine: deps.engine,
@@ -60952,33 +61155,33 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
60952
61155
  }
60953
61156
  var SpriteKindPool = class {
60954
61157
  constructor(capacity, defs, owners) {
60955
- __publicField2(this, "capacity", capacity);
60956
- __publicField2(this, "defs", defs);
60957
- __publicField2(this, "owners", owners);
60958
- __publicField2(this, "live", 0);
60959
- __publicField2(this, "drawCount", 0);
60960
- __publicField2(this, "position");
60961
- __publicField2(this, "color");
60962
- __publicField2(this, "alpha");
60963
- __publicField2(this, "size");
60964
- __publicField2(this, "next", 0);
60965
- __publicField2(this, "high", 0);
60966
- __publicField2(this, "velocity");
60967
- __publicField2(this, "age");
60968
- __publicField2(this, "life");
60969
- __publicField2(this, "size0");
60970
- __publicField2(this, "alive");
60971
- __publicField2(this, "kind");
60972
- __publicField2(this, "seed");
60973
- __publicField2(this, "alphaMul");
60974
- __publicField2(this, "tag");
60975
- __publicField2(this, "owner");
60976
- __publicField2(this, "colorHex");
60977
- __publicField2(this, "rgbStart");
60978
- __publicField2(this, "rgbEnd");
60979
- __publicField2(this, "bounced");
60980
- __publicField2(this, "floor");
60981
- __publicField2(this, "riseMul");
61158
+ __publicField3(this, "capacity", capacity);
61159
+ __publicField3(this, "defs", defs);
61160
+ __publicField3(this, "owners", owners);
61161
+ __publicField3(this, "live", 0);
61162
+ __publicField3(this, "drawCount", 0);
61163
+ __publicField3(this, "position");
61164
+ __publicField3(this, "color");
61165
+ __publicField3(this, "alpha");
61166
+ __publicField3(this, "size");
61167
+ __publicField3(this, "next", 0);
61168
+ __publicField3(this, "high", 0);
61169
+ __publicField3(this, "velocity");
61170
+ __publicField3(this, "age");
61171
+ __publicField3(this, "life");
61172
+ __publicField3(this, "size0");
61173
+ __publicField3(this, "alive");
61174
+ __publicField3(this, "kind");
61175
+ __publicField3(this, "seed");
61176
+ __publicField3(this, "alphaMul");
61177
+ __publicField3(this, "tag");
61178
+ __publicField3(this, "owner");
61179
+ __publicField3(this, "colorHex");
61180
+ __publicField3(this, "rgbStart");
61181
+ __publicField3(this, "rgbEnd");
61182
+ __publicField3(this, "bounced");
61183
+ __publicField3(this, "floor");
61184
+ __publicField3(this, "riseMul");
60982
61185
  const n = Math.max(1, capacity);
60983
61186
  this.position = new Float32Array(n * 3);
60984
61187
  this.color = new Float32Array(n * 3);
@@ -61471,15 +61674,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
61471
61674
  var SPRITE_KINDS = sprite_kinds_default;
61472
61675
  var SpriteKindSystem = class {
61473
61676
  constructor(options) {
61474
- __publicField2(this, "options", options);
61475
- __publicField2(this, "additive");
61476
- __publicField2(this, "normal");
61477
- __publicField2(this, "random");
61478
- __publicField2(this, "ids");
61479
- __publicField2(this, "defs");
61480
- __publicField2(this, "index", /* @__PURE__ */ new Map());
61481
- __publicField2(this, "owners", []);
61482
- __publicField2(this, "listeners", /* @__PURE__ */ new Map());
61677
+ __publicField3(this, "options", options);
61678
+ __publicField3(this, "additive");
61679
+ __publicField3(this, "normal");
61680
+ __publicField3(this, "random");
61681
+ __publicField3(this, "ids");
61682
+ __publicField3(this, "defs");
61683
+ __publicField3(this, "index", /* @__PURE__ */ new Map());
61684
+ __publicField3(this, "owners", []);
61685
+ __publicField3(this, "listeners", /* @__PURE__ */ new Map());
61483
61686
  const kinds = options.kinds ?? SPRITE_KINDS;
61484
61687
  this.ids = Object.keys(kinds);
61485
61688
  this.defs = this.ids.map((id) => kinds[id]);
@@ -61633,11 +61836,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
61633
61836
  }
61634
61837
  var DebrisPool = class {
61635
61838
  constructor(context) {
61636
- __publicField2(this, "context", context);
61637
- __publicField2(this, "pieces", Array.from({ length: CAPACITY }, createPiece));
61638
- __publicField2(this, "count", 0);
61639
- __publicField2(this, "next", 0);
61640
- __publicField2(this, "direction", { x: 0, y: 0, z: 0 });
61839
+ __publicField3(this, "context", context);
61840
+ __publicField3(this, "pieces", Array.from({ length: CAPACITY }, createPiece));
61841
+ __publicField3(this, "count", 0);
61842
+ __publicField3(this, "next", 0);
61843
+ __publicField3(this, "direction", { x: 0, y: 0, z: 0 });
61641
61844
  }
61642
61845
  spawn(options) {
61643
61846
  const random = this.context.random;
@@ -61724,10 +61927,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
61724
61927
  }
61725
61928
  var DecalPool = class {
61726
61929
  constructor(context) {
61727
- __publicField2(this, "context", context);
61728
- __publicField2(this, "decals", Array.from({ length: CAPACITY2 }, createDecal));
61729
- __publicField2(this, "count", 0);
61730
- __publicField2(this, "next", 0);
61930
+ __publicField3(this, "context", context);
61931
+ __publicField3(this, "decals", Array.from({ length: CAPACITY2 }, createDecal));
61932
+ __publicField3(this, "count", 0);
61933
+ __publicField3(this, "next", 0);
61731
61934
  }
61732
61935
  add(x, y, z, size, color2, options = {}) {
61733
61936
  const random = this.context.random;
@@ -61802,9 +62005,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
61802
62005
  var aboutX = (angle) => [Math.sin(angle / 2), 0, 0, Math.cos(angle / 2)];
61803
62006
  var MeshPool = class {
61804
62007
  constructor(capacity = CAPACITY3) {
61805
- __publicField2(this, "capacity", capacity);
61806
- __publicField2(this, "particles", []);
61807
- __publicField2(this, "serial", 0);
62008
+ __publicField3(this, "capacity", capacity);
62009
+ __publicField3(this, "particles", []);
62010
+ __publicField3(this, "serial", 0);
61808
62011
  }
61809
62012
  get count() {
61810
62013
  return this.particles.length;
@@ -61888,31 +62091,31 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
61888
62091
  var SpritePool = class {
61889
62092
  /** `carried`: the normal-blend pool (smoke, dust, steam), whose light sprites go round the closed spaces; the additive one (flames, sparks) does not. */
61890
62093
  constructor(capacity, context, carried = false) {
61891
- __publicField2(this, "capacity", capacity);
61892
- __publicField2(this, "context", context);
61893
- __publicField2(this, "carried", carried);
61894
- __publicField2(this, "count", 0);
61895
- __publicField2(this, "position");
61896
- __publicField2(this, "velocity");
61897
- __publicField2(this, "colorStart");
61898
- __publicField2(this, "colorEnd");
61899
- __publicField2(this, "life");
61900
- __publicField2(this, "maxLife");
61901
- __publicField2(this, "startSize");
61902
- __publicField2(this, "growth");
61903
- __publicField2(this, "startAlpha");
61904
- __publicField2(this, "gravity");
61905
- __publicField2(this, "drag");
61906
- __publicField2(this, "fadeIn");
61907
- __publicField2(this, "groundMode");
61908
- __publicField2(this, "decalSize");
61909
- __publicField2(this, "color");
61910
- __publicField2(this, "size");
61911
- __publicField2(this, "alpha");
61912
- __publicField2(this, "vectorArrays");
61913
- __publicField2(this, "scalarArrays");
61914
- __publicField2(this, "direction", { x: 0, y: 0, z: 0 });
61915
- __publicField2(this, "unit", { x: 0, y: 0, z: 0 });
62094
+ __publicField3(this, "capacity", capacity);
62095
+ __publicField3(this, "context", context);
62096
+ __publicField3(this, "carried", carried);
62097
+ __publicField3(this, "count", 0);
62098
+ __publicField3(this, "position");
62099
+ __publicField3(this, "velocity");
62100
+ __publicField3(this, "colorStart");
62101
+ __publicField3(this, "colorEnd");
62102
+ __publicField3(this, "life");
62103
+ __publicField3(this, "maxLife");
62104
+ __publicField3(this, "startSize");
62105
+ __publicField3(this, "growth");
62106
+ __publicField3(this, "startAlpha");
62107
+ __publicField3(this, "gravity");
62108
+ __publicField3(this, "drag");
62109
+ __publicField3(this, "fadeIn");
62110
+ __publicField3(this, "groundMode");
62111
+ __publicField3(this, "decalSize");
62112
+ __publicField3(this, "color");
62113
+ __publicField3(this, "size");
62114
+ __publicField3(this, "alpha");
62115
+ __publicField3(this, "vectorArrays");
62116
+ __publicField3(this, "scalarArrays");
62117
+ __publicField3(this, "direction", { x: 0, y: 0, z: 0 });
62118
+ __publicField3(this, "unit", { x: 0, y: 0, z: 0 });
61916
62119
  const vectorArray = () => new Float32Array(capacity * FLOATS_PER_VECTOR);
61917
62120
  const scalarArray = () => new Float32Array(capacity);
61918
62121
  this.position = vectorArray();
@@ -62060,25 +62263,25 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
62060
62263
  var TAIL_BRIGHTNESS = 0.15;
62061
62264
  var StreakPool = class {
62062
62265
  constructor(capacity, context) {
62063
- __publicField2(this, "capacity", capacity);
62064
- __publicField2(this, "context", context);
62065
- __publicField2(this, "count", 0);
62066
- __publicField2(this, "point");
62067
- __publicField2(this, "velocity");
62068
- __publicField2(this, "colorStart");
62069
- __publicField2(this, "colorEnd");
62070
- __publicField2(this, "life");
62071
- __publicField2(this, "maxLife");
62072
- __publicField2(this, "length");
62073
- __publicField2(this, "gravity");
62074
- __publicField2(this, "drag");
62075
- __publicField2(this, "groundMode");
62076
- __publicField2(this, "startAlpha");
62077
- __publicField2(this, "segment");
62078
- __publicField2(this, "segmentColor");
62079
- __publicField2(this, "vectorArrays");
62080
- __publicField2(this, "scalarArrays");
62081
- __publicField2(this, "direction", { x: 0, y: 0, z: 0 });
62266
+ __publicField3(this, "capacity", capacity);
62267
+ __publicField3(this, "context", context);
62268
+ __publicField3(this, "count", 0);
62269
+ __publicField3(this, "point");
62270
+ __publicField3(this, "velocity");
62271
+ __publicField3(this, "colorStart");
62272
+ __publicField3(this, "colorEnd");
62273
+ __publicField3(this, "life");
62274
+ __publicField3(this, "maxLife");
62275
+ __publicField3(this, "length");
62276
+ __publicField3(this, "gravity");
62277
+ __publicField3(this, "drag");
62278
+ __publicField3(this, "groundMode");
62279
+ __publicField3(this, "startAlpha");
62280
+ __publicField3(this, "segment");
62281
+ __publicField3(this, "segmentColor");
62282
+ __publicField3(this, "vectorArrays");
62283
+ __publicField3(this, "scalarArrays");
62284
+ __publicField3(this, "direction", { x: 0, y: 0, z: 0 });
62082
62285
  const vectorArray = () => new Float32Array(capacity * FLOATS_PER_VECTOR2);
62083
62286
  const scalarArray = () => new Float32Array(capacity);
62084
62287
  this.point = vectorArray();
@@ -62194,9 +62397,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
62194
62397
  var DEFAULT_LIGHT_DISTANCE = 14;
62195
62398
  var WaveRingPool = class {
62196
62399
  constructor() {
62197
- __publicField2(this, "rings", Array.from({ length: RING_CAPACITY }, () => ({ on: false, point: UP15, from: 0, to: 0, t: 0, duration: 1, color: 0, normal: UP15, hold: 0 })));
62198
- __publicField2(this, "count", 0);
62199
- __publicField2(this, "next", 0);
62400
+ __publicField3(this, "rings", Array.from({ length: RING_CAPACITY }, () => ({ on: false, point: UP15, from: 0, to: 0, t: 0, duration: 1, color: 0, normal: UP15, hold: 0 })));
62401
+ __publicField3(this, "count", 0);
62402
+ __publicField3(this, "next", 0);
62200
62403
  }
62201
62404
  add(point, from, to, duration, color2, normal, hold) {
62202
62405
  const ring22 = this.rings[this.next++ % RING_CAPACITY];
@@ -62226,13 +62429,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
62226
62429
  };
62227
62430
  var FlashLightPool = class {
62228
62431
  constructor(context) {
62229
- __publicField2(this, "context", context);
62230
- __publicField2(this, "lights", Array.from({ length: LIGHT_CAPACITY }, () => ({ x: 0, y: 0, z: 0, color: 16760944, distance: DEFAULT_LIGHT_DISTANCE, peak: 0, duration: 1, t: 0, intensity: 0, steady: false })));
62231
- __publicField2(this, "fire", [
62432
+ __publicField3(this, "context", context);
62433
+ __publicField3(this, "lights", Array.from({ length: LIGHT_CAPACITY }, () => ({ x: 0, y: 0, z: 0, color: 16760944, distance: DEFAULT_LIGHT_DISTANCE, peak: 0, duration: 1, t: 0, intensity: 0, steady: false })));
62434
+ __publicField3(this, "fire", [
62232
62435
  { x: 0, y: 0, z: 0, intensity: 0 },
62233
62436
  { x: 0, y: 0, z: 0, intensity: 0 }
62234
62437
  ]);
62235
- __publicField2(this, "next", 0);
62438
+ __publicField3(this, "next", 0);
62236
62439
  }
62237
62440
  get lit() {
62238
62441
  return this.lights.filter((light) => light.intensity > 0).length;
@@ -62283,21 +62486,21 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
62283
62486
  }
62284
62487
  var WorkshopEngine = class {
62285
62488
  constructor(options) {
62286
- __publicField2(this, "context");
62287
- __publicField2(this, "add");
62288
- __publicField2(this, "normal");
62289
- __publicField2(this, "streaks");
62290
- __publicField2(this, "debris");
62291
- __publicField2(this, "decals");
62292
- __publicField2(this, "rings", new WaveRingPool());
62293
- __publicField2(this, "lights");
62294
- __publicField2(this, "rain", new RainField(this));
62295
- __publicField2(this, "meshes", new MeshPool());
62296
- __publicField2(this, "screen", createScreenState());
62297
- __publicField2(this, "lens", []);
62298
- __publicField2(this, "post", {});
62299
- __publicField2(this, "placement");
62300
- __publicField2(this, "accumulators", /* @__PURE__ */ new Map());
62489
+ __publicField3(this, "context");
62490
+ __publicField3(this, "add");
62491
+ __publicField3(this, "normal");
62492
+ __publicField3(this, "streaks");
62493
+ __publicField3(this, "debris");
62494
+ __publicField3(this, "decals");
62495
+ __publicField3(this, "rings", new WaveRingPool());
62496
+ __publicField3(this, "lights");
62497
+ __publicField3(this, "rain", new RainField(this));
62498
+ __publicField3(this, "meshes", new MeshPool());
62499
+ __publicField3(this, "screen", createScreenState());
62500
+ __publicField3(this, "lens", []);
62501
+ __publicField3(this, "post", {});
62502
+ __publicField3(this, "placement");
62503
+ __publicField3(this, "accumulators", /* @__PURE__ */ new Map());
62301
62504
  const profile = options.profile ?? PROFILES.high;
62302
62505
  this.context = { random: options.random, groundAt: options.groundAt ?? workshopGround, quality: { level: 0, mult: 1 }, trace: options.trace, ...options.confiner ? { confiner: options.confiner } : {} };
62303
62506
  this.add = new SpritePool(profile.sprites.add, this.context);
@@ -65201,10 +65404,13 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
65201
65404
  const distance3 = () => options.soundDistance?.() ?? 0;
65202
65405
  const particles = createParticles(THREE, scene, groundAt, options.particleLimit);
65203
65406
  particles.onBounce = (kind, hit) => {
65204
- if (kind === "magazine") audio?.thud();
65205
- if (kind !== "casing" || !audio) return;
65206
- const caseType = hit?.object.userData["caseType"];
65407
+ if (!audio || kind !== "casing" && kind !== "magazine") return;
65207
65408
  const surface = hit ? options.surfaceAt?.(hit.object.position.x, hit.object.position.z) : void 0;
65409
+ if (kind === "magazine") {
65410
+ audio.thud({ ...surface ? { surface } : {}, ...hit ? { speed: hit.speed, bounce: hit.bounce } : {} });
65411
+ return;
65412
+ }
65413
+ const caseType = hit?.object.userData["caseType"];
65208
65414
  audio.casing({ ...caseType ? { caseType } : {}, ...surface ? { surface } : {}, ...hit ? { speed: hit.speed, bounce: hit.bounce } : {} });
65209
65415
  };
65210
65416
  if (!options.effects) warnOnce("game-weapons-three.own-effects-world", "game-weapons-three made an effects world of its own because the host lent none (options.effects); pass the host effects so the effects share one budget");
@@ -66664,6 +66870,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
66664
66870
  reloadClip: "Reload of {weapon}: {kind}, clip {clip} ({seconds} s)",
66665
66871
  soundCue: "Sound: {cue} ({weapon})",
66666
66872
  cueRecorded: " \xB7 recorded",
66873
+ cueFitted: " \xB7 fitted copy of the recording",
66667
66874
  cueCarried: " \xB7 inside the next recording",
66668
66875
  gunshotSound: "Shot sound: {profile}, take {take}/4, pitch {pitch}, {space}, {distance} m{far}",
66669
66876
  gunshotRecorded: " \xB7 recorded take {takes}",
@@ -66699,6 +66906,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
66699
66906
  reloadClip: "Recarga de {weapon}: {kind}, clipe {clip} ({seconds} s)",
66700
66907
  soundCue: "Som: {cue} ({weapon})",
66701
66908
  cueRecorded: " \xB7 grava\xE7\xE3o",
66909
+ cueFitted: " \xB7 c\xF3pia medida da grava\xE7\xE3o",
66702
66910
  cueCarried: " \xB7 dentro da grava\xE7\xE3o seguinte",
66703
66911
  gunshotSound: "Som do tiro: {profile}, tomada {take}/4, tom {pitch}, {space}, {distance} m{far}",
66704
66912
  gunshotRecorded: " \xB7 grava\xE7\xE3o, tomada {takes}",
@@ -66913,20 +67121,20 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
66913
67121
  engine: lentEngine,
66914
67122
  ...options.samples ? { samples: options.samples } : {},
66915
67123
  onGunshot: (shot, input, played) => {
66916
- const recorded = played.kind === "sample" && played.layers.length > 0 ? fill(text.gunshotRecorded, { takes: played.layers.map((layer3) => `${layer3.role} ${layer3.take + 1}`).join(", ") }) : "";
67124
+ const recorded = played.kind === "sample" && played.layers.length > 0 ? fill(text.gunshotRecorded, { takes: played.layers.map((layer3) => `${layer3.role} ${layer3.take + 1}`).join(", ") }) : played.kind === "fitted" ? text.cueFitted : "";
66917
67125
  lent.log(
66918
67126
  fill(text.gunshotSound, { profile: shot.profile, take: String(shot.take + 1), pitch: `${shot.pitch >= 1 ? "+" : ""}${((shot.pitch - 1) * 100).toFixed(1)} %`, space: text.spaces[input.space ?? "outdoor"], distance: String(Math.round(input.distance ?? 0)), far: shot.closeMix < 1 ? ` (${Math.round((1 - shot.closeMix) * 100)} % far)` : "" }) + recorded,
66919
67127
  { profile: shot.profile, take: shot.take, pitch: shot.pitch, space: input.space ?? "outdoor", distance: input.distance ?? 0, closeMix: shot.closeMix, delay: shot.delay, samples: shot.samples, played },
66920
67128
  "sound"
66921
67129
  );
66922
67130
  },
66923
- onCasing: (sound3, played) => lent.log(fill(text.casingSound, { case: sound3.kind, surface: text.surfaces[sound3.surface] }) + (played === "sample" ? text.cueRecorded : ""), { case: sound3.kind, surface: sound3.surface, sample: sound3.sample, played }, "sound")
67131
+ onCasing: (sound3, played) => lent.log(fill(text.casingSound, { case: sound3.kind, surface: text.surfaces[sound3.surface] }) + (played === "sample" ? text.cueRecorded : played === "fitted" ? text.cueFitted : ""), { case: sound3.kind, surface: sound3.surface, sample: sound3.sample, played }, "sound")
66924
67132
  });
66925
67133
  }
66926
67134
  let simulatedMs = 0;
66927
67135
  const offClock = lent.onFrame((dt) => simulatedMs += dt * 1e3);
66928
67136
  const created = createWeaponFx({
66929
- onSound: ({ weapon, cue: cue3, profile, played }) => lent.log(fill(text.soundCue, { weapon: arsenal.name(weapon), cue: text.soundCues[cue3] ?? cue3 }) + (played === "sample" ? text.cueRecorded : played === "carried" ? text.cueCarried : ""), { weapon, cue: cue3, weight: profile.weight, material: profile.material, ...played ? { played } : {} }, "sound"),
67137
+ onSound: ({ weapon, cue: cue3, profile, played }) => lent.log(fill(text.soundCue, { weapon: arsenal.name(weapon), cue: text.soundCues[cue3] ?? cue3 }) + (played === "sample" ? text.cueRecorded : played === "fitted" ? text.cueFitted : played === "carried" ? text.cueCarried : ""), { weapon, cue: cue3, weight: profile.weight, material: profile.material, ...played ? { played } : {} }, "sound"),
66930
67138
  THREE: lent.THREE,
66931
67139
  scene: lent.scene,
66932
67140
  camera: lent.camera,
@@ -66976,6 +67184,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
66976
67184
  const offEvents = lent.on((event) => {
66977
67185
  worldEffects.handle(event, lent.effects);
66978
67186
  if (event.type === "explosion") {
67187
+ if (lentEngine) return;
66979
67188
  const away = Math.hypot(event.point[0] - camera2.position.x, event.point[1] - camera2.position.y, event.point[2] - camera2.position.z);
66980
67189
  ownAudio()?.play("explosion", Math.min(1, EXPLOSION_VOLUME_BASE + event.radius * EXPLOSION_VOLUME_PER_METRE), away);
66981
67190
  return;