# `Cauldron2D.Sectors.Map`
[🔗](https://github.com/jaman/cauldron/blob/v0.2.2/cauldron_2d/lib/cauldron_2d/sectors/map.ex#L1)

A level made of sectors: rooms of any shape, each with its own floor and ceiling height,
joined and walled by lines, the geometry a sector view and sector movement read.

    map = %Cauldron2D.Sectors.Map{
      vertices: {{0.0, 0.0}, {256.0, 0.0}, ...},
      lines: {%{from: 0, to: 1, front: 0, back: nil, flags: MapSet.new(), special: 0, tag: 0}, ...},
      sides: {%{sector: 0, x_offset: 0.0, y_offset: 0.0, upper: nil, middle: 3, lower: nil}, ...},
      sectors: {%{floor: 0.0, ceiling: 128.0, floor_picture: 5, ceiling_picture: 6, light: 160, special: 0, tag: 0}, ...}
    }
    |> Cauldron2D.Sectors.Map.with_bsp()

Everything is addressed by position in its tuple. World units are whatever the game
chooses; `+y` is up the map. A **line** runs `from` vertex `to` vertex; its `front` side
is on its right looking along it, its `back` side (or `nil` for a wall with nothing
behind) on its left. A **side** says which sector it faces and which pictures it shows:
`upper` above a lower ceiling behind it, `lower` below a higher floor behind it,
`middle` across the opening — on a one-sided line, the whole wall. `x_offset` and
`y_offset` shift the side's pictures. A **sector** has `floor` and `ceiling` heights,
their pictures and a `light` of `0..255`; `special` and `tag` are the game's.

A line's `flags` is a set; the engine reads `:blocks` (nothing passes),
`:blocks_walkers` (bodies that walk do not pass), `:blocks_sound`, `:upper_unpegged`
(the upper picture hangs from the ceiling rather than standing on the opening),
`:lower_unpegged` (the lower picture hangs from the ceiling rather than from the
opening's floor, and a middle picture stands on the floor), `:secret` (shown as a plain
wall on the automap), `:hidden` (never on the automap) and `:mapped` (on the automap from
the start). Others are the game's.

`segs`, `subsectors` and `nodes` are the BSP that orders the level for drawing and for
finding a point's sector: built with `with_bsp/2`, or given, as a level file that
carries its own BSP gives it.

# `line`

```elixir
@type line() :: %{
  :from =&gt; non_neg_integer(),
  :to =&gt; non_neg_integer(),
  :front =&gt; non_neg_integer(),
  :back =&gt; non_neg_integer() | nil,
  :flags =&gt; MapSet.t(atom()),
  optional(:special) =&gt; term(),
  optional(:tag) =&gt; term()
}
```

# `point`

```elixir
@type point() :: {float(), float()}
```

# `sector`

```elixir
@type sector() :: %{
  :floor =&gt; number(),
  :ceiling =&gt; number(),
  :floor_picture =&gt; non_neg_integer(),
  :ceiling_picture =&gt; non_neg_integer(),
  :light =&gt; 0..255,
  optional(:special) =&gt; term(),
  optional(:tag) =&gt; term()
}
```

# `seg`

```elixir
@type seg() :: %{
  from: point(),
  to: point(),
  line: non_neg_integer(),
  side: 0 | 1,
  offset: float()
}
```

# `side`

```elixir
@type side() :: %{
  sector: non_neg_integer(),
  x_offset: number(),
  y_offset: number(),
  upper: non_neg_integer() | nil,
  middle: non_neg_integer() | nil,
  lower: non_neg_integer() | nil
}
```

# `t`

```elixir
@type t() :: %Cauldron2D.Sectors.Map{
  blockmap: term(),
  lines: tuple(),
  nodes: tuple() | nil,
  reject: term(),
  sectors: tuple(),
  segs: tuple() | nil,
  sides: tuple(),
  subsectors: tuple() | nil,
  vertices: tuple()
}
```

# `ends`

```elixir
@spec ends(t(), non_neg_integer()) :: {point(), point()}
```

Line `index`'s end points, `{from, to}`.

# `point_side`

```elixir
@spec point_side(point(), {number(), number(), number(), number()}) :: 0 | 1
```

Which side of the line from `{x, y}` along `{dx, dy}` a point is on: `0` on the right,
as a line's front is, `1` on the left. A point on a slanted line counts as the left; on
an upright or level line, as a BSP built for Doom-format levels expects.

# `sector_at`

```elixir
@spec sector_at(t(), point()) :: non_neg_integer()
```

The sector containing `point`, found through the BSP.

# `sector_lines`

```elixir
@spec sector_lines(t(), non_neg_integer()) :: [non_neg_integer()]
```

The lines that touch sector `index`.

# `side_sector`

```elixir
@spec side_sector(t(), non_neg_integer(), 0 | 1, tuple()) :: non_neg_integer() | nil
```

The sector side `side` of line `index` faces, or `nil` for a missing back.

# `subsector_at`

```elixir
@spec subsector_at(t(), point()) :: non_neg_integer()
```

The subsector containing `point`, found through the BSP.

# `vertex`

```elixir
@spec vertex(t(), non_neg_integer()) :: point()
```

The vertex at `index`.

# `with_bsp`

```elixir
@spec with_bsp(t(), keyword()) :: t()
```

The map with a BSP built from its lines by `Cauldron2D.Sectors.Bsp.build/2`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
