wren/val Public Public: anyone can read this; nobody can change it.
forked from benjivers/val
workbenchthis machine
Files b42aa0d0f5a2520c6a2bd99fd90ea66615e6c986
| 1 | /** |
| 2 | * The map: this game's one grid, and what its letters mean. |
| 3 | * |
| 4 | * Two sites (A left, B right), a mid corridor between the spawns, and a back |
| 5 | * corridor along the bottom that links A main, spawn and B main — the flank. |
| 6 | * Tiles are 80 units; a player is a circle of radius 16, so a one-tile |
| 7 | * corridor is comfortably wide and a wall is never thin enough for a ray to |
| 8 | * step over. |
| 9 | * |
| 10 | * The mechanics — collision, line of sight, the walk distance a bot uses to |
| 11 | * path — are `engine/grid.ts`, bound here to these rows. What is this |
| 12 | * game's own is the rows themselves and the reading of their letters: a |
| 13 | * plant site, a spawn, where the orbs sit. |
| 14 | */ |
| 15 | |
| 16 | import { makeGrid, segmentHitsCircle, segmentPoint, type Point } from "./engine/grid.ts"; |
| 17 | |
| 18 | export { segmentHitsCircle, segmentPoint, type Point }; |
| 19 | |
| 20 | export const TILE = 80; |
| 21 | |
| 22 | // '#' wall · '.' floor · 'A'/'B' plant site · 'a' attacker spawn · 'd' defender spawn |
| 23 | const ROWS_SRC = [ |
| 24 | "##############################", |
| 25 | "#........###.dddd.###........#", |
| 26 | "#.AAAAA..###.dddd.###..BBBBB.#", |
| 27 | "#.AAAAA..##........##..BBBBB.#", |
| 28 | "#.AAAAA..##.#....#.##..BBBBB.#", |
| 29 | "#.AAAAA..##........##..BBBBB.#", |
| 30 | "#...##......#....#......##...#", |
| 31 | "#..####....#......#....####..#", |
| 32 | "#..####..###......###..####..#", |
| 33 | "#..####..####....####..####..#", |
| 34 | "#..####..####.##.####..####..#", |
| 35 | "#........####.##.####........#", |
| 36 | "#..####..####....####..####..#", |
| 37 | "#..####..#####..#####..####..#", |
| 38 | "#..####..#####..#####..####..#", |
| 39 | "#..####..###......###..####..#", |
| 40 | "#........##..aaaa..##........#", |
| 41 | "#............aaaa............#", |
| 42 | "##############################", |
| 43 | ]; |
| 44 | |
| 45 | const board = makeGrid(ROWS_SRC, TILE); |
| 46 | |
| 47 | export const COLS = board.cols; |
| 48 | export const ROWS = board.rows; |
| 49 | export const WIDTH = board.width; |
| 50 | export const HEIGHT = board.height; |
| 51 | |
| 52 | export const grid: string[] = ROWS_SRC; |
| 53 | export const gridRows = (): string[] => ROWS_SRC.slice(); |
| 54 | |
| 55 | export type Site = "A" | "B"; |
| 56 | |
| 57 | export const solidTile = board.solidTile; |
| 58 | export const tileOf = board.tileOf; |
| 59 | export const centreOf = board.centreOf; |
| 60 | export const solidAt = board.solidAt; |
| 61 | export const moveCircle = board.moveCircle; |
| 62 | export const blockedCircle = board.blockedCircle; |
| 63 | export const wallBetween = board.wallBetween; |
| 64 | export const rayHitWall = board.rayHitWall; |
| 65 | export const walkDistance = board.walkDistance; |
| 66 | export const pathStep = board.pathStep; |
| 67 | export const clearPaths = board.clearPaths; |
| 68 | |
| 69 | /** The site a point plants on, or null: the spike only arms inside a site. */ |
| 70 | export const siteAt = (x: number, y: number): Site | null => { |
| 71 | const c = board.cellAt(x, y); |
| 72 | return c === "A" || c === "B" ? c : null; |
| 73 | }; |
| 74 | |
| 75 | export const spawnCells = (side: "atk" | "def"): Point[] => board.cellsOf(side === "atk" ? "a" : "d"); |
| 76 | export const siteCells = (site: Site): Point[] => board.cellsOf(site); |
| 77 | |
| 78 | export const siteCentre = (site: Site): Point => { |
| 79 | const cells = siteCells(site); |
| 80 | const sum = cells.reduce((a, p) => ({ x: a.x + p.x, y: a.y + p.y }), { x: 0, y: 0 }); |
| 81 | return { x: sum.x / cells.length, y: sum.y / cells.length }; |
| 82 | }; |
| 83 | |
| 84 | /** Ult orbs: one on each half of mid, free for whoever walks over them. */ |
| 85 | export const orbSpots = (): Point[] => [centreOf(4, 11), centreOf(25, 11)]; |