@adatechnology/game-test-room 0.28.0 → 0.28.2

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.
@@ -16750,7 +16750,7 @@ var GameTestRoom = (() => {
16750
16750
  const { core, def, random, x, y, z } = context;
16751
16751
  const mark = def.mark;
16752
16752
  const keepsMarks = !core.marklessAt?.(x, z);
16753
- if (keepsMarks && mark.crater && mark.dent && y < 1.2) {
16753
+ if (keepsMarks && mark.crater && mark.dent && y < 1.2 && (core.cratersAt?.(x, z) ?? true)) {
16754
16754
  core.emit({ type: "crater", x, z, radius: mark.crater, depth: mark.dent });
16755
16755
  core.trace?.crater?.(x, z, mark.crater, mark.dent);
16756
16756
  addCrater(core.marks, core.ground, random, { x, z, radius: mark.crater, depth: mark.dent, marks: core.layers.mark });
@@ -18516,6 +18516,7 @@ var GameTestRoom = (() => {
18516
18516
  clock: { time: 0, lastBlast: -1, lod: 1, forcedLod: null },
18517
18517
  groundAt,
18518
18518
  ...options.marklessAt ? { marklessAt: options.marklessAt } : {},
18519
+ ...options.cratersAt ? { cratersAt: options.cratersAt } : {},
18519
18520
  emit: (request) => options.onRequest?.(request)
18520
18521
  };
18521
18522
  function definitionOf(id) {
@@ -51099,10 +51100,14 @@ void main(){
51099
51100
  { id: "dry_clay", strata: [{ material: "clay", thickness: 0.35 }, { material: "soil", thickness: 1.5 }, { material: "stone", thickness: 0.5 }] },
51100
51101
  { id: "snow", strata: [{ material: "snow", thickness: 0.3 }, { material: "soil", thickness: 1.5 }, { material: "stone", thickness: 0.5 }] },
51101
51102
  { id: "cobblestone", strata: [{ material: "cobble", thickness: 0.12 }, { material: "sand", thickness: 0.06 }, { material: "gravel", thickness: 0.2 }, { material: "soil", thickness: 1.2 }] },
51103
+ // rock at the surface (an outcrop, a quarry floor): a blast only spalls it and a shot chips it
51104
+ { id: "bedrock", surfacePattern: "rock", strata: [{ material: "stone", thickness: 3 }] },
51102
51105
  { id: "paver_floor", strata: [{ material: "paver", thickness: 0.08 }, { material: "sand", thickness: 0.05 }, { material: "gravel", thickness: 0.15 }, { material: "soil", thickness: 1.2 }] },
51103
51106
  { id: "shallow_water", water: { liquid: "water", depth: 0.3, drag: 0.65, blowShare: WATER_BLOW_SHARE }, strata: [{ material: "mud", thickness: 0.15 }, { material: "soil", thickness: 1.5 }, { material: "stone", thickness: 0.5 }] }
51104
51107
  ];
51105
51108
  var DEFAULT_BAR_YIELD_JOULES = 24e5;
51109
+ var DEFAULT_BAR_DIAMETER = 0.01;
51110
+ var DEFAULT_BAR_YIELD_PA = 5e8;
51106
51111
  var DEFAULT_PROFILE = "concrete_slab";
51107
51112
  function createRandom(seed) {
51108
51113
  let state = seed | 0;
@@ -51384,6 +51389,7 @@ void main(){
51384
51389
  var RIGID_WIDENING = 2.5;
51385
51390
  var COLLAPSE_DEPTH_SHARE = 0.75;
51386
51391
  var COLLAPSE_SPREAD_BEND = 0.5;
51392
+ var BARS_SHARE_REACH = 0.6;
51387
51393
  var RIM_REACH = 1.45;
51388
51394
  var FLAME_MINIMUM = 200;
51389
51395
  var FLAME_REACH = 0.6;
@@ -51903,19 +51909,95 @@ void main(){
51903
51909
  }
51904
51910
  }
51905
51911
  }
51906
- if (collapsed) emitDeform(x, z, reach);
51907
- if (collapsed && profile.drop !== void 0) {
51908
- for (let row = row0; row <= row1; row++) {
51909
- for (let column = column0; column <= column1; column++) {
51910
- const index = row * stride + column;
51911
- if (barBend[index] >= COLLAPSE_SPREAD_BEND && dug[index] < limit + profile.drop) {
51912
- dug[index] = limit + profile.drop;
51913
- touchVertex(column, row);
51914
- }
51912
+ if (collapsed) giveWay({ x, z, reach, profile });
51913
+ return collapsed;
51914
+ }
51915
+ function giveWay(spec) {
51916
+ const { x, z, reach, profile } = spec;
51917
+ emitDeform(x, z, reach);
51918
+ if (profile.drop === void 0) return;
51919
+ const limit = maxDepthOfProfile(profile);
51920
+ const column0 = clampIndex(Math.floor((x - reach - x0) / cellSize), columns);
51921
+ const column1 = clampIndex(Math.ceil((x + reach - x0) / cellSize), columns);
51922
+ const row0 = clampIndex(Math.floor((z - reach - z0) / cellSize), rows);
51923
+ const row1 = clampIndex(Math.ceil((z + reach - z0) / cellSize), rows);
51924
+ for (let row = row0; row <= row1; row++) {
51925
+ for (let column = column0; column <= column1; column++) {
51926
+ const index = row * stride + column;
51927
+ if (barBend[index] >= COLLAPSE_SPREAD_BEND && dug[index] < limit + profile.drop) {
51928
+ dug[index] = limit + profile.drop;
51929
+ touchVertex(column, row);
51915
51930
  }
51916
51931
  }
51917
51932
  }
51918
- return collapsed;
51933
+ }
51934
+ function barsOf(profile) {
51935
+ const bars = profile.strata.find((stratum) => stratum.reinforcement);
51936
+ if (!bars?.reinforcement) return null;
51937
+ let cover = bars.reinforcement.cover;
51938
+ for (const stratum of profile.strata) {
51939
+ if (stratum === bars) break;
51940
+ cover += stratum.thickness;
51941
+ }
51942
+ return { stratum: bars, cover };
51943
+ }
51944
+ function bearAll(loads) {
51945
+ const bends = /* @__PURE__ */ new Map();
51946
+ const touched2 = [];
51947
+ for (const load of loads) {
51948
+ const spread2 = spreadLoad(load, bends);
51949
+ if (spread2) touched2.push({ load, ...spread2 });
51950
+ }
51951
+ let opened = false;
51952
+ for (const [index, bend] of bends) {
51953
+ if (barBend[index] >= bend) continue;
51954
+ barBend[index] = bend;
51955
+ const column = index % stride;
51956
+ const row = (index - column) / stride;
51957
+ touchVertex(column, row);
51958
+ const profile = profileList[profileIndex[index]];
51959
+ const limit = maxDepthOfProfile(profile);
51960
+ if (bend >= 1 && profile.drop !== void 0 && dug[index] >= limit * COLLAPSE_DEPTH_SHARE && dug[index] < limit + profile.drop) {
51961
+ dug[index] = limit + profile.drop;
51962
+ opened = true;
51963
+ }
51964
+ }
51965
+ if (opened) for (const { load, reach, profile } of touched2) giveWay({ x: load.x, z: load.z, reach, profile });
51966
+ return opened;
51967
+ }
51968
+ function spreadLoad(load, bends) {
51969
+ if (!contains(load.x, load.z) || load.newtons <= 0) return null;
51970
+ const profile = profileList[profileIndex[vertexOf(load.x, load.z).index]];
51971
+ const bars = barsOf(profile);
51972
+ if (!bars) return null;
51973
+ const reinforcement = bars.stratum.reinforcement;
51974
+ const moment = (reinforcement.yieldPa ?? DEFAULT_BAR_YIELD_PA) * (reinforcement.diameter ?? DEFAULT_BAR_DIAMETER) ** 3 / 6;
51975
+ const holds2 = 8 * moment / reinforcement.spacing;
51976
+ const footprint = load.radius * Math.SQRT2 + cellSize;
51977
+ const reach = Math.max(footprint, BARS_SHARE_REACH);
51978
+ const column0 = clampIndex(Math.floor((load.x - reach - x0) / cellSize), columns);
51979
+ const column1 = clampIndex(Math.ceil((load.x + reach - x0) / cellSize), columns);
51980
+ const row0 = clampIndex(Math.floor((load.z - reach - z0) / cellSize), rows);
51981
+ const row1 = clampIndex(Math.ceil((load.z + reach - z0) / cellSize), rows);
51982
+ const bare = [];
51983
+ let under = 0;
51984
+ let onBars = 0;
51985
+ for (let row = row0; row <= row1; row++) {
51986
+ for (let column = column0; column <= column1; column++) {
51987
+ const distance4 = Math.hypot(x0 + column * cellSize - load.x, z0 + row * cellSize - load.z);
51988
+ if (distance4 >= reach) continue;
51989
+ const index = row * stride + column;
51990
+ const isBare = dug[index] >= bars.cover;
51991
+ if (isBare) bare.push(index);
51992
+ if (distance4 >= footprint) continue;
51993
+ under++;
51994
+ if (isBare) onBars++;
51995
+ }
51996
+ }
51997
+ if (onBars === 0) return null;
51998
+ const bend = load.newtons * (onBars / under) / holds2;
51999
+ for (const index of bare) bends.set(index, (bends.get(index) ?? 0) + bend);
52000
+ return { reach, profile };
51919
52001
  }
51920
52002
  const maxDepthOfProfile = (profile) => maxDepthOf[indexOfProfile.get(profile.id)];
51921
52003
  function rebarShowing(profile, depth) {
@@ -52190,6 +52272,7 @@ void main(){
52190
52272
  strike,
52191
52273
  burn,
52192
52274
  applyHit,
52275
+ bear: bearAll,
52193
52276
  onDeform(listener) {
52194
52277
  deformListeners.add(listener);
52195
52278
  return () => deformListeners.delete(listener);
@@ -52333,7 +52416,7 @@ void main(){
52333
52416
  }
52334
52417
  };
52335
52418
  }
52336
- var TERRAIN_PATTERNS = ["plain", "grass", "soil", "sand", "asphalt", "concrete", "tile", "planks", "stone", "mud", "gravel", "clay", "snow", "cobble", "paver"];
52419
+ var TERRAIN_PATTERNS = ["plain", "grass", "soil", "sand", "asphalt", "concrete", "tile", "planks", "stone", "mud", "gravel", "clay", "snow", "cobble", "paver", "rock"];
52337
52420
  var STRIDE = 0.72;
52338
52421
  var FOOT_LENGTH = 0.15;
52339
52422
  var FOOT_APART = 0.11;
@@ -52381,10 +52464,10 @@ void main(){
52381
52464
  };
52382
52465
  }
52383
52466
 
52384
- // ../game-terrain-three/dist/chunk-B5EA72GU.js
52467
+ // ../game-terrain-three/dist/chunk-6YHNPX3W.js
52385
52468
  var PROFILE_NAMES = {
52386
- en: { lawn: "Lawn", dirt: "Dirt", sand: "Sand", road: "Asphalt road", concrete_slab: "Concrete slab", suspended_slab: "Slab over a void", tile_floor: "Tile floor", wood_floor: "Wood floor", stone_paving: "Stone paving" },
52387
- "pt-BR": { lawn: "Grama", dirt: "Terra", sand: "Areia", road: "Asfalto", concrete_slab: "Laje de concreto", suspended_slab: "Laje sobre v\xE3o", tile_floor: "Piso cer\xE2mico", wood_floor: "Assoalho", stone_paving: "Cal\xE7amento de pedra" }
52469
+ en: { lawn: "Lawn", dirt: "Dirt", sand: "Sand", road: "Asphalt road", concrete_slab: "Concrete slab", suspended_slab: "Slab over a void", tile_floor: "Tile floor", wood_floor: "Wood floor", stone_paving: "Stone paving", mud: "Mud", gravel_bed: "Gravel", dry_clay: "Dry clay", snow: "Snow", cobblestone: "Cobblestones", paver_floor: "Concrete pavers", shallow_water: "Shallow water", bedrock: "Bare rock" },
52470
+ "pt-BR": { lawn: "Grama", dirt: "Terra", sand: "Areia", road: "Asfalto", concrete_slab: "Laje de concreto", suspended_slab: "Laje sobre v\xE3o", tile_floor: "Piso cer\xE2mico", wood_floor: "Assoalho", stone_paving: "Cal\xE7amento de pedra", mud: "Lama", gravel_bed: "Cascalho", dry_clay: "Barro seco", snow: "Neve", cobblestone: "Paralelep\xEDpedo", paver_floor: "Bloquete", shallow_water: "\xC1gua rasa", bedrock: "Rocha" }
52388
52471
  };
52389
52472
  function terrainProfileName(profileId, localeId) {
52390
52473
  return (PROFILE_NAMES[localeId] ?? PROFILE_NAMES.en)[profileId] ?? profileId;
@@ -52394,20 +52477,20 @@ void main(){
52394
52477
  name: "Terrain",
52395
52478
  group: "Terrain",
52396
52479
  weight: "Concrete block (60 kg)",
52397
- surfaces: { dirt: "Dirt", lawn: "Lawn", sand: "Sand", road: "Asphalt", concrete_slab: "Concrete slab", suspended_slab: "Slab over a void", wood_floor: "Wood floor", tile_floor: "Tile", stone_paving: "Stone paving", mud: "Mud", gravel_bed: "Gravel", dry_clay: "Dry clay", snow: "Snow", cobblestone: "Cobblestones", paver_floor: "Concrete pavers", shallow_water: "Shallow water" }
52480
+ surfaces: { dirt: "Dirt", lawn: "Lawn", sand: "Sand", road: "Asphalt", concrete_slab: "Concrete slab", suspended_slab: "Slab over a void", wood_floor: "Wood floor", tile_floor: "Tile", stone_paving: "Stone paving", mud: "Mud", gravel_bed: "Gravel", dry_clay: "Dry clay", snow: "Snow", cobblestone: "Cobblestones", paver_floor: "Concrete pavers", shallow_water: "Shallow water", bedrock: "Bare rock" }
52398
52481
  },
52399
52482
  "pt-BR": {
52400
52483
  name: "Terreno",
52401
52484
  group: "Terreno",
52402
52485
  weight: "Bloco de concreto (60 kg)",
52403
- surfaces: { dirt: "Terra", lawn: "Grama", sand: "Areia", road: "Asfalto", concrete_slab: "Laje de concreto", suspended_slab: "Laje sobre v\xE3o", wood_floor: "Assoalho", tile_floor: "Cer\xE2mica", stone_paving: "Pedra", mud: "Lama", gravel_bed: "Cascalho", dry_clay: "Barro seco", snow: "Neve", cobblestone: "Paralelep\xEDpedo", paver_floor: "Bloquete", shallow_water: "\xC1gua rasa" }
52486
+ surfaces: { dirt: "Terra", lawn: "Grama", sand: "Areia", road: "Asfalto", concrete_slab: "Laje de concreto", suspended_slab: "Laje sobre v\xE3o", wood_floor: "Assoalho", tile_floor: "Cer\xE2mica", stone_paving: "Pedra", mud: "Lama", gravel_bed: "Cascalho", dry_clay: "Barro seco", snow: "Neve", cobblestone: "Paralelep\xEDpedo", paver_floor: "Bloquete", shallow_water: "\xC1gua rasa", bedrock: "Rocha" }
52404
52487
  }
52405
52488
  };
52406
52489
  var locale = (id) => LOCALES[id] ?? LOCALES.en;
52407
- var TERRAIN_STRIPS = ["lawn", "dirt", "sand", "mud", "dry_clay", "gravel_bed", "snow", "shallow_water", "road", "cobblestone", "paver_floor", "stone_paving", "concrete_slab", "suspended_slab", "tile_floor", "wood_floor"];
52408
- var LOT_WIDTH = 3.4;
52490
+ var TERRAIN_STRIPS = ["lawn", "dirt", "sand", "mud", "dry_clay", "gravel_bed", "snow", "shallow_water", "bedrock", "road", "cobblestone", "paver_floor", "stone_paving", "concrete_slab", "suspended_slab", "tile_floor", "wood_floor"];
52491
+ var LOT_WIDTH = 3;
52409
52492
  var LOT_DEPTH = 3.8;
52410
- var LOTS_PER_ROW = 8;
52493
+ var LOTS_PER_ROW = 9;
52411
52494
  var LOTS_Z1 = -1.4;
52412
52495
  var lotRect = (index) => {
52413
52496
  const row = Math.floor(index / LOTS_PER_ROW);
@@ -52500,11 +52583,18 @@ vec3 terrainSurface(vec3 base, vec2 xz, float kind) {
52500
52583
  float seam = max(tsLine(xz.y, 0.2, 0.014), tsLine(along, 0.3, 0.014));
52501
52584
  return base * (0.72 + 0.6 * tsHash(cell)) * (0.82 + 0.36 * tsFbm(xz * 22.0)) * (1.0 - 0.8 * seam);
52502
52585
  }
52503
- float row = floor(xz.y / 0.2);
52504
- float along = xz.x - mod(abs(row), 2.0) * 0.1;
52505
- vec2 cell = vec2(floor(along / 0.2), row);
52506
- float seam = max(tsLine(xz.y, 0.2, 0.008), tsLine(along, 0.2, 0.008));
52507
- return base * (0.86 + 0.26 * tsHash(cell)) * (0.92 + 0.16 * tsNoise(xz * 70.0)) * (1.0 - 0.7 * seam);
52586
+ if (k < 14.5) {
52587
+ float row = floor(xz.y / 0.2);
52588
+ float along = xz.x - mod(abs(row), 2.0) * 0.1;
52589
+ vec2 cell = vec2(floor(along / 0.2), row);
52590
+ float seam = max(tsLine(xz.y, 0.2, 0.008), tsLine(along, 0.2, 0.008));
52591
+ return base * (0.86 + 0.26 * tsHash(cell)) * (0.92 + 0.16 * tsNoise(xz * 70.0)) * (1.0 - 0.7 * seam);
52592
+ }
52593
+ // bare rock: weathered blotches, lichen-dark patches and a few long joints, no grid
52594
+ float blotch = tsFbm(xz * 0.9) * 0.6 + tsFbm(xz * 4.0 + 2.0) * 0.4;
52595
+ float joint = 1.0 - smoothstep(0.0, 0.035, abs(tsNoise(xz * vec2(0.7, 1.9)) - 0.5));
52596
+ float grain = tsNoise(xz * 95.0);
52597
+ return base * (0.62 + 0.75 * blotch) * (0.88 + 0.24 * grain) * (1.0 - 0.6 * joint);
52508
52598
  }
52509
52599
  `
52510
52600
  );
@@ -52533,9 +52623,9 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
52533
52623
  const index = row * terrain.stride + column;
52534
52624
  let material = terrain.vertexMaterial(column, row);
52535
52625
  if (terrain.loose[index] > LOOSE_VISIBLE) {
52536
- const profile = terrain.profileList[terrain.profileIndex[index]];
52537
- const first = profile.strata[0];
52538
- material = terrain.material(first.thickness < THIN_SKIN && profile.strata[1] ? profile.strata[1].material : first.material);
52626
+ const profile2 = terrain.profileList[terrain.profileIndex[index]];
52627
+ const first = profile2.strata[0];
52628
+ material = terrain.material(first.thickness < THIN_SKIN && profile2.strata[1] ? profile2.strata[1].material : first.material);
52539
52629
  }
52540
52630
  const broken = material.pattern === "concrete" && terrain.dug[index] > BROKEN_DEPTH;
52541
52631
  const tone = broken ? BROKEN_TONE : 1;
@@ -52544,7 +52634,9 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
52544
52634
  base[2] = material.color[2] * tone;
52545
52635
  shade[0] = Math.max(MIN_DEPTH_LIGHT, 1 - terrain.dug[index] / DEPTH_SHADE);
52546
52636
  shade[1] = terrain.scorch[index];
52547
- return patternIndex(broken ? "soil" : material.pattern);
52637
+ const profile = terrain.profileList[terrain.profileIndex[index]];
52638
+ const untouched = profile.surfacePattern !== void 0 && terrain.dug[index] <= BROKEN_DEPTH && terrain.loose[index] <= LOOSE_VISIBLE;
52639
+ return patternIndex(broken ? "soil" : untouched ? profile.surfacePattern : material.pattern);
52548
52640
  }
52549
52641
  function chunkVertexCount(terrain, chunk, step) {
52550
52642
  const lastColumn = Math.min(terrain.columns, chunk.column + chunk.cells);
@@ -53640,6 +53732,7 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
53640
53732
  "act.throw": "Threw {name} at {speed} m/s",
53641
53733
  "ground.name": "Ground",
53642
53734
  "act.landing": "{name} landed at {speed} m/s: {energy} J",
53735
+ "act.ground_gave_way": "the bare bars could not hold the weight on them: the slab gave way",
53643
53736
  "act.player_land": "You landed at {speed} m/s",
53644
53737
  "act.bench_failed": "{name} failed: {error}",
53645
53738
  "loading.working": "Working\u2026",
@@ -54009,6 +54102,7 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
54009
54102
  "act.throw": "Arremessou {name} a {speed} m/s",
54010
54103
  "ground.name": "Ch\xE3o",
54011
54104
  "act.landing": "{name} caiu a {speed} m/s: {energy} J",
54105
+ "act.ground_gave_way": "os vergalh\xF5es expostos n\xE3o aguentaram o peso: a laje cedeu",
54012
54106
  "act.player_land": "Voc\xEA aterrissou a {speed} m/s",
54013
54107
  "act.bench_failed": "{name} falhou: {error}",
54014
54108
  "loading.working": "Trabalhando\u2026",
@@ -55529,6 +55623,11 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
55529
55623
  var TERRAIN_CELL = 0.1;
55530
55624
  var GROUND_SPLASH_MAX_LITRES = 3;
55531
55625
  var WATER_ENTRY_SPEED = 1.5;
55626
+ var LOAD_EVERY = 0.2;
55627
+ var RESTING_GAP = 0.06;
55628
+ var PLAYER_FOOTPRINT = 0.25;
55629
+ var RESTING_SPEED = 0.3;
55630
+ var GRAVITY_EARTH = 9.81;
55532
55631
  var TERRAIN_MAX_CELLS = 1e3;
55533
55632
  var GROUND_BURST_MAX = 28;
55534
55633
  var GROUND_BURST_PER_METRE = 30;
@@ -55691,7 +55790,9 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
55691
55790
  profile: quality,
55692
55791
  ...options.debris?.particles ? { sprites: { kinds: patchSpriteKinds(SPRITE_KINDS, options.debris.particles) } } : {},
55693
55792
  groundAt,
55694
- marklessAt: (x, z) => terrain.waterAt(x, z) !== null
55793
+ marklessAt: (x, z) => terrain.waterAt(x, z) !== null,
55794
+ // the dirt crater of the effects only where the ground is loose; rock, asphalt and a slab keep the soot and the bowl the terrain itself dug
55795
+ cratersAt: (x, z) => terrain.material(terrain.columnAt(x, z).material).reposeDegrees !== void 0
55695
55796
  })
55696
55797
  });
55697
55798
  const renderer = createDestructionRenderer(THREE, {
@@ -57967,6 +58068,30 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
57967
58068
  for (const p of loose) floatPiece(p, dt);
57968
58069
  };
57969
58070
  const footprints = createFootprints(terrain);
58071
+ let loadClock = 0;
58072
+ const restingLoad = (piece) => {
58073
+ if (piece.held || Math.hypot(piece.velocity[0], piece.velocity[1], piece.velocity[2]) > RESTING_SPEED) return null;
58074
+ const box2 = tmpBox.setFromObject(piece.root);
58075
+ const centre = box2.getCenter(tmpV2);
58076
+ return { x: centre.x, z: centre.z, radius: Math.max(piece.halfExtents[0], piece.halfExtents[2]), newtons: piece.mass * GRAVITY_EARTH };
58077
+ };
58078
+ const updateLoads = (dt) => {
58079
+ loadClock += dt;
58080
+ if (loadClock < LOAD_EVERY) return;
58081
+ loadClock = 0;
58082
+ const loads = [];
58083
+ const [px, py, pz] = player.position;
58084
+ if (py - terrain.heightAt(px, pz) <= RESTING_GAP) loads.push({ x: px, z: pz, radius: PLAYER_FOOTPRINT, newtons: playerMass * GRAVITY_EARTH });
58085
+ for (const e of entries2.values()) {
58086
+ const load = e.piece ? restingLoad(e.piece) : null;
58087
+ if (load) loads.push(load);
58088
+ }
58089
+ for (const p of loose) {
58090
+ const load = restingLoad(p);
58091
+ if (load) loads.push(load);
58092
+ }
58093
+ if (loads.length > 0 && terrain.bear(loads)) action("ground_gave_way", t("act.ground_gave_way"));
58094
+ };
57970
58095
  const prevVy = /* @__PURE__ */ new Map();
57971
58096
  const tmpBox = new THREE.Box3();
57972
58097
  const onKey = (code, down, e) => {
@@ -58265,6 +58390,7 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
58265
58390
  vfx.update(dt);
58266
58391
  updateImpacts();
58267
58392
  updateWater(dt);
58393
+ updateLoads(dt);
58268
58394
  if (player.position[1] <= terrain.footAt(player.position[0], player.position[2]) + 0.15) footprints.update(player.position[0], player.position[2]);
58269
58395
  fluidView.update(dt);
58270
58396
  filmBridge.update(dt);