# Настройка idle актера human

## Основные принципы

Список FSM-состояний, из которых возможен запуск idle-анимаций:

* `board` - актер прилинкован к другому объекту;
* `lie_idle` - лежит;
* `snipe` - выглядывает из-за забора;
* `squat` - сидит;
* `idle` - стоит и ничем не занят.

Выбор idle-анимации происходит в два этапа:

{% stepper %}
{% step %}
**Выбор запроса для Селектора анимаций**

Логика выбора запроса описана в файле  **Селектора запроса** `\properties\animation_selector\`**`human_idle_selector.set`.**

{% hint style="info" %}
Опционально на данном этапе можно:

* &#x20;переключать состояние и/или задавать время блокировки [семафоров](#semafory) ;
* устанавливать новое FSM-состояние.
  {% endhint %}
  {% endstep %}

{% step %}
**Выбор idle-анимаций**&#x20;

По выбранному на первом шаге запросу выбираются конкретные idle-анимации.\
Логика выбора описана в файле  **`human_idle.inc`,** который является частью файла **Селектора анимаций** `\properties\animation_selector\`**`human.set`**
{% endstep %}
{% endstepper %}

Для создания цепочек переключения idle-состояний в FSM хранится текущее **idle-**&#x441;остояние актер&#x430;**.**

## Конфигурация Селектора idle-запроса

> **Синтаксис `human_idle_selector.set`**
>
> ```
> {init
> 	{state "<initial_state>"} ; обязательный параметр
> 	{semaphore "<name>" <time_from> <time_to>} 
> }
> {selector
> 	{if <condition>
> 		{idle
> 			{run "<request_name>"} ; имя запроса к Animation Selector
> 			{state "<new_state>"} ; при необходимости изменить состояние FSM
> 			{semaphore "<name>" <time_from> <time_to>} ; переопределение семафора
> 		}
> 	}
> 	[...]	
> 	{idle
> 		{run ""} ;запуск пустого запроса
> 	}
> }
> ```

<table><thead><tr><th width="228.0390625">Компонент</th><th>Описание</th></tr></thead><tbody><tr><td><code>{init ...}</code></td><td>Блок инициализации, вызывается при старте игры или спавне юнита. <br>Задаёт начальное состояние FSM (<code>state</code>) и устанавливает блокировки семафоров (<code>semaphore</code>).</td></tr><tr><td><code>state "&#x3C;initial_state>"</code></td><td>Устанавливает FSM-состояние актера сразу после его спавна. Обязательный параметр.<br>Пример: <code>"idle"</code>.</td></tr><tr><td><code>semaphore "&#x3C;name>" &#x3C;time_from> &#x3C;time_to></code></td><td>Блокирует или разблокирует <a href="#semafory">семафор</a> на указанное время (в секундах). Например, <code>semaphore "can_smoke" 10 30</code> означает запрет курения на случайный срок от 10 до 30 сек.</td></tr><tr><td><code>{selector ...}</code></td><td>Основной блок, в котором происходит логика выбора запросов к <strong>Селектору анимаций</strong> в зависимости от текущего состояния FSM и условий.</td></tr><tr><td><code>{if &#x3C;condition> ...}</code></td><td>Условная конструкция. <br>Проверяет состояние FSM (<code>fsm_tags</code>, <code>human_fsm_idle_state</code>), активность семафоров (<code>human_fsm_idle_semaphore</code>), наличие взаимодействия актера с предметами (например, <code>human_stuff holding</code>) и другие параметры. <br><a href="#usloviya">Подробнее про синтаксис условий </a></td></tr><tr><td><code>{idle ...}</code></td><td>Блок для описания набора действий, исполняемых, если соответствующее условие выполнилось. <br>Внутри блока  задается команда <code>run</code> запуска запроса для Селектора анимаций.  <br>Опционально может задаваться смена состояния (<code>state</code>) и семафоров (<code>semaphore</code>).</td></tr><tr><td><code>run "&#x3C;request_name>"</code></td><td>Команда активирует указанный запрос, который в дальнейшем используется в Селекторе анимаций (<code>animation_selector/human.set</code>). <br>Пример: <code>run "stand_smoking_begin"</code>.<br>По имени запроса будет подобран соответствующий набор анимаций. <br>Отсутствие указанного имени в команде означает запуск  пустого запроса. При этом сохраняется текущая анимация актера.</td></tr></tbody></table>

{% hint style="warning" %}
В случае выбора пустого запроса актер стоит неподвижно некоторое время, после чего выбор запроса стартует заново.
{% endhint %}

### Cостояния idle

В игре **Men of War II** используются два idle-состояния:

* `idle` - играет обычные idle анимации;
* `smoking` - играет анимации курения.

{% hint style="danger" %}
Чтобы добавить возможность выбора idle анимаций в состоянии, где его раньше никогда не было, необходимо добавить в коде состояния поддержку idle .&#x20;
{% endhint %}

### Семафоры в Селекторе idle-запросов

Семафоры применяются для управления частотой и условиями запуска определённых запросов. Они служат для задания временных ограничений, предотвращающих синхронное анимирование группы юнитов.

> **Синтаксис семафора**
>
> ```
> {semaphore "<semaphore_name>" N}
> ```
>
> `N` - время блокировки семафора, в секундах.

Семафор может быть в 2-х состояниях:

* разрешен - `N=0`;
* заблокирован на указанное в `N` время.

{% hint style="success" %}
&#x20;Рекомендуется указывать два числа для времени блокировки семаформа, чтобы создать рандомные задержки между переключениями в разные состояния для имитации естественного поведения юнита.
{% endhint %}

{% hint style="info" %}
Добавлять новые семафоры можно в блоке `init`
{% endhint %}

<details>

<summary>Семафоры idle-запросов, используемые в игре <strong>Men of War II</strong></summary>

<table><thead><tr><th width="161.4921875">Имя семафора</th><th>Описание</th></tr></thead><tbody><tr><td><code>can_smoke</code></td><td>Отвечает за доступность начала цикла курения. Пока семафор заблокирован, юнит не может вызвать запрос на начало курения (<code>stand_smoking_begin</code>). Блокируется после каждой сигареты, разблокируется через случайное время (например, 5–10 или 60–120 секунд).</td></tr><tr><td><code>can_inhale</code></td><td>Контролирует интервал между затяжками в процессе курения. <br>Используется внутри состояния <code>smoking</code> для определения, когда можно вызвать запрос <code>stand_smoking_process</code>. После каждой затяжки блокируется на несколько секунд.</td></tr><tr><td><code>can_action</code></td><td><p>Разрешает проигрывание активных <code>idle</code>-действий (почёсывание, переминание и т. п.). </p><p>Пока семафор заблокирован, юнит будет воспроизводить только нейтральные <code>idle</code>, такие как <code>stand_breath</code>, <code>squat_breath</code>, <code>lie_breath</code>. Блокировка регулирует частоту смены анимаций.</p></td></tr><tr><td><code>stop_smoking</code></td><td>Семафор, ограничивающий возможность завершения курения. Когда активен, запрос <code>stand_smoking_end</code> не будет выполнен. Используется для задания минимального времени нахождения в состоянии <code>smoking</code>, чтобы курение выглядело реалистично.</td></tr></tbody></table>

</details>

<details>

<summary>Пример использования семафоров в Селекторе idle-запросов</summary>

```
{init
	{state "idle"}
	{semaphore "can_smoke" 10 30} ; don't smoke right away
	{semaphore "can_inhale" 3 5}
	{semaphore "can_action" 5 15} ; start from breathing
}
{selector
	[...]
	{idle
		{run "stand_smoking_begin"} ; animations request string from human_idle.inc
		{state "smoking"} ; set new state
		{semaphore "stop_smoking" 20 40} ; disable semaphore for seconds in range
		{semaphore "can_inhale" 3 5} 
	}
	[...]
}
```

**Пояснения**

**Блок `init`**

* `{state "idle"}`\
  Устанавливает стартовое состояние FSM юнита после спауна — `idle` (покой).
* `{semaphore "can_smoke" 10 30}`\
  Блокирует возможность начать курение сразу. Юнит сможет курить только через 10–30 секунд.&#x20;
* `{semaphore "can_inhale" 3 5}`\
  Устанавливает интервал перед первой возможной затяжкой. Имеет значение, если юнит начнёт курить вскоре после появления.
* `{semaphore "can_action" 5 15}`\
  Задаёт паузу перед тем, как юнит сможет выполнять более активные idle-анимации, чем дыхание. Пока семафор заблокирован — проигрываются только idle-анимации дыхания.

**Блок idle**

* `{run "stand_smoking_begin"}`\
  Запускается запрос с именем `stand_smoking_begin`. Этот запрос будет передан в `animation_selector/human.set`, где будет выбран подходящий набор анимаций начала курения.
* `{state "smoking"}`\
  FSM-состояние юнита обновляется на `"smoking"` — это влияет на дальнейший выбор запросов и условий.
* `{semaphore "stop_smoking" 20 40}`\
  Устанавливает блокировку семафора `stop_smoking` на 20–40 секунд. Пока он активен, юнит не сможет завершить курение (вызов `stand_smoking_end` не сработает).
* `{semaphore "can_inhale" 3 5}`\
  Устанавливает паузу перед следующей затяжкой (например, для запуска `stand_smoking_process` в следующем цикле).

</details>

### Условия

Составные условия в **Селекторе idle-запроса** записываются с помощью логических операторов `and` , `or`  и `not`

Условия, которые используются  в первую очередь:

* {if human\_fsm\_idle\_semaphore "can\_smoke"
* {if human\_fsm\_idle\_state "smoking\_begin"
* {if fsm\_tags "board"

<details>

<summary>Примеры условий в <strong>Селекторе idle-запроса (</strong> <code>human_idle_selector.set)</code></summary>

<table><thead><tr><th width="349.80859375">Условие</th><th>Значение</th></tr></thead><tbody><tr><td><code>fsm_tags "board"</code></td><td>Проверка, есть ли у FSM-состояния тэг <code>"board"</code>.</td></tr><tr><td><code>human_fsm_counter "forced_smoke" once</code></td><td>Проверка счетчика FSM <code>"forced_smoke"</code>.<br><a href="/pages/wZsGv2KVqKOWehZQ6D2N#usloviya-proverki-fsm-schyotchikov">Подробнее про проверку счетчиков</a></td></tr><tr><td><code>human_stuff holding "nothing"</code></td><td>Проверка, что у актера в руках ничего нет.</td></tr><tr><td><code>human_fsm_idle_state "idle"</code></td><td>Проверка текущего FSM -состояния при простое.</td></tr><tr><td><code>human_fsm_idle_semaphore "can_smoke"</code></td><td>Проверка, разрешен ли указанный семафор.</td></tr><tr><td><code>able "attention"</code></td><td>Проверка доступности способности <code>attention</code>.</td></tr><tr><td><code>not able "attention"</code></td><td>Обратная проверка — <code>attention</code> недоступен.</td></tr></tbody></table>

</details>

<details>

<summary>Пример вложенного составного условия в Селекторе idle-запросов</summary>

```
{if fsm_tags "up" 
    {if human_fsm_counter "forced_smoke" once and human_stuff holding "nothing" and human_fsm_idle_state "idle"
        {idle [...]}
    }
}
```

Используется **двойное вложенное условие**, где каждая часть должна быть выполнена, чтобы сработал соответствующий блок `idle`.&#x20;

**Проверка первого уровня:**\
`{if fsm_tags "up"}`\
Этот блок обрабатывается только если FSM-состояние юнита помечено тегом `"up"` — например, стоит, находится вне укрытия и готов к действиям.

**Проверка второго уровня:**

Все три условия должны быть выполнены:

1. **`human_fsm_counter "forced_smoke" once`**\
   Проверяет значение счётчика `forced_smoke`:

   * если `> 0`, возвращает `true` и **сбрасывает** счётчик в `0`;
   * если `0`, возвращает `false`.

   Это механизм **одноразового принудительного действия** — использовать и обнулить.
2. **`human_stuff holding "nothing"`**\
   Проверяет, что в руках у юнита **ничего нет** (ни оружия, ни предметов).

   Если юнит держит что-то, то условие не выполнится.
3. **`human_fsm_idle_state "idle"`**\
   Проверяет, что текущее внутреннее состояние FSM в блоке idle — `"idle"`.

   Это исключает конфликты с другими процессами (например, если юнит уже курит, то не запускать запрос повторно)

</details>

### Варианты запроса для выбора idle-анимаций&#x20;

Варианты имен запросов для команды `run` приведены в таблице ниже.

{% hint style="info" %}
*Для запросов **\*\_idle**  предполагается какая-то серьёзная активность* \
*Для запросов **\*\_breath** - ожидаются анимации дыхания или небольшого шевеления*<br>
{% endhint %}

<table><thead><tr><th width="245.48046875">Запрос</th><th>Описание</th></tr></thead><tbody><tr><td><p><code>stand_idle</code></p><p><code>stand_breath</code></p></td><td>Стоит </td></tr><tr><td><p><code>squat_idle</code></p><p><code>squat_breath</code></p></td><td>Сидит</td></tr><tr><td><code>snipe_breath</code></td><td>Смотрит из-за горизонтального укрытия (окопы, заборы по пояс)</td></tr><tr><td><code>lie_idle</code><br><code>lie_breath</code></td><td>Лежит</td></tr><tr><td><code>stand_smoking_begin</code></td><td>Поджигает сигарету</td></tr><tr><td><code>stand_smoking_process</code></td><td>Делает затяжку</td></tr><tr><td><code>stand_smoking_end</code></td><td>Тушит сигарету</td></tr></tbody></table>

{% hint style="info" %}
Можно добавлять свои запросы на анимации и прописывать соответствующую выборку анимаций в файле `human_idle.inc`.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bestway-1.gitbook.io/documentation/gem-rts-v1-ru/animacii/anymatsyonnaia_systema_yunytov/animation_selector/nastroika-idle.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
