# view.ludic - the window onto the map: a square of `size` pixels at (x0, y0) showing `span` metres # across at zoom 1, centred on a world point. World to window and back, and a scale bar's length. var mm_x0: float = 0.0 var mm_y0: float = 0.0 var mm_size: float = 512.0 var mm_span: float = 6400.0 var mm_zoom_min: float = 0.5 var mm_zoom_max: float = 8.0 var mm_zoom_focus: float = 4.0 var mm_zoom: float = 1.0 var mm_vx: float = 0.0 var mm_vz: float = 0.0 var mm_have_view: bool = false # metres across the window at zoom 1, the zoom's range, and how close a focus goes at least export function minimap_config_view(span: float, zoom_min: float, zoom_max: float, focus: float) -> void { mm_span = Math.max(span, 1.0) mm_zoom_min = zoom_min mm_zoom_max = Math.max(zoom_max, zoom_min) mm_zoom_focus = focus mm_zoom = Math.clamp(1.0, mm_zoom_min, mm_zoom_max) mm_have_view = false } # where the window is on the screen this frame export function minimap_window(x0: float, y0: float, size: float) -> void { mm_x0 = x0 mm_y0 = y0 mm_size = Math.max(size, 1.0) } export function minimap_size() -> float { return mm_size } export function minimap_zoom() -> float { return mm_zoom } export function minimap_view_x() -> float { return mm_vx } export function minimap_view_z() -> float { return mm_vz } export function minimap_have_view() -> bool { return mm_have_view } # the metres the window shows across at the zoom export function minimap_span() -> float { return mm_span / mm_zoom } # pixels per metre export function minimap_scale() -> float { return mm_size / minimap_span() } # a world point on the screen export function minimap_px(x: float) -> float { return mm_x0 + mm_size * 0.5 + (x - mm_vx) * minimap_scale() } export function minimap_py(z: float) -> float { return mm_y0 + mm_size * 0.5 + (z - mm_vz) * minimap_scale() } # the world under a point of the window (pixels from its corner) export function minimap_wx(rx: float) -> float { return mm_vx + (rx - mm_size * 0.5) / minimap_scale() } export function minimap_wz(ry: float) -> float { return mm_vz + (ry - mm_size * 0.5) / minimap_scale() } # a round distance whose bar is no wider than a quarter of the window export function minimap_scale_metres() -> int { let steps = [2000, 1000, 500, 250, 100, 50, 25] for k in 0 .. len(steps) { if float(steps[k]) * minimap_scale() <= mm_size / 4.0 { return steps[k] } } return 25 } # the view's centre is kept where MinimapWorld allows, so the land can reach the edge but not leave export function minimap_clamp() -> void { mm_vx = Math.clamp(mm_vx, MinimapWorld.lo_x(), MinimapWorld.hi_x()) mm_vz = Math.clamp(mm_vz, MinimapWorld.lo_z(), MinimapWorld.hi_z()) } export function minimap_centre(x: float, z: float) -> void { mm_vx = x mm_vz = z mm_have_view = true minimap_clamp() } # the view on the camp, or on you export function minimap_recentre(on_you: bool) -> void { if on_you { minimap_centre(MinimapWorld.you_x(), MinimapWorld.you_z()) } else { minimap_centre(MinimapWorld.camp_x(), MinimapWorld.camp_z()) } } # go there AND close in; never out, since a player already closer asked for that export function minimap_focus(on_you: bool) -> void { minimap_recentre(on_you) if mm_zoom < mm_zoom_focus { mm_zoom = Math.clamp(mm_zoom_focus, mm_zoom_min, mm_zoom_max) } }