53 lines
1.8 KiB
JavaScript
53 lines
1.8 KiB
JavaScript
// ==================== ВОДА 3D — GrechkaCraft v3 ====================
|
||
// Та же логика 2D-игры (кислород, всплеск, болото), но с учётом Z.
|
||
import { TILE } from '../core/constants.js';
|
||
import { state } from '../core/state.js';
|
||
import { getBlock } from '../world/world-storage3d.js';
|
||
import { playSound } from '../audio/sound-engine.js';
|
||
|
||
function blockAt3(px, py, pz) {
|
||
const gx = Math.floor(px / TILE);
|
||
const gy = Math.floor(py / TILE);
|
||
const gz = Math.floor(pz / TILE);
|
||
return getBlock(gx, gy, gz);
|
||
}
|
||
|
||
function isWaterAt(px, py, pz) {
|
||
const b = blockAt3(px, py, pz);
|
||
return !!(b && (b.t === 'water' || b.t === 'swamp_water'));
|
||
}
|
||
|
||
function isSwampWaterAt(px, py, pz) {
|
||
const b = blockAt3(px, py, pz);
|
||
return !!(b && b.t === 'swamp_water');
|
||
}
|
||
|
||
// Обновляет флаги воды на сущности (игрок или моб).
|
||
// dt передаётся явно — в 2D-версии он был неявной переменной цикла.
|
||
export function updateWaterFlag3(e, dt) {
|
||
const cx = e.x + e.w / 2;
|
||
const cz = (e.z || 0) + (e.d || e.w) / 2;
|
||
const wasInWater = e.inWater;
|
||
|
||
const mid = isWaterAt(cx, e.y + e.h / 2, cz);
|
||
const feet = isWaterAt(cx, e.y + e.h - 2, cz);
|
||
e.inWater = mid || feet;
|
||
|
||
e.inSwampWater = isSwampWaterAt(cx, e.y + e.h / 2, cz);
|
||
e.headInWater = isWaterAt(cx, e.y + 4, cz);
|
||
|
||
if (e === state.player && !wasInWater && e.inWater && e.vy > 100) {
|
||
playSound('splash');
|
||
}
|
||
if (e === state.player && e.inSwampWater) {
|
||
state.player.hp -= 3 * (typeof dt === 'number' ? dt : 0.016);
|
||
}
|
||
}
|
||
|
||
// Лодка тонет, если под ней нет воды (с учётом Z).
|
||
export function updateWaterPhysics3(dt) {
|
||
void dt;
|
||
}
|
||
|
||
export { isWaterAt, isSwampWaterAt };
|