# `QuakeServer.Pmove`
[🔗](https://github.com/jaman/quake_server/blob/v0.1.0/lib/quake_server/pmove.ex#L1)

FTE's QuakeWorld player movement (`PM_PlayerMove`): one command of a player's input
moving a box through the world and the entities near it.

    pm = QuakeServer.Pmove.player_move(pm)

The caller fills a `QuakeServer.Pmove` with the player's state, the command
(`QuakeServer.Pmove.Command`), the movement settings (`QuakeServer.Pmove.Movevars`)
and the things it can meet (`physents`, a tuple of `QuakeServer.Pmove.Physent`, the
world first), and reads the state back.

  * `pm_type` — `:normal`, `:dead` (no acceleration, no jumping), `:fly` (flying,
    bumping into walls), `:none` and `:freeze` (no movement), `:spectator` and
    `:old_spectator` (flying through everything; the old one stops moving while at
    speed), `:wallwalk` (the wall under the player is the ground) or `:six_dof`
  * `gravitydir` — the way down; a zero vector is taken as `{0, 0, -1}`
  * `onground`, `groundent` (an index into `physents`) and `groundplane` (its normal) —
    what the player stands on
  * `waterlevel` 0 to 3 and `watertype`, the contents bits (`QuakeServer.Contents`) at
    the player's feet
  * `onladder` — set on reaching a ladder; only the caller clears it
  * `jump_held`, `jump_msec`, `waterjumptime` — the jump button's state and the seconds
    left of a jump out of water
  * `safeorigin` — the last spot the player was found to fit, where a stuck player is
    returned when `safeorigin_known`
  * `touched` — indexes into `physents` of what the move ran into, newest first

# `pm_type`

```elixir
@type pm_type() ::
  :normal
  | :old_spectator
  | :spectator
  | :dead
  | :fly
  | :none
  | :freeze
  | :wallwalk
  | :six_dof
```

# `t`

```elixir
@type t() :: %QuakeServer.Pmove{
  angles: Cauldron3D.Vec.t(),
  cmd: QuakeServer.Pmove.Command.t(),
  forward: Cauldron3D.Vec.t(),
  frametime: float(),
  gravitydir: Cauldron3D.Vec.t(),
  groundent: non_neg_integer() | nil,
  groundplane: Cauldron3D.Vec.t(),
  jump_held: boolean(),
  jump_msec: integer(),
  maxs: Cauldron3D.Vec.t(),
  mins: Cauldron3D.Vec.t(),
  movevars: QuakeServer.Pmove.Movevars.t(),
  onground: boolean(),
  onladder: boolean(),
  origin: Cauldron3D.Vec.t(),
  physents: tuple(),
  pm_type: pm_type(),
  right: Cauldron3D.Vec.t(),
  safeorigin: Cauldron3D.Vec.t(),
  safeorigin_known: boolean(),
  server: QuakeServer.Server.t(),
  touched: [non_neg_integer()],
  up: Cauldron3D.Vec.t(),
  velocity: Cauldron3D.Vec.t(),
  waterjumptime: float(),
  waterlevel: 0..3,
  watertype: non_neg_integer()
}
```

# `player_move`

```elixir
@spec player_move(t()) :: t()
```

Move the player for its command (`PM_PlayerMove`); `touched` starts empty.

---

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