Cauldron2D.Map (Cauldron2D v0.1.3)

Copy Markdown View Source

A tile map written as text: a grid of characters, one per tile, with optional name: value options ahead of it.

Two layouts are read:

  • a bare picture — every line is a row:

    ####
    #..#
    ####
  • the header format of XPilot's map files — options, then the grid between the multiline markers:

    mapwidth: 6
    mapheight: 3
    edgewrap: yes
    mapData: \multiline: EndOfMapdata
    xxxxxx
    x _  x
    xxxxxx
    EndOfMapdata

The engine attaches no meaning to any character, and to no option but the two that size the grid (mapwidth, mapheight) and the one parse/2 is told wraps it. A game supplies a legend to cells/2 and reads the options it honours with option/4. Option names are matched without regard to case.

A map wraps when the option named by :wrap is true: at/2 outside the grid then reads the tile on the opposite side, and otherwise reads a space.

Summary

Functions

The character at {x, y}; a space outside the grid, or the wrapped tile when the map wraps.

Every tile the legend gives a value for, as %{{x, y} => value}.

An option converted to type, or default when absent or not of that type.

Parse map text.

Read and parse a file, with parse/2's options; a .gz file is decompressed first.

Where char occurs, row by row then left to right.

Types

point()

@type point() :: {integer(), integer()}

t()

@type t() :: %Cauldron2D.Map{
  height: pos_integer(),
  options: %{required(String.t()) => String.t()},
  rows: tuple(),
  width: pos_integer(),
  wrap?: boolean()
}

Functions

at(map, arg2)

@spec at(t(), point()) :: String.t()

The character at {x, y}; a space outside the grid, or the wrapped tile when the map wraps.

cells(map, legend)

@spec cells(t(), (String.t() -> term())) :: %{required(point()) => term()}

Every tile the legend gives a value for, as %{{x, y} => value}.

legend is called with each character; a nil return leaves that tile out.

option(map, name, type, default)

@spec option(t(), String.t(), :string | :integer | :float | :boolean, term()) ::
  term()

An option converted to type, or default when absent or not of that type.

type is :string, :integer, :float or :boolean. Booleans read yes, true, on and 1 as true and no, false, off and 0 as false.

parse(text, opts \\ [])

@spec parse(String.t(), keyword()) :: {:ok, t()} | {:error, term()}

Parse map text.

Returns {:ok, map}, or {:error, :empty} for no rows at all. A multiline block with no closing marker runs to the end of the text; a row wider than mapwidth is cut to it and a shorter one padded with spaces; rows beyond mapheight are dropped and missing ones are blank.

Options

  • :wrap — the name of the header option that, when true, makes the map wrap ("edgewrap" in XPilot's files). Default: none, the map never wraps

parse_file(path, opts \\ [])

@spec parse_file(Path.t(), keyword()) :: {:ok, t()} | {:error, term()}

Read and parse a file, with parse/2's options; a .gz file is decompressed first.

positions(map, char)

@spec positions(t(), String.t()) :: [point()]

Where char occurs, row by row then left to right.