Drill: visible dust; pulses push loose material back and open a channel (t92)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+32
-17
@@ -115,7 +115,38 @@ function pulseTick(step = 0.5) {
|
||||
let e = p.en[k];
|
||||
if (e < 0.04) continue;
|
||||
const ray = pulseRay(p.ox, p.oy, p.ang, Wd, -1 + 2 * (k + p.jit) / p.n), ux = ray.ux, uy = ray.uy;
|
||||
let sd = p.s[k], kicks = 0;
|
||||
// Keep shaking the travelled path while the wave advances, including the pile interior.
|
||||
let shake = Wd.en, kicks = 0;
|
||||
for (let d = 0.5; d < lim && shake >= 0.04 && kicks < 3; d++) {
|
||||
const x = Math.floor(ray.x + ux * d), y = Math.floor(ray.y + uy * d);
|
||||
if (x < 0 || y < 0 || x >= W || y >= H) break;
|
||||
if (x >= bx0 && x <= bx1 && y >= by0 && y <= by1) continue;
|
||||
const i = y * W + x, m = mat[i], ph = PH[m];
|
||||
if (ph === PH_SOLID) break;
|
||||
if (ph === PH_LIQUID) { shake *= 0.970225; continue; }
|
||||
if (ph !== PH_POWDER) continue;
|
||||
shake *= 0.97;
|
||||
if (stamp[i] !== tickStamp && !occ[i] && !part[i] && rnd() < 0.55 * shake) {
|
||||
// Lead with the reverse ray; blocked grains can lift or spill to either side.
|
||||
const backX = Math.abs(ux) > 0.38 ? -Math.sign(ux) : 0;
|
||||
const backY = Math.abs(uy) > 0.38 ? -Math.sign(uy) : 0;
|
||||
const side = rnd() < 0.5 ? -1 : 1;
|
||||
for (let hop = 0; hop < 5; hop++) {
|
||||
const mx = hop < 2 ? backX : hop < 4 ? side : -side;
|
||||
const my = hop === 0 ? backY : hop === 1 ? -1 : -(hop & 1);
|
||||
const nx = x + mx, ny = y + my;
|
||||
if (nx < 0 || ny < 0 || nx >= W || ny >= H) continue;
|
||||
const j = ny * W + nx;
|
||||
if (mat[j] !== EMPTY && PH[mat[j]] !== PH_GAS) continue;
|
||||
if (occ[j] || part[j] || stamp[j] === tickStamp || !enter(m, ph, j, mx, my)) continue;
|
||||
if (my && CORNER_SEAL && PH[mat[i + mx]] === PH_SOLID && PH[mat[i + my * W]] === PH_SOLID) continue;
|
||||
move(i, j, x, y, nx, ny); kicks++;
|
||||
if (dust < 4) { emit({ t: 'debris', x, y, m, dust: true }); dust++; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
let sd = p.s[k];
|
||||
while (sd < lim && e >= 0.04) {
|
||||
sd += step;
|
||||
const x = Math.floor(ray.x + ux * sd), y = Math.floor(ray.y + uy * sd);
|
||||
@@ -130,22 +161,6 @@ function pulseTick(step = 0.5) {
|
||||
if (ph === PH_LIQUID) { e *= liquid; continue; }
|
||||
if (ph === PH_POWDER) {
|
||||
e *= loose;
|
||||
// At most three one-cell hops per ray/tick; gravity settles the shaken grains.
|
||||
if (kicks < 3 && stamp[i] !== tickStamp && !occ[i] && !part[i] && rnd() < 1.1 * e * step) {
|
||||
const side = rnd() < 0.5 ? -1 : 1;
|
||||
for (let hop = 0; hop < 4; hop++) {
|
||||
const mx = hop < 2 ? side : -side, my = -(hop & 1);
|
||||
const nx = x + mx, ny = y + my;
|
||||
if (nx < 0 || ny < 0 || nx >= W || ny >= H) continue;
|
||||
const j = ny * W + nx;
|
||||
if (mat[j] !== EMPTY && PH[mat[j]] !== PH_GAS) continue;
|
||||
if (occ[j] || part[j] || stamp[j] === tickStamp || !enter(m, ph, j, mx, my)) continue;
|
||||
if (my && CORNER_SEAL && PH[mat[i + mx]] === PH_SOLID && PH[mat[i - W]] === PH_SOLID) continue;
|
||||
move(i, j, x, y, nx, ny); kicks++;
|
||||
if (dust < 4) { emit({ t: 'debris', x, y, m }); dust++; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (builtCell(i, x, y)) { e *= built; continue; }
|
||||
|
||||
Reference in New Issue
Block a user