import { TILE } from '../core/constants.js'; import { BLOCKS } from '../data/blocks.js'; import { state } from '../core/state.js'; import { getBlock, removeBlock, k } from './world-storage.js'; import { calculateDamage } from '../entities/player.js'; import { playSound } from '../audio/sound-engine.js'; import { spawnExplosion } from '../render/particles.js'; import { rebuildHotbar } from '../ui/hotbar.js'; // TNT логика: цепь + усиление function activateTNT(b, fuse = 3.2) { if (b.dead) return; if (b.active) return; b.active = true; b.fuse = fuse; state.activeTNT.add(k(b.gx, b.gy)); } function explodeAt(gx, gy) { const center = getBlock(gx, gy); if (!center) return; // усиление: считаем сколько TNT рядом (в радиусе 2) и активируем их «почти сразу» let bonus = 0; for (let x = gx - 2; x <= gx + 2; x++) { for (let y = gy - 2; y <= gy + 2; y++) { const b = getBlock(x, y); if (b && !b.dead && b.t === 'tnt' && !(x === gx && y === gy)) { bonus += 0.8; activateTNT(b, 0.12); // цепь } } } const power = 1 + bonus; // условная мощность const radius = 3.2 + bonus * 0.7; // радиус разрушения в тайлах const dmgR = 150 + bonus * 60; // радиус урона в пикселях removeBlock(gx, gy); state.activeTNT.delete(k(gx, gy)); playSound('explode1'); // Звук взрыва spawnExplosion(gx * TILE + TILE / 2, gy * TILE + TILE / 2, power); for (let x = Math.floor(gx - radius); x <= Math.ceil(gx + radius); x++) { for (let y = Math.floor(gy - radius); y <= Math.ceil(gy + radius); y++) { const d = Math.hypot(x - gx, y - gy); if (d > radius) continue; const b = getBlock(x, y); if (!b || b.dead) continue; if (BLOCKS[b.t].fluid) continue; if (BLOCKS[b.t].unbreakable) continue; if (b.t === 'tnt') { activateTNT(b, 0.12); continue; } removeBlock(x, y); if (state.inv[b.t] !== undefined && Math.random() < 0.20) state.inv[b.t]++; // немного дропа } } rebuildHotbar(); // урон const hurt = (e) => { const dx = (e.x + e.w / 2) - (gx * TILE + TILE / 2); const dy = (e.y + e.h / 2) - (gy * TILE + TILE / 2); const dist = Math.hypot(dx, dy); if (dist < dmgR) { const dmg = (dmgR - dist) * 0.06 * power; if (e === state.player) { const actualDamage = calculateDamage(dmg); state.player.hp -= actualDamage; } else { e.hp -= dmg; } e.vx += (dx / dist || 0) * 600; e.vy -= 320; } }; hurt(state.player); state.mobs.forEach(hurt); } export { activateTNT, explodeAt };