Files
rogue/src/engine/world/world-logic.ts
2026-01-05 20:59:33 +11:00

61 lines
1.7 KiB
TypeScript

import type { World, EntityId } from "../../core/types";
import { isBlocking, isDestructible, getDestructionResult } from "../../core/terrain";
import { type EntityManager } from "../EntityManager";
export function inBounds(w: World, x: number, y: number): boolean {
return x >= 0 && y >= 0 && x < w.width && y < w.height;
}
export function idx(w: World, x: number, y: number): number {
return y * w.width + x;
}
export function isWall(w: World, x: number, y: number): boolean {
// Alias for isBlocking for backward compatibility
return isBlockingTile(w, x, y);
}
export function isBlockingTile(w: World, x: number, y: number): boolean {
const tile = w.tiles[idx(w, x, y)];
return isBlocking(tile);
}
export function tryDestructTile(w: World, x: number, y: number): boolean {
if (!inBounds(w, x, y)) return false;
const i = idx(w, x, y);
const tile = w.tiles[i];
if (isDestructible(tile)) {
const nextTile = getDestructionResult(tile);
if (nextTile !== undefined) {
w.tiles[i] = nextTile;
return true;
}
}
return false;
}
export function isBlocked(w: World, x: number, y: number, em?: EntityManager): boolean {
if (!inBounds(w, x, y)) return true;
if (isBlockingTile(w, x, y)) return true;
if (em) {
return em.isOccupied(x, y, "exp_orb");
}
for (const a of w.actors.values()) {
if (a.pos.x === x && a.pos.y === y && a.type !== "exp_orb") return true;
}
return false;
}
export function isPlayerOnExit(w: World, playerId: EntityId): boolean {
const p = w.actors.get(playerId);
if (!p) return false;
return p.pos.x === w.exit.x && p.pos.y === w.exit.y;
}