/**
 * Игрок (персонаж) — управляется WASD/прыжком в Play.
 * Скрипт может: перемещать, наносить урон/лечить, менять скорость/гравитацию,
 * включать GD-гейммоды, проигрывать эмоции, проверять состояние.
 *
 * Пример:
 *   game.player.teleport(0, 10, 0);
 *   game.player.setSpeed(0.5);            // в 2 раза медленнее
 *   if (!game.player.alive) { game.player.respawn(); }
 */
declare namespace game.player {
    // ── Позиция и поворот ──────────────────────────────────────────────

    /** Текущая позиция «низа ног» игрока (read-only — менять через teleport). */
    const position: game.Vector3;

    /**
     * Угол поворота игрока вокруг Y (в радианах).
     * 0 = смотрит в +Z, π/2 = +X, π = -Z, -π/2 = -X.
     */
    const yaw: number;

    /** Наклон вверх/вниз (в радианах). >0 = вверх. */
    const pitch: number;

    /**
     * Нормализованный вектор направления взгляда — куда смотрит игрок.
     * Удобно для спавна объектов «перед собой»:
     * @example
     * const f = game.player.forward;
     * const p = game.player.position;
     * game.scene.spawn('primitive:cube', {
     *     x: p.x + f.x * 3,
     *     y: p.y,
     *     z: p.z + f.z * 3,
     * });
     */
    const forward: game.Vector3;

    /**
     * Мгновенно переместить игрока в указанную точку.
     * @example
     * game.player.teleport(0, 5, 10);
     */
    function teleport(x: number, y: number, z: number): void;

    /**
     * Сдвинуть игрока ТОЛЬКО по X (не трогая Y/Z). Для раннеров — смена полосы.
     * @example game.player.setLaneX(-2);
     */
    function setLaneX(x: number): void;

    /** Развернуть модель игрока на угол yaw (радианы). 0 = лицом в +Z. */
    function setFacing(yaw: number): void;

    // ── Здоровье ───────────────────────────────────────────────────────

    /** Текущее HP игрока. */
    const hp: number;

    /** Максимальное HP. */
    const maxHp: number;

    /** Жив ли игрок (hp > 0). */
    const alive: boolean;

    /**
     * Состояние игрока: 'ground' (на земле), 'air' (в воздухе/прыжке), 'water'.
     * @example
     * game.onTick(() => {
     *     if (game.player.state === 'air') game.ui.showText('Лечу!', 0.2);
     * });
     */
    const state: game.PlayerState;

    /**
     * Нанести урон игроку. Учитываются i-frames (повтор в течение ~0.5с игнорится).
     * @example game.player.damage(10);
     */
    function damage(amount: number): void;

    /** Мгновенно убить игрока (игнорит i-frames). */
    function kill(): void;

    /** Восстановить здоровье. */
    function heal(amount: number): void;

    /** Вернуть игрока на spawn-point с полным HP. */
    function respawn(): void;

    /**
     * Назначить активный спавн (один из чек-поинтов сцены).
     * @param target ref чек-поинта или имя.
     */
    function setSpawn(target: game.Ref | string): void;

    // ── Движение и физика ──────────────────────────────────────────────

    /**
     * Множитель скорости. 1 = норма, 2 = в 2 раза быстрее, 0.5 = вдвое медленнее.
     * Действует пока не вызван `setSpeed(1)`.
     * @example
     * game.player.setSpeed(0.3); // замедление в болоте
     */
    function setSpeed(mul: number): void;

    /** Множитель силы прыжка. 1 = норма, 2 = в 2 раза выше. */
    function setJumpPower(mul: number): void;

    /**
     * Множитель гравитации. 1 = норма (-22 м/с²), 1.23 = GD-стиль (-27 м/с²).
     * Работает в обоих направлениях gravityDir.
     */
    function setGravityMul(mul: number): void;

    /** Явно установить направление гравитации: 1 = вниз (норма), -1 = вверх. */
    function setGravityDir(dir: 1 | -1): void;

    /**
     * Перевернуть гравитацию (как gravity portal в GD).
     * После flipGravity игрок прыгает к потолку. Повторный вызов возвращает.
     * Доступно только в sideview-режиме.
     */
    function flipGravity(): void;

    /**
     * Задать вертикальную скорость (м/с). +значение = вверх, - = вниз.
     * Используется для трамплинов (vy=16), jump orb (vy=14), boost-зон.
     */
    function setVy(vy: number): void;

    /**
     * Мгновенный подброс игрока вверх. strength=1 = обычный прыжок, strength=2 = в 2 раза выше.
     * Не требует Space — срабатывает сразу. Для трамплинов.
     */
    function boostJump(strength: number): void;

    /** Скользкость поверхности под игроком. 0 = норма, 0.85 = лёд, 1 = бесконечная инерция. */
    function setIceFriction(value: number): void;

    /** Двойной прыжок: true = разрешён, false = выключен. */
    function setDoubleJump(enabled: boolean): void;

    /** Текущее направление гравитации (+1 вниз, -1 вверх). */
    const gravityDir: 1 | -1;

    // ── Состояние клавиш и ввод ────────────────────────────────────────

    /**
     * Проверить зажата ли клавиша ПРЯМО СЕЙЧАС (для плавного движения по удержанию).
     * @param key 'w', 'a', 's', 'd', 'space', 'shift', 'arrowup' (lowercase)
     * @example
     * game.onTick(() => {
     *     if (game.player.isKeyDown('w')) game.ui.set('move', 'идёт вперёд');
     * });
     */
    function isKeyDown(key: string): boolean;

    // ── GD-гейммоды ────────────────────────────────────────────────────

    /**
     * GD-гейммод Ship: тап-удержание Space = подъём (как вертолёт).
     * Обычный прыжок отключается.
     */
    function setShipMode(enabled: boolean): void;

    /** GD-гейммод UFO: каждый тап Space = микропрыжок в воздухе (даже без касания земли). */
    function setUfoMode(enabled: boolean): void;

    /** GD-гейммод Wave: движение под ±45°. Space зажат → вверх, отпущен → вниз. */
    function setWaveMode(enabled: boolean): void;

    /** GD-гейммод Robot: высота прыжка зависит от длительности удержания Space. */
    function setRobotMode(enabled: boolean): void;

    /**
     * Кубикон Dash: авто-бег по +X со скоростью speed (м/с). 0 — отключить.
     * Работает только в sideview-камере.
     */
    function setAutoRun(speed: number): void;

    // ── Камера ─────────────────────────────────────────────────────────

    /**
     * Режим камеры: 'first' (от первого лица), 'third' (от третьего),
     * 'front' (вид спереди), 'sideview' (вид сбоку, для GD).
     */
    function setCameraMode(mode: game.CameraMode): void;

    // ── Прицел ─────────────────────────────────────────────────────────

    /**
     * Прицел в Play. Чтение — текущий тип, запись — меняет:
     * @example game.player.crosshair = 'cross';
     */
    let crosshair: game.Crosshair;

    // ── Анимации и эмоции ──────────────────────────────────────────────

    /**
     * Проиграть эмоцию-анимацию персонажа один раз.
     * @param name 'wave' (помахать) | 'dance' | 'cheer' (радость) | 'sit' | 'paint'
     * @example game.onKey('e', () => game.player.playAnimation('wave'));
     */
    function playAnimation(name: 'wave' | 'dance' | 'cheer' | 'sit' | 'paint' | string): void;

    /** Прервать текущую эмоцию персонажа. */
    function stopAnimation(): void;

    /** Алиас playAnimation — короче. */
    function playEmote(name: string): void;
    function stopEmote(): void;

    // ── Внешний вид ────────────────────────────────────────────────────

    /** Показать/скрыть скин персонажа. */
    function setSkinVisible(visible: boolean): void;

    // ── Команда (Teams) ────────────────────────────────────────────────

    /** Назначить игрока в команду по имени. */
    function setTeam(teamName: string): void;

    /** Текущая команда игрока (или null). */
    const team: string | null;

    // ── Инвентарь / Tool ───────────────────────────────────────────────

    /**
     * Выдать игроку предмет в руки/хотбар.
     * Принимает строку (id готовой модели типа 'weapon-sword') или Tool из
     * game.tools.create() (кастомный tool со своим onActivated).
     */
    function giveTool(toolType: string | game.Tool, opts?: { equip?: boolean }): void;

    /** Убрать предмет из инвентаря игрока. */
    function removeTool(toolType: string): void;

    /**
     * Подписаться на использование предмета (нажатие ЛКМ когда tool в руках).
     * @example
     * game.player.onToolUse(({ tool }) => game.log('применил:', tool));
     */
    function onToolUse(fn: (event: { tool: string }) => void): void;
}
