ludic/packages/ludic.minimap/grid.ludic

92 lines
4.3 KiB
Text

# grid.ludic - the explored grid: square cells round the origin, and the part of it "explored" is
# measured over (a core, so a bigger grid does not change what a share of it means)
export state MinimapState {
mm_seen_buf: pointer = null # minimap_seen_text's bytes, kept and written again on every save
mm_seen_cap: int = 0
mm_none: MinimapPin = new MinimapPin # minimap_pin past the end: an empty mark, the same one each time
mm_near: []int = new []int # minimap_pins_near's answer, cleared and refilled: a compass asks every frame
mm_land_n: int = 0 # land cells in the core, counted once per origin
mm_land_ox: float = 0.0
mm_land_oz: float = 0.0
mm_cells: int = 128 # per side
mm_cell_m: float = 100.0 # metres per cell
mm_core0: int = 0 # the measured square: from this cell, this many per side
mm_core_n: int = 128
mm_seen: []int = null # 0 / 1 per cell, row by row
mm_version: int = 0 # goes up whenever a cell is revealed or the grid is replaced
mm_pins: []MinimapPin = null
mm_pin_max: int = 32
mm_symbols: int = 8
mm_colours: int = 5
mm_open: int = -1
mm_followed: int = -1
mm_last: int = 0
mm_placing: bool = false
mm_x0: float = 0.0
mm_y0: float = 0.0
mm_size: float = 512.0
mm_span: float = 6400.0
mm_zoom_min: float = 0.5
mm_zoom_max: float = 8.0
mm_zoom_focus: float = 4.0
mm_zoom: float = 1.0
mm_vx: float = 0.0
mm_vz: float = 0.0
mm_have_view: bool = false
mm_panning: bool = false
mm_drag_rx: float = 0.0
mm_drag_ry: float = 0.0
mm_drag_vx: float = 0.0
mm_drag_vz: float = 0.0
}
# the grid: `cells` per side of `cell_m` metres, centred on MinimapWorld's origin; the whole of it
# is measured until minimap_config_core says otherwise
export function minimap_config(minimap_st: mut MinimapState, cells: int, cell_m: float) -> void {
minimap_st.mm_cells = Math.max(cells, 1)
minimap_st.mm_cell_m = Math.max(cell_m, 0.001)
minimap_st.mm_core0 = 0
minimap_st.mm_core_n = minimap_st.mm_cells
@alloc_ok("once per map configured: its explored grid")
minimap_st.mm_seen = new []int
@alloc_ok("once per map configured: as above")
for i in 0 .. minimap_st.mm_cells * minimap_st.mm_cells { push(minimap_st.mm_seen, 0) }
minimap_st.mm_land_n = 0
minimap_st.mm_version += 1
}
export function minimap_config_core(minimap_st: mut MinimapState, from: int, n: int) -> void {
minimap_st.mm_core0 = Math.clamp(from, 0, minimap_st.mm_cells - 1)
minimap_st.mm_core_n = Math.clamp(n, 1, minimap_st.mm_cells - minimap_st.mm_core0)
minimap_st.mm_land_n = 0
}
export function minimap_cells(minimap_st: MinimapState) -> int { return minimap_st.mm_cells }
export function minimap_cell_m(minimap_st: MinimapState) -> float { return minimap_st.mm_cell_m }
export function minimap_grid_half(minimap_st: MinimapState) -> float { return float(minimap_st.mm_cells) * minimap_st.mm_cell_m * 0.5 }
# the grid's west and north edges, and a column's or a row's
export function minimap_grid_x0(minimap_st: MinimapState) -> float { return MinimapWorld.origin_x() - minimap_grid_half(minimap_st) }
export function minimap_grid_z0(minimap_st: MinimapState) -> float { return MinimapWorld.origin_z() - minimap_grid_half(minimap_st) }
export function minimap_cell_x(minimap_st: MinimapState, i: int) -> float { return minimap_grid_x0(minimap_st) + float(i) * minimap_st.mm_cell_m }
export function minimap_cell_z(minimap_st: MinimapState, j: int) -> float { return minimap_grid_z0(minimap_st) + float(j) * minimap_st.mm_cell_m }
# the cell a point is in, -1 off the grid
export function minimap_cell(minimap_st: MinimapState, x: float, z: float) -> int {
let i = int(Math.floor((x - minimap_grid_x0(minimap_st)) / minimap_st.mm_cell_m))
let j = int(Math.floor((z - minimap_grid_z0(minimap_st)) / minimap_st.mm_cell_m))
if i < 0 or j < 0 or i >= minimap_st.mm_cells or j >= minimap_st.mm_cells { return -1 }
return j * minimap_st.mm_cells + i
}
function mm_grid(minimap_st: mut MinimapState) -> void { if minimap_st.mm_seen == null { minimap_config(minimap_st, minimap_st.mm_cells, minimap_st.mm_cell_m) } }
@alloc_ok("once per grid size: the save's bytes, kept")
function mm_seen_buf_make(minimap_st: mut MinimapState, cap: int) -> void {
let old = minimap_st.mm_seen_buf
unsafe {
if old != null { free(old) }
minimap_st.mm_seen_buf = bytes(cap)
}
minimap_st.mm_seen_cap = cap
}