import { Color, Grid, Point, Rect, Size } from "./engine/datatypes.ts"; import { DrawPile } from "./drawpile.ts"; import { GridArt } from "./gridart.ts"; import { C } from "./colors.ts"; export class World3D { #grid: Grid; constructor(size: Size) { this.#grid = new Grid(size, () => null); } set(at: Point, value: Element3D) { this.#grid.set(at, value); } drawCell(drawpile: DrawPile, gridArt: GridArt, xy: Point) { const OFFSET_AIR = 0; const OFFSET_TOP = 256; const OFFSET_TOP_OF_TOP = 512; let here = this.#grid.get(xy); if (here == null) { drawpile.add(OFFSET_TOP, () => { gridArt.drawCeiling(C.BG_CEILING); }); return; } const getRevealedBlock = (dx: number, dy: number): Block3D | null => { let xy2 = xy.offset(new Point(dx, dy)); if (!new Rect(new Point(0, 0), this.#grid.size).contains(xy2)) { return null; } let other = this.#grid.get(xy.offset(new Point(dx, dy))); if (other instanceof Block3D) { return other; } return null; }; let center = getRevealedBlock(0, 0); if (center) { drawpile.add(OFFSET_TOP, () => { gridArt.drawCeiling(center.ceiling); }); return; } let west = getRevealedBlock(-1, 0); let east = getRevealedBlock(1, 0); let north = getRevealedBlock(0, -1); let south = getRevealedBlock(0, 1); if (north && west) { drawpile.add(OFFSET_TOP_OF_TOP, () => { gridArt.drawMouldingTopLeft(north.moulding); }); } if (north) { drawpile.add(OFFSET_AIR, () => { gridArt.drawWallTop(north.dark); }); drawpile.add(OFFSET_TOP_OF_TOP, () => { gridArt.drawMouldingTop(north.moulding); }); } if (north && east) { drawpile.add(OFFSET_TOP_OF_TOP, () => { gridArt.drawMouldingTopRight(north.moulding); }); } if (west) { drawpile.add(OFFSET_AIR, () => { gridArt.drawWallLeft(west.dark); }); drawpile.add(OFFSET_TOP_OF_TOP, () => { gridArt.drawMouldingLeft(west.moulding); }); } if (south && west) { drawpile.add(OFFSET_TOP_OF_TOP, () => { gridArt.drawMouldingBottomLeft(south.moulding); }); } if (south) { drawpile.add(OFFSET_AIR, () => { gridArt.drawWallBottom(south.bright); }); drawpile.add(OFFSET_TOP_OF_TOP, () => { gridArt.drawMouldingBottom(south.moulding); }); } if (south && east) { drawpile.add(OFFSET_TOP_OF_TOP, () => { gridArt.drawMouldingBottomRight(south.moulding); }); } if (east) { drawpile.add(OFFSET_AIR, () => { gridArt.drawWallRight(east.bright); }); drawpile.add(OFFSET_TOP_OF_TOP, () => { gridArt.drawMouldingRight(east.moulding); }); } } } export type Element3D = Floor3D | Block3D | null; export class Floor3D { constructor() {} } export class Block3D { readonly bright: Color; readonly dark: Color; readonly ceiling: Color; get moulding(): Color { return this.dark; } constructor(bright: Color, dark: Color, ceiling: Color) { this.bright = bright; this.dark = dark; this.ceiling = ceiling; } static standardWall(): Block3D { return new Block3D(C.BG_OUTERWALL, C.BG_INNERWALL, C.BG_WALL_OR_UNREVEALED); } }