61 lines
1.6 KiB
JavaScript
61 lines
1.6 KiB
JavaScript
|
|
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);
|
||
|
|
}
|
||
|
|
}
|