Skip to content

Commit e00e2d6

Browse files
WomB0ComB0claude
andcommitted
fix: skip building placement below active water level
Buildings now use an attempt-based loop (up to 12× retries per settlement) that rejects positions where terrainHeight < waterLevel + 0.5 m, matching the existing guards on trees and rocks. Unused InstancedMesh slots are zero-scaled so they don't render. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent f0758fa commit e00e2d6

1 file changed

Lines changed: 18 additions & 1 deletion

File tree

src/ResQ.Viz.Web/client/terrain.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,11 +399,17 @@ export class Terrain {
399399
const dummy = new THREE.Object3D();
400400
let idx = 0;
401401

402+
const minH = _activePreset.waterLevel + 0.5;
403+
402404
for (const s of settlements) {
403-
for (let i = 0; i < s.count && idx < COUNT; i++, idx++) {
405+
let placed = 0;
406+
const maxTries = s.count * 12;
407+
for (let attempt = 0; attempt < maxTries && placed < s.count && idx < COUNT; attempt++) {
404408
const bx = s.cx + (rng() - 0.5) * s.r * 2;
405409
const bz = s.cz + (rng() - 0.5) * s.r * 2;
406410
const bh = terrainHeight(bx, bz);
411+
if (bh < minH) continue;
412+
407413
const w = 8 + rng() * 8;
408414
const d = 8 + rng() * 6;
409415
const ht = 5 + rng() * 9;
@@ -422,9 +428,20 @@ export class Terrain {
422428
dummy.rotation.set(0, rot + Math.PI * 0.25, 0);
423429
dummy.updateMatrix();
424430
roofs.setMatrixAt(idx, dummy.matrix);
431+
432+
placed++;
433+
idx++;
425434
}
426435
}
427436

437+
// Zero-scale any unused instance slots so they don't render
438+
dummy.scale.setScalar(0);
439+
dummy.updateMatrix();
440+
for (; idx < COUNT; idx++) {
441+
walls.setMatrixAt(idx, dummy.matrix);
442+
roofs.setMatrixAt(idx, dummy.matrix);
443+
}
444+
428445
walls.instanceMatrix.needsUpdate = true;
429446
roofs.instanceMatrix.needsUpdate = true;
430447
this._sceneAdd(scene, walls, roofs);

0 commit comments

Comments
 (0)