SandGame/smoke.js

61 lines
1.6 KiB
JavaScript
Raw Permalink Normal View History

import { grid, cols, rows } from './state.js';
import { config } from './config.js';
import { move, swap } from './actions.js';
export function updateSmoke(x, y, cell) {
// Check lifespan / dissipation
if (cell.lifespan !== undefined) {
cell.lifespan--;
if (cell.lifespan <= 0) {
grid[x][y] = null;
return;
}
} else if (Math.random() < config.smoke.dissipateChance) {
grid[x][y] = null;
return;
}
const above = y - 1;
if (above < 0) {
// Escapes into sky
grid[x][y] = null;
return;
}
// Try rising
const cellAbove = grid[x][above];
if (!cellAbove) {
move(x, y, x, above);
// Slight drift while rising
if (Math.random() < 0.4) {
const dir = Math.random() < 0.5 ? -1 : 1;
const nx = x + dir;
if (nx >= 0 && nx < cols && !grid[nx][above]) {
move(x, above, nx, above);
}
}
return;
}
// Bubble through liquids
if (cellAbove.type === 'water' || cellAbove.type === 'acid' || cellAbove.type === 'oil') {
swap(x, y, x, above);
return;
}
// Drifting sideways if blocked above
const leftIdx = x - 1;
const rightIdx = x + 1;
const leftFree = leftIdx >= 0 && !grid[leftIdx][y];
const rightFree = rightIdx < cols && !grid[rightIdx][y];
if (leftFree && rightFree) {
const dir = Math.random() < 0.5 ? -1 : 1;
move(x, y, x + dir, y);
} else if (leftFree) {
move(x, y, leftIdx, y);
} else if (rightFree) {
move(x, y, rightIdx, y);
}
}