
# Rotation

## `rotation`

While a managed rotation runs, the camera stays where it is and only the server-visible facing
turns. Requests share the same arbitration as the client's own modules.

| Function | Does |
|----------|------|
| `rotation.set(yaw, pitch[, priority])` | Requests a rotation, `true` when accepted |
| `rotation.look_at(pos[, priority])` | Faces a [vec3](vec3.md), measured from your eyes |
| `rotation.camera()` | Requests where the camera looks, at priority 100. Does nothing unless freelook is active |
| `rotation.active()` | `true` while a managed rotation runs |
| `rotation.lock_item_use()` | Blocks new rotations until the end of the tick |

A request lasts one tick, so keep requesting every tick to keep facing a direction, usually
from `pre_interaction` or `tick`. A request below the active priority is rejected.

```lua
module:event("pre_interaction", function()
    local target = world:player("Notch")
    if target then
        rotation.look_at(target:position() + vec3(0, target:height() / 2, 0), 10)
    end
end)
```

Every accepted rotation also fires the [`rotation` event](events.md#movement), where you can
adjust or cancel it.

## `freelook`

Detaches the camera from the facing. The rotation service turns it on by itself while aiming.

| Function | Does |
|----------|------|
| `freelook.active()` | `true` while freelook is on |
| `freelook.activate()`, `freelook.deactivate()` | Turns it on or off |
| `freelook.lock()`, `freelook.unlock()` | Freezes or unfreezes the camera |
| `freelook.locked()` | `true` while the camera is frozen |
| `freelook.yaw()`, `freelook.pitch()` | Current camera angles |

```lua
module:event("enable", function()
    freelook.activate()
    freelook.lock()
end)

module:event("disable", function()
    freelook.unlock()
    freelook.deactivate()
end)
```
