# О сайте

Наш ресурс содержит огромное количество уроков по скриптингу GTA San Andreas и GTA IV, полное описание всех часто используемых опкодов, правильные примеры скриптов, базу данных множества возможностей.

Кроме этого на сайте Вы сможете скачать разнообразные файлы для GTA: CLEO скрипты и ASI плагины, модели персонажей и оружия, новые карты, текстурные моды и многое другое.

Мы рады помочь каждому, кто интересуется играми замечательной серии GTA и хочет сделать что-то своё. Приятного времяпрепровождения на сайте!

Этот сайт будет преемником "ru-script.3dn.ru", так как старый сайт набит пропагандой войны в рекламе. Давайте жить дружно и не нападать на своих соседей!

{% hint style="danger" %}
Внимание! В данный момент идёт переоформление уроков! Все материалы уже доступны в разделе "Старые уроки". Вскоре они будут отсортированы по новым разделам.
{% endhint %}


# Проекту помогали

Список людей, которые сделали вклад в развитие проекта; давали консультации и советы; помогали уточнять детали, которые могут быть полезны новичкам и опытным.

<table><thead><tr><th>Ник</th><th width="323"> </th></tr></thead><tbody><tr><td><a href="https://github.com/DK22Pac">DK22Pac</a></td><td><mark style="color:red;">★★★★★</mark></td></tr><tr><td>SHooZ</td><td><mark style="color:red;">★★</mark></td></tr><tr><td>BoPoH</td><td><mark style="color:red;">★</mark></td></tr><tr><td>Slivkin-Sergey</td><td><mark style="color:red;">★</mark></td></tr><tr><td><a href="https://github.com/x87">Seemann</a></td><td><mark style="color:green;">★</mark></td></tr><tr><td><a href="https://github.com/VitalRus95">Vital</a></td><td><mark style="color:blue;">★</mark></td></tr><tr><td><a href="https://github.com/Vladik01-11">Vladik01-11</a></td><td><mark style="color:purple;">★</mark></td></tr></tbody></table>

### Особые благодарности:

[Yurko\_UA](https://github.com/YurkoUA), [mfisto](https://github.com/mfisto), Tom\_Harison, SINGER, SanKing, HYPERMUV, FOXMAN, Sid\_Vicious, AndNicen, Dock174, Костя, DromeoStalker, undead099032, NFSCarbon\_VSD, major, NARC, MISTER\_GONWIK, Sweeper, vKew, SnakeR, Drs36.


# Раздел 01. Основы


# Общие сведения об уроках и минимальный набор программ

В разделе «Основы» мы будем рассматривать различные функции, которые являются общими для GTA III, GTA VC и GTA SA. Основной акцент будет направлен на изучение базовых принципов работы скриптов. В большей степени на Вас ждёт теория и немного практики, которые являются фундаментом. Приступать к другим разделам не имеет особого смысла. В большинстве случаев Вы будете только копировать код, не осознавая суть его работы; и любые модфикации кода приведут к неправильный работе или вылетам игры. Надеюсь, что это понятно. Вы должны **самостоятельно** понимать основы, а только тогда приступать к изучению нового материала.

Как я сказал ранее, мы будем акцентировать внимание на линейке игр 3D вселенной GTA. Уроки будут расчитаны для PC-версий (исключая [DE](https://ru.wikipedia.org/wiki/Grand_Theft_Auto:_The_Trilogy_%E2%80%94_The_Definitive_Edition) и версию для Steam®). Для каждой игры будут добавлены отдельные главы, как способ дополнить общую информацию. Рассматривать мы будем только базовые возможности, не прибегая к экзотическим скриптам.

### Софт для скриптинга

Чтобы иметь возможность писать скрипты, нам нужен минимальный софт. Для SCM-скриптинга есть много инструментов. В качестве основного редактора я буду использовать Sanny Builder. Скачать эту программу можно из официального [репозитория Sanny Builder](https://github.com/sannybuilder/dev/releases) на GitHub. Я буду использовать последнюю версию на данный момент (`4.0.0`), но и новые версии в основном поддерживают старый код. Так что если эту статью Вы будете читать в 2030-м году, то, вероятно, код в уроках будет совместим с самой новой версией. По крайней мере автор стремится поддерживать обратную совместимость со старыми скриптами.

Кроме этого, нам нужны расширения, которые позволяют дополнить базовые возможности новыми функциями. Чем больше у нас возможностей, тем проще нам будет реализовать свою идею. В своих уроках я буду использовать CLEO, как основной инструмент для расширения возможностей. Также CLEO позволяет запускать скрипты отдельно от основного сценария, что очень хорошо подходит как для разработки независимых полноценных скриптов, так и использовать их как инструменты отладки других скриптов. Также библиотека позвоит нам непосредственно в изучении скриптового языка. Скачивается этот софт также из официального [репозитория](https://github.com/cleolibrary/CLEO5/releases) на GitHub. Для каждой игры есть своя версия CLEO.

{% hint style="danger" %}
Обратите внимание, что для скриптинга я не буду использовать CLEO Redux. Это — отдельная разработка, для которой требуются отдельные уроки. Если будет возможность, эти уроки будут добавлены. Пока я состредоточусь на классических версиях CLEO.
{% endhint %}

Остальной софт мы будем рассматривать по мере изучения новых материалов. На начальных этапах SB и CLEO будет достаточно, чтобы уже иметь возможность начать писать свои первые скрипты. Установку и настройку этих инструментов мы рассмотрим в другой главе.

Автор: **wmysterio**


# Установка Sanny Builder. Базовые настройки

В прошлой главе мы определились с программами, которые будем использовать для скриптов. Если Вы скачивали SB и CLEO по ссылкам, что я давал, то установка будет разключаться разве что в копировании файлов из ахивов в нужные папки. Для Sanny Builder это может быть любая папка<mark style="color:red;">\*</mark>, а для CLEO — папка нужной игры (место, где находятся файлы `*.exe`). Если вы скачивали установщики из официальных сайтов ([Sanny Builder](https://sannybuilder.com/), [CLEO](https://cleo.li/)) или недай Бог из неофициальных источников, то придётся всё делать через установщики.

### Установка Sanny Builder

Инсталятор не должен вызывать какие-либо трудности, хотя некоторые версии Windows могут блокировать установку и может понадобится отдельное разрешение. Тем не менее рассмотрим все шаги. Сначала мы выбираем язык установки:

![Выбор языка установки](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/images/sb_install_s1.png)

Далее принимаем лицензионное соглашение. После этого мы должны указать папку, в которую будут установлены файлы программы<mark style="color:red;">\*</mark>:

![Выбор папки установки](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/images/sb_install_s2.png)

{% hint style="danger" %} <mark style="color:red;">\*</mark> Я не рекомендую устанавливать программу на системный диск (обычно он подписан как `Диск C`). Это может привести к мутному геморрою в попытках исправить некоторые баги и глюки.
{% endhint %}

После этого мы можем указать дополнительные задачи:

![Дополнительные задачи установки](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/images/sb_install_s3.png)

Установите галочки в тех местах, где Вы считаете нужным. Здесь нет общих рекомендаций и является исключительно выбором пользователя. Мне нет необходимости их устанавливать, так что жму «Далее». Тоже самое нужно провернуть в окне «Сделать редактором по умолчанию». Если Вы хотите, чтобы Sanny Builder открывал файлы с расширением например `*.scm` напрямую из системы (как аудио-плеер для `*.mp3`), то поставьте галочку. Иначе — оставьте её пустой.

{% hint style="info" %}
Вы всегда можете включить или отключить различные опции через настройки программы.
{% endhint %}

Далее установщик попросит указать папку с игрой. Тут всё просто — указываем папку, где находится файл `*.exe` игры:

![Выбор папки игры](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/images/sb_install_s4.png)

После этого мы увидим предложение об установке библиотеки CLEO. В комплекте Sanny Builder уже есть некая версия CLEO и в 99% случаев она самая свежая. Но могут быть случаи, когда библиотека обновляется раньше, чем она будет идти в комплекте с SB. Я обычно ставлю галочку:

![Установка CLEO](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/images/sb_install_s5.png)

Все шаги установки похожи на установку Sanny Builder. Ну а SB тем временем будет уже установлен, так что запустим его.

### Выбор режима редактирования

Если всё правильно сделать, то ничего дополнительно делать не нужно. Тем не менее бывают случаи (не всегда после установки), что нужные настройки выставлены неправильно или устарели. Первым делом нужно убедиться, что установлен нужный режим редактирования и проверить обязательные для нас настройки. Для этого сделайте клик на иконку игры в правом нижнем углу. У нас появится список доступных режимов:

![Выбор режима редактирования Sanny Builder](https://raw.githubusercontent.com/wmysterio/scm-scripting-lessons/3e4b7d5fa5aa97067854d58b1eb5462386d24756/images/sb_install_s6.png)

Нужно выбрать тот режим, что подходит под нужную игру. Так как я делаю уроки по скриптингу для GTA III, GTA VC и GTA SA, то режим должен быть одним из выделенных:

![Режимы редактирования, которые будут рассматриваться в уроках](https://raw.githubusercontent.com/wmysterio/scm-scripting-lessons/3e4b7d5fa5aa97067854d58b1eb5462386d24756/images/sb_install_s7.png)

{% hint style="danger" %}
Для уроков я использую версии PC (не для DE и не для Steam® или прочих)!
{% endhint %}

Как только режим выбран, нужно убедиться, что кнопки «SBL» и «CLEO» имеют зелёную окантовку:

![Признак того, что CLEO не установлен или не указаны нужные настройки](https://raw.githubusercontent.com/wmysterio/scm-scripting-lessons/3e4b7d5fa5aa97067854d58b1eb5462386d24756/images/sb_install_s8.png)

Если они имеют красную окантовку, то это свидетельствует о том, что библиотека CLEO и/или SBL не установлены, не поддерживаются или не установлена папка с игрой в настройках. Проверить или сменить папку можно в меню `Сервис->Настройки` (на английском `Tools->Options`):

![Выбор папки игры через настройки](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/images/sb_install_s9.png)

После установки пути к папке с игрой, кнопка CLEO должна стать зелёной.

### Форматирование

Редактор по умолчанию уже имеет базовые настройки, которые не нуждаются в дополнительных правках. Тем не менее, одна настройка может влиять на работоспособность некоторых функций. Например, некоторые функции могут быть чувствительны к регистру букв. Я настоятельно рекомендую изменить регистр на «Как есть»:

![Выбор регистра букв](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/images/sb_install_s11.png)

Это поможет избежать различных «чудес» в будущем. Вы можете изменить внешний вид, горячие клавиши и так далее, но все эти настройки не влияют на сами скрипты. Так что рассматривать настройки в подробностях не имеет особого смысла. Если появится что-то важное, то я добавлю новую информацию в эту главу или буду ссылаться на них в других статьях.

Более детальную информацию про настройки читайте в [официальной документации Sanny Builder](https://docs.sannybuilder.com/v/ru/editor/options). А на этом пока всё, пока!

Автор: **wmysterio**


# Синтаксис, комментарии, опкоды, команды. Ключевые слова

В этой главе мы рассмотрим базовые понятия, которые Вы в любом случае будете использовать на практике и использовать их в общении с другими людьми.

Начнём из терминов и синтаксиса. Собственно первым будем само  слово «Синтаксис» — это набор правил, которые понимают редакторы кода (и Sanny Builder в том числе). Эти правила позволяют избежать ошибок, которые возникают при неправильном напасании кода в их окружении. Если написать что-то, что не соответсвует правилам, редакторы сообщают об синтаксиеской ошибке с описанием того, что там не так и где это случилось. Для успешного выпонения сборки нашего кода нужно будет написать код так, чтобы таких ошибок не возникало. Это можно навазать первым шагом — умение соблюдать синтаксис.

### «Комментарий»

Некоторый код Sanny Builder будет игнорировать при сборке скрипта. Такой код называют комментариями и смысл их как раз делать напоминание или уточние для себя или других людей. Я называю такие комментарии <mark style="color:orange;">**явными**</mark>. Сейчас есть три типа комментариев со следующим синтаксисом:

* Однострочный комментарий. Начинается символами `//` и продолжается до конца строки:

```clike
// это комментарий
```

* Многострочный комментарий. Текст между символами `/*` и `*/`:

```clike
/*
Можно написать комментарий в
несколько строк, если осталось мало места
и читать будет неудобно
*/
```

* Многострочный комментарий. Текст между  символами<mark style="color:red;">\*</mark> `{` и `}`:&#x20;

```pascal
{ Многострочные комментарии не обязательно писать на разных строках }
```

{% hint style="danger" %} <mark style="color:red;">\*</mark> Комментарием не будет считаться синтаксис, если после символа **`{`** сразу же идёт символ **`$`**. С этим исключением мы познакомимся при первой встрече с ним.
{% endhint %}

### «Опкод»

Под этим словом подразумевается некая команда, которую будет выполнять игра. За каждым опкодом закреплён его персональный уникальный идентификатор (также известен как номер опкода) и набор параметров (аргументов), которые необходимы для правильного выполнения игрой. Общий синтаксис опкода в Sanny Builder представлен следующим образом:

```
YXXX: 0 1 2
```

Где `YXXX` — это `ID`(идентификатор — число в [шестнадцатеричной системе](https://ru.wikipedia.org/wiki/%D0%A8%D0%B5%D1%81%D1%82%D0%BD%D0%B0%D0%B4%D1%86%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D1%87%D0%BD%D0%B0%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0_%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F) счисления), а `0 1 2` — это параметры. Количество параметров напрямую зависит от опкода. Их может быть несколько, они могут отсутствовать или не иметь фиксированного количества. Символ **`:`** используется как разделитель.

Часть числа, пемеченного как `Y`, имеет особое свойство. Дело в том, что многие опкоды могут использоваться не только как прямой вызов некой команды игры, но и использовать инвертированную версию этой команды для внутренней работы, например при проверках различных состояний (условий). В этом случае самый старший бит отвечает за версию опкода: если он равен `0`, то команда будет выполняться как обычно; если `1`, то — инвертированная версия. Больше подроностей я попытаюсь донести в статье об условиях.

**ID** опкода ограничен 2-мя байтами, так что общее число опкодов с учётом двух версий будет не более `7FFF`, то есть 32767 штук. Этого будет более чем достаточно для добавления опкодов плагинами в будущем :)

Если вспомнить секцию о комментариях, то я упомянул о неких <mark style="color:orange;">**явных**</mark> комментариях со своим синтакисом, то есть также <mark style="color:green;">**неявные**</mark>: описание опкода и его параметров, который также игнорируется Sanny Builder. Во внимание берётся только его параметры. Например, это будет восприниматься редакором как одно и тоже при создании скрипта:

```
0001: 1000
0001: wait 1000 ms
0001: my_any_custom_text 1000
```

Как правило, каждый опкод имеет описание и оно может отличаться в разных режимах редактирования. Более того, опкоды под разные игры и даже версии игр могут иметь разное количетсво параметров, не использоваться вовсе, делать разные вещи или просто ничего не делать. Всё это нужно будет изучать самостоятельно!

### «Команда»

Под этим словом подразумевается особый способ написания опкода. В синтаксисе команды не используется **ID** опкода, разделитель `:` и нет описания. Всё сводится к такому синтаксису:

```
wait 1000
```

Если параметры конкретно для **wait** можно запомнить, то когда будет больше таких параметров, вероятно мы забудет что за что отвечает. Выходом из ситуации оказалить <mark style="color:green;">**явные**</mark> комментарии. Они не нарушили синтаксис и дали возможность читать описание. В общем виде они представлены так:

```pascal
{0001:} wait {time} [int]
```

Здесь `wait` — это имя команды, а `[int]` помогает заранее узнать какой тип<mark style="color:red;">\*\*</mark> данных требуется для параметра. Оставить в таком виде мы не сможем из за синтаксической ошибки. Нам нужно заменить **\[int]** на конкретное значение. В данном случае я использую значение `1000` и икончательный вариант будет таков:

```pascal
{0001:} wait {time} 1000
```

{% hint style="warning" %} <mark style="color:red;">\*\*</mark> О типах данных будет отдельная статья!
{% endhint %}

### Поиск команд

Количество команд дастаточно много и постоянно пополняются разными расширениями, помимо базового CLEO. Много из них можно найти на сайте [библиотеки Sanny Builder](https://library.sannybuilder.com/) и получить больше сведений о нужной команде.

Нам доступен список команд также прямо из Sanny Builder в меню `Сервис->Инструменты->Поиск опкодов` (на английском: `Tools->IDE Tools->Opcode Search`) или использовать горячие клавиши: `Ctrl`+`Alt`+`2` (по умолчанию):

<figure><img src="https://github.com/wmysterio/scm-scripting-lessons/raw/resources/images/sb_opcode_search_tool.png" alt=""><figcaption><p>Окно поиска опкодов</p></figcaption></figure>

Поисковик можно испольовать оффлайн, так что в любом случае Вы будете иметь под рукой список команд.

### Ключевые слова

Кроме скриптовых команд (назовём их так), есть особые команды — команды, которые выполняет только Sanny Builder с целью собрать некоторый код, который вручную нужно выполнять часто и далеко не самым лёгким способом. Для таких команд будут целые статьи!

Автор: **wmysterio**. Спасибо **Seemann** за некотрые важные уточнения!


# Типы данных. Литералы. Константы

В этой статье мы рассмотрим фундаментальные понятия, которые так или иначе присутствуют в Sanny Builder.

Думаю стоит начать с понятия `тип данных`. В своей сути тип являются некой категорией для множества значений; группировкой значений по категории. SCM на даёт нам особой свободы в плане выбора, поэтому мы можем сразу определить доступные типы. Всего у нас будет две большие группы типов:

* Целые числа;
* Строки;

Эти группы в свою очередь делятся ещё на дополнительные подтипы:

<table><thead><tr><th>Строки</th><th width="215">Имя типа</th><th width="215.33333333333334">Пример</th></tr></thead><tbody><tr><td>Короткая</td><td>string</td><td><code>'STRING'</code>, <code>'HELLO'</code></td></tr><tr><td>Длинная</td><td>long string</td><td><code>"MY_STRING"</code>, <code>"WMYSTERIO"</code></td></tr></tbody></table>

<table><thead><tr><th>Числа</th><th width="215.33333333333334">Имя типа</th><th width="215.66666666666663">Пример</th></tr></thead><tbody><tr><td>Целые</td><td>int, integer</td><td><code>10</code>, <code>0</code>, <code>-100</code>, <code>0xAB</code>, <code>-0xAF</code>, <code>0b01101</code></td></tr><tr><td>Вещественные</td><td>float</td><td><code>6.0</code>, <code>0.0</code>, <code>-20.5</code></td></tr></tbody></table>

<table><thead><tr><th>Другие</th><th width="215.33333333333334">Имя типа</th><th width="215.66666666666663">Пример</th></tr></thead><tbody><tr><td>Булево</td><td>bool</td><td><code>True</code>, <code>False</code></td></tr><tr><td>ID модели</td><td>-</td><td><code>#ADMIRAL</code>, <code>#BUFFALO</code></td></tr><tr><td>Метки</td><td>-</td><td><code>@LABEL</code></td></tr><tr><td>...</td><td>...</td><td>...</td></tr></tbody></table>

Таблица типов `Другие` являются скорее полезными или косметическими; и более привычными по содержанию для опытных программистов. Значения этих типов в конечном итоге превращаются в целые числа. Эта таблица может быть дополнена в будущем, но основная суть не изменится.

### Литералы

Колонки `Пример` демонстрируют способ распознать или создать значение некого типа. Сами значения всегда являются фиксированными и неизменными для скриптера (ноль всегда будет нулём и т.п.). Для такой особой формы записи существует даже отдельный термин — **литерал**; он же константа без имени.

Особое внимание стоит обратить на литералы строк. Их содержимое обрамлено кавычками двух видов: `'` и `"`. Первый вид строк (короткие) имеет ограничение на максимальную длину символов, а именно до `15`. Второй вид (длинные) не имеют прямого ограничения на длину, но само ограничение устанавливает конкретный опкод и смотреть максимальную длину стоит исходя из его описания или банальными тестами. К слову, короткие строки, которые я встречал в оригинальных мейнах, всегда не больше 7 символов включительно. Я рекомендую придерживаться именно этого ограничения.

Также я хотел бы обратить внимание на разницу между формами записи целых и вещественных чисел. Хоть в математике `2.0` и `2` являются одинаковыми по значению, но в программировании это не всегда так. Исторически так сложилось, что вещественные числа (числа с "плавающей" запятой) кодируются и обрабатываются на уровне типа по другому принципу, поэтому и требуют особой формы с обязательной точкой для разделения целой части числа от дробной.

Кроме понятной формы целых чисел, есть ещё их специализированные литералы, которые позволяют записать число как в [шестнадцатеричной](https://ru.wikipedia.org/wiki/%D0%A8%D0%B5%D1%81%D1%82%D0%BD%D0%B0%D0%B4%D1%86%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D1%87%D0%BD%D0%B0%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0_%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F) системе счисления (`0xAB`, `-0xAF`), так и в [бинарной](https://ru.wikipedia.org/wiki/%D0%94%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D0%B0%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0_%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F) (двоичной) системе счисления (`0b01101`).

### Константы

Начнём с определения. Константа — это некое фиксированное значение, которому присвоено имя. Это имя, как и его значение, не может быть изменённым после его объявления.

Константы помогают лучше контролировать часть кода. В основном из за того, что они используются непосредственно в коде один или множество раз, тогда как изменения значения константы происходит в одном месте.

Объявляются константы в блоке `const ... end`, а синтаксис заполнения такой:

```
ИмяКонстанты = Значение
```

Для примера давайте создадим простой блок с константой, которая будут символизировать количество денег:

```
const
    MONEY_VALUE = 100
end
```

Теперь когда SB будет компилировать код, то он автоматически заменит `MONEY_VALUE` на число `100`. Кроме числа туда можно записывать и другие литералы. Плюс есть возможность записать в качестве значения ещё и свойства [классов](/00100/00100/000300#klassy):

```
MONEY = Player.Money($PLAYER_CHAR)
```

Конечно такую запись я никогда не использовал и не планирую, но могу только констатировать, что это возможно. Давайте лучше рассмотрим фрагмент кода простого скрипта с использованием констант:

```
const
    MONEY_VALUE = 100
    MONEY = Player.Money($PLAYER_CHAR)
end

MONEY += MONEY_VALUE
MONEY += MONEY_VALUE
```

В результате игроку дадут 200 баксов (дважды по 100). При компиляции `MONEY` будет заменён на `Player.Money($PLAYER_CHAR)` а `MONEY_VALUE` — на `100`, так что этот скрипт станет идентичным этому:

```
Player.Money($PLAYER_CHAR) += 100
Player.Money($PLAYER_CHAR) += 100
```

В примере кода константы могут показаться не целесообразными из за наличия дополнительного блока. Однако ценность существенно возрастает в более крупных проектах, где кода достаточно много и он постоянно разрастается.

{% hint style="success" %}
Константам лучше задавать запоминающиеся имена. Регистр может быть любым, но я рекомендую использовать название в верхнем регистре.
{% endhint %}

Автор: **wmysterio**

## Переменные

, которые присутствуют в скриптинге.

В этом уроке мы познакомимся с типами данных в SCM-скриптах и типами переменных. Также будут рассмотрены арифметические операции над числами.

Редактирование main.scm. Переменные (Часть 1)||wmysterio|wmysterio||||Вот так, понемножку, мы подошли к переменным. Что же это такое? Если образно представить, то можно сказать, что это ящик, в котором можно что то хранить. В потоках мы можем использовать много таких ящиков ( но не нужно забывать о лимитах ). Эти ящики называются **переменными**.

Так что же именно мы можем хранить? Давайте рассмотрим несколько типов данных:

| Тип данных | Пример                                 |                           |
| ---------- | -------------------------------------- | ------------------------- |
|            |                                        |                           |
| 1          | Целое число                            | 1, 0, -100                |
|            |                                        |                           |
| 2          | Дробное число                          | 6.0, 0.0, -20.5           |
|            |                                        |                           |
| 3          | Короткая строка ( максимум 7 символов) | 'STRING', 'HELLO'         |
|            |                                        |                           |
| 4          | Длинная строка ( максимум 15 символов) | "MY\_STRING", "RU-SCRIPT" |
|            |                                        |                           |

× \*\*Примечание:\*\* Все строки не имеют пробелов! В место них, как правило, пишется значок \*\*\_\*\*

Отличаются 3-й и 4-й тип тем, что они имеют свои ограничения по длине, в использовании, и пишутся они в разных скобках.

Естественно для этих типов есть свои правила, но запомнить нужно только то, что выполнять операции можно только между данными одинакового типа. Иначе результат будет неправильным. Кстати, насчёт операций... Давайте рассмотрим, что же можно делать с числами:

| Операция | Описание  |
| -------- | --------- |
|          |           |
| +=       | Сложение  |
|          |           |
| \*=      | Умножение |
|          |           |
| /=       | Деление   |
|          |           |
| -=       | Вычитание |
|          |           |

Приведу примеры этих операций:

| Правильно     | Не привильно |
| ------------- | ------------ |
|               |              |
| 2 += 2        | 22.5 += 7    |
|               |              |
| 0.25 \*= -0.1 | 5 \*= 3.4    |
|               |              |
| 220 /= 5      | 32.0 /= 4    |
|               |              |
| 33.3 -= 1.5   | 88 -= -55.5  |
|               |              |

× \*\*ВАЖНО:\*\* Делить на 0 и на 0.0 соответсвтенно нельзя!× \*\*ВАЖНО:\*\* Мы не можем выполнять арифметические операции между числами и строками, и наоборот - между строками и числами!

Вот, собственно, основные правила арифметических операций над числами. Правда записываются они в иной форме, так как что в место чисел слева у нас будут переменные! Думаю самое время рассказать о них.

Каждый человек имеет имя. Например, Ваня, Вася, Дима и т.п. Также имеют имена и наши переменные. Что бы создать переменную, нужно выполнить небольшую операцию: поставить знак доллара **$** и ввести имя.

× \*\*Примечание:\*\* Имена должны состоять только с латинских символов и не иметь пробелов! Допускаются ещё целые положительные числа и символ \*\*\_\*\*

Для примера, напишем несколько:

$WANYA\
$WASYA\
$DIMA

Итак, мы научились писать имена переменных. Их можно использовать во всём мейне и использовать во всех потоках. Такие переменные называю **глобальными**. Но есть и другие переменные, так званые - **локальные** - они тоже имеют имена, только, в отличии от глобальных, имена состоят только с положительных целых числел, а в конце имени стоит знак собаки электронной почты ( читается как "эт" ): **@**. Для примера, напишем несколько таких:

0@\
1@\
2@

Для строк синтаксис написания немного другой:

| Глобальные строки |                                                                                    |
| ----------------- | ---------------------------------------------------------------------------------- |
|                   |                                                                                    |
| v$WANYA           | Можно записать только строку с длинной в 15 символов, то есть с кавычкой \*\*"\*\* |
|                   |                                                                                    |
| s$WANYA           | Можно записать только строку с длинной в 7 символов, то есть с кавычкой \*\*'\*\*  |
|                   |                                                                                    |
| Локальные строки  |                                                                                    |
|                   |                                                                                    |
| 0\@v              | Можно записать только строку с длинной в 15 символов, то есть с кавычкой \*\*"\*\* |
|                   |                                                                                    |
| 0\@s              | Можно записать только строку с длинной в 7 символов, то есть с кавычкой \*\*'\*\*  |
|                   |                                                                                    |

Помните о ящиках? Так вот: всё куда то записывается! В нашем случае значение записываются в переменные ( образно - в ящики ). Давайте запишем число в переменную! Делается это так:

```
$WANYA = 2 // здесь операция = является записью числа 2 в переменную $WANYA
```

Мы записали в переменную "$WANYA" число 2. Правда не сложно? Давайте тогда умножим нашу переменную на число 3. Посмотрев операции над числами выше, напишем пример:

```
$WANYA *= 3 // умножаем переменную $WANYA на число 3
```

Следовательно, в переменной "$WANYA" теперь будет хранится число 6, так, как 2\*3=6. То есть, сначала идут арифметические операции, а результат сохраняется в той же переменной, стирая предыдущее значение. Напишем несколько таких операций:

```
$WANYA = 3
$WANYA *= 4
$WANYA /= 2
```

Не надо быть сильным в математике, что бы понять, что теперь в переменной "$WANYA" будет хранится число 6, хоть до операций в ней было число 3.

Но все те старания будут напрасны, если напишем следующее:

```
$WANYA = 3
$WANYA *= 4
$WANYA /= 2
$WANYA = 3
```

Почему напрасны? Потому что если написать так в скрипте, в "$WANYA" всё равно будет число 3 в независимости от выполненных ранее операций. Вот и особенность последовательности команд. Если всё же не поняли, приведу математический пример:

3 — 1-я операция - записываем число в переменную\
3\*4=12 — 2-я операция\
12/2=6 — 3-я операция\
3 — 4-я операция - записываем число в переменную

В общем основы с числовыми переменными думаю вы усвоили. Что же, давайте все арифметические операции перенесём в скрипт. Создадим поток с именем "MATEM" и напишем несколько операций в нём:

```
:MATEM
thread 'MATEM'
wait 0
$WASYA = 2
$WASYA += 4
$WASYA *= 3
$WASYA /= 9
$WASYA -= 2
end_thread
```

Ваша задача - посчитать, какое число будет в переменной "$WASYA" после завершения потока. Если у вас вышло число 0, то у вас огромный прогресс в операциях над переменными. Если всё же не вышло, попробуйте посчитать сначала. Это очень важно, так как мы учимся мыслить по-скриптерски.

Есть также операции, которые пишутся опкодами. Например, нужно переменную суммировать с другой переменной. Если написать так: "2@ += 3@" то появится ошибка:

Неверное выражение 2@ += 3\@. Одна из переменных имеет неизвестный тип, либо их типы несовместимы.

В санни билдере невозможно выполнить данную операцию в таком виде. Для этого нужно воспользоваться опкодом! Пришло время применить фукнцию поиска опкодов! Для этого нажмите CTRL`+<kbd>ALT`+2\`. Должно появится окошко:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/02251412.png)

В поле "Искать" введите следующее:

@ += @

И вот мы видим наш список сократился во много раз:

![](https://github.com/wmysterio/scm-scripting-lessons/blob/main/_pu/0/50360427.png)

Первые 2 опкода в списке - то, что искали. Осталось только определить тип данных, которых будет складывать. Оба типа должны совпадать! Если наши переменные - целые числа, то выделяем опкод, где есть комментарий "//(int)". Если наши переменные - дробные числа, то выделяем опкод, где есть комментарий "//(float)".

После этого жмём правую кн. мыши и жмём "Копировать":

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/55266821.png)

Закрываем окно, и вставляем его в редакторе:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/26139132.png)

Есть и другой способ облегчить этот процесс, но о нём мы вернёмся чуть позже.

Вот мы и скопировали опкод, который нам был нужен. В нашем случаи опкод будет суммировать 2 дробных числа локальных переменных. Всё, что нам осталось - это переименовать переменные на нужные. Думаю с этим проблем не возникнет. Главное не перепутать с типами ;)

Искать "/", "\*", "-" можно по аналогии к примеру выше.

Данный пример действует только на локальные переменные. Что бы искал глобальные, то пишите в поиске это:

$ += $

Дальше всё по аналогии. Если нужно сделать операции, где нужно от глобальной переменной отнять локальную переменную, то в поиске введите:

$ -= @

Но не советую вам делать операции, где есть локальная и глобальная переменная без крайней необходимости. Лучше что бы обе были либо локальными, либо глобальными.|1849|1|0|02251412`png`788`673`400`341``\|50360427`png`358`209

```
`\|55266821`png`787`354`400`179``\|26139132`png`501`363`400`289``\||redaktirovanie_main_scm_peremennye_chast_1|1498216856
```


# Типы проектов

Думаю, что нужно ещё рассказать о типах проектов, так как некоторые опкоды могут использоваться только в них. Сейчас существует два типа проектов в SB: «CLEO» и «main.scm».

Последние 2 опкода, которые мы рассмотрим в этом уроке, работают одинаково. Однако используются они в зависимости от типа проекта. Давайте сейчас рассмотрим эти типы.

Авторы: **wmysterio**


# Переменные. Операторы

В этой статье мы рассмотрим фундаментальное понятие переменной и операции, которые можно с ними провернуть.

Основополагающей составляющей скриптинга SCM и программирования в целом являются переменные. Очень важно рассмотреть эту статью, так как без базовых знаний этой темы дальнейшее развитие навыков теряет смысл. Поэтому начнём!

А начнём мы, как и обычно, из определения. Переменная — это некий контейнер (область в памяти), где сохраняются данные. Это её главная функция — **хранение**. Эти данные можно получить или перезаписать в зависимости от ситуации. Возможность перезаписи данных оправдывают название контейнера, так как данные не фиксированы.

Для чтения и записи нужны инструменты. В первую очередь нужно знать как обращаться к данным. Для этого существуют особые формы записи. Эти формы имеют особый контекст и разделяются на две категории:

* Локальные
* Глобальные

Контекст определяет область применения этих переменных. В CLEO-скриптах подавляющие количество переменных являются локальными, потому начнём детальный разбор именно из них!

### Локальные переменные

Само название говорит, что такие переменные используются локально. Другими словами на них накладываются ограничения: все локальные переменные могут использоваться только в границах **текущего скрипта**! Каждый скрипт имеет собственный набор локальных переменных и нет возможности напрямую влиять на значения таких переменных в других скриптах. Это является как преимуществом, так и недостатком. К последнему можно отнести тот факт, что количество локальных переменных строго ограничено и нужно с умом использовать всю доступную область.

Синтаксис локальных переменных не славится читаемостью:

<table><thead><tr><th width="323">Пример</th><th>Предназначение</th></tr></thead><tbody><tr><td><code>0@</code></td><td>Хранение любых чисел</td></tr><tr><td><code>0@s</code></td><td>Хранение коротких строк до 7 символов<mark style="color:red;"><strong>*</strong></mark></td></tr><tr><td><code>0@v</code></td><td>Хранение длинных строк до 15 символов<mark style="color:red;"><strong>*</strong></mark></td></tr></tbody></table>

Сначала пишется числовой идентификатор (номер переменной); далее особый символ-маркер `@` для компилятора; и суффикс<mark style="color:red;">**\***</mark>, тоже для компилятора.

{% hint style="danger" %} <mark style="color:red;">**\***</mark> Только для GTA San Andreas!
{% endhint %}

Номера переменных имеют следующие ограничения:

| III    | VC     | SA                                                        |
| ------ | ------ | --------------------------------------------------------- |
| `0-15` | `0-15` | `0-31`                                                    |
|        |        | `0-31`, `34-1023`<mark style="color:red;">**\*\***</mark> |

{% hint style="danger" %} <mark style="color:red;">**\*\***</mark> Только в режиме миссии!
{% endhint %}

Я специально дал именно такой диапазон, поскольку в них можно гарантированно сохранить данные. Но есть особые локальные переменные, которые «слишком переменные», то есть у нас нет способа обеспечить их постоянность. Связано это с механикой их работы, описанной ниже.

#### Локальные переменные-таймеры скрипта

Каждый скрипт имеет два так называемых таймера скрипта. Они постепенно увеличивают своё значение на время, затраченное на ожидание. Они не привязаны к реальному времени. По крайней мере их значения не совпадали с моими ожиданиями, хоть и были достаточно похожими вначале тестов. Номера этих переменных написаны в таблице ниже:

| III     | VC      | SA      |
| ------- | ------- | ------- |
| `16-17` | `16-17` | `32-33` |

К счастью запоминать конкретно эти значения нам не нужно. Современный Sanny Builder предоставляет готовые [константы](https://docs.sannybuilder.com/v/ru/coding/variables#peremennye-taimery), которые автоматически будут ссылаться на нужные таймеры в зависимости от выбранной игры. Их имена: `TIMERA` и `TIMERB`. Мы ещё вернёмся к ним в других статьях, где будет их явная роль. Пока только запомните эту информацию.

### Хранение строк в локальных переменных

Скриптинг **GTA SA** даёт нам больше гибкости в плане хранения данных, позволяя записывать строки в переменные. Если с числами нет особых заморочек, то вот строки требуют более детального разбора.

Для каждого типа строки есть свой тип переменной. Короткие строки помечены суффиксом `s`, а длинные строки — `v`.

Поскольку строки требуют больше места для хранения — в отличии от чисел — то и&#x20;

В скриптинге **GTA SA** есть особые типы переменных, предназначенных для хранения строк. Они помеченные суффиксами `s` (короткая строка) и `v` (длинная строка). Отличаются они в первую очередь размером

В отличии от переменных для чисел, они требуют больше места для хранения. &#x20;

Это значит, что строки требуют больше переменных ввиду специфики их хранения. Для короткой s-строки используются сразу две переменные: та, что объявлена под номером и одна следующая. Для v-строк используется тот же принцип, только количество переменных для хранения больше ещё на две штуки. В целом всё это можно представить так:

<table><thead><tr><th width="179"> </th><th width="179"> Запись</th><th align="right">Строка</th></tr></thead><tbody><tr><td><code>1@s</code></td><td><p><code>1@</code>=<code>'DEMO'</code></p><p><code>2@</code>=<code>'STR'</code></p></td><td align="right"><code>DEMOSTR</code></td></tr><tr><td><code>4@v</code></td><td><p><code>4@</code>=<code>'STRI'</code></p><p><code>5@</code>=<code>'NGEX'</code></p><p><code>6@</code>=<code>'AMPL'</code></p><p><code>7@</code>=<code>'E'</code></p></td><td align="right"><code>STRINGEXAMPLE</code></td></tr></tbody></table>

Хоть в колонке "Запись" и показан пример записи строки, фактически происходит её кодирование в числовой вид. Это позволяет запись её в одну переменную.&#x20;

&#x20;когда условные строки кодируются в числовой вид, что позволяет записать их в одну переменную. В качестве вывода можем констатировать, что хоть синтаксически используется одна переменная, изнутри

Редактирование main.scm. Переменные (Часть 2)|В этом уроке речь идёт о локальных и глобальных переменных, и о том, как они используются в потоках.|wmysterio|wmysterio||||В предыдущем уроке мы рассмотрели как создавать глобальные переменные. Такой формат позволяет нам Sanny Builder ( чем мы собственно воспользовались ). Однако сами переменные в конечном итоге будут записаны как:

$ИНДЕКС

Если мы задаём имя не числом, то компилятор автоматически подбирает свободный индекс в общем массиве глобальных переменных. Таким образом глобальная переменная получает синоним, который ввёл скриптер.

Некоторые синонимы уже зарезервированны компилятором и записывать на их место значения отличных от их первоначальных целей не рекомендовано. Давайте рассмотрим глобальные переменные, которые не рекомендовано перезаписывать:

| Индексная переменная | Синоним        | Описание                                                       |
| -------------------- | -------------- | -------------------------------------------------------------- |
|                      |                |                                                                |
| $2                   | $PLAYER\_CHAR  | Переменная, которая хранит ссылку на игрока                    |
|                      |                |                                                                |
| $3                   | $PLAYER\_ACTOR | Переменная, которая хранит ссылку персонажа игрока             |
|                      |                |                                                                |
| $11                  | $PLAYER\_GROUP | Переменная, которая хранит ссылку на группу (банды) игрока     |
|                      |                |                                                                |
| $409                 | $ONMISSON      | Переменная, которая хранит флаг миссии (1 - включена, 0 - нет) |
|                      |                |                                                                |

В предыдущих уроках я уже публиковал код мейна, где уже использовались эти переменные и они были заданы необходимыми значениями, так что о них волноваться по этому поводу не нужно - главное не записывайте значения в эти переменные вне потока "MAIN". Это нужно хотя бы для того, чтобы CLEO-скрипты других разработчиков могли полноценно работать.

Кроме тех типов данных, которые были в предыдущем уроке, существуют ещё ссылки ( указатели или хэндлы ). Они ссылаются на какие-то сущности, которые были созданы в игре скриптами. В меременные записывается число, которое является адресом где-то там в памяти. Но сейчас нас это не должно волновать - позже всё станет ясно. Вот пример некоторых сущностей, которые можно хранить в переменных:

| ACTOR  | Актёр - это любой персонаж в игре: полицейский, байкер, шлюха и т.п.                                                 |
| ------ | -------------------------------------------------------------------------------------------------------------------- |
|        |                                                                                                                      |
| CAR    | Транспорт - это средство передвижения в игре: лодка, байк, велик, машина и т.п.                                      |
|        |                                                                                                                      |
| OBJECT | Объект - это дома, бочки, дороги, двери. В общем сложно объяснить, что это. Скажем — мелкие или большие детали игры. |
|        |                                                                                                                      |

Эти и остальные хэндлы мы изучим в следующих уроках и более детально изучим их. Я хотел просто показать что может хранится в переменных.

Рассмотрим также использование локальных переменных в потоках. Всё, о чём я сейчас расскажу очень важно в скриптинге. Создадим 2 потока: ":A" и ":B":

```
// ...
create_thread @A
create_thread @B
end_thread

:A
thread 'A'
wait 0
0@ = 0
jump @A

:B
thread 'B'
wait 0
0@ = 1
jump @B
```

Вопрос: что будет хранится в переменной 0@? 1? 0? Не правильно! В переменной 0@ будут хранится оба числа! Почему так? Потому, что потоки в данном случае работают параллельно ( как бы одновременно ). Что бы вам объяснить, рассмотрим пример в реальной жизни:

Представим обычною городскую школу. Представим классы. Например: 11-й. Учеников много, поэтому их распределили на A, B, C. Вот возьмём имена учеников. Ученики будут нашими переменными:

```
0@ - Вася
1@ - Славик
2@ - Макс
3@ - Юра 
```

Они учатся в классе "11 A". В параллельном классе, то есть в "11 B", есть ученики с теми самими именами:

```
0@ - Вася
1@ - Славик
2@ - Макс
3@ - Юра 
```

Видим, что имена одинаковы, но не забываем, что характер, черты лица всегда разные, то есть каждый человек - индивидуальный. Так же само с переменными - имена одинаковы, но находятся они в разных потоках. Следовательно они могут изменятся только в пределах своего потока. Что это значит "своего потока"? Наш 1-й поток — это класс "11 A". Все ученики заперты в своём классе! ( Пусть этого не будет в реальной жизни :) ) В нём они творят то, что нам захочется. Как и ученити, так и переменные - заперты в потоке. Если вызывается 1-й поток командой "сreate\_thread", значит строится класс "11 A". Следовательно "end\_thread" — разрушает этот класс в месте с учениками и о них больше ни слова, ни духа, пока мы опять не построим класс ( станем вызывать тот же поток ).

Одновременно нельзя построить 2 одинаковых класса, то есть:

```
// ...
create_thread @A 
create_thread @A
end_thread
```

Вернее можно, но крайне не рекомендовано, так как это приводит к вылету игры. Такой вариант не правильный, потому что мы вызываем работающий поток, запущенный ранее. Об этом я вам уже рассказывал в предыдущих уроках.

Так же не забываем о игровых лимитах: в потоке может быть не больше 33 локальных переменных. То есть максимум в классе может быть 33 ученика с разными именами. Этого вполне достаточно для потока.

× \*\*Примечание:\*\* Все имена должны быль меньше числа 34.

Если написать так:

102@ = 1

то компилятор сообщит об ошибке: "Локальная переменная вне доступных границ"

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/84748247.png)

Так что пользуемся формулой:

от 0 до 33 + @

Это правило действует только на локальные переменные!

× \*\*ВАЖНО:\*\* Последние две перемененные - таймеры и они всегда меняют своё значение, поэтому для хранения данных они не подходят.

Поэтому лимит переменных будет ещё большим: от 0 до 31. О таймерах мы поговорим в следующих уроках.

Глобальные же переменные имеют больше возможностей. Они могут существовать и без активного потока и при этом сохранять какую то информацию, а в потоках - изменяться или влиять на что-то. Давайте рассмотрим пример использования глобальной переменной:

![](https://github.com/wmysterio/scm-scripting-lessons/blob/main/_pu/0/97568642.png)

Как видим вначале переменная "$DIMA" была равна нулю. После создания потока "А", мы добавили к ней число "5". Легко догадаться, что в переменной "$DIMA" теперь будет число "5". Но особенностью глобальных переменных в том, что поток "B" будет знать о переменной "$DIMA", хоть она там и не использовалась.

Можно привести пример с реальной жизни. Тоже представим школу и классы. А $DIMA — - это директор. Во все классы он может зайти или выйти. Значит изменять или проверять переменную можно в любом месте скрипта. Значение переменной может быть любым, в зависимости от последней выполненной операции над ней. В нашем случаи поток будет знать, что в переменной $DIMA будет число 5.

В следующем уроке мы рассмотрим перемененные, которые могут иметь одинаковые имена.|1470|1|0|84748247`png`445`134`400`120``\|97568642`png`188`306

```
`\||redaktirovanie_main_scm_peremennye_chast_2|1498222439
```


# 00012. Редактирование main.scm. Переменные (Часть 3)

Редактирование main.scm. Переменные (Часть 3)|Мы продолжаем дальше изучать переменные. Этот урок посвящён массивам. Что это такое и с чем его едят мы рассмотрим здесь.|wmysterio|wmysterio||||Давайте представим опять школу, в школе есть "11-А" класс. Опять в классе есть ученики. Довольно часто случается так, что в классе есть люди, в которых имена одинаковы. Что бы не путать мы часто называем их по фамилиям, что бы человек знал, что обращаются именно к нему. Также и переменные могут иметь свои "фамилии", то есть то, что отличает его от других. В программировании часто это называют массивом. Массив — набор однотипных данных. Массивы имеют не сложный синтаксис, так что напишем пример одного из них:

Допустим в нашем классе будут учится 4 девушки с именем Рита. Что бы различать их, мы проиндексируем их, то есть зададим какое то число, что будет их фамилией. В скриптинге обозначают их квадратными скобками:\*\*\[ \*\* и **]**, в середине которых находится число:

$RITA\[0]\
$RITA\[1]\
$RITA\[2]\
$RITA\[3]

В реальной жизни можно написать аналогичный пример:

$RITA\[Иваненко] (имеет индекс 0)\
$RITA\[Сагаева] (имеет индекс 1)\
$RITA\[Рейна] (имеет индекс 2)\
$RITA\[Пушкинка] (имеет индекс 3)

Как видим в скобках написаны фамилии. Думаю посмотрев оба примера вы уже поняли как их писать и имеете базовое представление о массивах. Каждый массив имеет ограничение, но ограничения ставим мы сами, то есть нам решать сколько человек с одинаковым именем будет в классе. Что бы сделать ограничение, нужно написать слово **var** и закрыть его командой **end**. В середине этого блока объявляются массивы. Делается это следующей формулой:

```
VAR
$RITA: array 10 of integer
END
```

Рассмотрим детальнее:

VAR - открывается контейнер\
$RITA - имя переменной, которая будет считаться массивом\
10 - максимальное количество элементов массива (максимальное количество фамилий, одинаковых фамилий не может быть )\
integer - тип данных, который будут хранится\
END - закрывается контейнер<br>

Написав всё это мы можем использовать переменные в своих целях.

Как и глобальные, так и локальные переменные могут быть массивами. Рассмотрим пример с локальными переменными. Объявлять массив так же само, а вот синтаксис совсем другой:

```
// объявление
VAR
0@: array 4 of integer
END

// использование
0@(5@, 4i)
```

Рассмотрим подробнее написанное:

0@ - имя перемененной, которая будет считаться массивом\
4 - максимальное количество элементов массива\
i - тип данных, который будет хранить массив\
5@ - дополнительная переменная, которая будет служить индексом<br>

Всё было бы хорошо, если не дополнительная переменная. Если в место неё написать числовой индекс, то возникнет ошибка: "имя индексной перемененной не найдено":

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/49600884.png)

Поэтому нужно создать дополнительную переменную, которая будет служить нашим индексом. Сделаем это:

```
5@ = 0
0@(5@, 4i)
```

По структуре будет работать также, как и переменная "$RITA\[0]".

Что бы заполнить весь массив нужно написать в два раза больше кода, чем при написании массивов глобальных переменных. Давайте сравним примитивный вариант заполнения локальных и глобальных массивов:

<table><thead><tr><th>Для локальных переменных</th><th>Для глобальных переменных</th></tr></thead><tbody><tr><td><p>```</p><p>var 0@: array 4 of integer end</p><p>5@ = 0 0@(5@, 4i) = 50 5@ += 1 0@(5@, 4i) = 100 5@ += 1 0@(5@, 4i) = 1000 5@ += 1 0@(5@, 4i) = -15</p><pre><code>&#x3C;/td>&#x3C;td>
</code></pre><p>var $RITA:array 4 of integer end</p><p>1@ = 0 $RITA[1@] = 50 1@ += 1 $RITA[1@] = 100 1@ += 1 $RITA[1@] = 1000 1@ += 1 $RITA[1@] = -15</p><pre><code>&#x3C;/td>&#x3C;td>
</code></pre><p>var $RITA:array 4 of integer end</p><p>$RITA[0] = 50 $RITA[1] = 100 $RITA[2] = 1000 $RITA[3] = -15</p><pre><code>&#x3C;/td>&#x3C;/tr>
&#x3C;/tbody>&#x3C;/table>

В этой таблице видим, что кода больше в 1-й и 2-й колонке, так как используется дополнительная переменная. 3-я колонка имеет меньше кода. по этому советую использовать массивы глобальных переменных, та как их легче запомнить или писать. Но о локальных переменных тоже не следует забывать.

\<div class="alert alert-danger alert-dismissible" role="alert">
\<button type="button" class="close" data-dismiss="alert" aria-label="Close">\<span aria-hidden="true">\&times;\</span>\</button>
**ВАЖНО:** Локальные переменные имеют неприятное свойство - они "забирают" количество переменных под массив, из за этого правильным способом будет оградить себя от от использования некоторых переменных. В нашем случаи это переменные 0@ 1@ 2@ 3@ и 4\@. Количество элементов массива равняется количеству пропускаемых переменных и начинается от переменной, объявленной как массив. В таком случаи мы избегаем возможность переписать элемент массива.
\</div>

Рассмотрим основные типы данных, которые может хранить массив:

\<table class="table table-bordered">\<tbody>
\<tr>\<th>Массив\</th>\<th>Тип данных\</th>\<th>Префикс\</th>\<th>Описание\</th>\</tr>
\<tr>\<td rowspan="4">0@: array 4 of\</td>\<td>integer\</td>\<td>i\</td>\<td>Целые значения, размер элемента: 4 байта\</td>\</tr>
\<tr>\<td>float\</td>\<td>f\</td>\<td>Дробные значения, размер элемента: 4 байта\</td>\</tr>
\<tr>\<td>short string\</td>\<td>s\</td>\<td>Строки с длиной до 7 символов включительно, размер элемента: 8 байт\</td>\</tr>
\<tr>\<td>long string\</td>\<td>v\</td>\<td>Строки с длиной до 15 символов включительно, размер элемента: 16 байт\</td>\</tr>
\</tbody>\</table>

Давайте сделаем локальную переменную-массив дробных чисел:

</code></pre><p>var 0@: array 4 of float end</p><p>5@ = 0 0@(5@, 4f) = -0.5</p><pre><code>

\<div class="alert alert-danger alert-dismissible" role="alert">
\<button type="button" class="close" data-dismiss="alert" aria-label="Close">\<span aria-hidden="true">\&times;\</span>\</button>
**ВАЖНО:** Индекс всегда целое число, по этому дополнительную переменную следует объявлять тоже как целое. Идентификатор **всегда** начинается с 0 и увеличивается на единицу. Индекс не может быть больше максимального количества элементов, описанных в блоке "var".
\</div>

Вот так, по аналогии, вы можете создавать массивы любых доступных типов данных. Главное, что бы идентификатор типа совпадал с типом данных, описанного в блоке "var". Например: "float" и "f". ( смотрите таблицу выше, что бы не путали ).

Есть ещё типы данных и некоторые трюки, но о них я расскажу в следующих уроках.

\<div class="alert alert-warning alert-dismissible" role="alert">
\<button type="button" class="close" data-dismiss="alert" aria-label="Close">\<span aria-hidden="true">\&times;\</span>\</button>
**Примечание:** На самом деле глобальные массивы имеют тотже синтаксис, что и локальные ( $RITA($INDEX,4i) ), но Sanny Builder позволяет нам использовать упрощённый синтаксис.
\</div>|1392|1|0|49600884`png`446`133`400\`119\`\`||redaktirovanie\_main\_scm\_peremennye\_chast\_3|1498484960 </code></pre></td><td></td></tr></tbody></table>


# 000175. Трюк с локальными массивами

Трюк с локальными массивами|В этом уроке Вы узнаете об одном трюке, который существенно сократит время написания однотипного кода.|wmysterio|wmysterio||||Всем привет! С Вами**wmysterio**. В этом уроке Вы узнаете об одном интересном методе, который упростит написание кода с локальными массивами.

Как известно, каждый поток имеет свой набор локальных переменных, доступ к которым осуществляется с помощью символа **@**. Массивы же являются группой переменных из этого диапазона. Многие забывают, что мы можем использовать отдельно переменную из этого массива и обращаться как к обычной переменной. Этот трюк заключается как раз в этом - мы можем брать отдельную переменную из массива или формировать массивы из отдельных переменных, что идут последовательно.

Рассмотрим следующий код:

```
{$CLEO} 
0@ = 0 
0376: 10@(0@,5i) = create_random_actor_at 2505.6489 -1664.1635 13.397 
0@ += 1 
0376: 10@(0@,5i) = create_random_actor_at 2506.1484 -1668.5974 13.3742 
0@ += 1 
0376: 10@(0@,5i) = create_random_actor_at 2504.1794 -1673.494 13.3634 
0@ += 1 
0376: 10@(0@,5i) = create_random_actor_at 2499.0459 -1675.1171 13.3458 
0@ += 1 
0376: 10@(0@,5i) = create_random_actor_at 2495.4204 -1660.1552 13.3359 

for 0@ = 0 to 4 
0187: 20@(0@,5i) = create_marker_above_actor 10@(0@,5i) 
end 

0A93: end_custom_thread
```

А теперь представьте, что нужно изменить тип маркера только одного элемента из массива. Что же нам теперь при необходимости менять значение 0@, чтобы добиться доступа к конкретной переменной?

```
0@ = 3
07E0: set_marker 20@(0@,5i) type_to 1
```

А что будет, если нам нужна будет эта переменная везде, при этом у нас есть ещё некая работа с элементами массива по-отдельности? Естественно, такой метод нас не устроит! Значит, нам нужно использовать тот трюк, что написан выше. Для начала нужно разобраться какой диапазон актёров и маркеров содержит массив. В нашем случаи - это 5 актёров и 5 маркеров. Соответственно, диапазон актёров составляет последовательность из переменных: 10@ 11@ 12@ 13@ 14@, а диапазон маркеров - 20@ 21@ 22@ 23@ 24@

Формат массива всегда указывает количество переменных, их тип а также начальную переменную массива. Всё, что нам оставалось - это посчитать диапазон: 10 + 5 = 15. Поскольку итерация начинается с 0 а не с 1 в Sanny Builder, то число 15 уже не входит в диапазон, а последним элементом является 14. Немного математики и, по-аналогии, я так рассчитал диапазон для маркеров.

Теперь вернёмся к нашему примеру и попробуем изменить тип 3-го элемента массива. Начиная отсчёт с нуля, мы получили переменную 22\@.

```
07E0: set_marker 22@ type_to 1
```

Как видите, мы сократили скрипт на 1 опкод. В крупных проектах этих команд наберётся целая куча, которая будет занимать существенное место по объёму и скрипт будет выполнять намного больше команд, чем требуется. Аналогичным образом, давайте сократим скрипт с созданием актёров:

```
{$CLEO}

0376: 10@ = create_random_actor_at 2505.6489 -1664.1635 13.397 
0376: 11@ = create_random_actor_at 2506.1484 -1668.5974 13.3742 
0376: 12@ = create_random_actor_at 2504.1794 -1673.494 13.3634 
0376: 13@ = create_random_actor_at 2499.0459 -1675.1171 13.3458
0376: 14@ = create_random_actor_at 2495.4204 -1660.1552 13.3359

for 0@ = 0 to 4
0187: 20@(0@,5i) = create_marker_above_actor 10@(0@,5i)
end

07E0: set_marker 22@ type_to 1
0A93: end_custom_thread
```

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/68703011.png)<br>

Такой код намного легче читать, если знать этот трюк! Изначально скрипт имел размер 219 байт. После нашего исправления - 153 байта. Фактически, мы сэкономили 66 байт на наш скрипт. Оптимизация по размеру и быстродействию составляет 69%!!! И это только в небольшом скрипте. В крупных проектах эта цифра будет ещё больше.

Согласитесь, такой подход существенно улучшает производительность нашего кода а также упрощает его читаемость. Если немного потренироваться, то метод освоить не составит труда. Спасибо всем за внимание!|1421|1|0|68703011`png`480`360`320\`240\`\`||trjuk\_s\_lokalnymi\_massivami|1509826424


# 00073. Переменные, как члены класса. Коментарии в поиске опкодов. Макросы

Переменные, как члены класса. Коментарии в поиске опкодов. Макросы|Здравствуйте, уважаемы пользователи сайта! Здесь пойдёт речь о классах, а именно отнесения переменной к нему и её использование.|wmysterio|wmysterio||||Прежде всего, нам понадобится блок **VAR...END**, так, как именно он позволяет такую возможность. Давайте сначала выберем класс и переменную, которая будет отнесена к нему. Допустим, это будет класс "player", а переменная - "$PLAYER\_CHAR". Объявим всё это в блоке:

```
var
$PLAYER_CHAR: player
end
```

Это позволит нам использовать переменную в место класса! Причём этой переменной будут доступны все процедуры, свойства и условия этого класса! Для примера, введём эту переменную в поле SB и нажмём "**.**", как это обычно делается, и видим, что нам предлагают доступные для неё действия:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/20375270.png)

Давайте таким образом добавим деньги игроку. Используя возможность, это будет выглядеть так:

```
$PLAYER_CHAR.Money += 2000
```

Это существенно сокращает время, чем использовать обычный режим ввода. Давайте напишем пример скрипта, где при нажатии кнопки 1\`, игроку будут добавлять 1 доллар:

```
{$CLEO}
0000:

var
$PLAYER_CHAR: player
end

while true
 if
 0AB0: key_pressed 49 // 1
 then
 $PLAYER_CHAR.Money += 1
 end
wait 0
end
```

По аналогии, сделаем похожий скрипт загрузки модели. Нам нужно взять класс "model", а также номер ( или текстовой идентификатор ) модели. Допустим, это будет "#ADMIRAL". В блоке **var** пишем название модели и класс:

```

{$CLEO}
0000:

var
#ADMIRAL: model
end

:A
thread 'A'
wait 0
#ADMIRAL.Load
038B: load_requested_models
 
:A_1
wait 0
if
#ADMIRAL.Available
jf @A_1
0A93: end_custom_thread
```

Тогда код загрузки будет выглядеть так:

```
var
#ADMIRAL: model
end
```

Объявление переменных как членов класса очень удобная штука! Правда её редко используют новички, так как им ещё не понятно назначение этой возможности и из-за этого возникают много ошибок, например: пытаются привязать переменную к классу "camera", который по-сути не может иметь хендлов на субъекты.

Для закрепления этого небольшого материала вам задание - создать автомобиль, используя переменную "0@" как член класса.

Вторая часть урока будет посвящена комментариям в поисковике опкодов. Думаю многие заметили, что в результатах поиска бывают комментарии. Вот я Вам расскажу суть некоторых из них:

| Комментарий     | Описание                                                                           |
| --------------- | ---------------------------------------------------------------------------------- |
| // ( int )      | указывает, что переменные должны быть целыми числами                               |
| // ( float )    | указывает, что переменные должны быть дробными числами                             |
| // mission only | указывает, что опкод можно использовать только в миссиях                           |
| // IF and SET   | указывает, что опкод можно использовать как проверку, и как процедуру              |
| // any          | указывает, что переменная будет ассоциироваться, как номер                         |
| // versionA     | указывает, что опкод можно использовать для версии игры ( или какого то метода ) А |
| // v$           | указывает, что нужно использовать строковую переменную типа V                      |
| // s$           | указывает, что нужно использовать строковую переменную типа S                      |
| // see ped.dat  | указывает, что данные берутся с файла ( и их описание можно найти там )            |

Это только некоторые их комментариев, которые я часто использую.

**Макросы.**

Хм... Интересное название. Это наверное самая полезная возможность в Sanny Builder! Главная задача макросов - быстрая вставка кода. Изначально в СБ есть парочка стандартных макросов. Увидеть их можно, нажав комбинацию CTRL`+<kbd>J`:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/55487539.png)

Давайте выберем из списка макрос "else" и нажмём ENTER\`. Видим, что в окно программы вставился текст:

```
if

then

else

end // if
```

Теперь нам не нужно тратить время на написания команд )) Но, естественно, будет полезная возможность вставки своих кодов, поэтому давайте напишем небольшой скрипт:

```
model.Load(#ADMIRAL)
038B: load_requested_models

while not model.Available(#ADMIRAL)
wait 0
end

0@ = car.Create(#ADMIRAL, 0.0, 0.0, 0.0)
car.Angle(0@) = 0.0
model.Destroy(#ADMIRAL)
```

Теперь выделим этот текст и нажимаем "Добавить макрос", что находится в меню "Сервис":

![](https://github.com/wmysterio/scm-scripting-lessons/blob/main/_pu/1/28459959.png)

После этого выскочит окно и предложит сохранить макрос. Заполним поля и нажимаем "ок":

![](https://github.com/wmysterio/scm-scripting-lessons/blob/main/_pu/1/66264246.png)

Всё! Макрос добавлен! Теперь остаётся вызвать его, используя горячие клавиши! Очистите поле редактирования и повторите вставку макроса ( в списке появится добавленный ранее шаблон ).

Советую вам сделать шаблон Cleo-скрипта и миссии. Это намного сэкономит ваше время!|828|1|0|20375270`png`456`181`400`158``\|55487539`png`580`205`400`141\`\`|28459959`png`400\`311

```
`\|66264246`png`260`191
```

\`||peremennye\_kak\_chleny\_klassa\_komentarii\_v\_poiske\_opkodov\_makrosy|1499709653


# 00017. Условия в Sanny Builder (Часть 1)

Условия в Sanny Builder (Часть 1)|Наконец мы дошли до условий! Весь скриптинг, как и большинство языков программирования, состоит из сплошных условий.|wmysterio|wmysterio||||Что же такое условие? Условие — это проверка на правдивость или ложь какого либо действия или события в игре. То есть скрипт будет продолжаться только тогда, когда будет выполнены ( или не выполнены ) условия.

Что бы написать условие особых знаний не нужно. Для этого нужно написать слово **if**. После этого написать условие которое мы хотим проверить на правдивость или ложь. Давайте напишем небольшой пример:

```
// ...
create_thread @METKA
end_thread

:METKA
thread 'METKA'
wait 0
$DIMA = 0

:METKA_1
wait 0
IF
$DIMA == 1
JF @METKA_1
end_thread 
```

В нашем примере мы проверяем на правдивость ( далее - истину ). То есть проверяем: равна ли переменная "$DIMA" числу 1. Если переменная будет равна, то мы продолжаем движение по скрипту, иначе делаем прыжок на какую-то метку ( в нашем случаи мы прыгаем на метку ":METKA\_1", так, как ранее мы задали ей значение 0 ). И так пока переменная каким-то образом не станет единицей мы будем прыгать так по кругу. Давайте графически представим наш скрипт:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/18698668.png)

В нашем случаи:

IF - указываем компилятору, что сейчас будет проверка\
$DIMA == 1 - это и есть сама проверка. На этом месте всегда пишется условный опкод\
JF @METKA\_1 - указываем куда будет прыгать шарик, если условие НЕ выполнилось.× \*\*ВАЖНО:\*\* знаки \*\*=\*\* и \*\*==\*\* не одно и тоже! \*\*==\*\* является проверкой! Так же проверками будут знаки: \*\*<=\*\* и \*\*>=\*\* ( меньше равно, больше равно ).

Наш пример скрипта проверяет на правдивость. Что бы была проверка на ложь, нужно перед проверкой написать слово **not**. Вот пример скрипта:

```
// ... 
create_thread @METKA
end_thread 

:METKA 
thread 'METKA' 
wait 0 
$DIMA = 0

:METKA_1
wait 0
IF
NOT $DIMA == 1
JF @METKA_1
end_thread
```

То есть фактически мы можем сказать о проверка: переменная "$DIMA" не равна "1"? Можно сказать что мы спрашиваем в игры :) Рассмотрим графический вариант:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/40510976.png)

Принцип работы скрипта остаётся такой же, как и предыдущий вариант. Нас интересует проверка с "not". Мы проверяем переменную, то есть спрашиваем: "Переменная $DIMA не равна 1?". Так как в нашей переменной ранее был записан ноль, то условие срабатывает, потому что 0 не равен 1 в текущий момент. Скрипт идёт дальше ( не прыгает на метку, как в предыдущем варианте ) и в конце-концов доходит до завершение потока.

× \*\*Примечание:\*\* На самом деле условие выполняет проверки всегда на истину. Поэтому и есть вариации проверок ( с not или без ).

Очень часто приходится проверять на выполнение сразу нескольких условий. Для этого нужно после слова "if" дописать слово "and", то есть в нас должно получится: **if and**. После этого нужно написать несколько условных опкодов. Здесь есть ограничение: нельзя написать больше 9-и условий, иначе компилятор нам сообщит: "Неверное число условий. Максимум 9.":

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/90941240.png)

Давайте напишем пример скрипта, где используются несколько условий:

```
// ...
create_thread @METKA
end_thread

:METKA
thread 'METKA'
wait 0
$DIMA = 0 
$WASYA = 1 

:METKA_1
wait 0
if AND
$DIMA == 0 
$WASYA == 1
jf @METKA_1
end_thread
```

В нашем случаи есть две переменных. А проверяем мы:

* Равна ли переменная $DIMA числу 0;
* Равна ли переменная $WASYA числу 1;

Другими словами, если ВСЕ проверки будут истинными, то поток завершится.

Если оба условия выполняются мы продолжаем скрипт до его конца. Если мы напишем возле "$DIMA" слово "not", то условия не будут выполнятся и мы будем постоянно прыгать на назначенную метку до тех пор, пока каким то образом в переменной "$DIMA" не будет 0.

Так же в скриптинге существует условие **if or**. То есть если хотя бы одно условие будет выполнено. Возьмем для примера тот же скрипт, только немного его изменим:

```
...
create_thread @METKA
end_thread

:METKA
thread 'METKA'
wait 0
$DIMA = 1 
$WASYA = 1 

:METKA_1
wait 0
if OR
$DIMA == 0 
$WASYA == 1
jf @METKA_1
end_thread
```

В нашем случаи обе переменных равны единице. Мы можем спросить: "Переменная $DIMA равна 1 ИЛИ переменная $WASYA равна 1?" В нашем примере выполняется 1-но условие, поэтому дальше будет завершен поток. Если все условие не выполнялись бы, то мы сделали прыжок на метку ":METKA\_1". И так до тех пор, пока хотя бы одно условие не будет выполнено.

Расскажу ещё несколько слов о команде **jf**. Она используется всегда после всех условных опкодов, использующийся в условиях "if", и выполняет переход в случае истинности всех переданных проверок.|3972|1|0|18698668`png`910`281`400`123``\|40510976`png`522`273`400`209``\|90941240`png`443`131`400`118``||uslovija\_i\_klassy\_v\_sanny\_builder\_chast\_1|1498498758


# 00018. Условия в Sanny Builder (Часть 2)

Условия в Sanny Builder (Часть 2)|Это очередной наш урок, и мы рассмотрим условия, а точнее условия с использованием ключевого слова "then".|wmysterio|wmysterio||||Это, наверное, самая используемая конструкции в скриптинге. Если дословно перевести, то получится:

если - то - конец

Рассмотрим поподробнее эту конструкцию и правила её написания. Итак, начнём:

```
// ...
create_thread @METKA
end_thread

:METKA
thread 'METKA'
wait 0
$RITA = 0

:METKA_1
wait 0
if
$RITA == 2
then
jump @METKA_2
end
jump @METKA_1

:METKA_2
wait 0
end_thread
```

Графически такую конструкцию можно представить так:

![](https://github.com/wmysterio/scm-scripting-lessons/blob/main/_pu/0/13073727.png)

Смысл в том, что если условие срабатывает, то выполняется какое то действие ( в нашем случаи будет прыжок на метку ":METKA\_2" ). Но так, как условие ложно, то мы продолжаем идти по скрипту вниз. В конце обычно ставят прыжок на начальную метку, в нашем случаи это прыжок на метку ":METKA\_1". Это сделано для того, что бы зациклить скрипт. В большинстве случаев так делают, но это не всегда обязательно. Вот пример:

```
// ...
create_thread @METKA
end_thread
 
:METKA
thread 'METKA'
wait 0
$RITA = 2
 
:METKA_1
wait 0
if
$RITA == 2
then
$RITA = 1
jump @METKA_2
end
 
:METKA_2
wait 0
end_thread
```

А вот графический вариант:

![](https://github.com/wmysterio/scm-scripting-lessons/blob/main/_pu/0/13366438.png)

В нашем случаи даже если условие не выполнится, то мы всё равно будем идти по скрипту вниз, то есть мы автоматически прыгнем на метку ":METKA\_2". Ничего особенно не произойдёт. Но если наше условие сработает, как в данном случаи, то мы переменной "$RITA" будет задано число 1, а затем уже прыгнем на метку ":METKA\_2". В обеих случаях мы завершим скрипт. Напишем более сложный скрипт и подробно его осмотрим:

```
// ...
create_thread @METKA
end_thread

:METKA
thread 'METKA'
wait 0
$RITA = 2
$INNA = 1 
$KATYA = 0

:METKA_1
wait 0
if OR
$RITA == 1
$RITA == 0
then
$INNA = 0
end

if AND
$KATYA == 1
$INNA == 0
then
jump @METKA_2
end

if
$KATYA == 0
then
gosub @METKA_3
end
jump @METKA_1 

:METKA_2
wait 0
end_thread

:METKA_3
wait 0
$KATYA = 1
$RITA = 0
return
```

И по традиции рассмотрим графический вариант:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/43101005.png)

Думаю, что для новичков такой скрипт все мозги взломает, но раз вы хотите научится скриптингу, а вы хотите научится, раз читаете этот урок, то давайте изучим такой скрипт :)

В первую очередь, на что следует обратить внимание, это на количество "if" в нашем скрипте. Как видим, таких в нас насчиталось три. Дальше, после этого мы смотрим что после них идёт. В нашем случаи - это прыжок на другую метку. Метку, которая зацикливает наш скрипт - делает так, что бы код повторялся. Раз он повторяется, то значит вполне возможно, что из него есть выход! Смотрим на наш скрипт, а точнее на то, что будет после слова "then". Мы видим, что после второго "then" есть прыжок, который дальше должен завершить скрипт. Дальше мы смотрим на условия, при которых он будет делать прыжок.

В нашем случаи это будет тогда, когда переменные "$KATYA" и "$INNA" будут равны 1 и 0 соответственно, причём одновременно! Как видим, пока эти условие не выполняются, так как в них разные значения. Смотрим дальше скрипт. Видим "gosub" на метку ":METKA\_3". А условие, при котором будет прыжок выполняется. Значит прыгаем на метку, в корой изменяются значение переменных "$KATYA" и "$RITA". Как видим для завершения скрипта нам необходимо, что бы ещё переменная "$INNA" была равна нулю. Как видим пока она не равна, значит условие не выполняется и мы дальше продолжаем скрипт.

Дальше мы видим условие на выполнение хотя бы одного с них. Но мы уже видим, что 1-но точно выполняется ( я имею ввиду 1-й "if" ). Переменная "$RITA" равна 0. Раз условие срабатывает, значит переменная "$INNA" станет равной нулю, так как написано в скрипте ( см. первый "then", когда выполняется условие ), а раз она равна нулю и переменная "$KATYA" будет равна 1, то значит выполняются оба условия, при которых идёт прыжок на завершение скрипта.

Естественно, когда в условиях мы используем числа, то понять такой код сложнее, так как мы сами задаём соотвествующие значения и нет возможности, чтобы игра предоставила свои данные, на которые мы влиять не может. Но такие конструкции нужно понимать в первую очередь, так как умение проверять переменные играет важную роль.|1205|1|0|13073727`png`229\`363

```
`\|13366438`png`227`362
```

`\|43101005`png`429`758`282`500\`\`||uslovija\_v\_sanny\_builder\_chast\_2|1498507531


# 00019. Условия в Sanny Builder (Часть 3)

Условия в Sanny Builder (Часть 3)|Мы продолжаем изучать условия, и на этот раз мы рассмотрим конструкцию "if-then-else-end".|wmysterio|wmysterio||||Довольно хорошая конструкция, так как мы указываем что будет выполнятся, когда условие не срабатывает, а так же указываем действия, при которых условия срабатывают.

Рассмотрим конкретный пример, что бы разобраться в этой конструкции.

```
:METKA_1
wait 0
if
$RITA == 0
then
$KATYA = 1
else
$KATYA = 0
end
jump @METKA_1
```

Судя но логике, если переменная "$RITA" равна нулю, то переменная "$KATYA" будет равна 1. Если переменная $RITA **НЕ** будет равна нулю, то переменная "$KATYA" будет равна 0. Слово **else** переводится как "иначе". Конструкция довольно проста, её очень часто используют в скриптинге. Расмотрим более сложный пример и изучим его детально. Изучать его будем на примере с реальной жизни, так как показала статистика, наши уроки более понятны, когда мы наводим примеры именно из жизни.

Опять представим школу, представим какой то урок, например математики ( я не люблю математику от рождения :) ). Допустим кого-то с учеников вызвали к доске, например, Иванова, и предлагают ему решить задачу. В нас есть 2 варианта: либо он решит её и получит пятёрку, либо он нифига ( как и я :) ) не шарит её и получит двойку. Давайте сопоставим данные и напишем скрипт.

Первым делом нужно определится с переменными, которые будут использоваться в нашем скрипте. В первую очередь нужно назначить переменную, которая будет хранить оценку. Допустим это будет переменная "$OTSENKA", которая вначале будет равна нулю. Дальше мы нам нужно написать условие на то: решит ли он задачу. Соответственно, нам нужно написать переменную, которая будет проверятся. Допустим, это будет переменная "$ZNAYET". Соответственно, если он знает, то проверять мы будет: не равна ли эта переменная 1 - так мы будем знать решил ли он задачу или нет. Если переменная не равна 1, то значит переменная будет равна нулю, то есть он не знает ничего, чисто ноль :)

Думаю хватит теории и напишем скрипт:

```
create_thread @ZNANIE
end_thread

:ZNANIE
thread 'ZNANIE' 
wait 0
$OTSENKA = 0 // зададим значение изначальной оценки
$ZNAYET = 0 // переменная, которую мы будем проверять, то есть решил он задачу или нет
 
:ZNANIE_1
wait 0 
if
$ZNAYET == 1 // проверяем: знает ли он задачу ?
then
$OTSENKA = 5 // если да, то оценка 5
else
$OTSENKA = 2 // если нет, то оценка 2
end
end_thread // конец потока
```

Рассмотрим пример, но используя в реальной жизни:

:ZNANIE\
thread 'ZNANIE'\
wait 0\
оценка 0, то есть нустота, в Иванова нет оценки\
первоначальный этам знания мы написали, что равен нулю\
\
:ZNANIE\_1\
wait 0\
if\
решил ли он задачу\
then если да, то\
оценка 5\
else если нет, то\
оценка 2\
end\
end\_thread // конец потока

Разобраться с этой конструкцией не так то тяжело, так мы сможем лучше контролировать(проверять) процессы в нашем скрипте. Дальше мы будем рассматривать примеры с опкодами и там мы ещё детальнее рассмотрим эту конструкцию.

В Sanny Builder возможны и вложенные условия, то есть проверять новые условия, при выполнении предыдущих. Это довольно тяжело объяснить простым языком, но я всё же попытаюсь. Давайте напишем скрипт с использованием простого примера:

```
:ZNANIE
thread 'ZNANIE' 
wait 0
$IVAN = 0
$IGOR = 0

:ZNANIE_1
wait 0
if
$IVAN == 0
then
 if
 $IGOR == 1
 then
 jump @ZNANIE_2
 else
 jump @ZNANIE_3
 end
else
 if
 $IGOR == 1
 then
 jump @ZNANIE_2
 else
 jump @ZNANIE_3
 end
end
jump @ZNANIE_1
 
:ZNANIE_2
wait 0
end_thread 

:ZNANIE_3
wait 0
end_thread
```

Рассмотрим графический вариант этого скрипта:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/75963058.png)

Довольно сложно на первый взгляд, но, поверьте это ещё лёгкий пример, по сравнению с тем, что пишут опытные скриптеры. Обратим внимание на то, что есть 2 места финиша шарика! Это значит, что условиями мы можем манипулировать шариком. Это значит, что в зависимости от условий, шарик может завершать работу в том или ином месте. В нашем случаи таких мест два.

Сразу можно заметить, что в скрипте присутствуют три конструкции "if-then-else-end". Первой идёт проверка равности переменной "$IVAN". Если проверка срабатывает ( то есть переменная равна 0 ), то идёт новая проверка на равенство переменной "$IGOR". Если условие срабатывает, то идёт прыжок на метку "@ZNANIE\_2", если не срабатывает, то идёт прыжок на метку "@ZNANIE\_3". Если переменная "$IVAN" не равна 0, то идёт 3-я конструкция "if-then-else-end", которая такая же, как и вторая, проверяет на равенство переменную "$IGOR".

Ну что же, думаю необходимый минимум я вам предоставил, дальше мы ещё не раз будем рассматривать эти конструкции и постараюсь вам ещё подробнее рассказать о условиях.|1865|1|0|75963058`png`858`646`400\`301\`\`||uslovija\_v\_sanny\_builder\_chast\_3|1498508831


# 000181. Условия в Sanny Builder (Часть 4)

Условия в Sanny Builder (Часть 4)|В этом кратком уроке мы рассмотрим некоторые опкоды, которые работают в связке с условиями (0AA0 и 0AA1). Спустя столько времени, нашлось место и для четвёртой части этой темы.|wmysterio|wmysterio||||Привет! Несколько дней назад некоторые опкоды привлекли моё внимание и я решил протестировать их работу. Хоть и обычных инструментов для работы с условиями достаточно, опкоды 0AA0 и 0AA1 оказались довольно простыми в использовании.

Начну с опкода**0AA0**. Он позволяет выполнить переход на метку с возвратом, если условия не выполнились. Например: мы можем проверить существование актёра. Если он не создан, то сразу создать его:

```
{$CLEO}

00D6: if
056D: actor 0@ defined
0AA0: gosub_if_false @CREATE_NEW_ACTOR

05E2: AS_actor 0@ kill_actor $PLAYER_ACTOR
0A93: end_custom_thread

:CREATE_NEW_ACTOR
Model.Load(#WMYST)
038B: load_requested_models
0@ = Actor.Create(4,#WMYST,2490.5225, -1665.5012, 13.3437)
Model.Destroy(#WMYST)
return
```

Смысл думаю понятный. Если актёр "0@" не существует, то делаем переход к метке "CREATE\_NEW\_ACTOR", создаём актёра, и делаем возврат. После этого созданный актёр будет пытаться убить игрока. Это примерно тоже самое, что и этот код, только короче:

```
{$CLEO}

00D6: if
856D: not actor 0@ defined
then
gosub @CREATE_NEW_ACTOR
end

AS_actor 0@ kill_actor $PLAYER_ACTOR
0A93: end_custom_thread

:CREATE_NEW_ACTOR
Model.Load(#WMYST)
038B: load_requested_models
0@ = Actor.Create(4,#WMYST,2490.5225, -1665.5012, 13.3437)
Model.Destroy(#WMYST)
return
```

Если Вы читали статью [Избавляемся от "ёлочек"](https://github.com/wmysterio/scm-scripting-lessons/blob/main/publ/raznoe/izbavljaemsja_ot_jolochek/62-1-0-262/README.md), то вариант с опкодом 0AA0 позволит ещё и избавляться от конструкций "IF-THEN-END". Вот результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/42197446.png)

Конечно, этот пример достаточно прост, чтобы его переписать привычным для Вас способом. Однако будут "экзотические" ситуации, когда переход в случае не выполнения условий, будет оправдан в полной мере.

Далее поговорим об опкоде**0AA1**. Он менее полезен, так как используется внутри перехода с возвратом. Давайте рассмотрим следующий пример:

```
{$CLEO}
0209: 1@ = random_int_in_ranges 0 100 
if
1@ > 49
then
Model.Load(#WMYST)
038B: load_requested_models
0@ = Actor.Create(4,#WMYST,2490.5225, -1665.5012, 13.3437)
Model.Destroy(#WMYST)
0209: 2@ = random_int_in_ranges 20 200
0209: 3@ = random_int_in_ranges 20 101
Actor.Health(0@) = 2@
02E2: set_actor 0@ weapon_accuracy_to 3@
end

gosub @BABEL

0A93: end_custom_thread

// *** *** ***

:BABEL
if
056D: actor 0@ defined
jf @LABEL_END
if
0184: actor 0@ health >= 100 
jf @LABEL_END
05E2: AS_actor 0@ kill_actor $PLAYER_ACTOR

:LABEL_END
return
```

Суть скрипта проста: создаём актёра с вероятностью 50 на 50. Далее устанавливаем ему случайное здоровье и точность. Далее идёт переход к метке. Вот она нас и интересует. В ней мы даём команду убить игрока, если актёр создан и его здоровье минимум стандартное.

Таких условий может быть много. Но суть здесь в том, что мы делаем прыжок на метку "LABEL\_END", если эти условия не сработают. Опкод "0AA1: return\_if\_false" помогает избавится от этой метки, так как он делает возврат, если условие ложно (в опкоде описание какое-то кривое, уместно было бы "0AA1: else\_return", но да ладно ).

Давайте теперь перепишем метку уже с использованием нового (надеюсь) для Вас опкода:

```
{$CLEO}
0209: 1@ = random_int_in_ranges 0 100 
if
1@ > 49
then
Model.Load(#WMYST)
038B: load_requested_models
0@ = Actor.Create(4,#WMYST,2490.5225, -1665.5012, 13.3437)
Model.Destroy(#WMYST) 
0209: 2@ = random_int_in_ranges 20 200
0209: 3@ = random_int_in_ranges 20 101
Actor.Health(0@) = 2@
02E2: set_actor 0@ weapon_accuracy_to 3@
end

gosub @BABEL

0A93: end_custom_thread

// *** *** ***

:BABEL

if
056D: actor 0@ defined
0AA1: return_if_false // 0AA1: else_return

if
0184: actor 0@ health >= 100 
0AA1: return_if_false // 0AA1: else_return

05E2: AS_actor 0@ kill_actor $PLAYER_ACTOR
return
```

Опять же, его полезно использовать в "экзотических" случаях. Надеюсь, эти случаи будут попадаться чаще, чтобы пользоваться опкодом 0AA1.

На этом "экзотический" урок закончен. Спасибо за внимание!

× \*\*ВАЖНО:\*\* Опкоды доступны в библиотеке CLEO 4.0 и старше!|1|1|0|42197446\`png\`640\`384\`320\`192\`\`\\||uslovija\_v\_sanny\_builder\_chast\_4|1569703253


# 00045. Циклы (Часть 1 - while)

Циклы (Часть 1 - while)|Этот урок посвящен очень важной теме - циклам. А именно тем циклам, которые существенно упрощают написание скриптов.|wmysterio|wmysterio||||Есть три типа циклов: "while", "for", "repeat". Мы рассмотрим простое использование циклов. Прежде всего нужно понять как работают эти циклы и я постараюсь на примерах объяснить их использование. Поехали! :)

В этом уроке я расскажу о цикле **while**. Конструкция:

```
while 1@ == 0 // условие
wait 0
 // ...действия...
end
```

Суть этого цикла в том, что пока выполняется условие будут выполняются какие то-действия внутри блока. Если дословно перевести "while", то получится "Пока". Таким образом выйдет:

```
Пока 1@ == 0
Ждать 0
 ...действия...
КонецЦикла
```

После слова "while" обязательно должно быть **условие**! Напишем простой пример скрипта:

```
while not actor.Dead($PLAYER_ACTOR)
wait 0
 player.Money($PLAYER_CHAR) += 100
end
```

× \*\*ВАЖНО:\*\* в этом цикле обязательно нужно ставить задержку! Минимальная задержка - 0, но если нам не нужно выполнять его очень часто ( например: в стартерах ), то можно её увеличить.

Пока СЖ не умрёт он будет получать 100$. Как только он склеит ласты, он и перестанет получать деньги. Довольно трудно объяснить принцип работы цикла и в новичков часто возникают проблемы с написанием скриптов с этими конструкциями. Я постараюсь как-можно проще описать суть цикла, ведь это важный фундамент для написания хороших скриптов.

Рассмотрим пример из жизни. Прежде всего придумаем условие: "Сергей на работе?". Дальше придумаем что будет, если он на работе: "Он получает деньги". Таким образом можно образовать цикл как:

```
Пока Сергей на работе
 Он получает деньги
КонецЦикла

Сергей перестаёт получать деньги
```

Следовательно если Сергей не на работе - деньги ему не светят, то есть цикл завершается.

Особенностью цикла в том, что он выполняются по кругу неограниченное количество раз. Выйти с цикла, как уже сказано, можно только тогда, когда условие возле "while" перестает выполняется. Но есть способ прервать цикл принудительно, даже если условие выполняется. Для этого используется команда - **break** ( прервать ). Давайте напишем скрипт с теми же деньгами:

```
while not actor.Dead($PLAYER_ACTOR)
wait 0
 0@ = player.money($PLAYER_CHAR)

 if
 0@ > 5000
 then
 break
 end

 player.Money($PLAYER_CHAR) += 100
end
```

Данный скрипт будет постоянно давать СЖ деньги. Если он умрёт, то осуществится выход с цикла. И тут появилось ещё одно условие: если деньги СЖ превышают 5000, то мы принудительно завершаем цикл и не важно СЖ жив или мёртв. Таким образом мы сделали два выхода с цикла.

Давайте добавим ещё один выход с цикла, когда СЖ-я арестовали:

```
while not actor.Dead($PLAYER_ACTOR)
wait 0
 0@ = player.money($PLAYER_CHAR)
 
 if
 0@ > 5000
 then
 break
 end

 if
 0741: actor $PLAYER_ACTOR busted
 then
 break
 end 
 
 player.Money($PLAYER_CHAR) += 100
end
```

Обычно скриптеры объединяют условия выхода в один if. Это экономит место кода и делает скрипт более читабельным. Вот и мы немного упростим этот цикл:

```
while not actor.Dead($PLAYER_ACTOR)
wait 0
 0@ = player.money($PLAYER_CHAR) 

 if or
 0@ > 5000
 0741: actor $PLAYER_ACTOR busted
 then
 break
 end 

 player.Money($PLAYER_CHAR) += 100

end
```

Давайте графически покажем работу цикла:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/56999064.png)

Цвета линий:

* Желтый - обычное движение шарика;
* Красный - движение шарика, если условие НЕ выполняется;
* Зелёный - движение шарика, если условие выполняется;
* Фиолетовый - это сами условия;

Попробуйте и вы создать подобный скрипт и нарисовать к нему рисунок с движениями. Это поможет вам быстрее понять работу цикла. Свои варианты присылайте на форум. В большинстве случаев, человек, научившись делать такие схемы быстрее сможет научится скриптингу.

Существует также ещё один оператор. Это команда **continue** ( можно перевести как "продолжить" ). Суть команды в том, что она начинает цикл сначала, не выполняя опкоды, написанные после неё. Это существенно сокращает время выполнения цикла, так как не нужно будет выполнять команды, что находятся ниже по коду. Для примера можно написать скрипт, который будет генерировать целые числа, если они положительные, то с ними произойдут арифметические изменения. Если число будет ноль - прервём цикл. Если отрицательное - будем начинать цикл сначала. Напишем такой скрипт:

```
$MONEY = 10 

while 10000 > $MONEY
wait 0
 0209: $TEMP = random_int_in_ranges -10 10

 if
 0 > $TEMP
 then
 continue
 end
 
 if
 $TEMP == 0
 then
 break
 end

 $TEMP *= 2
 0058: $MONEY += $TEMP // (int)
end

player.Money($PLAYER_CHAR) += $MONEY
```

А вот и графический вариант:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/69422868.png)\
\
× \*\*ВАЖНО:\*\* Операторы "break" и "continue" используются только в циклах! Задержку в 0 мсек рекомендовано использовать сразу же после объявления цикла, если в нём существует оператор продолжения. Во многих случаях такой способ избавляет от зацикливания, что ведёт к зависанию игры

Также есть возможность использовать цикл в середине другого цикла, но об этом мы поговорим немного позже.|981|1|0|56999064`png`715`523`400`292``\|69422868`png`590`434`400`294\`\`||cikly\_chast\_1\_while|1498998674


# 00047. Циклы ( Часть 2 - for )

Циклы ( Часть 2 - for )|Мы продолжаем изучать циклы и в этом уроке вы познакомитесь с другим типом циклов.|wmysterio|wmysterio||||Вторая часть уроков о циклах посвящена циклу **for**. Особенностью этого цикла в том, что он может выполнить одну и ту же последовательность действий несколько раз, используя специальный счётчик. Например, этот счётик можно использовать для создания актёров или транспорта. Отличие этого цикла от "while" в том, что мы сами задаём сколько раз нужно обойти цикл, а "while" понятия не имеет сколько раз он будет это делать. Вот просто пример "for":

```
for 0@ = 0 to 16 step 1
 // ...опкоды...
end
```

Здесь:\
0@ = 0 - назначаем переменную в качестве счётчика\
16 - указываем границу, если переменная 0@ будет больше этого числа, то цикл прекращается\
step 1 - указываем шаг, то есть число, которое будет прибавляться к 0@ после прохождения кода внутри блока. Если шаг равен 1, то писать его не нужно, так как по-умолчанию этот шаг равен 1.

Такой цикл может только прибавлять к переменной шаг, однако есть возможность и убавлять. Вот пример:

```
for 0@ = 16 downto 0 step 1
 // ...опкоды...
end
```

Принцип работы такой же, как и в предыдущем примере, только от переменной 0@ будет отниматься 1 ( step ) до тех пор, пока переменная не будет меньше 0 ( downto ). "Зачем он нужен?" - спросите вы. Отвечу. Вот, например, нам нужно создать 5 актёров. Ну 5 - это не так и много, а представьте, что вам нужно создать 100 актёров. Вручную их писать будет только безумец, поэтому и создан этой цикл - для облегчения подобной рутины. Нам нужно только подставить несколько опкодов для создания. Давайте, для примера, создадим скрипт, который будет спавнить 100 автомобилей:

```
var
$CAR : array 100 of car
end

:CAR
thread 'CAR'
wait 0
gosub @CAR_1
$X = 2493.0298
$Y = -1658.8713
$Z = 13.3487

for $I = 0 to 100 step 1
 $CAR[$I] = car.Create(#MANANA, $X, $Y, $Z)
 car.Angle($CAR[$I]) = 170.1416
 $X += -4.0
end

Model.Destroy(#MANANA)
end_thread

:CAR_1
wait 0
model.Load(#MANANA)
038B: load_requested_models

:CAR_2
wait 0
if
model.Available(#MANANA)
jf @CAR_2
return
```

Сначала нужно объявить массив автомобилей. Дальше в цикле создаём транспорт, путём изменения индекса, которой изменяется в цикле ( переменная "$I" ) а так же изменяем в цикле координату "$X", чтобы тачки не спавнились в одном месте. Не стоит забывать, что память не резиновая, поэтому не надо злоупотреблять количеством создаваемых игровых объектов.

× \*\*Примечание:\*\* for - это цикл с известным количеством итераций ( повторений ), поэтому задержку здесь не обязательно

Думаю необходимую информацию я вам предоставил. Вам остаётся делать свои тесты. И, для практики, предлагаю вам создать небольшую армию ( Пед "#ARMY" с оружием "#M4" ). Ваши скрипты пишите на форум. Если что не ясно - спрашивайте!|1025|1|0||cikly\_chast\_2\_for|1499000408


# 00049. Циклы ( Часть 3 - repeat ). Вложенные циклы

Циклы ( Часть 3 - repeat ). Вложенные циклы|Мы опять изучаем циклы, и на очереди в нас - repeat.|wmysterio|wmysterio||||С вами wmysterio, и циклы далеко от меня и вас не делись :) Сегодня поговорим об третьем типе циклов - **repeat**. Этот цикл очень похож на "while", но отличие в том, что "repeat" сначала выполняет действия, а потом проверяет условия. При этом, в отличии от"while", выход с цикла будет если условие истинно! Вот для примера небольшой скрипт:

```
repeat
wait 0
 // ...опкоды...
until 0@ == 0
```

Сначала будут выполняться опкоды в блоке "repeat-until". После этого идёт проверка условия "0@ == 0". Если это условие выполняется, то мы выходим с цикла. Если нет, то начинаем цикл заново. Давайте напишем самый простой скрипт с использованием этого цикла:

```
:UNTIL
thread 'UNTIL'
wait 0

repeat
wait 0
 player.Money($PLAYER_CHAR) += 100
until actor.Dead($PLAYER_ACTOR)

end_thread
```

Смысл скрипта в том, что пока СЖ будет жив, он будет постоянно получать +100 денег. Давайте рассмотрим графический вариант этого скрипта:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/15530028.png)

И так, уже по-традиции, цвета линий:

* Желтый - обычное движение шарика;
* Фиолетовый - условие;
* Красный - движение шарика, если условие НЕ выполняется;
* Зелёный - движение шарика, если условие выполняется;

Лично я практически не использую этот цикл, но уверен, что он существенно упрощает коддинг и делает скрипт более читабельным.

Естественно в таком цикле можно использовать операторы "break" и "continue". Ваша задача - сделать скрипт с использованием этих операторов. :)

Итак, циклы мы рассмотрели. Осталось только одна важная тема - вложенные циклы. Что значит "вложенные"? Это циклы, которые находятся внутри других циклов. Вот небольшой пример использования вложенных циклов:

```
:UNTIL
thread 'UNTIL'
wait 0

for $Attempt = 1 to 5 step 1

 repeat
 wait 0
 player.Money($PLAYER_CHAR) += 100
 until actor.Dead($PLAYER_ACTOR)

end

end_thread
```

Как видите, цикл "repeat" вложен в цикл "for". Как и предыдущем примере, СЖ-ю будет постоянно прибавляться денюжка. Если СЖ умрёт, то денюжка будет и дальше прибавляться, но пока он не умрёт больше 5 раз ( исходя из цикла "for" ). Новичкам довольно сложно понять принцип работы скрипта, так как им тяжело представлять сами движения, но сделав пару скриптов, большинство начинает понимать как работает такая система. Чем больше попыток, тем лучше будет осваиваться материал.

Ваша задача - сделать три вложенных цикла ( в любом порядке ), а свои примеры пишите на форум. Я специально даю задания, что бы вы учились работать с циклами, так как это переход на новый уровень скриптинга.|1180|1|0|15530028`png`403`210`400\`208\`\`||cikly\_chast\_3\_repeat\_vlozhennye\_cikly|1499000993


# 00087. Таблицы переходов

Таблицы переходов|Всем привет! Сегодняшний урок посвящен таблицам переходов. Это довольно сложная в освоении тема, особенно для тех, кто не встречался со словом "программирование". Но я постараюсь вам предоставить необходимую информацию, чтобы основы этой темы вам запомнились и было понятно, для чего нужны эти таблицы.|wmysterio|wmysterio||||Если у Вас есть опыт в программировании, то слово **switch** вам говорит о многом. Для тех скриптеров, которые и не видели среды программирования объясню что к чему. Оператор "switch" предназначен для организации выбора из множества различных вариантов. Сами варианты написаны в блоке **case**...**break**. Оператор принимает какое то значение, и если оно совпало со значением "case", то выполняется соответственный участок кода. Для примера, вот вам фрагмент кода из C++:

```
cpp
int А;
scanf( "%d", &А );

switch(А) {
 case 1: {
 ... 
 break; 
 }

 case 2: {
 ... 
 break; 
 }

 default: {
 ... 
 break; 
 }
}
```

Суть проста. Считываем значение переменной "А". Передаём её в оператор "switch". Дальше идёт сравнение значений "case", которые задаются изначально ( обычно это целые числа ) и если переменная "А" равна значению "case" ( в нашем случае числа 1 и 2 ), то будет выполняться код в этом блоке. Допустим, пользователь ввёл число 1. Далее оператор сравнивает это число со всеми "case". Как видите, переменная "А" равна единице и один из "case" тоже равен единице. Выполняются оба условия, и начинается выполнение блока "case 1 ... break".

Закончили с программированием, перейдём скриптам. Для осуществления подобной операции используется опкод с огромным количеством параметров:

```
0871: init_jump_table $CHECK total_jumps 4 default_jump 0 @J_E jumps 0 @J_0 1 @J_1 2 @J_2 3 @J_3 -1 @J_E -1 @J_E -1 @J_E
```

Давайте разбирать, что к чему :)

Здесь:\
$CHECK - переменная, которая сравнивается с номером метки ( обычно содержит целое число и начинаться, которое начинается нуля )\
total\_jumps 4 - количество рабочих прыжков, включая прыжок, если ни один из вариантов не подошел\
default\_jump 0 @J\_E - прыжок на метку @J\_E по-умолчанию. Выполняется тогда, когда переменная $CHECK не соответствует номерам меток. Так же метка является выходом из таблицы переходом\
1 @J\_1 - \*\*1\*\* это номер метки, \*\*@J\_1\*\* сама метка. Максимальное и минимальное количество меток - 7. Если номер поставить в -1, то проверка "$CHECK == номер метки?" выполнятся не будет, а саму метку пишут в качестве метки-выхода

Давайте напишем пример, который, в зависимости от вы нажатой клавиши, меняет скин игрока:

```
{$CLEO}
0000:

var
$CHECK: integer = 0
end

:JUMP
thread 'JUMP'
wait 0

if
0AB0: key_pressed 49 // 1
then
$CHECK = 3
gosub @JUMP_A
end

if
0AB0: key_pressed 50 // 2
then
$CHECK = 2
gosub @JUMP_A
end

if
0AB0: key_pressed 51 // 3
then
$CHECK = 1
gosub @JUMP_A
end

if
0AB0: key_pressed 52 // 4
then
$CHECK = 0
gosub @JUMP_A
end

jump @JUMP

{* НАША ТАБЛИЦА ПЕРЕХОДОВ *}

:JUMP_A
wait 0
0871: init_jump_table $CHECK total_jumps 4 default_jump 0 @JUMP_EXIT jumps 0 @JUMP_0 1 @JUMP_1 2 @JUMP_2 3 @JUMP_3 -1 @JUMP_EXIT -1 @JUMP_EXIT -1 @JUMP_EXIT

:JUMP_0 // номер метки с таблицы переходов = 0
wait 0
model.Load(#WMYST)
038B: load_requested_models

:JUMP_0_1
wait 0
if
model.Available(#WMYST)
jf @JUMP_0_1
09C7: change_player $PLAYER_CHAR model_to #WMYST
model.Destroy(#WMYST)
jump @JUMP_EXIT

:JUMP_1 // номер метки с таблицы переходов = 1
wait 0
model.Load(#BMYDRUG)
038B: load_requested_models

:JUMP_1_1
wait 0
if
model.Available(#BMYDRUG)
jf @JUMP_1_1
09C7: change_player $PLAYER_CHAR model_to #BMYDRUG
model.Destroy(#BMYDRUG)
jump @JUMP_EXIT

:JUMP_2 // номер метки с таблицы переходов = 2
wait 0
model.Load(#WMYCLOT)
038B: load_requested_models

:JUMP_2_1
wait 0
if
model.Available(#WMYCLOT)
jf @JUMP_2_1
09C7: change_player $PLAYER_CHAR model_to #WMYCLOT
model.Destroy(#BMYDRUG)
jump @JUMP_EXIT

:JUMP_3 // номер метки с таблицы переходов = 3
wait 0
09C7: change_player $PLAYER_CHAR model_to #NULL
jump @JUMP_EXIT

:JUMP_EXIT
return
```

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/39868936.png)

Естественно можно было куда легче сделать этот скрипт, однако этот пример отлично подходит для темы этого урока. Если разобраться что куда ставить, то можно сделать очень много полезных вещей для ваших модификций. Например, в глобальных скриптовых модах можно организовать различные концовки игры.

Теперь собственно задание для самоконтроля - организовать выбор стилей борьбы для CJ. Пример у Вас есть, так что особой сложности в написании не должно возникнуть. Если всёже есть вопросы по этой теме - обращайтесь на [форум](https://github.com/wmysterio/scm-scripting-lessons/blob/main/forum/6-9-1/README.md) :)|1168|1|0|39868936`png`600`360`400\`240\`\`||tablicy\_perekhodov|1500713685


# 00059. Подключение текстовых файлов, scm-функции

Подключение текстовых файлов, scm-функции|Сегодня мы рассмотрим одну из интереснейших тем - создание SCM-функций.|wmysterio|wmysterio||||Здравствуйте, дорогие друзья. Начинаем очередной урок по скриптингу. Использование функций очень удобно, когда нужно выполнять один и тот же код несколько раз. Действуют функции по аналогии с **gosub**, только в функции можно передавать параметры. Есть два опкода для работы с функциями:

```
0AB1: call_scm_func @GetSQR 1 10 $result
```

Здесь:\
@GetSQR - указывается метка, где будет выполнятся функция\
1 - количество передаваемых параметров\
10 - это сами параметры\
$result - результат выполнения функции ( если такой есть )

```
0AB2: ret 1 0@
```

Здесь:\
1 - количество возвращаемых параметров\
0@ - сами параметры

Давайте напишем саму функцию:

```
:GetSQR
wait 0
006A: 0@ *= 0@ // (int)
0AB2: ret 1 0@
```

Обратите внимание, что передаваемые параметры имеют переменные 0@, 1@, 2@ и так до 32-х штук. Но они не влияют на переменные в самом потоке. То есть если у нас был раньше актёр в переменной 0@, то после выполнения функции он так и останется в ней. Рассмотрим лучший пример:

```
:LABEL
thread 'LABEL'
wait 0 
0AB1: call_scm_func @SPAWN_ACTOR 4 spawn_at -1390.0 14.0 39.0 angle 180.0 $ACTOR
05E2: AS_actor $ACTOR kill_actor $PLAYER_ACTOR
end_thread
 
:SPAWN_ACTOR
wait 0
model.Load(#WMYDRUG)
038B: load_requested_models

:SPAWN_ACTOR_1
wait 0
if
model.Available(#WMYDRUG)
jf @SPAWN_ACTOR_1
4@ = actor.Create(4, #WMYDRUG, 0@, 1@, 2@)
actor.Angle(4@) = 3@
model.Destroy(#WMYDRUG)
0AB2: ret 1 4@
```

Обратите внимание на параметры функции. При вызове каждый параметр получает свою локальную переменную в функции, где мы можем обрабатывать их с какой-то целью. Рассмотрим рисунок, который покажет как работает функция:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/36274742.png)\
\
× \*\*ВАЖНО:\*\* Параметры функции, который возвращает опкод "0AB2" всегда должны стоять после передаваемых параметров

Запускаем игру - отлично! Созданный нами актёр хочет убить нас, что и нужно было доказать :)

Один интересный факт насчет опкода 0AB1. Как видите, в нём мы можем дописывать различные строки, например: "pawn\_at" и в любых местах. Компилятору будет по-барабану :) Даже если функция будет написана так:

```
0AB1: @SPAWN_ACTOR 4 2475.1167 -1674.4192 13.3368 287.7152 $ACTOR
```

Главное, что бы были параметры и метка ;)

"Зачем это нужно?" - Спросите Вы. Ведь функцию всё равно нужно будет писать каждый раз в скрипте. Естественно можно и обойтись без функций, но что если нужно одну и туже функцию применять в 2-х разных скриптах? Зачем писать их две штуки, если можно написать только одну, которая будет хранится в файле! Мы только подключим его в нужный скрипт и будем использовать функцию.

Подключение файла напоминает команду из языка программирования C/C++: #include "file.h", только здесь нужно писать так:

```
{$I file.txt}
```

Здесь:\
$i - указываем компилятору, что нужно подключить файл ( include )\
file.txt - название файла. Расширение может быть любое, но в нём должен быть текст, то есть что бы мы могли его редактировать блокнотом и прочими текстовыми редакторами

Поиск файла ведётся относительно следующих папок:

* Папка, где находится файл, содержащий данную директиву;
* Папка Sanny Builder\data\\\<game>
* Корневая папка Sanny Builder;
* Корневая папка игры;

Давайте создадим текстовый файл "function.txt" в папке с "gta\_sa.exe". Открываем файл. Копируем код функции с SB в текстовый файл. После этого очищаем скрипт от кода функции. В скрипте должно быть только эти строки:

```
{$CLEO}
{$I function.txt}

:LABEL
thread 'LABEL'
wait 0 
0AB1: call_scm_func @SPAWN_ACTOR 4 spawn_actor_at 2475.1167 -1674.4192 13.3368 angle 287.7152 $ACTOR
05E2: AS_actor $ACTOR kill_actor $PLAYER_ACTOR
0A93: end_custom_thread
```

Сохраняем файл "function.txt" и пытаемся скомпилировать скрипт. В нас ошибка: "Переход на нулевой оффсет". Давайте поставим опкод "0000". Та же ошибка! Что делать? А спасёт нас оператор **goto**. Действует он точно как и "jump". Нам нужно отредактировать текстовый файл. Для этого создадим метку ":SPAWN\_ACTOR\_END" в самом конце файла "function.txt". А в самом верху, перед меткой ":SPAWN\_ACTOR" делаем переход с помощью оператора "goto". Таким образом содержимое "function.txt" будет таково:

```
goto @SPAWN_ACTOR_END // начало "обёртки" функции
:SPAWN_ACTOR
wait 0
model.Load(#WMYDRUG)
038B: load_requested_models

:SPAWN_ACTOR_1
wait 0
if
model.Available(#WMYDRUG)
jf @SPAWN_ACTOR_1
4@ = actor.Create(6, #WMYDRUG, 0@, 1@, 2@)
actor.Angle(4@) = 3@
model.Destroy(#WMYDRUG)
0AB2: ret 1 4@
:SPAWN_ACTOR_END // конец "обёртки" функции
```

Думаю постоянно метку писать как то неудобно, да большинство из них можно и не запомнить а постоянно открывать файл ещё неудобнее. Поэтому давайте дадим имя метки с помощью констант:

```
const
spawn_actor = @SPAWN_ACTOR
end
```

и добавим этот текст в начало файла "function.txt". Теперь сама функция может иметь такой вид:

```
0AB1: spawn_actor 4 at 2475.1167 -1674.4192 13.3368 angle 287.7152 handle $ACTOR
```

Как видите мы сократили длину функции, что очень удобно и легко запоминается! Теперь эту функцию можно использовать в любом скрипте, подключив этот файл :)

× \*\*Примечание:\*\* испольховать такие константы в крупных проектах проблематично, по-этому рекомендую использовать метки× \*\*ВАЖНО:\*\* функции нужно объявлять в начале скрипта и только потом писать его код

Задания!

* Написать две функции:
* Функция считывает цвета машины и заносит их в ini-файл "color.ini";
* Функция устанавливает цвета машины, используя параметры ini-файла "color.ini";
* Написать скрипт, что бы каждая новая машина, в которую входит СЖ, меняла свои цвета на цвета предыдущей машины;

Посмотрите на картинку выше. На ней есть незначительная ошибка. Тот, кто первый найдёт её - получит + к репутации :D|1496|1|0|36274742`png`1171`564`399\`192\`\`||podkljuchenie\_tekstovykh\_fajlov\_scm\_funkcii|1499599651


# 000155. Использование SCM-функций (опкод 0AB1)

Использование SCM-функций (опкод 0AB1)|Что же такое SCM-функция? На деле это выглядит так, словно мы вызываем опкод, который создали сами и, он выполняет определённые действия. С одной стороны, он похож на стандартный gosub, но принцип работы у SCM-функции другой - все переменные сохраняют свои значения, несмотря на то, что в функции используются те же переменные ( имеются ввиду локальные переменные )|BoPoH|BoPoH||||Основное назначение SCM-функций - укорачивание кода скрипта и улучшение его читабельности, если в нём используются одни и те же конструкции во многих местах. За вызов SCM-функции отвечает опкод 0AB1. Этот опкод добавляется библиотекой CLEO, поэтому если у вас её нет - опкод работать не будет. Давайте рассмотрим подробнее его параметры.

```
0AB1: call_scm_func @function num_params 1 10
```

Здесь:\
@function - это метка, указывающая на код нашей SCM-функции\
1 - это количество параметров, которые мы передаём в функцию ( не более 32 ). Эти параметры используются функцией для выполнения определённых задач, связанных с этими параметрами. К примеру, если функция будет помещать актёра в определённую точку, то в неё мы будем передавать хендл актёра.\
10 ( и т.п. ) - это те параметры, которые будут передаваться в функцию ( не более 32 ). Их количество должно совпадать со вторым параметром. Т.е. если вы вторым параметром указали число 3, значит после него вы должны указать 3 параметра, которые передадутся в функцию.

Например:

```
0AB1: call_scm_func @function num_params 4 $PLAYER_ACTOR 1@ 2@ 3@
```

Оставшиеся параметры ( переменные ) будут получать возвращаемые функцией данные. SCM-функция может возвращать одно и более значений при помощи опкода 0AB2. Если функция не возвращает параметров, то никаких переменных в конце опкода писать не нужно. Попробуем разобрать пример, приведённый ниже:

```
model.Load(#ELEGY)
038B: load_requested_models

while true
wait 0
 if
 0AB0: key_pressed 48
 then
 0AB1: call_scm_func @SpawnCarBeforePlayer 5 $PLAYER_ACTOR 0.0 5.0 0.0 #ELEGY 0@
 car.SetImmunities(0@, 1, 1, 1, 1, 1)
 while 0AB0: key_pressed 48
 wait 0
 end
 end
end

:SpawnCarBeforePlayer
04C4: store_coords_to 10@ 11@ 12@ from_actor 0@ with_offset 1@ 2@ 3@
13@ = car.Create(4@, 10@, 11@, 12@)
0AB2: ret 1 13@
```

По нажатию клавиши 0\`, перед игроком заспаунится элегия и ей присвоятся иммунитеты. Рассмотрим вызов функции опкодом 0AB1. Здесь у нас 5 параметров, которые передаются в функцию, и одно возвращаемое значение - хендл созданной машины.

Сама SCM-функция находится за пределами основного цикла скрипта. Исполнение скрипта не должно дойти до неё иным способом, кроме как через опкод 0AB1. Проще говоря, SCM-функции лучше всего оставлять в конце скрипта, а не в середине и уж тем более, не в начале.

Исходя из того, что компилятор спокойно воспринимает изменения описаний опкодов, мы можем спокойно изменить внешний вид опкода 0AB1 под свои нужды. К примеру, так:

```
0AB1: @SpawnCarBeforePlayer 5 actor $PLAYER_ACTOR offset_XYZ 0.0 5.0 0.0 car_model #ELEGY get_handle_to 0@
```

Таким образом, вызов фукции становится более читабельным. Описание к каждой функции можно придумывать своё.

Лично я перед меткой функции оставляю комментарий с примером вызова функции, чтобы не забывать, какие параметры передаются в функцию и какие возвращаются.

Теперь разберём саму функцию. Параметры, которые передаются опкодом 0AB1 в функцию, записываются последовательно в локальные переменные функции, начиная с 0\@. В нашем случае, в 0@ запишется хендл актёра, в 1@, 2@ и 3@ - смещение от актёра, а в 4@ - модель машины.

Заканчивается работа функции опкодом 0AB2.

Первый параметр в этом опкоде - количество параметров, которые возвращаются из функции и запишутся в соответствующие переменные, указанные в опкоде 0AB1. Если функция не должна возвращать параметров, то указываем 0. Если функция возвращает один или несколько параметров - указываем соответствующее значение и далее вписываем необходимые значения или переменные, значения которых должны быть возвращены.

SCM-функции могут быть вложенными, как и gosub-ы - можно использовать SCM-функции внутри других SCM-функций.

У каждой функции есть свой независимый набор локальных переменных - можно вызывать их, не боясь, что вы потеряете данные из локальных переменных основного потока.

У SCM-функций есть один неприятный недостаток - они сильно замедляют работу скрипта. Если использование десятка-другого функций за один цикл игры никак не отразится на производительности игры, то сотня функций за один цикл игры может заметно снизить фпс. Таким образом, не рекомендуется использовать SCM-функции в циклах с большим количеством итераций.

У SCM-функций есть одна особенность - если передавать в неё строковые переменные ( 13\@v, например ), то в соответствующую локальную переменную функции запишется указатель на строковую переменную ( т.е. на переменную 13@ в данном примере). Для тех, кто не разбирается в работе с памятью, могу объяснить проще - строковые параметры в обычном виде в функцию передать нельзя. Если вы хотите передать строку, то нужно передавать её в виде 4 последовательных переменных, начиная с той, в которую записана строка. Например:

```
10@v = "Function"
0AB1: @AddGXT 4 10@ 11@ 12@ 13@
```

А в функции уже можно использовать её как строковую переменную:

```
:AddGXT
0ADF: add_dynamic_GXT_entry "MYTBL" text 0@v
0AB2: ret 0
```

Я думаю, на этом закончим урок. Я постарался раскрыть все известные мне детали, хотя мог что-нибудь и упустить. Если есть вопросы или вы хотели бы видеть урок по теме, которая вас интересует - пишите в комментариях.|1983|315|0||ispolzovanie\_scm\_funkcij\_opkod\_0ab1|1504597275


# 000162. Используем scm-функции в качестве проверок

Используем scm-функции в качестве проверок|Вроде нигде не видел подобного урока, поэтому решил написать о использовании scm-функции в качестве проверок.|BoPoH|BoPoH||||Впрочем, тут и писать особо нечего. Например, вам нужно сделать scm-функцию поиска педа в радиусе с определённым ID модели. Выглядеть она будет примерно так:

```
:SearchPedWithModel
/*
 0AB1: @SearchPedWithModel 5 point 0@ 1@ 2@ radius 40.0 model 7 get_handle 5@
*/

if
0AE1: 5@ = random_actor_near_point 0@ 1@ 2@ in_radius 3@ find_next 0 pass_deads 0
then
 if
 02F2: actor 5@ model == 4@
 then
 0AB2: ret 1 5@
 end
 
 while 0AE1: 5@ = random_actor_near_point 0@ 1@ 2@ in_radius 3@ find_next 1 pass_deads 0
 if
 02F2: actor 5@ model == 4@
 then
 0AB2: ret 1 5@
 end
 end
end
0AB2: ret 1 0
```

В основном коде вы можете сделать так:

```
0AB1: @SearchPedWithModel 5 point 0@ 1@ 2@ radius 40.0 model 7 get_handle 5@
if
056D: actor 5@ defined
then
 // выполняем действие
end
```

Но, согласитесь, было бы гораздо удобнее иметь такую конструкцию:

```
if
0AB1: @SearchPedWithModel 5 point 0@ 1@ 2@ radius 40.0 model 7 get_handle 5@
then
 // выполняем действие
end
```

Для того, чтобы такая конструкция сработала, нам необходимо вставить следующие строки в функцию перед возвратом значения:

```
0A9F: 0@ = current_thread_pointer
0AA6: call_method 0x4859D0 struct 0@ num_params 1 pop 0 return 0xFF
```

Вместо переменной 0@ здесь можно использовать любую удобную переменную, главное заменить её в обеих строках. Значение 0xFF в конце означает возвращаемое булевое значение: если вы укажете **0xFF**, то функция вернёт **true**, а если укажете **0**, то функция вернёт **false**.

Однако, если мы захотим использовать несколько проверок в основном коде сразу ( **if and** или **if or** ), то нашу функцию нужно ставить в самое начало проверок. К тому же, если мы захотим использовать сразу несколько функций-проверок, то они будут работать только если внутри функций нет проверок/циклов. Короче говоря, лучше всего использовать такие проверки поодиночке. В конечном счёте, наша функция будет выглядеть так:

```
:SearchPedWithModel
/*
 0AB1: @SearchPedWithModel 5 point 0@ 1@ 2@ radius 40.0 model 7 get_handle 5@
*/

if
0AE1: 5@ = random_actor_near_point 0@ 1@ 2@ in_radius 3@ find_next 0 pass_deads 0
then
 if
 02F2: actor 5@ model == 4@
 then
 0A9F: 30@ = current_thread_pointer
 0AA6: call_method 0x4859D0 struct 30@ num_params 1 pop 0 return 0xFF
 0AB2: ret 1 5@
 end
 
 while 0AE1: 5@ = random_actor_near_point 0@ 1@ 2@ in_radius 3@ find_next 1 pass_deads 0
 if
 02F2: actor 5@ model == 4@
 then
 0A9F: 30@ = current_thread_pointer
 0AA6: call_method 0x4859D0 struct 30@ num_params 1 pop 0 return 0xFF
 0AB2: ret 1 5@
 end
 end
end
0A9F: 30@ = current_thread_pointern
0AA6: call_method 0x4859D0 struct 30@ num_params 1 pop 0 return 0x0
0AB2: ret 1 0
```

|1421|315|0|69473416`png`793`510`400\`257\`\`||ispolzuem\_scm\_funkcii\_v\_kachestve\_proverok|1504601800


# Координаты. Угол. Получение координат и угла Z

Если Вы ещё новичок в скриптинге, то эта информация будет для Вас полезной. Речь пойдёт о пространстве игры, а точнее о координатах и углах.

В этом уроке мы рассмотрим концепцию координат в играх серии GTA. Если смотреть в общем, то игровой мир — это большой квадрат, внутри которого находится игровой мир. Как правило, в играх есть координатная сетка, по которой можно узнать где сейчас находится игрок, объект и прочее. Если смотреть на мир что называется сверху, то сетка имеет две оси: `X` и `Y`. Центр обычно находится в координатах `{0.0; 0.0}`. Давайте посмотрим на карту:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/56448064.png)

Центр мы видим, и его координаты мы знаем. Какая же максимальная длина "X" и "Y"? Каждой карте всегда есть предел. В нашем случае длина не может составлять больше 3000.0. Для моддинга рекомендую 2800.0 единиц, иначе если выйти за его пределы, то карта станет невидимой (но поверхность всё равно ощущать можно). Это конкретно для GTA SA; а вот для  GTA 3 и GTA Vice City эти значения ещё меньше, так как размер карты там меньше.

Также в 3D играх (в том числе и в наших GTA-шек), существует и 3-й компонент: `Z`. Как уже многие догадались, это высота (например, над уровнем моря). На картинке такую высоту определить нельзя, однако в игровом мире мы это ясно видим.

### Поиск координат и угла поворота

Чтобы разместить в игре какой-нибудь субъект, нужно получить координаты. Sanny Builder позволяет это сделать. Для этого нужно запустить игру и подождать, пока игра не даст контроль над главным героем. Затем выбрать нужную позицию:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/00814873.png)

&#x20;Далее свернуть игру любым способом (например, кнопкой `WINDOWS` или `Alt`+`Tab`), и в Sanny Builder нажать на кнопки `CTRL`+`SHIFT`+`C`:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/09504944.png)

Это сработает, если есть активная вкладка. Координаты должны появиться возле курсора. Первое число — позиция по оси "X", другая — позиция по оси "Y", и третья — позиция по оси "Z". В зависимости от ситуации, игровую сущность нужно повернуть на определённый угол. Для этого развернём главного героя в нужную сторону:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/36238161.png)

и воспользуемся комбинацией кнопок `CTRL`+`SHIFT`+`E`:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/07641083.png)

В нашем случае угол равен 308.2786 градусов. Если нужно только просмотреть координаты и угол, то можно использовать комбинацию `CTRL`+`SHIFT`+`1` и тогда появится окно с нужной информацией.

{% hint style="success" %}
Комбинации кнопок можно сменить на более удобные в настройках SB.
{% endhint %}

Обратите внимание, что угол в этом контексте является углом по оси "Z", то есть относительно высоты. В большинстве случаев этого будет достаточно. Однако стоит упомянуть, что есть ещё и углы по осям "X" и "Y" и получить их горячими клавишами уже нельзя. Можно только через скрипты или другими программами.

{% hint style="warning" %}
Координаты обычно являются вещественными числами, поэтому в скрипте они пишутся через точку!
{% endhint %}

Думаю, что общие сведения и навыки Вы получили.

### Как можно представить поиск координат?

В качестве дополнения, можно условно представить как происходит поиск. На деле всё делается путём чтения значений по адресам игровой памяти. Это другой процесс и на текущем этапе думать над этим ненужно.

Для начинающих всё это можно представить так: сначала идёт поиск по оси "Х" по условной шкале (ось "X"). Если смотреть на карту, то слева-направо. Останавливается поиск тогда, когда найдена позиция игрока игрока по этой оси. Дальше идёт поиск по оси "Y" (то есть идёт поиск снизу-вверх). Ну и также проходит поиск по высоте (ось "Z"). Когда все значения найдены, компилятор сообщает нам текущую позицию игрока на карте в виде координат. Это происходит и с углом "Z".

Не забываем также и о отрицательных величинах! Координаты левого нижнего угла карты пишутся так: `{-2800.0; -2800.0}`, соответственно координаты правого верхнего угла карты: `{2800.0; 2800.0}`.

Как видим, есть и отрицательные числа. Все координаты, которые по оси "X" находятся левее от центра будут "идти" в минус, причём чем далее от центра, тем больше число с минусом. По аналогии и по осям "Y" и "Z". Посмотрите на карту и представьте эту сетку и её координаты.

Что касается углов (по всем осям), то устанавливаются лимиты: от 0 до 360 градусов. Но справедливости ради встречаются и отрицательные числа: от 0 до -360 градусов. Игровой движок вполне работает с отрицательными числами. Поэтому если угол будет отрицательной величиной, то ничего страшного не случится. Игровые движки умеют самостоятельно все эти числа конвертировать в нужный их формат.

Автор: **wmysterio**


# 000154. Вся правда о wait 0

Вся правда о wait 0|Многие из скриптеров, прочитав название статьи, подумают - "А чего там знать? Просто нужно не забывать ставить wait 0 после каждой метки и всё!". Но, к сожалению, они окажутся неправы.|BoPoH|BoPoH||||Подавляющая часть скриптеров училась либо по справке к SB, либо у тех, кто учился по этой справке. В конечном итоге, они используют wait 0 после каждой метки или в каждом цикле, ведь так делалось в примерах в справке, а справка "никогда не врёт". Но тут стоит обратить внимание на то, что автор справки ( **Alexander**, насколько я знаю написал б**о**льшую её часть ) сам мало знал о том, для чего на самом деле предназначен опкод задержки.

Давайте попробуем выяснить, для чего же он, на самом деле, существует в языке скриптинга. Для того, чтобы это понять, нам нужно образно представить себе, как работает игра. Многие могут подумать, что всё происходит параллельно - скрипты выполняются сами по себе, физика просчитывается сама по себе, и на экране всё рендерится параллельно всему вышеперечисленному. По крайней мере, так думал я до некоторых пор.

На самом деле, такого понятия как параллельность не может существовать в рамках одного процессора ( процессорного ядра ). Все "движки" игры выполняются последовательно. Если использовать синтаксис SB, то это будет выглядеть примерно так ( на номера опкодов внимания не обращаем ):

```
while true 
 0001: process_animations
 0002: process_physics
 0003: process_AI
 0004: process_scripting
 0005: process_render
end
```

Здесь мы видим бесконечный цикл который содержит последовательное выполнение различных процессов игры. Здесь всё представлено образно, на самом деле всё выглядит немного иначе, но в общих чертах - всё именно так.

Итак, вернёмся к нашему "wait 0". Предположим, выполнение кода игры дошло до процесса скриптинга. Наш скрипт начал выполняться. Возьмём такой пример, пока что на основе меток:

```
{$CLEO}
0000: NOP // Чтобы SB не ругался на переход на нулевой оффсет

:label_1
if
0AB0: key_pressed 48
then
 actor.Health($PLAYER_ACTOR) = 100
end
wait 0
jump @label_1
```

Как только наш скрипт начал выполняться, мы попадаем на проверку нажатия клавиши 0\`. Если клавиша нажата - даём игроку полное здоровье и идём дальше. Если не нажата - просто идём дальше. Дальше у нас стоит "wait 0". Обычно его пишут в начале, сразу после метки или перед проверкой, но я специально поставил его в конец. Когда скриптовый процесс достигает опкода "wait", он получает задачу переключиться на выполнение следующего скрипта, или, если это был последний скрипт в очереди - закончить скриптовый процесс и приступить к следующему игровому процессу.

Как мы все прекрасно знаем, если убрать "wait 0" в такой конструкции, то игра зависнет. Вообще, любое зависание любой программы с большой нагрузкой на ЦП - это, чаще всего, попадание в *бесконечный цикл*. Так и здесь. Так как опкод задержки является своеобразным "*сигналом*" для скриптового процесса для переключения на следующие процессы игры, то его отсутствие будет равносильно бесконечному выполнению только одного скриптового движка. Проще говоря, скриптовый процесс будет бесконечно проверять, нажата ли наша кнопка, а другие игровые процессы выполняться не будут ( такие как рендер новых кадров, например ), поэтому нам кажется, что игра зависла, но на самом деле она работает, но расчёты физиких моделей, их анимации, а также вывод новых "картинок" на экран не производятся.

"*Разве плохо ставить wait 0 после каждой метки?*" - спросите вы. Не всегда это плохо. Но давайте разберём случай, когда "wait 0" после каждой метки будет лишним. К примеру, нам нужно проверить несколько клавиш, на каждую из которых предусмотрено определённое действие.

```
{$CLEO}
0000: NOP

:label_1
wait 0
if
0AB0: key_pressed 48
then
 actor.Health($PLAYER_ACTOR) = 10
else
 jump @label_2
end
jump @label_1

:label_2
wait 0
if
0AB0: key_pressed 49
then
 actor.Health($PLAYER_ACTOR) = 20
else
 jump @label_3
end
jump @label_1

:label_3
wait 0
if
0AB0: key_pressed 50
then
 actor.Health($PLAYER_ACTOR) = 30
else
 jump @label_1
end
jump @label_1
```

Итак, давайте посмотрим, как будет выполняться наш код. Сперва метка **label\_1** и "wait 0". Пропустим их. Дальше проверка на нажатие клавиши 0\` и соответствующее ей действие - установка игроку здоровья равному 10. Если клавиша не нажата - переходим на **label\_2**. Тут у нас снова "wait 0", который передаст управление игрой другим процессам, и только после их выполнения вернётся к скрипту, к месту после "wait 0". Тут снова проверка на нажатие клавиши и соответствующее действие. Если не нажата - идём к третьей метке. Здесь опять же "wait 0", после которого выполнение скрипта прервётся, чтобы выполнить другие процессы и, после этого - вернётся обратно в это же место. Таким образом, прежде чем мы дойдём до проверки третьей клавиши, у нас образуется задержка в 3 общих цикла игры ( будем называть их кадрами ).

Вы скажете - "*Но ведь мы написали wait **0**, а раз там ноль, значит задержки никакой не будет!*". Но даже если там указан ноль, процессор не успеет настолько быстро обработать все остальные процессы игры, чтобы за 0 миллисекунд вернуться обратно к выполнению скриптового процесса. Таким образом, создаётся задержка в несколько миллисекунд - примерно 10-20 мс при 60 фпс. Три таких задержки равны уже 60 мс. А что, если таких проверок много? Придётся зажимать клавишу на полсекунды-секунду, чтобы её нажатие обработалось.

В том, что задержка действительно есть даже у "wait 0" мы можем легко убедиться с помощью следующего скрипта:

```
{$CLEO}
0000: NOP

while true
 33@ = 0
 wait 0
 0AD1: show_formatted_text_highpriority "%d" time 2000 33@
end
```

Как мы знаем из той же справки, переменные 32@ и 33@ являются таймерами и изменяют своё значение после каждого цикла ( "wait 0" ) на такое кол-во миллисекунд, которое прошло с момента начала прошлого цикла. Перед "wait 0" мы обнуляем значение переменной, а после - выводим её значение на экран, получая ту самую задержку, создаваемую опкодом "wait 0".

В результате, в скрипте с тремя проверками, выше, можно убрать "wait 0" после второй и третьей метки - тогда все проверки выполнятся подряд, без задержек, а после проверок код всё равно вернётся к метке **label\_1** где стоит "wait 0". Таким образом мы убъём двух зайцев сразу - избежим зависания и уберём задержку между проверками.

Подобная проблема может возникнуть при работе с массивами переменных. К примеру, у нас есть массив актёров и нам нужно узнать, у которого из них здоровье не полное и удалить его. В данном случае мы можем применить цикл for, так как он будет весьма удобным решением подобной проблемы с конкретным размером массива.

```
for 0@ = 0 to 20 step 1
 if
 actor.Defined($ACTORS[0@])
 then
 1@ = actor.Health($ACTORS[0@])
 if
 1@ < 100
 then
 actor.DestroyInstantly($ACTORS[0@])
 actor.RemoveReferences($ACTORS[0@])
 end
 end
end
```

Я не вставил в эту конструкцию ни одного "wait", так как мы знаем, что цикл **НЕ** будет выполняться бесконечно, а лишь **20 раз**, поэтому шансов на зависание в данном участке кода нет. Если мы вставим в конструкцию "wait 0", то "поиск раненого" будет длиться дольше из-за задержек, создаваемых "wait 0".

Если взять бесконечные циклы, такие как "while true", к примеру, то они должны в себе содержать "wait 0" - иначе мы снова попадём в зависание.

Сами создатели игры - Rockstar конечно тоже использовали "wait 0" по назначению, поэтому можно у них поучиться, посмотрев строение скриптов-потоков в оригинальном "main.scm".

Таким образом мы должны наблюдать за тем, как выполняется код и следить за тем, чтобы не создавалось бесконечных циклов, в которых скрипт не будет давать возможности выполняться другим процессам игры. В то же время, нужно исключить все лишние задержки, которые могут навредить работе вашего скрипта.|1777|315|0||vsja\_pravda\_o\_wait\_0|1504596516


# Раздел 02. CLEO


# Текст


# 000158. Динамическая GXT-таблица или виртуальные GXT-записи

Динамическая GXT-таблица или виртуальные GXT-записи|Всем привет! С Вами wmysterio, и сегодня мы рассмотрим небольшую тему, связанную с игровыми текстами.|wmysterio|wmysterio||||В [этом](https://github.com/wmysterio/scm-scripting-lessons/blob/main/publ/uroki_skriptinga/gta_sa/rabota_s_tekstom/34-1-0-35/README.md) уроке мы рассматривали возможность создания текстовых таблиц ( GXT-таблицы ). Теперь у нас появилась возможность создавать такие таблицы динамически ( их называют ещё виртуальными ), прямо в скрипте. Таким образом мы изучим четвёртый способ использования текстовый тип данных. Напомню, что ранее мы было опубликовано такие темы как FXT-архивы, форматированный текст и GXT-таблицы.

Для добавления в динамичную таблицу текста в скрипте мы должны использовать следующий опкод:

```
0ADF: add_dynamic_GXT_entry "DYNTABL" text "My test string"
```

Здесь:\
"DYNTABL" - имя поля в нашей виртуальной таблице. Важно! Длина имени должна составлять не больше 7 символов, как и в обычной GXT- или FXT-записи. Кроме этого, они обязательно должны быть взяты именно в двойные кавычки.\
"My test string" - содержание поля

Для удаления нужно использовать:

```
0AE0: remove_dynamic_GXT_entry "DYNTABL"
```

Здесь:\
"DYNTABL" - имя поля в нашей виртуальной таблице.

Также нам доступны следующие опкоды, которые помогают избежать вылетов или неточностей:

```
0ADE: 0@ = text_by_GXT_entry 0@v
```

Получает позицию входа записи в виртуальной таблице, где:

Здесь:\
0@ - переменная, в которую будет записана позиция строки 0\@v в таблице

Также мы можем получать длину строки, что иногда полезно при рисовании на экране:

```
09FD: get_gxt_string 'XSELECT' width_to 0@
0A08: get_gxt_string_1number 'XSELECT' number 1@ width_to 0@
```

Здесь:\
'XSELECT' - имя записи\
1@ - значение, которое будет подставлено вместо \~1\~\
0@ - переменная, в которою запишется длина

Кроме этого, нам доступна важная проверка, которая проверяет на пустоту строки. Полезно, когда строка не загрузилась и нам не пришлось потом выводить деформированную запись:

```
0844: string s$GXT_NAME empty
```

Здесь:\
s$GXT\_NAME - имя записи

Давайте напишем скрипт, который будет последовательно выводить текст:

```
{$CLEO}
wait 2000
0ADF: add_dynamic_GXT_entry "DYNTABL" text "My test string ~1~"

for 0@ = 0 to 5
01E5: show_text_1number_highpriority GXT 'DYNTABL' number 0@ time 1000 flag 1
wait 1000
end

0AE0: remove_dynamic_GXT_entry "DYNTABL"
0A93: end_custom_thread
```

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/77832249.png)\
\
× \*\*ВАЖНО:\*\* Кода мы заполняли виртуальную таблицу записями, мы использовали её как vСтрока, но обращаться к самой записи мы должны как sСтроке

Рассмотрим пример с массивами. Здесь дела интереснее. Я потратил целый день, чтобы составить адекватный алгоритм, который будет работоспособным для панели, которую я и предлагаю сделать сейчас.

Для начала нам необходимо объявить 2 массива, чтобы сократить код с помощью цикла:

```
var
$TAB_NAME: array 5 of string
$TAB_LIST: array 5 of longstring
end
```

$TAB\_NAME будет отвечать за имя виртуальной GXT-записи. Второй массив $TAB\_LIST будет отвечать за содержимое записи ( **vСтрока** ), поэтому тип указываем как **longstring**. Далее заполняем наш массив значениями и создаём виртуальную GXT-таблицу в цикле:

```
s$TAB_NAME[0] = 'DYNTAB0'
s$TAB_NAME[1] = 'DYNTAB1'
s$TAB_NAME[2] = 'DYNTAB2'
s$TAB_NAME[3] = 'DYNTAB3'
s$TAB_NAME[4] = 'DYNTAB4'
 
v$TAB_LIST[0] = "Black_Admiral" 
v$TAB_LIST[1] = "Sanchez_as_Bike" 
v$TAB_LIST[2] = "Remingtn"
v$TAB_LIST[3] = "Hotrina_Car" 
v$TAB_LIST[4] = "Monster"

for $INDEX = 0 to 4
0ADF: add_dynamic_GXT_entry $TAB_NAME[$INDEX] text $TAB_LIST[$INDEX] 
end
```

Здесь главное указывать значения для s$TAB\_NAME длиной не больше **7** символов. В противном случае таблица будет пустой. Значения для v$TAB\_LIST заполняем как обычно.

× \*\*ВАЖНО:\*\* Я заметил, что по-умолчанию игнорируются все пробелы при выводе текста. Чтобы игра адекватно отображала этот символ, его нужно подменить на символ '\*\*\_\*\*'. В таком формате символ пробела отображается как и ожидалось

Заполнение массива в цикле должно быть без приставок **v** или **s** возле переменных. После этого мы можем вывести панель ( таблицу ):

```
08D4: 1@ = create_panel_with_title 'DUMMY' position 29.0 170.0 width 200.0 columns 1 interactive 1 background 1 alignment 0
08DB: set_panel 1@ column 0 header 'DUMMY' data s$TAB_NAME[0] s$TAB_NAME[1] s$TAB_NAME[2] s$TAB_NAME[3] s$TAB_NAME[4] 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY'
```

Дальше нужно использовать короткие строки ( 8-ми байтные ), по-этому возле массива указываем s$TAB\_NAME а не v$TAB\_NAME. Когда панель нам больше не нужна, выгружаем виртуальную таблицу GXT-записей:

```
for $INDEX = 0 to 4
0AE0: remove_dynamic_GXT_entry $TAB_NAME[$INDEX]
end
```

Полный код скрипта будет следующим:

```
{$CLEO}
0000: NOP

var
$TAB_NAME: array 5 of string
$TAB_LIST: array 5 of longstring
end

s$TAB_NAME[0] = 'DYNTAB0'
s$TAB_NAME[1] = 'DYNTAB1'
s$TAB_NAME[2] = 'DYNTAB2'
s$TAB_NAME[3] = 'DYNTAB3'
s$TAB_NAME[4] = 'DYNTAB4'
 
v$TAB_LIST[0] = "Black_Admiral" 
v$TAB_LIST[1] = "Sanchez_as_Bike" 
v$TAB_LIST[2] = "Remingtn"
v$TAB_LIST[3] = "Hotrina_Car" 
v$TAB_LIST[4] = "Monster"

for $INDEX = 0 to 4
0ADF: add_dynamic_GXT_entry $TAB_NAME[$INDEX] text $TAB_LIST[$INDEX] 
end

08D4: 1@ = create_panel_with_title 'DUMMY' position 29.0 170.0 width 200.0 columns 1 interactive 1 background 1 alignment 0 // Imports
08DB: set_panel 1@ column 0 header 'DUMMY' data s$TAB_NAME[0] s$TAB_NAME[1] s$TAB_NAME[2] s$TAB_NAME[3] s$TAB_NAME[4] 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY'

while true
wait 0
 08D7: 0@ = panel 1@ active_row
 if
 0AB0: key_pressed 32 // SPACE
 then
 if
 0@ == 0
 then
 Player.Money($PLAYER_CHAR) += 1000
 break
 else
 break
 end
 end
end

08DA: remove_panel 1@

for $INDEX = 0 to 4
0AE0: remove_dynamic_GXT_entry $TAB_NAME[$INDEX]
end

0A93: end_custom_thread
```

Суть этого скрипта проста: нажимаем пробел - панель убирается. Если при этом выбрана первая строка, то даём в придачу ещё 1000 долларов. Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/21104994.png)

Также я заметил, что важно ещё и то, что массивы вступают в силу только тогда, когда весь код скрипта не приводит к ошибке. Это очень плохо, потому, что нельзя узнать будет отображаться текст или нет. Возможно ( и я надеюсь ), что это только у меня так :)

На этом всё. С Вами был wmysterio, до встречи в новых уроках!|1636|1|0|21104994`png`1280`768`400`240``\|77832249`png`600`360`400`240\`\`||dinamicheskie\_tesktovye\_gxt\_tablicy|1504601423


# 00033. Работа с текстом

Работа с текстом|В этом уроке мы рассмотрим способы вывода текста.|wmysterio|wmysterio||||Важную роль в играх имеет текст, так как мы узнаём с помощью его что нужно сделать в миссии. Давайте модернизируем нашу миссию, добавив текст.

В первую очередь, рассмотрим текст-бокс. Это такие сообщения, в левом верхнем угле, в который сообщается о каких-то событиях. Вот скрин:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/68549768.png)

Чтобы вывести на экран такой текст нужно воспользоваться опкодом:

```
03E5: show_text_box 'HELP101'
```

Здесь:\
'HELP101' - имя GXT-записи

Если вы не знаете как создать такую запись, то прочтите эти уроки: [FXT Editor](https://github.com/wmysterio/scm-scripting-lessons/blob/main/publ/gta_sa/dokumentacii_k_programmam/rukovodstvo_po_ispolzovaniju_programmy_fxteditor/54-1-0-5/README.md) и [Rus2gxtCoder](https://github.com/wmysterio/scm-scripting-lessons/blob/main/publ/gta_sa/dokumentacii_k_programmam/rukovodstvo_po_ispolzovaniju_programmy_rus2gxtcoder/54-1-0-4/README.md). Рассмотрим самый распространённый опкод:

```
00BB: show_text_lowpriority GXT 'IE23' time 3000 flag 1
```

Этот опкод явно отличается от предыдущего, так как здесь присутствуют два других параметра:

Здесь:\
3000 - время демонстрации текста\
1 - флаг текста ( я не знаю, что он с себя представляет, так что оставляйте единицу )

Этот текст будет выводится в виде диалоговых текстов. Скрин:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/33411750.png)

Используя этот опкод текст всегда будет писаться внизу. Есть очень похожий опкод на этот, с теми же параметрами. Разница только в том, что он будет показан сразу. Предыдущий менее приоритетный для игры:

```
00BC: show_text_highpriority GXT 'MTIME3' time 1000 flag 1
```

Рассмотрим так же опкод, с использованием стилей. Вы уже его встречали в предыдущих уроках. Вот этот опкод:

```
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1
```

Здесь:\
'M\_FAIL' - имя GXT-ключа\
5000 - время демонстрации текста. Этот параметр всё равно показывает фиксированное время, так что менять его бесполезно\
1 - стиль текста. Посмотреть все известные мне стили можно в нашей [базе данных](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/nomera_stilej_teksta/1-1-0-42/README.md).

Есть ещё очень много опкодов, которые связаны с тестом, но ещё детальнее мы ознакомимся с ними, когда будем изучать рисование на экране. В этом уроке мы рассмотрели основные опкоды для работы с текстом. Давайте теперь используем их, что бы модернизировать наш скрипт мисси. Создадим новый fxt-файл со следующим содержимым:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/33822757.png)\
\
1-я запись: "Охота на объект" - это будет название миссии\
2-я запись: "Идитe к тoчкe!"\
3-я запись: "Уничтожьте объект!"

Вставим эти стоки в скипт и получим:

```
// WMYSTERIO, ru-script.3dn.ru

DEFINE OBJECTS 1
DEFINE OBJECT SANNY BUILDER 3.04 

DEFINE MISSIONS 1
DEFINE MISSION 0 AT @MISSION_0 
 
DEFINE EXTERNAL_SCRIPTS 0

DEFINE UNKNOWN_EMPTY_SEGMENT 0

DEFINE UNKNOWN_THREADS_MEMORY 3072

{$VERSION 3.1.0027}

//-------------MAIN---------------
thread 'MAIN'
set_wb_check_to 0
set_weather 0
select_interior 0
fade 0 0
0180: set_on_mission_flag_to $ONMISSION
00C0: set_current_time_hours_to 8 minutes_to 0
04E4: unknown_refresh_game_renderer_at 2491.1572 -1670.3434
Camera.SetAtPos(2491.1572, -1670.3434, 12.3359)
$PLAYER_CHAR = Player.Create(#NULL, 2491.1572, -1670.3434, 12.3359)
$PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
Actor.Angle($PLAYER_ACTOR) = 66.3548
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
Camera.SetBehindPlayer
Player.SetClothes($PLAYER_CHAR, "WORKTRCAMOGRN", "WORKTR", 2)
Player.SetClothes($PLAYER_CHAR, "SNEAKERBINCGANG", "SNEAKER", 3)
Player.SetClothes($PLAYER_CHAR, "TSHIRTERISORN", "TSHIRT", 0) 
Player.Build($PLAYER_CHAR)
Player.CanMove($PLAYER_CHAR) = True
$TRAMPLIN = object.Create(#AD_JUMP, 2480.5842, -1721.8175, 12.5488)
object.Angle($TRAMPLIN) = 180.0
object.SetImmunities($TRAMPLIN, 1, 1, 1, 1, 1)
Object.Indestructibility($TRAMPLIN) = False
Object.RemoveFromMissionCleanupList($TRAMPLIN)
0879: enable_gang_wars 1
076C: set_zone 'GAN1' gang 1 density_to 40 
076C: set_zone 'GAN2' gang 1 density_to 80 
076C: set_zone 'IWD1' gang 0 density_to 40 
076C: set_zone 'IWD2' gang 0 density_to 80 
076C: set_zone 'IWD3A' gang 2 density_to 40 
076C: set_zone 'IWD3B' gang 2 density_to 80 
0237: set_gang 0 weapons_to 22 31 14 
0237: set_gang 1 weapons_to 30 28 17 
0237: set_gang 2 weapons_to 36 15 27 
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 0
0746: set_acquaintance 0 of_actors_pedtype 8 to_actors_pedtype 0
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 0
0767: set_zone 'MARKST' popcycle_group_for_peds_and_cars_to 14
0767: set_zone 'UNITY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'LAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2A' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2B' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'BLUF1A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BLUF2' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3C' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN4' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'COM1A' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM1B' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PER1' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'CHC1A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC1B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC3' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'CHC1A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC1B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC3' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4B' popcycle_group_for_peds_to 9 
0767: set_zone 'CONF1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'CONF1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'THALL1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDOC1A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3C' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDT1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1C' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LDT5' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT6' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE3C' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'ELCO1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'ELCO2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELCO1' popcycle_group_for_peds_to 9 
0874: set_zone 'ELCO2' popcycle_group_for_peds_to 9 
0767: set_zone 'GAN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GAN2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'GAN1' popcycle_group_for_peds_to 1 
0874: set_zone 'GAN2' popcycle_group_for_peds_to 1 
0767: set_zone 'GLN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GLN2A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'IWD1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD4' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD5' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'IWD1' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD2' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3A' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3B' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD4' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD5' popcycle_group_for_peds_to 1 
0767: set_zone 'JEF1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3C' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LFL1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LFL1B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'LFL1A' popcycle_group_for_peds_to 9 
0874: set_zone 'LFL1B' popcycle_group_for_peds_to 9 
0767: set_zone 'LMEX1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LMEX1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ELS1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS1B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS4' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELS1A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS1B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS2' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS4' popcycle_group_for_peds_to 10 
0767: set_zone 'MAR1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'MAR2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MAR3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MKT1' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT2' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT3' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT4' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MUL1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL2A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL2B' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL3' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL4' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL6' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'PLS' popcycle_group_for_peds_and_cars_to 8
0767: set_zone 'RIH1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH2' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD1A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD5B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SMB1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'SMB2' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VIN2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VERO1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'VERO2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO4A' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VERO4B' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'CRANB' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CALT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'SUNMA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SUNNN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'BATTP' popcycle_group_for_peds_and_cars_to 2
0767: set_zone 'ESPN1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'BAYV' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'PARA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'JUNIHO' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JUNIHI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CIVI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CHINA' popcycle_group_for_peds_and_cars_to 9
0874: set_zone 'CHINA' popcycle_group_for_peds_to 6
0767: set_zone 'SFDWT1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT5' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT6' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'FINA' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'CITYS' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'WESTP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'THEA1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'GARC' popcycle_group_for_peds_and_cars_to 7
0767: set_zone 'HASH' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'OCEAF1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'OCEAF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'OCEAF3' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'DOH1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'DOH2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'CUNTC1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SFGLF1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF2' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF3' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF4' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'HILLP' popcycle_group_for_peds_and_cars_to 10
0767: set_zone 'SILLY1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY4' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR4' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR5' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'EASB1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'EASB2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'ESPE1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'LINDEN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YELLOW' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'BFC1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BFC2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'RIE' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'LDM' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'RSW1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSW2' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSE' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'LDS' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'SRY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JTS1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTS2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LVA1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'LVA3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'VAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LVBAG' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'GGC1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'GGC2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'BFLD1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BFLD2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'WWE' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'WWE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PINT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YBELL2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'YBELL1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'JTW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN5' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN6' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN8' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'HGP' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SPIN' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'BINT1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PRP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'REDE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'REDW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'REDW4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ROCE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'ROCE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'OVS' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CREE' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'STRIP1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP2' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STRIP3' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP4' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'PILL1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PILL2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'RING' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'ISLE' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STAR1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STAR2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'ROY' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CAM' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'LOT' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PIRA' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'VISA1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'VISA2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'DRAG' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PINK' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'HIGH' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CONST1' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'ANGPI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'SHACA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BACKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BEACO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FARM' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'PALO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT1' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MTCHI1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI2' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI3' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI4' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'HBARNS' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'DILLI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'PANOP' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUAC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MAKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FERN' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'NROCK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'HANKY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'LEAFY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'RED' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FLINTC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'WHET' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BIGE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELQUE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BARRA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'CARSO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PAYAS' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PROBE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELCA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTR' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ARCO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'VALLE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTI' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'MONINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'TOM' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ALDEA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BRUJA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBAD' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BONE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'HAUL' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'QUARY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'OCTAN' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'PALMS' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'DAM' popcycle_group_for_peds_and_cars_to 18
014B: $MY_CAR = init_parked_car_generator #BULLET color -1 -1 0 alarm 0 door_lock 0 1 10000 at 2474.2131 -1690.8783 12.1239 angle 180.0
014C: set_parked_car_generator $MY_CAR cars_to_generate_to 101
0213: $PICKUP_0001 = create_pickup #BODYARMOUR type 15 at 2491.0 -1685.8561 13.5107
032B: $PICKUP_0002 = create_weapon_pickup #MINIGUN group 15 ammo 60 at 2493.0 -1685.8561 13.5107 
02E1: $PICKUP_0003 = create_cash_pickup 500 at 2495.0 -1685.8561 13.5107 permanence_flag 1 
04A6: $PICKUP_0004 = create_asset_money_pickup_at 2497.0 -1685.8561 13.5107 money 10000 10000
016C: restart_if_wasted_at 2027.77 -1420.52 15.99 angle 137.0 town_number 0 // íàøè íîâûå òî÷êè ðåñòàðòà!!!
016C: restart_if_wasted_at 1180.85 -1325.57 12.58 angle 271.4 town_number 0
016D: restart_if_busted_at 1550.68 -1675.49 14.51 angle 90.0 town_number 0
016C: restart_if_wasted_at 1244.437 331.2261 18.5547 angle 7.5465 town_number 1
016D: restart_if_busted_at 632.2344 -571.7104 15.3515 angle 267.2 town_number 1
016C: restart_if_wasted_at -2199.719 -2308.075 29.6181 angle 322.8928 town_number 1
016D: restart_if_busted_at -2163.829 -2387.817 29.625 angle 134.2066 town_number 1
016C: restart_if_wasted_at -2670.285 616.4364 13.4531 angle 183.1042 town_number 1
016D: restart_if_busted_at -1605.792 716.8598 11.0241 angle 355.2978 town_number 1
016C: restart_if_wasted_at -316.3832 1056.045 18.7344 angle 1.6017 town_number 2
016D: restart_if_busted_at -212.1889 979.4168 18.3219 angle 278.0478 town_number 2
016C: restart_if_wasted_at -1514.823 2527.119 54.7443 angle 2.3546 town_number 2
016D: restart_if_busted_at -1393.072 2633.116 54.9491 angle 86.0424 town_number 2
016C: restart_if_wasted_at 1578.446 1770.682 9.8358 angle 99.7567 town_number 2
016D: restart_if_busted_at 2337.083 2453.802 13.9765 angle 90.7643 town_number 2
fade 1 0
create_thread @SAVE 
create_thread @STARTER
end_thread 

:SAVE
thread 'SAVE'
wait 0
if AND
$ONMISSION == 0
0AB0: key_pressed 115
then
03D8: show_save_screen 
wait 250
end
jump @SAVE

:STARTER 
thread 'STARTER'
wait 0
$ICON = marker.CreateIconAndSphere(15, 2287.793, -1667.109, 15.0317)

:STARTER_1
wait 0
if AND
$ONMISSION == 0
00EC: actor $PLAYER_ACTOR 0 near_point 2287.793 -1667.109 radius 15.0317 3.0 
jf @STARTER_1
marker.Disable($ICON)
00BA: show_text_styled GXT 'MIS_01' time 1000 style 2 // Новый код
start_mission 0
end_thread

//-------------Mission 0---------------
// Originally: MISSION_0

:MISSION_0
thread 'MISSION_0'
gosub @MISSION_0_29_57 
if 
wasted_or_busted 
jf @MISSION_0_29_46 
gosub @MISSION_0_29_144 

:MISSION_0_29_46
$ONMISSION = 0 
mission_cleanup 
end_thread 

:MISSION_0_29_57
increment_mission_attempts 
$ONMISSION = 1 
018A: 1@ = create_checkpoint_at 2184.3604 -1774.8608 12.3665
03BC: 2@ = create_sphere_at 2184.3604 -1774.8608 12.3665 radius 2.0 
00BB: show_text_lowpriority GXT 'MS_0101' time 3000 flag 1 // новый код

:MISSION_0_A
wait 0
if
00EC: actor $PLAYER_ACTOR 0 near_point 2184.3604 -1774.8608 radius 12.3665 3.0
jf @MISSION_0_A
marker.Disable(1@)
03BD: destroy_sphere 2@ 
model.Load(#BARREL4)
038B: load_requested_models 

:MISSION_0_B
wait 0
if
model.Available(#BARREL4)
jf @MISSION_0_B
0@ = object.Create(#BARREL4, 2153.9919, -1796.8591, 12.5507)
object.Angle(0@) = 277.5201
model.Destroy(#BARREL4)
3@ = marker.CreateAboveObject(0@)
00BB: show_text_lowpriority GXT 'MS_0102' time 3000 flag 1 // новый код

:MISSION_0_C
wait 0
if
0366: object 0@ damaged
jf @MISSION_0_C
0318: set_latest_mission_passed 'MIS_01' // новый код
01E3: show_text_1number_styled GXT 'M_PASS' number 5000 time 4000 style 1 
Player.Money($PLAYER_CHAR) += 5000
0394: play_music 1
gosub @MISSION_0_END
create_thread @STARTER
return 

:MISSION_0_29_144
wait 0 
gosub @MISSION_0_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 
create_thread @STARTER
return

:MISSION_0_END
wait 0
if
03CA: object 0@ exists
then
object.RemoveReferences(0@)
object.Destroy(0@)
end 
marker.Disable(1@)
marker.Disable(3@)
03BD: destroy_sphere 2@ 
return 
```

В результате, мы получим текст во время миссий:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/39807839.png)

Так же следует обратить внимание на опкод:

```
0318: set_latest_mission_passed 'MIS_01'
```

Когда мы прошли миссию и сохранились, то при попытке загрузки игры мы увидим текст который заменяет предыдущий текст миссий. Если раньше при загрузке миссии нам писало "В самом начале", то теперь мы увидим название текста, содержащийся в FXT-записи: "Охота за объектом", который был показан в начале миссии:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/70774744.png)

Этот опкод также обновляет статистику пройденных миссий. Если мы пройдём миссию без использования этого опкода, то при загрузке игры ( сохранив игру перед этим ) будет отображаться только дата, а в поле текста ничего не будет.|1851|1|0|68549768`png`640`438`400`273``\|33411750`png`826`358`400`173``\|33822757`png`437`344`400`314``|39807839`png`640`400`400`250``\|70774744`png`640`400`400`250\`\`||rabota\_s\_tekstom|1498861603


# Игрок


# 00021. Одежда СЖ

Одежда СЖ|В этом уроке Вы узнаете как одеть CJ в одежду.|wmysterio|wmysterio||||Как видим наш, в нашем предыдущем скрипте, СЖ был в трусах. Это не совсем красиво ))) Поэтому давайте его приоденем как следует :)

В первую очередь вам нужно знать о переменной $PLAYER\_CHAR. Эта переменная игрока, то есть того, за кого мы сейчас играем. Что бы одеть СЖ нужно использовать опкод:

```
Player.SetClothes($PLAYER_CHAR, "WORKTRCAMOGRN", "WORKTR", 2)
```

Здесь: $PLAYER\_CHAR — переменная игрока, которого мы одеваем\
"WORKTRCAMOGRN" - имя текстуры модели\
"WORKTR" - имя самой модели\
2 - тип одежды ( см. в нашей [базе данных](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/chasti_tela_igroka/1-1-0-37/README.md) )× \*\*ВАЖНО:\*\* Так одеть можно только CJ'я!

Давайте всё же оденем нормально игрока. Вот я подобрал на скорую руку одежду:

```
Player.SetClothes($PLAYER_CHAR, "WORKTRCAMOGRN", "WORKTR", 2)
Player.SetClothes($PLAYER_CHAR, "SNEAKERBINCGANG", "SNEAKER", 3)
Player.SetClothes($PLAYER_CHAR, "TSHIRTERISORN", "TSHIRT", 0)
```

Мы должны сначала перечислить всю одежду, которую мы хотим видеть на СЖ. В результате мы получим такой вид СЖ:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/43381799.png)

Но этого пока недостаточно, потому что нужно закрепить одежду. Это делается командой:

```
Player.Build($PLAYER_CHAR)
```

Давайте наш мини-код добавим в наш скрипт:

```
// WMYSTERIO, ru-script.3dn.ru
DEFINE OBJECTS 1
DEFINE OBJECT SANNY BUILDER 3.04 

DEFINE MISSIONS 0

DEFINE EXTERNAL_SCRIPTS 0

DEFINE UNKNOWN_EMPTY_SEGMENT 0

DEFINE UNKNOWN_THREADS_MEMORY 3072

{$VERSION 3.1.0027}

//-------------MAIN---------------
thread 'MAIN'
set_wb_check_to 0
set_weather 0
select_interior 0
fade 0 0
0180: set_on_mission_flag_to $ONMISSION
00C0: set_current_time_hours_to 8 minutes_to 0
04E4: unknown_refresh_game_renderer_at 2491.1572 -1670.3434
Camera.SetAtPos(2491.1572, -1670.3434, 12.3359)
$PLAYER_CHAR = Player.Create(#NULL, 2491.1572, -1670.3434, 12.3359)
$PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
Actor.Angle($PLAYER_ACTOR) = 66.3548
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
Camera.SetBehindPlayer
// начало нового кода
Player.SetClothes($PLAYER_CHAR, "WORKTRCAMOGRN", "WORKTR", 2)
Player.SetClothes($PLAYER_CHAR, "SNEAKERBINCGANG", "SNEAKER", 3)
Player.SetClothes($PLAYER_CHAR, "TSHIRTERISORN", "TSHIRT", 0)
Player.Build($PLAYER_CHAR)
// конец нового кода
Player.CanMove($PLAYER_CHAR) = True
fade 1 0
0879: enable_gang_wars 1
076C: set_zone 'GAN1' gang 1 density_to 40 
076C: set_zone 'GAN2' gang 1 density_to 80 
076C: set_zone 'IWD1' gang 0 density_to 40 
076C: set_zone 'IWD2' gang 0 density_to 80 
076C: set_zone 'IWD3A' gang 2 density_to 40 
076C: set_zone 'IWD3B' gang 2 density_to 80 
0237: set_gang 0 weapons_to 22 31 14 
0237: set_gang 1 weapons_to 30 28 17 
0237: set_gang 2 weapons_to 36 15 27 
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 0
0746: set_acquaintance 0 of_actors_pedtype 8 to_actors_pedtype 0
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 0
end_thread
```

Теперь компилируем, и заходим в игру, проверяем :) Экспериментируйте с одеждой, добавляйте больше примочек! Главное, что бы список был **до** опкода Player.Build($PLAYER\_CHAR).

× \*\*Примечание:\*\* если мы укажем в списке одежды одинаковые типы, то СЖ будет одет в ту, которая написанна ниже по коду.× \*\*Примечание:\*\* Закрепить одежду недостаточно, так как при смерти СЖ опять появится в трусах. Сохранить одежду можно опкодом:

```
0793: save_player_clothes
```

Я не стал включать его в код скрипта, так как в нём пока нет необходимости.

|1585|1|0|43381799\`png\`640\`400\`400\`250\`\`\\||odezhda\_szh|1498567660


# Транспорт


# 00026. Создание транспорта

Создание транспорта|Этот урок посвящен транспорту. Мы научимся ставить средства передвижения в определённых координатах.|wmysterio|wmysterio||||Есть несколько способов. Но для начала определим координаты появления транспорта и угол поворота. Вот у меня такие: 2474.2131 -1690.8783 12.1239 и угол 180.0 градусов. Далее используем опкод:

```
014B: $MY_CAR = init_parked_car_generator #BULLET color -1 -1 0 alarm 0 door_lock 0 1 10000 at 2474.2131 -1690.8783 12.1239 angle 180.0
```

Здесь:\
$MY\_CAR — как вы уже догадались, это имя нашей машины\
\#BULLET — модель нашей машины. В этом опкоде загружать модель не нужно! [Здесь](https://github.com/wmysterio/scm-scripting-lessons/blob/main/data_base/sa/car_id.rar) Вы можете скачать архив, где есть большинство автомобилей с картинками.\
-1 -1 — указываем цвет машины ( см. [Цвета транспортных средств](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/cveta_avtomobilej_v_gta_san_andreas/1-1-0-19/README.md) ). Если поставить -1, то цвета будут генерироваться случайным образом\
alarm 0 — указывается вероятность сигнализации, в процентах ( от 0 до 100 )\
door\_loock 0 — указывается вероятность запертых дверей, в процентах ( от 0 до 100 )\
1 — параметр, указывающий на то как будут реагировать копы. В данном случаи если при полицейском сесть в машину, то коп будет считать это за угон. Если поставить 0, то копам будет по-барабану\
10000 — сколько времени нужно ждать пока появится транспорт. В даном случае 10000 милисекунд (10 секунд )\
2474.2131 -1690.8783 12.1239 — координаты\
180.0 — угол

Есть аналогичный опкод:

```
09E2: $MY_CAR = parked_car_generator_w_numberplate #BULLET -1 -1 0 alarm 0 door_lock 0 1 10000 plate "MYSTERY" at 2474.2131 -1690.8783 12.1239 angle 180.0
```

Параметры те же, что и в предыдущем примере. Единственное отличие в том, что здесь ещё и указываются и номерной знак. В нашем случаи на номерах будет написано "MYSTERY". Длина номерных знаков не должна превышать 8 символов а так же не содержать спец-символов ( кроме **\_** ) и пробелов. Знак должен состоять из латинских букв или с чисел.

Чтобы транспорт появлялся, нужно так же задать и частоту его появления. Делается это опкодом:

```
014C: set_parked_car_generator $MY_CAR cars_to_generate_to 101
```

Здесь:\
$MY\_CAR — имя нашей машины\
101 — частота появления ( наверное в процентах ). Если поставить 0, то транспорт появляться не будет, если 101 — то будет появляться постоянно

Эти опкоды используются для парковки, так называемые "генераторы парковок". Вот пример:

```
014B: $MY_CAR = init_parked_car_generator #BULLET color -1 -1 0 alarm 0 door_lock 0 1 10000 at 2474.2131 -1690.8783 12.1239 angle 180.0
014C: set_parked_car_generator $MY_CAR cars_to_generate_to 101
```

Если вставить этот код в стартовый поток, то результат будет таковым:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/14172346.png)\
\
× \*\*Примечание:\*\* Если начать игру возле точки парковки, то тачка может не появится. Нужно отойти от этого места недалеко, а затем вернутся. Эти опкоды используются тогда, когда нужно что бы в определённом месте \*\*постоянно\*\* появлялась машина. В миссиях обычно машины таким образом не создают.

Рассмотрим другой вариант создания транспорта. Он позволяет вмиг создать транспорт в нужной точке. Такой вариант отлично подходит для миссий, когда нужно быстро создать транспорт. Рассмотрим его подробнее. В первую очередь определим координаты и угол. Вот у меня, например, такие: 2485.2769 -1652.943 11.8878 и угол 90.0 градусов. Дальше нам необходимо загрузить модель транспорта. После этого уже создавать его следующими опкодами:

```
$CAR_001 = car.Create(#INFERNUS, 2485.2769, -1652.943, 11.8878)
car.Angle($CAR_001) = 90.0
```

Здесь:\
\#INFERNUS — имя нашей модели\
Остальные параметры нет смысла объяснять, так как и так понятно что это координаты и угол.

Давайте отредактируем наш скрипт с актёром, что бы в место него появлялась машина. Всё, что нам нужно — это заменить модель в коде, а так же команду создания актёра. Вот наш скрипт:

```
// WMYSTERIO, ru-script.3dn.ru
DEFINE OBJECTS 1
DEFINE OBJECT SANNY BUILDER 3.04 

DEFINE MISSIONS 0

DEFINE EXTERNAL_SCRIPTS 0

DEFINE UNKNOWN_EMPTY_SEGMENT 0

DEFINE UNKNOWN_THREADS_MEMORY 3072

{$VERSION 3.1.0027}

//-------------MAIN---------------
thread 'MAIN'
set_wb_check_to 0
set_weather 0
select_interior 0
fade 0 0
0180: set_on_mission_flag_to $ONMISSION
00C0: set_current_time_hours_to 8 minutes_to 0
04E4: unknown_refresh_game_renderer_at 2491.1572 -1670.3434
Camera.SetAtPos(2491.1572, -1670.3434, 12.3359)
$PLAYER_CHAR = Player.Create(#NULL, 2491.1572, -1670.3434, 12.3359)
$PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
Actor.Angle($PLAYER_ACTOR) = 66.3548
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
Camera.SetBehindPlayer
Player.SetClothes($PLAYER_CHAR, "WORKTRCAMOGRN", "WORKTR", 2)
Player.SetClothes($PLAYER_CHAR, "SNEAKERBINCGANG", "SNEAKER", 3)
Player.SetClothes($PLAYER_CHAR, "TSHIRTERISORN", "TSHIRT", 0)
Player.Build($PLAYER_CHAR)
Player.CanMove($PLAYER_CHAR) = True
$TRAMPLIN = object.Create(#AD_JUMP, 2480.5842, -1721.8175, 12.5488)
object.Angle($TRAMPLIN) = 180.0
object.SetImmunities($TRAMPLIN, 1, 1, 1, 1, 1)
Object.Indestructibility($TRAMPLIN) = False
Object.RemoveFromMissionCleanupList($TRAMPLIN)
0879: enable_gang_wars 1
076C: set_zone 'GAN1' gang 1 density_to 40 
076C: set_zone 'GAN2' gang 1 density_to 80 
076C: set_zone 'IWD1' gang 0 density_to 40 
076C: set_zone 'IWD2' gang 0 density_to 80 
076C: set_zone 'IWD3A' gang 2 density_to 40 
076C: set_zone 'IWD3B' gang 2 density_to 80 
0237: set_gang 0 weapons_to 22 31 14 
0237: set_gang 1 weapons_to 30 28 17 
0237: set_gang 2 weapons_to 36 15 27 
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 0
0746: set_acquaintance 0 of_actors_pedtype 8 to_actors_pedtype 0
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 0
0767: set_zone 'MARKST' popcycle_group_for_peds_and_cars_to 14
0767: set_zone 'UNITY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'LAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2A' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2B' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'BLUF1A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BLUF2' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3C' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN4' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'COM1A' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM1B' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PER1' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'CHC1A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC1B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC3' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'CHC1A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC1B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC3' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4B' popcycle_group_for_peds_to 9 
0767: set_zone 'CONF1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'CONF1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'THALL1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDOC1A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3C' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDT1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1C' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LDT5' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT6' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE3C' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'ELCO1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'ELCO2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELCO1' popcycle_group_for_peds_to 9 
0874: set_zone 'ELCO2' popcycle_group_for_peds_to 9 
0767: set_zone 'GAN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GAN2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'GAN1' popcycle_group_for_peds_to 1 
0874: set_zone 'GAN2' popcycle_group_for_peds_to 1 
0767: set_zone 'GLN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GLN2A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'IWD1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD4' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD5' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'IWD1' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD2' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3A' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3B' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD4' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD5' popcycle_group_for_peds_to 1 
0767: set_zone 'JEF1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3C' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LFL1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LFL1B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'LFL1A' popcycle_group_for_peds_to 9 
0874: set_zone 'LFL1B' popcycle_group_for_peds_to 9 
0767: set_zone 'LMEX1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LMEX1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ELS1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS1B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS4' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELS1A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS1B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS2' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS4' popcycle_group_for_peds_to 10 
0767: set_zone 'MAR1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'MAR2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MAR3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MKT1' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT2' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT3' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT4' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MUL1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL2A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL2B' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL3' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL4' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL6' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'PLS' popcycle_group_for_peds_and_cars_to 8
0767: set_zone 'RIH1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH2' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD1A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD5B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SMB1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'SMB2' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VIN2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VERO1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'VERO2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO4A' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VERO4B' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'CRANB' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CALT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'SUNMA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SUNNN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'BATTP' popcycle_group_for_peds_and_cars_to 2
0767: set_zone 'ESPN1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'BAYV' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'PARA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'JUNIHO' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JUNIHI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CIVI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CHINA' popcycle_group_for_peds_and_cars_to 9
0874: set_zone 'CHINA' popcycle_group_for_peds_to 6
0767: set_zone 'SFDWT1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT5' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT6' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'FINA' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'CITYS' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'WESTP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'THEA1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'GARC' popcycle_group_for_peds_and_cars_to 7
0767: set_zone 'HASH' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'OCEAF1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'OCEAF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'OCEAF3' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'DOH1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'DOH2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'CUNTC1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SFGLF1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF2' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF3' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF4' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'HILLP' popcycle_group_for_peds_and_cars_to 10
0767: set_zone 'SILLY1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY4' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR4' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR5' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'EASB1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'EASB2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'ESPE1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'LINDEN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YELLOW' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'BFC1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BFC2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'RIE' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'LDM' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'RSW1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSW2' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSE' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'LDS' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'SRY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JTS1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTS2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LVA1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'LVA3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'VAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LVBAG' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'GGC1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'GGC2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'BFLD1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BFLD2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'WWE' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'WWE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PINT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YBELL2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'YBELL1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'JTW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN5' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN6' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN8' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'HGP' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SPIN' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'BINT1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PRP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'REDE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'REDW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'REDW4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ROCE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'ROCE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'OVS' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CREE' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'STRIP1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP2' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STRIP3' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP4' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'PILL1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PILL2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'RING' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'ISLE' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STAR1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STAR2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'ROY' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CAM' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'LOT' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PIRA' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'VISA1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'VISA2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'DRAG' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PINK' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'HIGH' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CONST1' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'ANGPI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'SHACA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BACKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BEACO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FARM' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'PALO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT1' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MTCHI1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI2' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI3' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI4' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'HBARNS' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'DILLI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'PANOP' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUAC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MAKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FERN' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'NROCK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'HANKY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'LEAFY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'RED' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FLINTC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'WHET' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BIGE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELQUE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BARRA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'CARSO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PAYAS' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PROBE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELCA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTR' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ARCO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'VALLE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTI' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'MONINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'TOM' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ALDEA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BRUJA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBAD' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BONE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'HAUL' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'QUARY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'OCTAN' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'PALMS' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'DAM' popcycle_group_for_peds_and_cars_to 18
014B: $MY_CAR = init_parked_car_generator #BULLET color -1 -1 0 alarm 0 door_lock 0 1 10000 at 2474.2131 -1690.8783 12.1239 angle 180.0 // Наш новый код!
014C: set_parked_car_generator $MY_CAR cars_to_generate_to 101 // Наш новый код!
fade 1 0
create_thread @SAVE 
create_thread @MODEL 
end_thread 

:SAVE
thread 'SAVE'
wait 0
if AND
$ONMISSION == 0
0AB0: key_pressed 115
then
03D8: show_save_screen 
wait 250
end
jump @SAVE

:MODEL
thread 'MODEL'
wait 0
if
0AB0: key_pressed 8
then
gosub @MODEL_1
$CAR_001 = car.Create(#INFERNUS, 2485.2769, -1652.943, 11.8878) // Наш новый код!
car.Angle($CAR_001) = 90.0 // Наш новый код!
model.Destroy(#INFERNUS) // Наш новый код!
jump @MODEL_3
end
jump @MODEL

:MODEL_3
wait 0
end_thread

:MODEL_1
wait 0
model.Load(#INFERNUS) // Наш новый код!
038B: load_requested_models 

:MODEL_2
wait 0
if
model.Available(#INFERNUS) // Наш новый код!
jf @MODEL_2
return
```

Давайте проверим скрипт. Скомпилируем его начнём новую игру. В результате, при нажатии кнопки BACKSPACE\`, я получил:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/53961394.png)

Думаю и у вас получится что-то в этом роде.|1149|1|0|14172346`png`640`400`400`250``\|53961394`png`640`400`400`250\`\`||sozdanie\_transporta|1505505937


# 000115. Работа с грузовиками и прицепами

Работа с грузовиками и прицепами|Доброго времени суток, уважаемые пользователи сайта RU-SCRIPT.3DN.RU! Мы продолжаем изучать скриптинг GTA SA, и сегодня речь пойдёт о грузовиках и их прицепах.|wmysterio|wmysterio||||Сами прицепы в игре имеют название "trailer", а грузовики, которые могут цеплять прицеп - "cab". Так, как опкодов по ним немного, то я решил сделать Cleo-миссию на тему "Дальнобойщик". Нам дадут прицеп с грузом и нужно его доставить в целостности на маркер. Начнём с опкодов:

```
0893: put_trailer 0@ on_cab 1@ // Цепляет трейлер 0@ к грузовику 1@
07AC: detach_trailer 0@ from_cab 1@ // Отцепляет трейлер 0@ от грузовика 1@
07AB: trailer 0@ attached_to_cab 1@ // Проверка: "Трейлер 0@ прицеплен к грузовику 1@ ?"
```

Часто при работе с прицепами задают ему некую раскраску с помощью опкода:

```
0506: set_vehicle_model #ARTICT1 next_variation 3 3
```

Два последних параметра должны быть равны, так как большинство машин имеют только 1 вариант изменения ( смотрите [Варианты изменения транспорта](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/varianty_izmenenija_transporta/1-1-0-34/README.md) ). Перейдём к миссии. Напишем простенький стартер:

```
{$CLEO}
0000:

:STARTER
thread 'STARTER'
wait 0
if
player.Defined($PLAYER_CHAR)
jf @STARTER_END
03A1: show_sphere_at -2031.6582 148.4805 28.8359 radius 1.5

if AND
$ONMISSION == 0
00EC: actor $PLAYER_ACTOR 0 near_point -2031.6582 148.4805 radius 2.0 2.0
not actor.Driving($PLAYER_ACTOR)
then
jump @STARTER_1
end
jump @STARTER

:STARTER_1
wait 0
player.CanMove($PLAYER_CHAR) = false
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
0ACF: show_formatted_styled_text "~y~Run in the Cab" time 5000 style 2
fade 0 1000
wait 1000
0A94: start_custom_mission "TheCab"
wait 1000
jump @STARTER

:STARTER_END
wait 0
0A93: end_custom_thread
```

Код миссии будет в следующем виде:

```
{$CLEO .cm}

//------------- TheCab ---------------

:TheCab
thread 'TheCab'
gosub @TheCab_29_57
if
wasted_or_busted
jf @TheCab_29_46
gosub @TheCab_29_144

:TheCab_29_46
$ONMISSION = 0
mission_cleanup
end_thread

:TheCab_29_57
increment_mission_attempts
$ONMISSION = 1
model.Load(#LINERUN)
model.Load(#ARTICT1)
038B: load_requested_models

:TheCab_AA
wait 0
if AND
model.Available(#LINERUN)
model.Available(#ARTICT1)
jf @TheCab_AA
0506: set_vehicle_model #ARTICT1 next_variation 3 3
0@ = car.Create(#ARTICT1, -2039.5044, 136.4451, 28.4465)
car.Angle(0@) = 269.9084
1@ = car.Create(#LINERUN, -2025.8435, 136.9129, 28.4438)
car.Angle(1@) = 271.0394
model.Destroy(#ARTICT1)
model.Destroy(#LINERUN)
072A: put_actor $PLAYER_ACTOR into_car 1@ driverseat
041E: set_radio_station 12
0893: put_trailer 0@ on_cab 1@
camera.Restore_WithJumpCut
Camera.SetBehindPlayer
wait 1000
fade 1 1000
wait 1000
player.CanMove($PLAYER_CHAR) = true
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)

:TheCab_BB
wait 0
marker.Disable(4@)
marker.Disable(5@)
018A: 2@ = create_checkpoint_at -2669.6782 1377.9211 8.0797
03BC: 3@ = create_sphere_at -2669.6782 1377.9211 8.0797 radius 2.5
0AD1: show_formatted_text_highpriority "Drive Cab inpoint!" time 4000

:TheCab_BB_1
wait 0
if OR
car.Wrecked(0@)
02BF: car 0@ sunk
car.Wrecked(1@)
02BF: car 1@ sunk
then
jump @TheCab_29_144_CAR_WRECKED
end

if AND
01AE: car 1@ sphere 0 near_point -2669.6782 1377.9211 radius 2.5 2.5 stopped
07AB: trailer 0@ attached_to_cab 1@
then
jump @TheCab_CC
end

if OR
87AB: not trailer 0@ attached_to_cab 1@
not actor.InCar($PLAYER_ACTOR, 1@)
then
jump @TheCab_BB_2
end
jump @TheCab_BB_1

:TheCab_BB_2
wait 0
marker.Disable(2@)
03BD: destroy_sphere 3@
4@ = marker.CreateAboveCar(0@)
5@ = marker.CreateAboveCar(1@)
07E0: set_marker 4@ type_to 1
07E0: set_marker 5@ type_to 1
0AD1: show_formatted_text_highpriority "Enter Cab and attach Trailer!" time 4000

:TheCab_BB_2_1
wait 0
if OR
car.Wrecked(0@)
02BF: car 0@ sunk
car.Wrecked(1@)
02BF: car 1@ sunk
then
jump @TheCab_29_144_CAR_WRECKED
end
if AND
07AB: trailer 0@ attached_to_cab 1@
actor.InCar($PLAYER_ACTOR, 1@) 
then
jump @TheCab_BB
end
jump @TheCab_BB_2_1

:TheCab_CC
wait 0
gosub @TheCab_END
player.Money($PLAYER_CHAR) += 20000
0ACF: show_formatted_styled_text "Mission passed!~n~ ~w~+%d" time 5000 style 1 20000
return

:TheCab_29_144
wait 0
gosub @TheCab_END
0ACF: show_formatted_styled_text "~r~Mission crash!" time 5000 style 1
return

:TheCab_29_144_CAR_WRECKED
wait 0
gosub @TheCab_END
0AD1: show_formatted_text_highpriority "You Cab or Trailer destroyed!" time 4000
0ACF: show_formatted_styled_text "~r~Mission crash!" time 5000 style 1
return

:TheCab_END
wait 0
if
056E: car 1@ defined
then
car.RemoveReferences(1@)
end
if
056E: car 0@ defined
then
car.RemoveReferences(0@)
end
marker.Disable(2@)
03BD: destroy_sphere 3@
marker.Disable(4@)
marker.Disable(5@)
return
```

Результаты:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/11165286.png) ![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/04397259.png)

Миссия будет считаться проваленной, если трейлер или грузовик упадёт в воду или взорвётся. Маркер будет появляться когда игрок в транспорте и трейлер прицеплен. В противном случаи над субъектами будут созданы соответствующие маркеры.

Вот такая простенькая миссия получилась :) Оставайтесь с нами!|1659|1|0|04397259`png`600`336`400`224``\|11165286`png`600`337`400`224\`\`||rabota\_s\_gruzovikami\_i\_pricepami|1504504367


# 000172. Эктра-части автомобилей

Эктра-части автомобилей|Всем привет! Этот небольшой урок будет посвящен двум опкодам, которые привлек моё внимание в последнее время.|wmysterio|wmysterio||||Это:

```
08A4: set_car 0@ extra_parts_angle_to 1@
098D: get_car 0@ extra_parts_angle 1@
```

Если применять эти команды к транспорту, но ничего, казалось, не происходит. Однако это не так. Не все автомобили имеют эти экстра-части и у Вас, наверное, уже терзает любопытство узнать что это за части.

Под экстра-частями имеется ввиду части, которые умеют двигаться ( по-умолчанию клавишами NUM8 `и <kbd>NUM2` ). Многие уже догадались о чём идёт речь. Опкоды позволяют получать и устанавливать своего рода угол этих частей.

Для примера мы возьмём бульдозер:

```
{$CLEO}
Model.Load(#DOZER)
038B: load_requested_models
0@ = Car.Create(#DOZER, 2495.1104, -1669.1406, 13.3359)
Car.Angle(0@) = 89.9275
Model.Destroy(#DOZER)
0A93: end_custom_thread
```

Скрин:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/34916962.jpg)

Его ковш будет экстра-частью и если задать значение в 1.0, то будет видно, что он двигается:

```
{$CLEO}
Model.Load(#DOZER)
038B: load_requested_models
0@ = Car.Create(#DOZER, 2495.1104, -1669.1406, 13.3359)
Car.Angle(0@) = 89.9275
Model.Destroy(#DOZER)
08A4: set_car 0@ extra_parts_angle_to 1.0 // задаём амплитуду
0A93: end_custom_thread
```

Теперь ковш будет приподнят:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/93409240.jpg)

Обратите внимание, что амплитуда является диапазоном от 0.0 до 1.0. Иными словами это максимальные и минимальные значения для опкода **08A4**. Как уже было сказано ранее, не все автомобили имеют экстра-части. Ваше задание - найти другие автомобили с ними и проверить опкоды :)

Что-же, урок окончен. Спасибо что всё ещё с нами. С Вами был **wmysterio**.|1500|1|0|34916962`jpg`480`404`400`336``\|93409240`jpg`480`274`400`228\`\`||ehktra\_chasti\_avtomobilej|1504602137


# 00042. Всё о поездах

Всё о поездах|В этом уроке Вы узнаете о том, как создать поезд и какие команды существуют для поездов.|wmysterio|wmysterio||||С вами wmysterio, и это очередной урок. Прежде чем рассмотреть опкоды, связанных с поездами, хотелось сказать, что создать их можно только на рельсах. В других местах поезда не появляются. Обычно игра ищет ближайшие рельсы и там уже создаёт поезд. Также поезд можно создать только в тех местах, где поезда обычно ездят ( прописаны пути для них ). Для начала рассмотрим типы поездов. Тип указывает количество вагонов и их модели. Все типы и их описание доступны в [базе данных - номера поездов](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/tipy_poezdov/1-1-0-44/README.md).

Сначала определим тип поезда. Пусть это будет 5. Смотрим БД, и загружаем необходимые модели:

```
:TRAIN
wait 0
model.Load(#STREAK)
model.Load(#STREAKC) 
038B: load_requested_models
 
:TRAIN_1
wait 0 
if AND
model.available(#STREAK)
model.available(#STREAKC)
jf @TRAIN_1
```

Дальше находим место в игре, где будет создавать поезд. Вот я нашел координаты: "2018.9946 -1953.9517 13.5469". Создаём этой командой:

```
06D8: $TRAIN = create_train_at 2018.9946 -1953.9517 13.5469 type 5 direction 1
```

Здесь:\
$TRAIN - имя перменной нашего поезда\
2018.9946 -1953.9517 13.5469 - координаты, где должен появится поезд\
5 - тип поезда\
1 - определяет в какую торону будет ездить поезд. 1 - будет ездить за часовой стрелкой, 0 - против часовой стрелки

Теперь поезд будет стоять в нужном месте:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/19606736.png)

Рассмотрим команды, которые связаны с поездами:

```
06D7: enable_train_traffic 0 // устанавливает трафик поездов: 0 - выключить трафик, 1 - включить трафик
07BD: destroy_train $TRAIN // уничтожает созданный поезд
06DB: destroy_all_trains // уничтожает все созданные поезда
06DC: set_train $TRAIN acc 20.0 // задаёт поезду $TRAIN ускорение 20.0
06DD: set_train $TRAIN speed 10.0 // задаёт поезду $TRAIN скорость 10.0
07C7: put_train $TRAIN at 1880.06 -1953.67 12.44 // перемещает поезд в нужные координаты
0981: train $TRAIN wrecked // проверка: "поезд $TRAIN уничтожен?"
09AE: actor $ACTOR driving_train // проверка: "Актёр едет в поезде?"
```

Есть также и другие проверки, но рассматривать пока мы их не будем. Давайте напишем скрипт, что бы когда игрок вставал на сферу, появлялся поезд. Поток будет одноразовым и добавим его в мейн: [посмотреть](https://github.com/wmysterio/scm-scripting-lessons/blob/main/data_base/sa/TRAIN.txt).

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/57557264.png)|1608|1|0|19606736\`png\`640\`400\`400\`250\`\`\\|57557264\`png\`640\`400\`400\`250\`\`\\||vsjo\_o\_poezdakh|1498944696


# 00080. Тюнинг транспорта, работа с компонентами тюнинга

Тюнинг транспорта, работа с компонентами тюнинга|Этот урок будет посвящен тюннингу, используя скриптинг.|wmysterio|wmysterio||||Одним из главных нововведений в ГТА стал тюнинг транспорта. В первую очередь обращаю Ваше внимание на том, что не все автомобили могут быть тюнингированы и, к тому-же, некоторый тюнинг доступный только конкретной машине. Спойлер, колёса, бампера и т.п являются компонентами автомобиля. Количество таких компонентов зависит от автомобиля, что "прокачивается". В этом уроке мы попробуем тюнингировать #ELEGY.

Первое, что нужно сделать - узнать какие компоненты доступны для тюнинга. Для этого откроем файл "carmods.dat" любым текстовым редактором и ищем строку, которая начинается с ELEGY:

elegy, exh\_a\_l, exh\_c\_l, fbmp\_a\_l, fbmp\_c\_l, nto\_b\_l, nto\_b\_s, nto\_b\_tw,\
rbmp\_a\_l, rbmp\_c\_l, rf\_a\_l, rf\_c\_l, spl\_a\_l\_b, spl\_c\_l\_b, wg\_l\_a\_l,\
wg\_l\_c\_l

Каждой запятоц выделено компонент, доступный для тюнинга. Во многих случаях компоненты начинаются с одного префикса:

\*\*nto\*\*\_b\_l\
\*\*nto\*\*\_b\_s\
\*\*nto\*\*\_b\_tw

В таких случаях можно выбрать только один компонент из этих префиксов ( думаю вы видели, что можно выбрать только один тип нитро ). Для Вас ( чтобы Вы не парились какой префикс что значит ) я сделал таблицу некоторых префиксов, которые обозначают компонент:

| Префикс | Описание                                                   |
| ------- | ---------------------------------------------------------- |
| exh     | Выхлопная труба                                            |
| fbmp    | Передний бампер ( \*\*f\*\*orward \*\*b\*\*u\*\*mp\*\*er ) |
| nto     | Нитро ( \*\*n\*\*i\*\*t\*\*r\*\*o\*\* )                    |
| rbmp    | Задний бампер                                              |
| spl     | Спойлер                                                    |

Существуют и другие компоненты, но Вы уже сами протестируете их. Я только привел пример этих префиксов. Суть этой информации в том, что бы не делать ошибок при загрузке компонентов. Мне иногда приходят письма об этих компонентах и как же удивляются адресанты когда я им отвечаю, что "нельзя загружать два одинаковых компонента", хотя как они пишут: "Эти компоненты находятся в списке". Отвечаю наперёд: можно использовать только один компонент из одинаковых префиксов.

Это теория. Советую вам обратить большое внимание на это, так как это поможет вам миновать ошибки. Перейдём к опкодам:

```
06E9: load_car_component #rbmp_c_l // загрузить компонент
06EA: car_component #rbmp_c_l available // проверка "Загрузился ли компонент?"
06E7: 1@ = add_car_component #rbmp_c_l to_car 0@ // устанавливает компонент транспорту
```

Здесь:\
1@ - в эту переменную будет записан компонент\
\#rbmp\_c\_l - модель загруженного компонента\
0@ - наш автомобиль

Как только компонент прицеплен к машине, можем смело очищать память игры от загруженной модели компонента:

```
06EB: release_car_component #rbmp_c_l
```

Наш скрипт будет примерно таким:

```
{$CLEO}
0000:

:1
thread '1'
wait 0
06E9: load_car_component #rbmp_c_l
model.Load(#ELEGY)
038B: load_requested_models

:1_1
wait 0
if AND
06EA: car_component #rbmp_c_l available
model.Available(#ELEGY)
jf @1_1
0@ = car.Create(#ELEGY, 2493.1716, -1667.1075, 12.3437)
car.Angle(0@) = 178.0475
model.Destroy(#ELEGY)
06E7: 1@ = add_car_component #rbmp_c_l to_car 0@
06EB: release_car_component #rbmp_c_l
0A93: end_custom_thread
```

Результат нашего тюнинга:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/90309845.png)

Как видим, задний бампер успешно поставлен!

Кроме загрузки компонентов, возможно давать автомобилю некоторые примочки. Рассмотрим несколько опкодов из этой категории ( компонентов загружать не нужно ):

```
09E9: car 0@ add_single_nitro // установить одноразовый нитроускоритель
07FF: set_car 0@ hydraulics 1 // установить гидравлику
0216: enable_taxi 0@ light 1 // включает или выключает значок "Такси" на машине ( только для машин такси )
0572: enable_taxi_nitros 1 // опкод включает нитро во всех такси
```

Есть ещё проверка "Машина имеет гидравлику?":

```
0803: car 0@ have_hydraulics
```

Одпокы для работы с покраской:

```
06ED: set_car 0@ paintjob 2
0988: get_car 0@ paintjob 1@
```

Опкод установит/получит тачке необходимую покраску ( они ещё называются винилы ).

Здесь:\
0@ - машина\
2 - номер винила. Диапазон винил: от 0 до 2. Если поставить число больше или меньше, то покраска не поставится. Тоже самое касается автомобилей, которые не поддерживают перекраски винил\
1@ - в эту переменную будет занесен номер текущей покраски опкодоа 06ED

Опкоды, для работы с цветом машины:

```
0229: set_car 0@ primary_color_to 11 secondary_color_to 0 // задать основные цвета
03F3: get_car 0@ primary_color_to 1@ secondary_color_to 2@ // получить основные цвета
```

Так же существуют и такие странные опкоды:

```
0A11: set_car 0@ tertiary_color_to 11 quaternary_color_to 0 // задать вторичные цвета
0A12: get_car 0@ tertiary_color_to 1@ quaternary_color_to 2@ // получить вторичные цвета
```

Это как бы 3-й и 4-й цвет ( используется не некоторых автомобилях ). Также мы можем задать номерной знак автомобилю опкодом:

```
0674: set_car_model #ELEGY numberplate "AA_TELL"
```

Здесь:\
\#ELEGY - модель транспорта. Использовать опкод нужно перед созданием машины\
"AA\_TELL" - текст номерного знака. Не всегда работает и обычно меняются только задние номера

Ну и напоследок давайте прокачаем наш ELEGY:

```
{$CLEO}
0000:

:1
thread '1'
wait 0
06E9: load_car_component #rbmp_c_l
06E9: load_car_component #spl_a_l_b
model.Load(#ELEGY)
038B: load_requested_models

:1_1
wait 0
if AND
06EA: car_component #rbmp_c_l available
06EA: car_component #spl_a_l_b available 
model.Available(#ELEGY)
jf @1_1
0@ = car.Create(#ELEGY, 2493.1716, -1667.1075, 12.3437)
car.Angle(0@) = 178.0475
model.Destroy(#ELEGY)

06E7: 1@ = add_car_component #rbmp_c_l to_car 0@
06E7: 2@ = add_car_component #spl_a_l_b to_car 0@ 
06EB: release_car_component #rbmp_c_l
06EB: release_car_component #spl_a_l_b 
 
09E9: car 0@ add_single_nitro
07FF: set_car 0@ hydraulics 1
06ED: set_car 0@ paintjob 1 

0A93: end_custom_thread
```

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/56885858.png)

На этом урок окончен. =)|2567|1|0|56885858`png`500`300`400`240``\|90309845`png`500`300`400`240\`\`||tjuning\_transporta\_rabota\_s\_komponentami|1499755417


# 00029. Транспорт и команды, свойственны ему

Транспорт и команды, свойственны ему|Как и в предыдущем уроке, мы рассмотрим опкоды. Но на этот раз тема касается транспорта.|wmysterio|wmysterio||||Транспорт разделяется условно на 4 группы: машины ( в том числе байки и велики ), поезда, лодки, воздушные средства передвижения. Большинство опкодов можно применить ко всем видам транспорта. Рассмотрим их:

| Безусловные                                                                                                                                                                                                                                                                                                   |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| car.PutAt($Car, 10.0, -1400.0, 18.0)                                                                                                                                                                                                                                                                          |
| перемещает машину в заданные координаты                                                                                                                                                                                                                                                                       |
| car.Destroy($Car)                                                                                                                                                                                                                                                                                             |
| уничтожить машину                                                                                                                                                                                                                                                                                             |
| car.Health($CAR) = 500                                                                                                                                                                                                                                                                                        |
| устанавливает количество жизни машине ( если ниже 251 то машина начнёт гореть! )                                                                                                                                                                                                                              |
| car.RemoveReferences($Car)                                                                                                                                                                                                                                                                                    |
| стирает все сведения о машине                                                                                                                                                                                                                                                                                 |
| 03C0: $Car = actor $PLAYER\_ACTOR car                                                                                                                                                                                                                                                                         |
| записывает в переменную машину, в которой сидит актёр                                                                                                                                                                                                                                                         |
| 02E3: $Speed = car $Car speed                                                                                                                                                                                                                                                                                 |
| записывает в переменную скорость с которой едет транспорт                                                                                                                                                                                                                                                     |
| 04BA: set\_car $Car speed\_instantly 20.0                                                                                                                                                                                                                                                                     |
| устанавливает машине скорость                                                                                                                                                                                                                                                                                 |
| Car.SetMaxSpeed($Car, 10.0)                                                                                                                                                                                                                                                                                   |
| устанавливает максимальную скорость машины, до которой она может разогнаться ( если за рулём машини СЖ, то опкод не работает )                                                                                                                                                                                |
| 0294: set\_car $Car sprayable 1                                                                                                                                                                                                                                                                               |
| машину можно перекрашивать ( если поставить 0 - то нельзя )                                                                                                                                                                                                                                                   |
| car.DoorStatus($Car) = 2                                                                                                                                                                                                                                                                                      |
| замыкает двери машины( если поставить 0 то двери можно будет открывать)                                                                                                                                                                                                                                       |
| 0229: set\_car $Car color\_to 11 0                                                                                                                                                                                                                                                                            |
| устанавливает цвета машины ( см. [Цвета автомобилей](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/cveta_avtomobilej_v_gta_san_andreas/1-1-0-19/README.md) ) Первая цифра: основной цвет, другая - вторичный цвет.                                                                  |
| car.SetImmunities($Car,1,1,1,1,1)                                                                                                                                                                                                                                                                             |
| устанавливает машине иммунитеты от взрывов, падения и т.п.                                                                                                                                                                                                                                                    |
| 0ABE: vehicle $Car engine\_on                                                                                                                                                                                                                                                                                 |
| включает мотор машины                                                                                                                                                                                                                                                                                         |
| 02D4: car $Car turn\_off\_engine                                                                                                                                                                                                                                                                              |
| выключает мотор машины                                                                                                                                                                                                                                                                                        |
| 0A26: set\_radio\_to\_favorite\_station                                                                                                                                                                                                                                                                       |
| устанавливает радио на самую используемую радиостанцию                                                                                                                                                                                                                                                        |
| 041E: set\_radio\_station 0                                                                                                                                                                                                                                                                                   |
| устанавливает радио на определённую радиостанцию. Список радиостанций смотрите в нашей [базе данных](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/id_radio_stancij/1-1-0-41/README.md). Если вы используете служебный транспорт ( пожарную, скорую ), то опкод может не сработать. |

| Условные                                          |
| ------------------------------------------------- |
| 0495: car $Car burning                            |
| роверка: машина горит?                            |
| car.Defined($CAR)                                 |
| проверка: машина существует?                      |
| 02BF: car $Car sunk                               |
| проверка: машина упала в воду?                    |
| 01C1: car $Car stopped                            |
| проверка: машина остановилась?                    |
| 03C9: car $Car damaged                            |
| проверка: машина повреждена?                      |
| 01F3: car $Car airborne                           |
| проверка: машина в воздухе?                       |
| 0119: car $Car wrecked                            |
| проверка: машина уничтожена?                      |
| 051D: cars $Car1 and $Car2 collided               |
| проверка: машина1 столкнулась с машиной2?         |
| 01F4: car $Car flipped                            |
| проверка: машина перевернулась?                   |
| 03CE: car $Car stuck                              |
| проверка: машина застряла ( не может двигаться )? |

Команды, свойственны только машинам, великам и байкам:

| Безусловные                                                                                                                                                                                                                                        |                                               |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| car.DriveTo($car, -6.0, 1350.0, 47.0)                                                                                                                                                                                                              |                                               |
| заставляет машину ехать в заданные координаты                                                                                                                                                                                                      |                                               |
| car.ToggleTaxiLight($Car) = true                                                                                                                                                                                                                   |                                               |
| включить значок ТАКСИ на машине ( если поставить false - то выключить значок )                                                                                                                                                                     |                                               |
| 067F: set\_car $Car headlights 2                                                                                                                                                                                                                   |                                               |
| включить фары в машине ( если поставить 0 - то выключить )                                                                                                                                                                                         |                                               |
| 01EC: make\_car $Car very\_heavy 1                                                                                                                                                                                                                 |                                               |
| делает машину очень тяжелой ( как отключить этот параметр я не знаю )                                                                                                                                                                              |                                               |
| Car.SetToNormalDriver($Car)                                                                                                                                                                                                                        |                                               |
| машине будет обычный водитель                                                                                                                                                                                                                      |                                               |
| Сar.SetToPsychoDriver($Car)                                                                                                                                                                                                                        |                                               |
| в машине будет сумасшедший водитель                                                                                                                                                                                                                |                                               |
| Car.SetDriverBehaviour($Car, Nowhere)                                                                                                                                                                                                              |                                               |
| устанавливает тип езды машине. Вот все типы, известные мне:                                                                                                                                                                                        |                                               |
| Тип                                                                                                                                                                                                                                                | Описание                                      |
| 0                                                                                                                                                                                                                                                  | никуда не ехать                               |
| 1                                                                                                                                                                                                                                                  | следовать дороге                              |
| 2                                                                                                                                                                                                                                                  | ездить за игроком                             |
| 4                                                                                                                                                                                                                                                  | ездить за игроком                             |
| 8                                                                                                                                                                                                                                                  | ехать напрямик, не обращая внимания на дорогу |
| 07F8: car $Car1 follow\_vehicle $Car2 radius 27.0                                                                                                                                                                                                  |                                               |
| заставляет машину1 следовать за машиной2 на растоянии 27.0                                                                                                                                                                                         |                                               |
| car.ToggleHydraulics($Car) = true                                                                                                                                                                                                                  |                                               |
| устанавливает на машину гидравлику                                                                                                                                                                                                                 |                                               |
| 0657: car $Car open\_component 0                                                                                                                                                                                                                   |                                               |
| открывает часть машины. Вот список известных мне частей:                                                                                                                                                                                           |                                               |
| Часть                                                                                                                                                                                                                                              | Описание                                      |
| 0                                                                                                                                                                                                                                                  | Капот.                                        |
| 1                                                                                                                                                                                                                                                  | Багажник.                                     |
| 2                                                                                                                                                                                                                                                  | Дверь водителя или левого переднего места.    |
| 3                                                                                                                                                                                                                                                  | Дверь правого переднего места.                |
| 4                                                                                                                                                                                                                                                  | Дверь заднего левого места.                   |
| 5                                                                                                                                                                                                                                                  | Дверь заднего правого места.                  |
| 00AE: set\_car $Car traffic\_behaviour\_to 2                                                                                                                                                                                                       |                                               |
| машина будет игнорировать светофоры                                                                                                                                                                                                                |                                               |
| Car.SetAnimation($Car, 9, 4000)                                                                                                                                                                                                                    |                                               |
| <p>некая анимация для транспорта ( нужно, что бы в машине был водитель ).Здесь:<br>4000 - время за которое будет воспроизводится данная анимация<br>9 - номер анимации. Все известные мне на данный момент анимации перечислены в таблице ниже</p> |                                               |
| Тип                                                                                                                                                                                                                                                | Описание                                      |
| 3                                                                                                                                                                                                                                                  | едет задом                                    |
| 5                                                                                                                                                                                                                                                  | поворачивает колёса вправо                    |
| 6                                                                                                                                                                                                                                                  | едет по кругу против часовой стрелки          |
| 8                                                                                                                                                                                                                                                  | едет по кругу по часовой стрелке              |
| 9                                                                                                                                                                                                                                                  | едет прямо                                    |

| Тип | Описание                             |
| --- | ------------------------------------ |
| 3   | едет задом                           |
| 5   | поворачивает колёса вправо           |
| 6   | едет по кругу против часовой стрелки |
| 8   | едет по кругу по часовой стрелке     |
| 9   | едет прямо                           |

| Часть | Описание                                   |
| ----- | ------------------------------------------ |
| 0     | Капот.                                     |
| 1     | Багажник.                                  |
| 2     | Дверь водителя или левого переднего места. |
| 3     | Дверь правого переднего места.             |
| 4     | Дверь заднего левого места.                |
| 5     | Дверь заднего правого места.               |

| Тип | Описание                                      |
| --- | --------------------------------------------- |
| 0   | никуда не ехать                               |
| 1   | следовать дороге                              |
| 2   | ездить за игроком                             |
| 4   | ездить за игроком                             |
| 8   | ехать напрямик, не обращая внимания на дорогу |

Команды, свойственны самолётам:

| Безусловные                                                                                                                                                              |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 04D2: set\_plane $PLANE fly\_autopilot\_around\_point 600.0 250.0 16.0 altitude\_between 0.0 and 0.0                                                                     |
| заставляет самолёт лететь в заданную точку ( последние 2 параметра не трогайте )                                                                                         |
| 070F: plane $PLANE fly\_direction 180.0 altitude\_between 200.0 and 200.0                                                                                                |
| заставляет самолёт лететь под определённым углом ( в нашем случаи под 180.0 градусом ), остальные параметры одинаковы и указывают высоту ( в данном случаи 200.0 )       |
| 084E: flying\_vehicle $PLANE use\_primary\_gun 1                                                                                                                         |
| использование ракет                                                                                                                                                      |
| 0841: flying\_vehicle $PLANE use\_secondary\_gun 1                                                                                                                       |
| использование пулемёта                                                                                                                                                   |
| 0724: flying\_vehicle $PLANE follow\_and\_attack\_player $PLAYER\_CHAR radius 40.0                                                                                       |
| самолёт будет летать около игрока в радиусе 40.0 и атаковать его ( учтите, что самолёт будет атаковать только СЖ, по этому не меняйте переменную $PLAYER\_CHAR в опкоде) |

Команды, применяемые к вертолётам:

| Безусловные                                                                       |
| --------------------------------------------------------------------------------- |
| 04A2: heli $HELI fly\_to 640.0 480.0 128.0 speed 60.0 70.0                        |
| заставляет вертолёт лететь в заданную точку со скоростью 60.0 и на высоте 70.0    |
| 084E: flying\_vehicle $Heli use\_primary\_gun 1                                   |
| использование вертолётом ракет                                                    |
| 0841: flying\_vehicle $Heli use\_secondary\_gun 1                                 |
| использование вертолётом пулемёта                                                 |
| 0724: flying\_vehicle $Heli follow\_and\_attack\_player $PLAYER\_CHAR radius 40.0 |
| тоже самое, что и опкод 0724, только с вертолётом ( заставляет атаковать СЖ )     |
| 0788: enable\_heli $Heli magnet 1                                                 |
| устанавливает на вертолёт магнит, если 0 то убирает магнит                        |
| 0789: set\_heli $Heli release\_stuff\_from\_magnet                                |
| забирает магнит с вертолёта                                                       |

Команды, применяемые к лодкам:

| Безусловные                                   |
| --------------------------------------------- |
| 02D3: boat $Boat drive\_to 10000.0 -100.0 0.0 |
| заставляет лодку плыть в заданные координаты  |
| 02DB: set\_boat $Boat speed\_to 50.0          |
| устанавливает лодке нужную скорость           |

Команды для поездов:

| Безусловные                                                                                                                                                                                                                                                                                  |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 06D8: $Train = create\_train\_at 2285.1523 -1257.4998 23.0 type 15 direction 1                                                                                                                                                                                                               |
| создаёт поезд в нужных координатах. Здесь 15 - тип поезда ( в основном тип влияет на модели поезда и вагона а так же на количество самих вагонов ), 1 - указывается направление поезда. Координаты задавайте такие, что бы они были ближе к рельсам, иначе поезд создастся чёрт знает где :) |
| 06DD: set\_train $Train speed 23.0                                                                                                                                                                                                                                                           |
| устанавливает скорость поезду                                                                                                                                                                                                                                                                |
| 06DC: set\_train $Train acc 7.0                                                                                                                                                                                                                                                              |
| устанавливает ускорение для поезда                                                                                                                                                                                                                                                           |
| 06D7: toggle\_train\_traffic 1                                                                                                                                                                                                                                                               |
| параметр влияет на появление поездов: 1 - будут появляться как обычно, 0 - не будут появляться вообще                                                                                                                                                                                        |
| 09CF: set\_train $Train flag 0                                                                                                                                                                                                                                                               |
| задаёт поезду флаги. Что именно задаёт этот опкод я не знаю и не использую его                                                                                                                                                                                                               |

К поездам мы ещё вернёмся и детально изучим их. Сейчас я выложил только опкоды.|2988|1|0||transport\_i\_komandy\_svojstvenny\_im|1498658527


# 00046. Плавающие и лётные средства передвижения

Плавающие и лётные средства передвижения|Всем привет! В этом уроке мы рассмотрим детальнее ещё несколько типов транспорта - лодки, самолёты в вертолёты. Как-то совсем забыл о них, поэтому пришло их время :)|wmysterio|wmysterio||||Начнём с лодок. Существует всего три одкода для работы с ними:

```
02D3: boat 0@ sail_to 3007.8489 -1994.3662 1.5716 // Заставляет лодку плыть в указанную точку
02DB: set_boat 0@ speed_to 10.0 // устанавливать скорость, с которой она будет двигаться
0323: enable_boat 0@ anchor 1 // Включает или отключает у лодки якорь ( судя по описанию ). Правда какой-то явного изменения в поведении лодки не наблюдалось.
```

Наведу простейший пример:

```
{$CLEO}
Model.Load(#REEFER)
038B: load_requested_models
0@ = Car.Create(#REEFER, 2937.3284, -1895.0162, 1.178)
Car.Angle(0@) = 260.6488
Model.Destroy(#REEFER)
02DB: set_boat 0@ speed_to 10.0
02D3: boat 0@ sail_to 3007.8489 -1994.3662 1.5716
0A93: end_custom_thread
```

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/80715311.png)

Интересно то, что лодка будет бороздить возле этой точки, так как попасть именно в неё очень малый шанс.

Для самолётов уже другое дело. Рассмотрим опкоды. Чтобы заставить самолёт лететь, достаточно использовать:

```
04D2: set_plane 0@ fly_autopilot_around_point 2279.0786 -1652.6747 48.4595 altitude_between 30.0 and 30.0
```

Здесь:\
0@ - хэндл самолёта\
2279.0786 -1652.6747 48.4595 - точка, куда должен добраться транспорт\
30.0 - минимальная и максимальная высота над уровнем моря. Как правило эти параметры ставят одинаковыми, если поверхность ровная маршрута и бед препятствий.

```
070F: plane 0@ fly_direction 180.0 altitude_between 200.0 and 200.0
```

Устанавливает направление самолёту ( должен уже лететь ).

Здесь:\
0@ - хэндл самолёта\
180.0 - угол направления\
200.0 - минимальная и максимальная высота над уровнем моря. Как правило эти параметры ставят одинаковыми

```
0710: plane 0@ follow_actor $PLAYER_ACTOR follow_car -1 radius 70.0
```

Заставляет самолёт следовать за актёром или транспортом.

Здесь:\
0@ - хэндл самолёта\
$PLAYER\_ACTOR - объект следования ( актёр ).\
-1 - объект следования ( транспорт ).\
70.0 - радиус. Будет петлять около ceбъекта.

```
08E6: set_plane 0@ landing_gear 1
```

Открыть ( 1 ) или закрыть ( 0 ) шасси в самолёта 0\@.

Среди опкодов, выделяются и конкретно под Гидру ( #HYDRA ). Их всего три:

```
0745: set_hydra 0@ thrust_to_horizontal
070E: hydra 0@ attack_player_car $PLAYER_CHAR radius 10.0
08A2: set_hydra 0@ attack_with_rockets_car_of_player $PLAYER_CHAR radius 30.0
```

Первый опкод поворачивает эту фиговину ( не знаю как правильно это называется ) в горизонтальное положение:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/39124344.png)

Второй опкод заставляет Гидру атаковать игрока находясь в радиусе 10.0. Третий опкод действует также, как и второй, только Гидра атакует, используя ракеты. Пример скрипта:

```
{$CLEO}
Model.Load(#HYDRA)
038B: load_requested_models
0@ = Car.Create(#HYDRA, 945.858, 253.3596, 29.1832)
Car.Angle(0@) = 222.5565
Model.Destroy(#HYDRA)
08A2: set_hydra 0@ attack_with_rockets_car_of_player $PLAYER_CHAR radius 30.0
0A93: end_custom_thread
```

Дальше на очереди у нас вертолёты. С ними работать проще. Перечислю основные опкоды для работы с ними.

```
04A2: set_heli 0@ fly_to -2244.48 129.14 34.56 altitude_between 0.0 and 0.0
0743: heli 0@ fly_to -2244.48 129.14 34.56 altitude 0.0 0.0
```

Опкоды заставляют вертолёт лететь в указанную точку на указанной высоте.

```
04D0: force_heli 0@ looking_angle_to 270.0
04D1: reset_heli 0@ looking_angle
0564: heli 0@ simulate_crash_landing
```

Первый опкод закрепляет угол кабины, старается смотреть нос самолёта в нужный угол. Второй опкод возвращает угол в управление пилота. Третий заставляет вертолёт упасть, симулировать падение. В оригинальных миссиях наблюдался такой случай когда вертолёт с СЖ сбили и он падал в океан.

Следующие опкоды заставляют вертолёт следовать за Актёрами ( или атаковать его ), транспортом и игроком:

```
0724: heli 0@ follow_and_attack_player $PLAYER_CHAR radius 50.0
0726: heli 0@ follow_actor $PLAYER_ACTOR follow_car -1 radius 20.0
0727: set_heli 0@ behavior_to_police_heli_and_follow_actor $PLAYER_ACTOR follow_car -1 radius 20.0
0780: heli 0@ hover_above actor $PLAYER_ACTOR car -1 altitude 15.0 170.0
```

× \*\*Примечание:\*\* Вертолёт должен иметь водителя!

Следующая пачка опкодов связана с двигателем:

```
07BB: set_heli 0@ horizontal_thrust_power 10
0825: set_helicopter 0@ instant_rotor_start
0A1C: set_helicopter 0@ play_engine_sounds 1
```

Первый заставляет отлетать вертолёт от земли с силой 10. Второй запускает двигатель. Третий включает или выключает звук мотора. Пример:

```
{$CLEO}
Model.Load(#MAVERICK)
Model.Load(#WMYDRUG)
038B: load_requested_models
0@ = Car.Create(#MAVERICK, 945.858, 253.3596, 29.1832)
Car.Angle(0@) = 222.5565
Model.Destroy(#MAVERICK)
Model.Destroy(#WMYDRUG)
0129: 1@ = create_actor_pedtype 4 model #WMYDRUG in_car 0@ driverseat
0825: set_helicopter 0@ instant_rotor_start
0A1C: set_helicopter 0@ play_engine_sounds 1
0726: heli 0@ follow_actor $PLAYER_ACTOR follow_car -1 radius 20.0
0A93: end_custom_thread
```

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/77045220.png)

К летающим средствам, которые имеют оружие ( пулемёт или ракеты ), можно применить следующие опкоды, которые заставляют использовать их:

```
084E: flying_vehicle 149@ use_primary_gun 1 
0841: flying_vehicle 114@ use_secondary_gun 1
```

Также есть опкоды, связанные с магнитами, но о них мы поговорим в следующих уроках, где будем писать новую полноценную миссию. На этом всё, с вами был wmysterio. Пока!|1816|1|0|80715311`png`800`480`400`240``\|39124344`png`800`480`400`240``\|77045220`png`800`480`400`240``||plavajushhie\_i\_ljotnye\_sredstva\_peredvizhenija|1504599897


# 00082. Работа с частями автомобиля

Работа с частями автомобиля|В этом уроке Вы узнаете о частях автомобиля.|wmysterio|wmysterio||||Это какбы вторая часть работы с компонентами, только отличается он именно основным частям автомобиля.

К частям автомобиля относятся: двигатель, двери и т.п. Рассмотрим опкоды:

```
067F: set_car $Car headlights 2
```

Позволяем влючить фары в автомобиля.

Здесь:\
$Car - хендл автомобиля\
2 - включить фары ( если поставить 0 - выключить ). Это при условиях, что эти части не повреждены. Так же работают ( или видны ) только ночью

```
0657: car $Car open_component 0
```

Открывает часть машины. Вот таблица того, что можно открыть ( не помню писал я её или нет =) ) ранее, так что вот:

| Номер | Часть                                     |
| ----- | ----------------------------------------- |
| 0     | Капот                                     |
| 1     | Багажник                                  |
| 2     | Дверь водителя или левого переднего места |
| 3     | Дверь правого переднего места             |
| 4     | Дверь заднего левого места                |
| 5     | Дверь заднего правого места               |

Обратите внимание, что это называется компонент автомобиля, а НЕ компонент тюнинга! Чтобы не путать я назвал это именно частью автомобиля. Далее в нас опкод, который позволяет проверить "Компонент открыт?":

```
08A7: car $Car componentA 1 opened_or_not_present
```

Этот опкод запишет в переменную слот компонента:

```
096D: get_car $Car car_component 1 on_slot 1@
```

Здесь:\
$Car - хендл автомобиля\
1 - номер компонента\
1@ - переменная, в которою будет записан слот

Ну и теперь напишем самый простой скрипт, который спавнит машину на Гроув и сразу открывает ей багажник:

```
{$CLEO}
0000:
 
:1
thread '1'
wait 0
model.Load(#BLISTAC)
038B: load_requested_models 
 
:1_1
wait 0
if 
model.Available(#BLISTAC)
jf @1_1
0@ = car.Create(#BLISTAC, 2493.1716, -1667.1075, 12.3437)
car.Angle(0@) = 178.0475
model.Destroy(#BLISTAC)
0657: car 0@ open_componentA 1 
0A93: end_custom_thread
```

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/86589679.png)|1506|1|0|86589679\`png\`500\`300\`400\`240\`\`\\||rabota\_s\_chastjami\_avmomobmlja|1499843915


# Актёры


# 000152. Заставляем актёра говорить. Аудио-таблицы

Заставляем актёра говорить. Аудио-таблицы|Доброго времени суток всем посетителям сайта! Этот урок будет полезен, в первую очередь, опытным скриптерам, имеющим приличный стаж в GTA-моддинге. Он посвящён аудио-таблицам, которые есть в игре.|SanKing|SanKing|||<http://gtaforums.com/topic/505421-gta-san-andreas-speech-id-list/|Естественно>, у вас возникает вопрос: а что это вообще такое? Ответ: аудио-таблицы - это своеобразная "тема" для высказывания актёром, например:

```
05C1: AS_actor $PLAYER_ACTOR speak_from_audio_table 230
```

Здесь:\
$PLAYER\_ACTOR - переменная, или хэндл, актёра, который будет говорить\
230 - id аудио-таблицы ( смотрите таблицу знаечний чуть ниже )

Вот пример кода:

```
:NONAME
wait 0
if
0AB0: key_pressed 90 //нажата клавиша Z
jf @NONAME
// самое главное. 137 заставляет игрока говорить что-то вроде "Спасибо":
05C1: AS_actor $PLAYER_ACTOR speak_from_audio_table 137
wait 1000
jump @NONAME
```

× \*\*Примечание:\*\* есть таблицы для игрока, для бандитов и для обычных педов. У них разный набор фраз!

Список ID звуков Вы сможете найти в надей [базе данных](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/id_zvukov_peshekhodov_iz_audio_tablic/1-1-0-56/README.md).

Есть ещё фразы девушек Си-Джея и некоторых педов отдельно, но это уже мелкие детали. Лично я думаю, что фразами, данными здесь, можно пользоваться в скриптах всю жизнь и не ощущать недостатка :)

Если тема заинтересовала, то эксперементируйте с id таблиц и применяйте к разным актёрам. При знании английского некоторые фразы могут улыбнуть :)

С вами был SanKing, пока!|1800|48|0||zastavljaem\_aktjora\_govorit\_audio\_tablicy|1504594946


# 000177. Трюк со специальными актёрами

Трюк со специальными актёрами|Зравствуйте, друзья! Спустя столько лет я не думал, что скриптинг сможет меня удивить. Но как показало время - может! Возможно, сейчас это не секрет, но я обязан поделиться новой порцией своих знаний.|wmysterio|wmysterio||||Речь сегодня пойдёт о специальных актёрах. В [этом уроке](https://github.com/wmysterio/scm-scripting-lessons/blob/main/publ/gta_sa/gta_sa/specialnye_aktjory/34-1-0-69/README.md) я уже рассказывал о них. Сегодня я расскажу о одном интересном трюке, который позволяет загружать любых специальных актёров, а не только тех, которые приведены в справке. Эти актёры не привязаны к конкретным ID, а модели сохранены в файле "gta3.img". Давайте попробуем сделать следующее:

* Скачаем любую модель актёра, например [эту](https://github.com/wmysterio/scm-scripting-lessons/blob/main/load/gta_sa/modeli_i_tekstury/fejt_s_mirrors_edge/70-1-0-165/README.md). Переименуем файлы модели и текстуры, например, на "FAITCON";
* Загружаем файлы в архив gta3.img с помощью любого IMG-редактора;
* Пишем следующий скрипт:

```
{$CLEO}
023C: load_special_actor 'FAITCON' as 1 // models 290-299
038B: load_requested_models

repeat
wait 0
until 023D: special_actor 1 loaded

0@ = Actor.Create(5, #SPECIAL01, 2499.3953, -1657.634, 12.3805)
Actor.Angle(0@) = 136.2072
0296: unload_special_actor 1

0A93: end_custom_thread
```

И вот результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/80008710.jpg)

Из этого я могу зделать вывод, что мы можем загружать таким образом огромное количество актёров без замены оригинальных специальных актёров! Есть правда один недостаток - актёры полностью немые, но даже этого вполне хватит, чтобы использовать этот трюк в своих модах!

Спасибо за внимание! С вами попрежнему wmysterio.|783|1|0|80008710`jpg`640`359`320\`180\`\`||trjuk\_so\_specialnymi\_aktjorami|1499498839


# 00020. Типы пешеходов, номера банд и отношение между ними

Типы пешеходов, номера банд и отношение между ними|Этот урок я посвящу бандам, то есть мы научим банды контролировать улицы, указывать отношение банд к игроку ( CJ ).|wmysterio|wmysterio||||Пришло время нам немного бросить теорию и начать делать что то с игрой :)

Для начала нужно знать кто такой актёр ( actor ). Актёр — это любой персонаж в игре, в том числе и СЖ. Каждый такой актёр имеет свой тип, то есть какую роль он будет выполнять в игре. Таблицу всех известных типов можно найти в справке SB или в нашей [базе данных](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/tipy_peshekhodov/1-1-0-35/README.md)).

Банда — это небольшое количество людей, в которых общие цели. Всего в игре есть около 10 банд. И каждая банда имеет свой уникальный номер. Номера банд можно узнать со справки компилятора или посмотреть нашу [базу данных](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/nomera_band/1-1-0-36/README.md). Обратите внимание, что счёт ведётся с нуля.

Итак, давайте укажем зону, которую будут контролировать банды. Делается это опкодом:

```
076C: set_zone 'GAN1' gang 1 density_to 80
```

Здесь:\
'GAN1' — это имя зоны, которую будут контролировать банды ( имя игровые зоны можно найти в справке или в нашей [базе данных](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/nazvanie_zon_dlja_gta_san_andreas/1-1-0-16/README.md) )\
1 — номер банды, которая будет контролировать, в нашем случаи это гроув\
80 — это плотность ( сила ) банды. Советую брать диапазон от 1 до 100. Учтите, что чем меньше плотность, тем реже будут появляться члены банд на улице.<br>

Чтобы в банд было какое-то оружие, нужно написать опкод:

```
0237: set_gang 1 weapons_to 24 29 4
```

1 — номер банды\
24 - номер первого оружия\
29 - номер второго оружия\
4 - номер третьего оружия

Все номера оружия вы сможете просмотреть в нашей [базе данных](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/oruzhie_v_gta_san_andreas/1-1-0-14/README.md) ( см. колонку "Номер оружия" ).

Если мы хотим, что бы велась война за территории ( их можно было захватить ), то используйте опкод:

```
0879: enable_gang_wars 1
```

Здесь:\
1 - включить возможность ( если поставить 0, то такой возможности не будет ).× \*\*Примечание:\*\* Можно отбирать территории только в Баллас и Вагос. Менять цвет или добавлять новый опкодом нельзя! Ещё нету такой возможности, что бы СЖ стал представителем какой то банды ( не гров ). Такие возможности скорее можно делать только через игровую память, но там я не силён.× \*\*ВАЖНО:\*\* Чтобы увидеть окраску зон, нужно зайти в любой интерьер ( например, дом Карла ) и снова выйти на улицу. Если эффект не достигается, то как правило, достаточно убить игрока и зоны окрасятся в нужные цвета. Также иногда помогает загрузка сохранения.

Давайте напишем скрипт, что бы было парочка районов, которых можно захватить:

```
// WMYSTERIO, ru-script.3dn.ru
DEFINE OBJECTS 1
DEFINE OBJECT SANNY BUILDER 3.04 

DEFINE MISSIONS 0

DEFINE EXTERNAL_SCRIPTS 0

DEFINE UNKNOWN_EMPTY_SEGMENT 0

DEFINE UNKNOWN_THREADS_MEMORY 3072

//-------------MAIN---------------
thread 'MAIN'
set_wb_check_to 0
set_weather 0
select_interior 0
fade 0 0
0180: set_on_mission_flag_to $ONMISSION
00C0: set_current_time_hours_to 8 minutes_to 0
04E4: unknown_refresh_game_renderer_at 2491.1572 -1670.3434
Camera.SetAtPos(2491.1572, -1670.3434, 12.3359)
$PLAYER_CHAR = Player.Create(#NULL, 2491.1572, -1670.3434, 12.3359)
$PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
Actor.Angle($PLAYER_ACTOR) = 66.3548
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
Camera.SetBehindPlayer
Player.Build($PLAYER_CHAR)
Player.CanMove($PLAYER_CHAR) = True
fade 1 0
// старт нового кода
0879: enable_gang_wars 1
076C: set_zone 'GAN1' gang 1 density_to 40 
076C: set_zone 'GAN2' gang 1 density_to 80 
076C: set_zone 'IWD1' gang 0 density_to 40 
076C: set_zone 'IWD2' gang 0 density_to 80 
076C: set_zone 'IWD3A' gang 2 density_to 40 
076C: set_zone 'IWD3B' gang 2 density_to 80 
0237: set_gang 0 weapons_to 22 31 14 
0237: set_gang 1 weapons_to 30 28 17 
0237: set_gang 2 weapons_to 36 15 27 
// конец нового кода
end_thread
```

Давайте проверим наш скрипт. Как видим, наша задача выполнена. Просмотрев карту, мы увидим примерно такое:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/09129058.png)

Всё, что нам осталось - это захватить их. Как это делается, думаю, вам известно :) Давайте напишем как будут относится к СЖ банды или другие педы ( актёры(люди) ). Вот опкод, который отвечает за это:

```
0746: set_acquaintance 1 of_actors_pedtype 8 to_actors_pedtype 0
```

Здесь:\
1 — это само отношение. Таблица возможных отношений приведена ниже\
8 — тип актёра, который относится к кому-то\
0 — тип актёра, к которому относятся

| Таблица отношений |                                                             |
| ----------------- | ----------------------------------------------------------- |
| Номер             | Отношение                                                   |
| 0                 | Превознесение ( не будут нападать )                         |
| 1                 | Уважение ( могут отвечать на атаки в их сторону )           |
| 2                 | Ранодушее ( будут нападать только тогда, когда атакуют их ) |
| 3                 | Неприязнь ( есть шанс напасть без причины )                 |
| 4                 | Ненависть ( будут нападать при первой возможности )         |

В нашем примере банда гров относится к СЖ с уважением. Если мы хотим, что бы СЖ-я ненавидела банда Гров, то 1 нужно поменять на 4.

Давайте сделаем так, что бы были постоянно перестрелки между бандами и копами, то есть что бы они ненавидели друг друга. То же самое касается и банд:

```
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 6
```

После этого, как только банды ( гров, вагос, баллас ) увидят копов, сразу же попытаются их убить. Что бы копы тоже ненавидели банды, допишем строки:

```
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 9
```

Таким образом мы сделали поставленную задачу. Теперь нам осталось только написать отношение банд к другим бандам, а так же отношение банд к СЖ:

```
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 0
0746: set_acquaintance 0 of_actors_pedtype 8 to_actors_pedtype 0
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 0
```

Вот мы и написали отношение банд к СЖ, к другим бандам и копам. Нам осталось только вставить результат в скрипт и проверить.

```
// WMYSTERIO, ru-script.3dn.ru
DEFINE OBJECTS 1
DEFINE OBJECT SANNY BUILDER 3.04 

DEFINE MISSIONS 0

DEFINE EXTERNAL_SCRIPTS 0

DEFINE UNKNOWN_EMPTY_SEGMENT 0

DEFINE UNKNOWN_THREADS_MEMORY 3072

//-------------MAIN---------------
thread 'MAIN'
set_wb_check_to 0
set_weather 0
select_interior 0
fade 0 0
0180: set_on_mission_flag_to $ONMISSION
00C0: set_current_time_hours_to 8 minutes_to 0
04E4: unknown_refresh_game_renderer_at 2491.1572 -1670.3434
Camera.SetAtPos(2491.1572, -1670.3434, 12.3359)
$PLAYER_CHAR = Player.Create(#NULL, 2491.1572, -1670.3434, 12.3359)
$PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
Actor.Angle($PLAYER_ACTOR) = 66.3548
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
Camera.SetBehindPlayer
Player.Build($PLAYER_CHAR)
Player.CanMove($PLAYER_CHAR) = True
fade 1 0
0879: enable_gang_wars 1 // наш новый код!
076C: set_zone 'GAN1' gang 1 density_to 40 
076C: set_zone 'GAN2' gang 1 density_to 80 
076C: set_zone 'IWD1' gang 0 density_to 40 
076C: set_zone 'IWD2' gang 0 density_to 80 
076C: set_zone 'IWD3A' gang 2 density_to 40 
076C: set_zone 'IWD3B' gang 2 density_to 80 
0237: set_gang 0 weapons_to 22 31 14 
0237: set_gang 1 weapons_to 30 28 17 
0237: set_gang 2 weapons_to 36 15 27 
// старт нового кода
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 0
0746: set_acquaintance 0 of_actors_pedtype 8 to_actors_pedtype 0
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 0
// конец нового кода
end_thread
```

С таким кодом в игре обязательно должны случатся массовые перестрелки, что повышает криминальность города. Так же можно сделать, что бы банды не приставали к СЖ, когда он возле них. Экспериментируйте с отношениями и типами актёров. Если есть вопросы по этой теме пишите комментарии или обращайтесь на [форум](https://github.com/wmysterio/scm-scripting-lessons/blob/main/forum/6-9-0-17/README.md).

P. S. Думаю бессмысленно указывать отношение СЖ к другим педам, так как управляете им вы! =)|2637|1|0|09129058`png`1314`788`400\`239\`\`||tipy\_peshekhodov\_i\_band|1498566085


# 00024. Модель. Создание актёра

Модель. Создание актёра|Итак, в этом уроке мы научимся создавать пешеходов, они же актёры. Также научимся загружать необходимые модели.|wmysterio|wmysterio||||Любой пешеход в игре является актёром. Начнём с того, что ознакомимся с опкодами, с помощью которых он будет создаваться.

В первую очередь нужно загрузить в память модель актёра. Начинающим скриптерам, да и опытным, очень помогает программа Ped Editor ( вот [урок](https://github.com/wmysterio/scm-scripting-lessons/blob/main/publ/gta_sa/dokumentacii_k_programmam/rukovodstvo_po_ispolzovaniju_programmy_pededitor/54-1-0-3/README.md) для тех, кто не читал ), в которой можно просмотреть модели всех пешеходов. Давайте найдём нужную модель. Запускаем программу и выберем в списке интересующую нас модель. Вот, например я выбрал такую:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/15152977.jpg)

Как видите я хочу создать актёра, модель которого: BMYPOL1, что бы загрузить такую модель, нужно воспользоваться опкодом:

```
Model.Load(#BMYPOL1)
```

Здесь:\
\#BMYPOL1 - выбранная нами модель

Обратите внимание на то, что перед именем модели всегда пишется знак "диез" или, как в народе говорят, решетки. Также есть возможность загрузки модели по её ID, как видите, в нашем случаи, ID этой модели - 66 ( выделено зелёным цветом ). Написанный нами опкод выше — всё равно, что: Model.Load(66). Если вы будете набирать модель, то вы обязательно можете узнать её ID ( см. картинку ниже ).

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/16242540.png)

Этот опкод перечисляет модели, которые нужно загрузить. Сама загрузка начитается опкодом:

```
038B: load_requested_models
```

Таким образом результат должен быть такой:

```
Model.Load(#BMYPOL1)
038B: load_requested_models
```

После этого нам нужно проверять на загрузку модели. Проверка загрузки делается опкодом:

```
Model.Available(#BMYPOL1)
```

Здесь:\
\#BMYPOL1 - выбранная нами модель× \*\*Примечание:\*\* после использования опкода 038B делать проверку не обязательно, но рекомендую использовать её для предотвращения вылетов на старых компах, которые могут не успеть загрузить модель.

Давайте рассмотрим полный пример загрузки модели:

```
:MODEL
wait 0
model.Load(#BMYPOL1)
038B: load_requested_models

:MODEL_1
wait 0
if
model.Available(#BMYPOL1)
jf @MODEL_1
```

Если нам необходимо загрузить несколько моделей, то можно использовать такой пример:

```
:MODEL
wait 0
model.Load(#BMYPOL1)
model.Load(#FAM1)
model.Load(#FAM2)
038B: load_requested_models

:MODEL_1
wait 0
if AND
model.Available(#BMYPOL1)
model.Available(#FAM1)
model.Available(#FAM2)
jf @MODEL_1
```

Достаточно часто пишут такие варианты:

<table><thead><tr><th>Вариант 1</th><th>Вариант 2</th></tr></thead><tbody><tr><td><pre><code>:MODEL
wait 0
model.Load(#BMYPOL1)
038B: load_requested_models
model.Load(#FAM1)
038B: load_requested_models
model.Load(#FAM2)
038B: load_requested_models

:MODEL\_1
wait 0
if AND
model.Available(#BMYPOL1)
model.Available(#FAM1)
model.Available(#FAM2)
jf @MODEL\_1 </code></pre></td><td><pre><code>:MODEL
wait 0
model.Load(#FAM1)
model.Load(#FAM1)
038B: load\_requested\_models

:MODEL\_1
wait 0
if AND
model.Available(#FAM1)
model.Available(#FAM1)
jf @MODEL\_1 </code></pre></td></tr></tbody></table>

1-й вариант ещё допустим, но он не рационален. 2-й вариант вовсе бредовый. Почему? Потому, что если мы загружаем одну модель, то она всегда будет хранится в памяти, и мы можем в любой момент использовать её. Вариант 2 дважды загружает одну и туже модель, а этого делать не нужно. Поэтому можете использовать мои примеры, что бы оптимизировать Ваш код.

Если есть загрузка, то есть и удаление ( очищение ). Что бы не грузить память, так же нужно удалять модель после использования. Делается это командой:

```
Model.Destroy(#BMYPOL1)
```

Здесь:\
\#BMYPOL1 - выбранная нами модель

Итак, с загрузкой моделей разобрались. Наша цель - создать актёра. Прежде чем приступать, определим координаты. Заходим в игру и ищем нужное место. Далее сворачиваем игру ( клавиша WINDOWS `), и в Sanny Builder нажмём знакомые нам комбинации клавиш <kbd>CTRL`+SHIFT`+<kbd>C` и CTRL`+<kbd>SHIFT`+E\`. Я получил координаты: 2506.8359 -1669.4536 12.3772, а также угол поворота: 88.2883. Создадим нашего первого педа ( актёра )! Воспользуемся такой командой:

```
$IVAN = actor.Create(4, #BMYPOL1, 2506.8359, -1669.4536, 12.3772)
```

Здесь:\
$IVAN — имя ( хендл ) переменной для нашего актёра, я назвал её человеческим именем, что бы Вам было понятнее\
4 — тип актёра ( см. [Типы пешеходов](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/tipy_peshekhodov/1-1-0-35/README.md) )\
\#BMYPOL1 — как вы уже догадались, модель актёра\
2506.8359, -1669.4536, 12.3772 — мои координаты

А так же зададим ему угол поворота:

```
actor.Angle($IVAN) = 88.2883
```

Здесь:\
$IVAN — имя ( хендл ) переменной для нашего актёра\
88.2883 — угол поворота нашего педа

Обычно эти опкоды пушить в месте:

```
$IVAN = actor.Create(4, #BMYPOL1, 2506.8359, -1669.4536, 12.3772)
actor.Angle($IVAN) = 88.2883
```

Совсем не правильным будет такой вариант:

```
actor.Angle($IVAN) = 88.2883
$IVAN = actor.Create(4, #BMYPOL1, 2506.8359, -1669.4536, 12.3772)
```

Так, как вначале мы не создавали ранее актёра с именем "$IVAN", то игра вылетит, так как она не знает кого поворачивать. Но если такой актёр существует, то никакой ошибки не будет.

Давайте напишем примитивный скрипт, что бы при нажатии кнопки BACKSPACE\`, в наших координатах появлялся актёр. Для этого создадим новый поток с именем "@Model", и добавим код. Должно получится такое:

```
// WMYSTERIO, ru-script.3dn.ru
DEFINE OBJECTS 1
DEFINE OBJECT SANNY BUILDER 3.04 

DEFINE MISSIONS 0

DEFINE EXTERNAL_SCRIPTS 0

DEFINE UNKNOWN_EMPTY_SEGMENT 0

DEFINE UNKNOWN_THREADS_MEMORY 3072

{$VERSION 3.1.0027}

//-------------MAIN---------------
thread 'MAIN'
set_wb_check_to 0
set_weather 0
select_interior 0
fade 0 0
0180: set_on_mission_flag_to $ONMISSION
00C0: set_current_time_hours_to 8 minutes_to 0
04E4: unknown_refresh_game_renderer_at 2491.1572 -1670.3434
Camera.SetAtPos(2491.1572, -1670.3434, 12.3359)
$PLAYER_CHAR = Player.Create(#NULL, 2491.1572, -1670.3434, 12.3359)
$PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
Actor.Angle($PLAYER_ACTOR) = 66.3548
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
Camera.SetBehindPlayer
Player.SetClothes($PLAYER_CHAR, "WORKTRCAMOGRN", "WORKTR", 2)
Player.SetClothes($PLAYER_CHAR, "SNEAKERBINCGANG", "SNEAKER", 3)
Player.SetClothes($PLAYER_CHAR, "TSHIRTERISORN", "TSHIRT", 0)
Player.Build($PLAYER_CHAR)
Player.CanMove($PLAYER_CHAR) = True
fade 1 0
0879: enable_gang_wars 1
076C: set_zone 'GAN1' gang 1 density_to 40 
076C: set_zone 'GAN2' gang 1 density_to 80 
076C: set_zone 'IWD1' gang 0 density_to 40 
076C: set_zone 'IWD2' gang 0 density_to 80 
076C: set_zone 'IWD3A' gang 2 density_to 40 
076C: set_zone 'IWD3B' gang 2 density_to 80 
0237: set_gang 0 weapons_to 22 31 14 
0237: set_gang 1 weapons_to 30 28 17 
0237: set_gang 2 weapons_to 36 15 27 
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 0
0746: set_acquaintance 0 of_actors_pedtype 8 to_actors_pedtype 0
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 0
0767: set_zone 'MARKST' popcycle_group_for_peds_and_cars_to 14
0767: set_zone 'UNITY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'LAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2A' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2B' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'BLUF1A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BLUF2' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3C' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN4' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'COM1A' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM1B' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PER1' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'CHC1A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC1B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC3' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'CHC1A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC1B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC3' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4B' popcycle_group_for_peds_to 9 
0767: set_zone 'CONF1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'CONF1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'THALL1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDOC1A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3C' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDT1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1C' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LDT5' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT6' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE3C' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'ELCO1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'ELCO2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELCO1' popcycle_group_for_peds_to 9 
0874: set_zone 'ELCO2' popcycle_group_for_peds_to 9 
0767: set_zone 'GAN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GAN2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'GAN1' popcycle_group_for_peds_to 1 
0874: set_zone 'GAN2' popcycle_group_for_peds_to 1 
0767: set_zone 'GLN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GLN2A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'IWD1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD4' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD5' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'IWD1' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD2' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3A' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3B' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD4' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD5' popcycle_group_for_peds_to 1 
0767: set_zone 'JEF1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3C' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LFL1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LFL1B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'LFL1A' popcycle_group_for_peds_to 9 
0874: set_zone 'LFL1B' popcycle_group_for_peds_to 9 
0767: set_zone 'LMEX1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LMEX1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ELS1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS1B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS4' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELS1A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS1B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS2' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS4' popcycle_group_for_peds_to 10 
0767: set_zone 'MAR1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'MAR2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MAR3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MKT1' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT2' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT3' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT4' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MUL1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL2A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL2B' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL3' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL4' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL6' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'PLS' popcycle_group_for_peds_and_cars_to 8
0767: set_zone 'RIH1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH2' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD1A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD5B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SMB1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'SMB2' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VIN2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VERO1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'VERO2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO4A' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VERO4B' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'CRANB' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CALT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'SUNMA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SUNNN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'BATTP' popcycle_group_for_peds_and_cars_to 2
0767: set_zone 'ESPN1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'BAYV' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'PARA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'JUNIHO' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JUNIHI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CIVI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CHINA' popcycle_group_for_peds_and_cars_to 9
0874: set_zone 'CHINA' popcycle_group_for_peds_to 6
0767: set_zone 'SFDWT1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT5' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT6' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'FINA' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'CITYS' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'WESTP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'THEA1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'GARC' popcycle_group_for_peds_and_cars_to 7
0767: set_zone 'HASH' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'OCEAF1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'OCEAF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'OCEAF3' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'DOH1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'DOH2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'CUNTC1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SFGLF1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF2' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF3' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF4' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'HILLP' popcycle_group_for_peds_and_cars_to 10
0767: set_zone 'SILLY1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY4' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR4' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR5' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'EASB1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'EASB2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'ESPE1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'LINDEN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YELLOW' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'BFC1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BFC2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'RIE' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'LDM' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'RSW1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSW2' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSE' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'LDS' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'SRY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JTS1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTS2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LVA1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'LVA3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'VAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LVBAG' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'GGC1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'GGC2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'BFLD1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BFLD2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'WWE' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'WWE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PINT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YBELL2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'YBELL1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'JTW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN5' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN6' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN8' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'HGP' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SPIN' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'BINT1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PRP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'REDE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'REDW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'REDW4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ROCE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'ROCE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'OVS' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CREE' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'STRIP1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP2' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STRIP3' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP4' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'PILL1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PILL2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'RING' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'ISLE' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STAR1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STAR2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'ROY' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CAM' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'LOT' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PIRA' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'VISA1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'VISA2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'DRAG' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PINK' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'HIGH' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CONST1' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'ANGPI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'SHACA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BACKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BEACO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FARM' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'PALO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT1' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MTCHI1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI2' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI3' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI4' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'HBARNS' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'DILLI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'PANOP' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUAC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MAKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FERN' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'NROCK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'HANKY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'LEAFY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'RED' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FLINTC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'WHET' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BIGE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELQUE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BARRA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'CARSO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PAYAS' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PROBE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELCA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTR' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ARCO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'VALLE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTI' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'MONINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'TOM' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ALDEA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BRUJA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBAD' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BONE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'HAUL' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'QUARY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'OCTAN' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'PALMS' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'DAM' popcycle_group_for_peds_and_cars_to 18
create_thread @SAVE 
create_thread @MODEL // Наш новый код! 
end_thread 

:SAVE
thread 'SAVE'
wait 0
if AND
$ONMISSION == 0
0AB0: key_pressed 115
then
03D8: show_save_screen 
wait 250
end
jump @SAVE

// начало нового кода
:MODEL
thread 'MODEL'
wait 0
if
0AB0: key_pressed 8
then
gosub @MODEL_1
$IVAN = actor.Create(4, #BMYPOL1, 2506.8359, -1669.4536, 12.3772)
actor.Angle($IVAN) = 88.2883 
model.Destroy(#BMYPOL1)
jump @MODEL_3
end
jump @MODEL

:MODEL_3
wait 0
end_thread

:MODEL_1
wait 0
model.Load(#BMYPOL1)
038B: load_requested_models 

:MODEL_2
wait 0
if
model.Available(#BMYPOL1)
jf @MODEL_2
return
// конец нового кода
```

Компилируем и начинаем **новую** игру. После нажатия нужной кнопки, я получил такое:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/03258234.png)

То есть свою задачу я выполнил - создал актёра. Но на этом скрипт и заканчиваться. Так же он одноразовый, то есть больше такой возможности не будет, так, как судя по скрипту, поток заканчивается после создания актёра. Рассмотрим наш код в графическом варианте:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/79193594.png)\
\
Здесь:\
Зелёные стрелки указывают на, что условие выполнилось\
Красные стрелки - прыжки когда условие не выполнилось ( или просто прыжки )\
Фиолетовые - прыжки с возвратом

В следующих уроках я расскажу о командах, которые можно применить к актёрам.|1220|1|0|15152977`jpg`640`376`400`235``\|16242540`png`516`304`400`235``\|03258234`png`640`400`400`250``|79193594`png`878`598`400\`272\`\`||model\_i\_sozdanie\_aktjora|1498575327


# 00028. Актёры и команды, свойственны им. Команды для игрока

Актёры и команды, свойственны им. Команды для игрока|В этом уроке мы рассмотрим команды, которые будут влиять на актёров и игрока.|wmysterio|wmysterio||||Естественно от одного созданного актёра пользы не будет, так как он будет стоять. Все команды можно разделить на 2 большие группы: условные ( опкоды, назначены для проверок ) и безусловные. Начнём с самых простых:

| Безусловные                                                                                                                                                                                                                 |                                                    |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- |
| Actor.Health($Actor) = 1000                                                                                                                                                                                                 |                                                    |
| устанавливает кол-во жизни у актёра                                                                                                                                                                                         |                                                    |
| Actor.Armour($Actor) = 150                                                                                                                                                                                                  |                                                    |
| устанавливает кол-во брони актёра                                                                                                                                                                                           |                                                    |
| Actor.Angle($Actor) = 250.24                                                                                                                                                                                                |                                                    |
| устанавливает угол поворота актёра                                                                                                                                                                                          |                                                    |
| actor.RemoveReferences($ACTOR)                                                                                                                                                                                              |                                                    |
| стирает все сведения о актёре. другими словами - актёр нам больше не нужен и игра уже будет сама решать что ему делать                                                                                                      |                                                    |
| actor.DestroyInstantly($Actor)                                                                                                                                                                                              |                                                    |
| уничтожает созданного ранее актёра                                                                                                                                                                                          |                                                    |
| actor.PutAt($Actor, 1234.0, -189.0, 36.0)                                                                                                                                                                                   |                                                    |
| перемещает актёра в заданные координаты                                                                                                                                                                                     |                                                    |
| 05D4: AS\_actor $Actor rotate\_angle 175.8                                                                                                                                                                                  |                                                    |
| актёр повернётся на заданный угол ( в отличии от Actor.Angle мы сможем увидеть как он будет поворачиваться )                                                                                                                |                                                    |
| 0672: AS\_actor $Actor attack\_car $Car                                                                                                                                                                                     |                                                    |
| актёр будет атаковать заданную машину                                                                                                                                                                                       |                                                    |
| 0850: AS\_actor $Actor follow\_actor $Actor2                                                                                                                                                                                |                                                    |
| актёр1 будет следовать за актёром2                                                                                                                                                                                          |                                                    |
| 04EB: AS\_actor $Actor crouch 1                                                                                                                                                                                             |                                                    |
| заставляет актёра присесть, если поставить 0, то заставляет актёра встать.                                                                                                                                                  |                                                    |
| 0332: set\_actor $Actor bleeding\_to 1                                                                                                                                                                                      |                                                    |
| заставляет актёра истекать кровью                                                                                                                                                                                           |                                                    |
| 03FE: set actor $Actor money 0                                                                                                                                                                                              |                                                    |
| устанавливает актёру кол-во денег                                                                                                                                                                                           |                                                    |
| 05CD: AS\_actor $Actor exit\_car $Car                                                                                                                                                                                       |                                                    |
| заставляет актёра выйти с заданной машины                                                                                                                                                                                   |                                                    |
| Actor.WeaponAccuracy($Actor) = 95                                                                                                                                                                                           |                                                    |
| устанавливает актёру точность стрельбы                                                                                                                                                                                      |                                                    |
| 05E2: actor $Actor1 kill\_actor $Actor2                                                                                                                                                                                     |                                                    |
| заставляет актёра1 убивать актёра2                                                                                                                                                                                          |                                                    |
| 0639: AS\_actor $Actor1 rotate\_to\_actor $Actor2                                                                                                                                                                           |                                                    |
| заставляет актёра1 повернуться лицом к актёру2                                                                                                                                                                              |                                                    |
| 0729: AS\_actor $Actor hold\_cellphone 1                                                                                                                                                                                    |                                                    |
| заставляет актёра взять телефон и приложить его к уху, если поставить 0, то актёр положит телефон обратно в карман ( учтите, что бы было видно телефон нужно загрузить модель #CELLPHONE, а потом использовать этот опкод ) |                                                    |
| 0321: kill\_actor $Actor                                                                                                                                                                                                    |                                                    |
| убить актёра                                                                                                                                                                                                                |                                                    |
| 05BC: AS\_actor $Actor jump 0                                                                                                                                                                                               |                                                    |
| заставляет пригнуть актёра ( 0 - стиль прыжка, так его и оставляйте, так как ничего особого не поменяется )                                                                                                                 |                                                    |
| actor.SetImmunities($Actor, 1, 1, 1, 1, 1)                                                                                                                                                                                  |                                                    |
| устанавливает актёру иммунитеты к ударам, взрывам и прочего.                                                                                                                                                                |                                                    |
| 07FE: set\_actor $Actor fighting\_style\_to 5 6                                                                                                                                                                             |                                                    |
| устанавливает актёру определённый стиль драки                                                                                                                                                                               |                                                    |
| 08C6: set\_actor $Actor stay\_on\_bike 1                                                                                                                                                                                    |                                                    |
| актёр не сможет упасть с байка, если поставить 0 - то сможет                                                                                                                                                                |                                                    |
| 06B0: AS\_actor $Actor sit\_down 5000 ms                                                                                                                                                                                    |                                                    |
| заставляет актёра сидеть 5 секунд ( 1000 ms = 1 сек. )                                                                                                                                                                      |                                                    |
| 05BA: AS\_actor $Actor chew\_gum 5000 ms                                                                                                                                                                                    |                                                    |
| заставляет актёра жевать жвачку 5 секунд ( 1000 ms = 1 сек. ), но иногда не срабатывает                                                                                                                                     |                                                    |
| 0245: set\_actor $Actor walk\_style\_to "FATMAN"                                                                                                                                                                            |                                                    |
| устанавливает актёру определённый стиль походки. Я нашел только эти стили:                                                                                                                                                  |                                                    |
| Стиль                                                                                                                                                                                                                       | Описание                                           |
| "FATMAN"                                                                                                                                                                                                                    | толстяк                                            |
| "GANG1"                                                                                                                                                                                                                     | гангстер 1                                         |
| "GANG2"                                                                                                                                                                                                                     | гангстер 2                                         |
| "MAN"                                                                                                                                                                                                                       | мужчина                                            |
| "WOMAN"                                                                                                                                                                                                                     | женщина                                            |
| "BLINDMAN"                                                                                                                                                                                                                  | слепой мужчина                                     |
| "SEXYWOMAN"                                                                                                                                                                                                                 | сексуальная женщина                                |
| "DRUNKMAN"                                                                                                                                                                                                                  | алкаш                                              |
| "PLAYER"                                                                                                                                                                                                                    | стиль игрока ( СЖ ), но я не тестировал этот стиль |
| 0446: set\_actor $Actor immune\_to\_headshots 0                                                                                                                                                                             |                                                    |
| устанавливает актёру иммунитет от хеадшотов ( выстрелов в голову ), если поставить 1 - то, как уже догадались, прострелить голову будет нельзя                                                                              |                                                    |

| Стиль       | Описание                                           |
| ----------- | -------------------------------------------------- |
| "FATMAN"    | толстяк                                            |
| "GANG1"     | гангстер 1                                         |
| "GANG2"     | гангстер 2                                         |
| "MAN"       | мужчина                                            |
| "WOMAN"     | женщина                                            |
| "BLINDMAN"  | слепой мужчина                                     |
| "SEXYWOMAN" | сексуальная женщина                                |
| "DRUNKMAN"  | алкаш                                              |
| "PLAYER"    | стиль игрока ( СЖ ), но я не тестировал этот стиль |

Вот список условных опкодов, то есть тех, которые должны использоваться в блоке "if"

| Условные                                                |
| ------------------------------------------------------- |
| 0965: actor $Actor swimming\_in\_water                  |
| проверка: находится актёр в воде?                       |
| 06EE: actor $Actor in\_group $Player\_Group             |
| проверка: находится актёр в группе $Player\_Group?      |
| actor.InCar($PLAYER\_ACTOR, $Car)                       |
| проверка: находится актёр в заданной машине?            |
| actor.Driving($PLAYER\_ACTOR)                           |
| проверка: сидит актёр за рулём(или в транспорте)?       |
| actor.DrivingPoliceVehicle($PLAYER\_ACTOR)              |
| проверка: сидит актёр за рулём полицейского транспорта? |
| actor.DrivingTaxiVehicle($PLAYER\_ACTOR)                |
| проверка: актёр сидит за рулём в такси?                 |
| 04A7: actor $PLAYER\_ACTOR driving\_boat                |
| проверка: актёр сидит за рулём(штурвалом) лодки?        |
| actor.DrivingVehicleType($ACTOR, #CAR\_MODEl)           |
| проверка: модель машины актёра равна #CAR\_MODEl?       |
| actor.Dead($PLAYER\_ACTOR)                              |
| проверка: актёр умер?                                   |
| actor.Stopped($PLAYER\_ACTOR)                           |
| проверка: актёр остановился(не бежит)?                  |
| 04C5: actor $PLAYER\_ACTOR photographed                 |
| проверка: актёр фотографирует?                          |
| 056D: actor $ACTOR defined                              |
| проверка: существует ли актёр?                          |

Эти опкоды можно использовать со всеми актёрами, в том числе СЖ. Однако есть опкоды, которые свойственны только игроку. Рассмотрим некоторые с них:

| Безусловные                                                                                                                                       |
| ------------------------------------------------------------------------------------------------------------------------------------------------- |
| 052C: set\_player $PLAYER\_CHAR drunk\_visuals 100                                                                                                |
| заставляет экран шататься, как будто игрок пьян (100 - сила шатания, не советую делать очень большие цифры, иначе шатание превратится в мерцание) |
| player.CanMove($PLAYER\_CHAR) = false                                                                                                             |
| вы не сможете ничего делать. Если поставить true, то сможете. Очень часто используется, особенно при видеороликах.                                |
| player.ClearWantedLevel($PLAYER\_CHAR)                                                                                                            |
| очищает уровень розыска                                                                                                                           |
| player.Money($PLAYER\_CHAR) += 1000                                                                                                               |
| прибавляет игроку 1000 денег                                                                                                                      |
| 0998: add respect 5                                                                                                                               |
| прибавляет игроку респект ( уважение )                                                                                                            |
| 0992: set\_player $PLAYER\_CHAR weapons\_scrollable 1                                                                                             |
| даёт игроку возможность менять оружие, которое у него в руках. Если поставить 0 то вы не сможете менять ( как бы замораживает его в руке )        |

| Условные                                                                                               |
| ------------------------------------------------------------------------------------------------------ |
| Player.Defined($PLAYER\_CHAR)                                                                          |
| проверка: игрок существует?                                                                            |
| player.PressingHorn($PLAYER\_CHAR)                                                                     |
| проверка: игрок сигналит? Что бы сработала эта проверка нужно находится в транспорте и нажать "Сигнал" |
| wasted\_or\_busted                                                                                     |
| проверка: игрок пойман или арестован? Использовать только в миссиях!!!                                 |
| Player.Controllable($PLAYER\_CHAR)                                                                     |
| проверка: игрок контролируем?                                                                          |
| 0457: player $PLAYER\_CHAR aiming\_at\_actor $Actor                                                    |
| проверка: игрок целится в актёра?                                                                      |
| Player.WantedLevel($PLAYER\_CHAR) > 0                                                                  |
| проверка: уровень розыска игрока больше нуля? Максимальный уровень розыска может быть 6 и не более.    |

Это только самые распространённые команды в скрипте. Есть очень большое количество опкодов и по мере изучения скриптинга в целом мы будем изучать новые и новые опкоды.

Стоит также расказать о разнице между "$PLAYER\_ACTOR" и "$PLAYER\_CHAR". Новички часто путают эти переменные и используют их не там, где нужно. Если в описании опкода есть слово "actor", то в тотальном большинстве случаев нужно использовать "$PLAYER\_ACTOR". Если в опкоде есть слово "player", то нужно использовать "$PLAYER\_CHAR".|2652|1|0||aktjory|1498735550


# 00056. Специальные актёры

Специальные актёры|В этом уроке мы рассмотрим специальных актёров.|wmysterio|wmysterio||||Доброго времени времени суток, уважаемые пользователи. Думаю, Вы уже не мало создали актёров в своих скриптах. Пришло время познакомится ещё и со специальными актёрами. Что значит "специальные"? Это те актёры, которых не встретишь на улицах. Например: Свита, Райдера и других "сюжетных" актёров. Загрузка спец.актёров немного другая, чем у обычных актёров. В спец.актёров есть свои имена ( см. [Специальные актёры](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/specialnyt_aktjory_v_gta_sa/1-1-0-25/README.md) ).

Для начала, нужно загрузить модель актёра опкодом:

```
023C: load_special_actor 'TENPEN' as 1
```

Здесь:\
'TENPEN' - имя модели актёра\
1 - указывается номер актёра

Дальше необходимо проверить на загруженность:

```
023D: special_actor 1 loaded
```

Здесь:\
1 - указанный ранее номер актёра

Обратите, внимание, что конкретной модели специальные актёры не имеют. Но нужно всё же как то их создать :) А создаются они как и обычные:

```
$TEMPEN = actor.Create(4, #SPECIAL011, 0.0, 0.0, 0.0)
```

Здесь:\
$TEMPEN - естественно указываем переменную, которая будет хранить актёра\
4 - тип актёра\
0.0, 0.0, 0.0 - координаты появления\
\#SPECIAL01 - вот это уже интереснее. Для специальных актёров существуют и специальные модели, которые подходят любым специальным актёрам. Всего их 10 штук.× \*\*Примечание:\*\* Номер актёра должен совпадать с окончанием возле #SPECIAL ( #SPECIAL <с 01 по 10> )

Так же необходимо выгрузить с памяти модель, после создания ( на актёра это не повлияет, действует как "model.destroy()":

```
0296: unload_special_actor 1
```

Теперь давайте напишем простой скрипт, что бы Темпени появлялся рядом с CJ:

```
{$CLEO}
0000:

:TEMP
thread 'TEMP'
wait 0
023C: load_special_actor 'TENPEN' as 1 // загружаем Темпени
038B: load_requested_models

:TEMP_1
wait 0
if
023D: special_actor 1 loaded // проверяем на загрузку
jf @TEMP_1
00A0: store_actor $PLAYER_ACTOR position_to 1@ 2@ 3@ // считываем координаты CЖ
2@ += 2.0 // смещаем позицию y на 2.0
$TEMPEN = actor.Create(4, #SPECIAL01, 1@, 2@, 3@) // создаём Темпени возле СЖ
actor.Angle($TEMPEN) = 0.0
0296: unload_special_actor 1 // выгружаем модель
0A93: end_custom_thread
```

Как видим, Темпени появился как миленький:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/20576223.png)

Все опкоды, связанные с актёрами, действуют и на специальных актёров. Теперь задание: при нажатии кнопки R `создаются два спец. актёра. Устройте поединок между ними ( чтобы били друг друга ).|1974|1|0|20576223`png`600`375`400`250\`\`||specialnye\_aktjory|1499526491


# 00060. События актёров

События актёров|В этом уроке мы рассмотрим события актёров.|wmysterio|wmysterio||||Каждый актёр выполняет какое то действие. Оно записывается в специальную переменную, в которой хранится событие, совершающее актёром в текущий момент. Событий не так уж много, но из них можно сделать неплохие скрипты. Список всех известных событий вы можете найти в нашей [базе данных - события](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/sobytija_aktjorov/1-1-0-45/README.md). А теперь рассмотрим опкоды для работы с событиями:

```
074F: actor 1@ ped_event == 10
```

Проверка: "Актёр выполняет событие 10?"\
Здесь:\
1@ - хендл актёра\
10 - ID события

```
080E: get_actor 1@ ped_event_to 0@
```

Опкод записывает в переменную текущее событие актёра\
Здесь:\
1@ - хендл актёра\
0@ - в эту переменную будет записан ID события, выполняющегося в данный момент

Используя эти опкоды, давайте напишем скрипт, который будет хранить количество убитых CJ-ем персов. Для этого создадим в папке Cleo ini-файл "kill.ini", содержание которого:

```
ini
[a]
kill=0
```

Здесь будет хранится количество убитых персов. Вот код самого скрипта:

```
{$CLEO}
0000:

while true 
 03F0: enable_text_draw 1
 0AF0: 0@ = get_int_from_ini_file "CLEO&#92;kill.ini" section "a" key "kill"
 045A: draw_text_1number 20.0 20.0 GXT 'GXTNAME' number 0@ // Kills: ~1~
 if
 0AD2: 1@ = player $PLAYER_CHAR targeted_actor //IF and SET
 then
 if
 074F: actor 1@ ped_event == 10
 then
 0@ += 1
 0AF1: write_int 0@ to_ini_file "CLEO&#92;kill.ini" section "a" key "kill"
 end
 end
wait 0
end
```

Так же на экране будет выведено количество жертв ![smile](http://s49.ucoz.net/sm/15/smile.gif) Правда минус в том, что нужно всегда целится в актёра, иначе не сработает условие. Вы можете использовать события актёров для написания скриптов, так что вперёд! ![wink](http://s49.ucoz.net/sm/15/wink.gif)|1388|1|0||sobytija\_aktjorov|1499600461


# 00084. Модели поведения актёров

Модели поведения актёров|Сегодня мы опять каснёмся темы актёров. На этот раз мы рассмотрим их модели поведения. Тоесть будем сами указывать как должен вести себя актёр в определённых ситуациях.|wmysterio|wmysterio||||Приветствую Вас, уважаемые пользователи нашего сайта RU-SCRIPT.3DN.RU! Для начала, рассмотрим опкоды, которые умеют создавать модели поведения:

```
060A: create_decision_maker_type 0 store_to $DM
06AE: create_group_decision_maker_type 0 store_to $GDM
```

Здесь:\
0 - тип поведения ( смотрите таблицу 1 )\
$DM и $GDM - переменные самых моделей поведения

Первый опкод задаёт поведения для актёра, второй - для целой группы ( банды ). Рассмотрим таблицу типов:

| Таблица 1     |                           |
| ------------- | ------------------------- |
| Тип поведения | Описание                  |
| 0             | Поведение актера в группе |
| 1             | Модель поведения копа     |
| 2             | Обычная модель            |
| 3             | Храброе поведение         |
| 4             | Трусливое поведение       |

После того, как модель объявлена, нужно присвоить её актёру или группе:

```
060B: set_actor 1@ decision_maker_to $DM 
06AD: set_group $PLAYER_GROUP group_decision_maker_to $GDM
```

Здесь:\
1@ - переменная актёра, который будет следовать заданной модели поведения\
$PLAYER\_GROUP - переменная группы, для которой будет присвоена модель поведения\
$DM и $GDM - переменные самых моделей поведения

Есть опкод, который проверяет: "Существует ли модель поведения?":

```
09F2: decision_maker $DM exists
```

Так же есть возможность сбросить стоковую реакцию актера на событие:

```
0708: reset_decision_maker $DM event 9
```

Здесь:\
$DM - переменная модели поведения 9 - событие, которые будет сбрасываться ( см. [События актёров](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/sobytija_aktjorov/1-1-0-45/README.md) ). Насколько я понял, актёр не будет выполнять ( или будет пытаться не выполнять ) событие. Тоесть, если сбросить событие поднятия рук когда в него целится, он не будет поднимать их. Это уже плюс к интеллекту противника

Ну и, естественно, если модель поведения больше нужна, то её следует выгрузить с памяти:

```
065C: remove_references_to_decision_maker $DM
```

Так же можно задать стиль походки нужного актёра:

```
0245: set_actor 1@ walk_style_to "FATMAN"
```

Здесь:\
1@ - сам актёр\
"FATMAN" - стиль походки ( смотрите таблицу в этом [уроке](https://github.com/wmysterio/scm-scripting-lessons/blob/main/publ/gta_sa/obucheniye_skriptinga/aktjory/34-1-0-29/README.md) )

Теперь к примерам. Давайте создадим актёра на Гроув используя модели поведения:

```
{$CLEO}
0000:
 
:DM
thread 'DM'
wait 0
060A: create_decision_maker_type 4 store_to 1@
0376: 0@ = create_random_actor_at 2486.2708 -1655.7012 12.3363
actor.Angle(0@) = 195.281
actor.Health(0@) = 90000
077A: set_actor 0@ acquaintance 2 to_actors_pedtype 0 // see ped.dat 
0446: set_actor 0@ immune_to_headshots 0 
0245: set_actor 0@ walk_style_to "GANG1"
0708: reset_decision_maker 1@ event 9
060B: set_actor 0@ decision_maker_to 1@ 
 
while not actor.Dead(0@)
wait 0
end
 
065C: remove_references_to_decision_maker 1@
0A93: end_custom_thread
```

Теперь посмотрите, как будет себя вести актёр:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/23347036.png)

А вот, что будет, если буквально поменять тип поведения на трусливое ( decision\_maker\_type "3" ) при этом же скрипте:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/09675361.png)

Как видите, результат противоположный. Можно сказать, что мы можем управлять даже характером актёров :) Какой вариант подойдёт вашим актёрам? :)|1581|1|0|09675361`png`500`300`400`240``\|23347036`png`500`300`400`240\`\`||modeli\_povedenija\_aktjorov|1499846220


# Объекты


# 00030. Объекты и команды, свойственны им

Объекты и команды, свойственны им|В этом уроке мы рассмотрим команды, применяемые к объектам.|wmysterio|wmysterio||||

| Безусловные                                                                                                                                                                 |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 071F: set\_object $Obj mass 10                                                                                                                                              |
| задаёт объекту массу                                                                                                                                                        |
| 0453: object $Obj set\_rotation 90.0 270.0 180.0                                                                                                                            |
| поворачивает объект на все возможные углы на всех осях. Вы можете экспериментировать с углами и посмотреть как опкод работает                                               |
| Object.PutAt($obj,1600.0,1200.0,16.0)                                                                                                                                       |
| перемещает объект в заданные координаты                                                                                                                                     |
| Object.RemoveReferences($Obj)                                                                                                                                               |
| удаляет все сведения об объекте                                                                                                                                             |
| 0566: object $Obj set\_interior 8                                                                                                                                           |
| устанавливает интерьер для объекта ( об интерьерах мы ещё поговорим в следующих уроках )                                                                                    |
| 08E9: set\_object $Obj liftable 1                                                                                                                                           |
| делает объект поднимаемым ( если поставить 0 - то его нельзя будет поднять )                                                                                                |
| Object.ToggleInMovingList($Obj) = True                                                                                                                                      |
| объект можно будет двигать( если поставить false - то он будет стоять на месте )                                                                                            |
| Object.SetImmunities($Obj,1,1,1,1,1)                                                                                                                                        |
| установить иммунитеты для объекта                                                                                                                                           |
| 035D: toggle\_object $Obj targetable 1                                                                                                                                      |
| даёт возможность сделать объект целью ( если поставить 0 - то забирает эту возможность )                                                                                    |
| Object.KeepInMemory($obj) = True                                                                                                                                            |
| сохранять данные об объекте в памяти. Используйте опкод если вы уверены, что объект может куда то пропасть. Если поставить false, то игра не будет хранить данные в памяти. |

| Условные                                      |
| --------------------------------------------- |
| 03CA: object $Obj exists                      |
| проверка: объект существует?                  |
| 0685: object $Obj attached                    |
| объект прицеплен к чему либо?                 |
| 023B: actor $Act colliding\_with\_object $Obj |
| проверка: актёр прикасается к объекту?        |
| 0737: actor $Act lifting\_object $Obj         |
| проверка: актёр поднимает объект?             |
| 0179: actor $Act picked\_up\_object $Obj      |
| проверка: актёр поднял объект?                |
| 0366: object $Obj blown\_up                   |
| проверка: объект взорвался?                   |
| 04E7: object $Obj in water                    |
| проверка: объект в воде?                      |

Как видите, на объекты опкодов не много, в отличии от актёров и транспорта, но их достаточно, что бы сделать даже целую миссию. Кстати о миссиях. Рассмотрев часто используемые опкоды можно сделать первую миссию и через несколько уроков мы это сделаем! :)|1040|1|0||obekty\_i\_komandy\_svojstvenny\_im|1498736009


# 00025. Создание объекта

Создание объекта|Этот урок посвящен созданию объектов.|wmysterio|wmysterio||||Объектом можно назвать ящик, стол, трамплин, здание и т.п. Чтобы создать объект, нужно сначала загрузить его модель ( этого можно и не делать, так как объект всё равно появится, правда на это нужно некоторое время ). В нашем примере мы сделаем трамплин у дома CJ. Как и в предыдущем уроке, зайдём в игру и выберем место для трамплина а также его угол поворота. Например: у меня получились такие координаты 2480.5842 -1721.8175 12.5488 и угол 180.0 градусов. Дальше рассмотрим команды для создания объектов. Таких команд я знаю две:

```
$TRAMPLIN = object.Create(#AD_JUMP, 2480.5842, -1721.8175, 12.5488)
$TRAMPLIN = object.Init(#AD_JUMP, 2480.5842, -1721.8175, 12.5488)
```

Здесь:\
$TRAMPLIN — имя нашего объекта\
\#AD\_JUMP — модель объекта ( см. [Объекты](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/obekty_v_gta_sa/1-1-0-18/README.md) ), в нашем случаи это трамплин\
2480.5842, -1721.8175, 12.5488 — координаты расположения объекта

Почему придумали два опкода для создания я не знаю, но разница в них есть. Разница в координате, отвечающая за ось Z ( высоту ). "Init" создаёт объект немного выше, чем мы задавали. Советую вам использовать "Сreate". После этого, обычно указывают угол поворота объекта. Рассмотрим эту команду:

```
object.Angle($TRAMPLIN) = 180.0
```

Здесь:\
$TRAMPLIN — имя нашего объекта\
180.0 — угол поворота объекта

С этим, думаю, никаких вопросов возникнуть не должно. Если мы планируем использовать объект всегда, то есть хотим, что бы объект не исчезал, то нам нужно написать опкод:

```
Object.RemoveFromMissionCleanupList($TRAMPLIN)
```

Этот опкодом мы указываем, что объект всегда будет на этом месте. Если перевести, то получится: "Удалить со списка очищаемых объектов в миссии", то есть сохранять его, когда игрок в не миссии.

× \*\*ВАЖНО:\*\* Эту комманду нужно использовать только когда выполняется миссия! Но об этом чуть позже.

Так же нам нужно, что бы объект нельзя было разрушить. Установим иммунитеты объекту:

```
object.SetImmunities($TRAMPLIN, 1, 1, 1, 1, 1)
```

Здесь:\
$TRAMPLIN — имя нашего объекта\
$TRAMPLIN — имя нашего объекта\
1, 1, 1, 1, 1 — иммунитеты ( устойчивость ). Каждый из этих параметром может быть либо нулём, либо единицей ( выключено или включено ). Вот параметры:

* защита от пуль ( если будут стрелять по объекту, то ему будет по-барабану );
* защита от огня;
* защита от взрывов;
* защита от оружия ближнего боя;
* защита от падения;

В нашем случаи объект защищен на максимум :) Есть ещё одна команда для объектов:

```
Object.Indestructibility($TRAMPLIN) = False
```

Если перевести слово "Indestructibility", то это значит "неразрушимость". Параметр "False" указывает будет ли он разрушаемым. В нашем случаи это ложь ( выключено ). Используя эти опкоды, давайте напишем код:

```
$TRAMPLIN = object.Create(#AD_JUMP, 2480.5842, -1721.8175, 12.5488)
object.Angle($TRAMPLIN) = 180.0
object.SetImmunities($TRAMPLIN, 1, 1, 1, 1, 1)
Object.Indestructibility($TRAMPLIN) = False
Object.RemoveFromMissionCleanupList($TRAMPLIN)
```

Обратите внимание, что команда RemoveFromMissionCleanupList написана в низу. Потому, что объект нужно выгружать всегда после всех проведённых над ним операциям. Теперь давайте добавим этот код в начало нашего скрипта:

```
// WMYSTERIO, ru-script.3dn.ru
DEFINE OBJECTS 1
DEFINE OBJECT SANNY BUILDER 3.04 

DEFINE MISSIONS 0

DEFINE EXTERNAL_SCRIPTS 0

DEFINE UNKNOWN_EMPTY_SEGMENT 0

DEFINE UNKNOWN_THREADS_MEMORY 3072

{$VERSION 3.1.0027}

//-------------MAIN---------------
thread 'MAIN'
set_wb_check_to 0
set_weather 0
select_interior 0
fade 0 0
0180: set_on_mission_flag_to $ONMISSION
00C0: set_current_time_hours_to 8 minutes_to 0
04E4: unknown_refresh_game_renderer_at 2491.1572 -1670.3434
Camera.SetAtPos(2491.1572, -1670.3434, 12.3359)
$PLAYER_CHAR = Player.Create(#NULL, 2491.1572, -1670.3434, 12.3359)
$PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
Actor.Angle($PLAYER_ACTOR) = 66.3548
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
Camera.SetBehindPlayer
Player.SetClothes($PLAYER_CHAR, "WORKTRCAMOGRN", "WORKTR", 2)
Player.SetClothes($PLAYER_CHAR, "SNEAKERBINCGANG", "SNEAKER", 3)
Player.SetClothes($PLAYER_CHAR, "TSHIRTERISORN", "TSHIRT", 0)
Player.Build($PLAYER_CHAR)
Player.CanMove($PLAYER_CHAR) = True
// начало нового кода
$TRAMPLIN = object.Create(#AD_JUMP, 2480.5842, -1721.8175, 12.5488)
object.Angle($TRAMPLIN) = 180.0
object.SetImmunities($TRAMPLIN, 1, 1, 1, 1, 1)
Object.Indestructibility($TRAMPLIN) = False
Object.RemoveFromMissionCleanupList($TRAMPLIN)
// конец нового кода
0879: enable_gang_wars 1
076C: set_zone 'GAN1' gang 1 density_to 40 
076C: set_zone 'GAN2' gang 1 density_to 80 
076C: set_zone 'IWD1' gang 0 density_to 40 
076C: set_zone 'IWD2' gang 0 density_to 80 
076C: set_zone 'IWD3A' gang 2 density_to 40 
076C: set_zone 'IWD3B' gang 2 density_to 80 
0237: set_gang 0 weapons_to 22 31 14 
0237: set_gang 1 weapons_to 30 28 17 
0237: set_gang 2 weapons_to 36 15 27 
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 0
0746: set_acquaintance 0 of_actors_pedtype 8 to_actors_pedtype 0
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 0
0767: set_zone 'MARKST' popcycle_group_for_peds_and_cars_to 14
0767: set_zone 'UNITY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'LAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2A' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2B' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'BLUF1A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BLUF2' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3C' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN4' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'COM1A' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM1B' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PER1' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'CHC1A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC1B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC3' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'CHC1A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC1B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC3' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4B' popcycle_group_for_peds_to 9 
0767: set_zone 'CONF1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'CONF1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'THALL1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDOC1A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3C' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDT1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1C' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LDT5' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT6' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE3C' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'ELCO1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'ELCO2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELCO1' popcycle_group_for_peds_to 9 
0874: set_zone 'ELCO2' popcycle_group_for_peds_to 9 
0767: set_zone 'GAN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GAN2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'GAN1' popcycle_group_for_peds_to 1 
0874: set_zone 'GAN2' popcycle_group_for_peds_to 1 
0767: set_zone 'GLN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GLN2A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'IWD1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD4' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD5' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'IWD1' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD2' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3A' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3B' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD4' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD5' popcycle_group_for_peds_to 1 
0767: set_zone 'JEF1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3C' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LFL1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LFL1B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'LFL1A' popcycle_group_for_peds_to 9 
0874: set_zone 'LFL1B' popcycle_group_for_peds_to 9 
0767: set_zone 'LMEX1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LMEX1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ELS1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS1B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS4' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELS1A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS1B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS2' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS4' popcycle_group_for_peds_to 10 
0767: set_zone 'MAR1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'MAR2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MAR3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MKT1' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT2' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT3' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT4' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MUL1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL2A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL2B' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL3' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL4' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL6' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'PLS' popcycle_group_for_peds_and_cars_to 8
0767: set_zone 'RIH1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH2' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD1A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD5B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SMB1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'SMB2' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VIN2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VERO1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'VERO2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO4A' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VERO4B' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'CRANB' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CALT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'SUNMA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SUNNN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'BATTP' popcycle_group_for_peds_and_cars_to 2
0767: set_zone 'ESPN1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'BAYV' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'PARA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'JUNIHO' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JUNIHI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CIVI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CHINA' popcycle_group_for_peds_and_cars_to 9
0874: set_zone 'CHINA' popcycle_group_for_peds_to 6
0767: set_zone 'SFDWT1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT5' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT6' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'FINA' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'CITYS' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'WESTP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'THEA1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'GARC' popcycle_group_for_peds_and_cars_to 7
0767: set_zone 'HASH' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'OCEAF1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'OCEAF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'OCEAF3' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'DOH1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'DOH2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'CUNTC1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SFGLF1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF2' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF3' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF4' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'HILLP' popcycle_group_for_peds_and_cars_to 10
0767: set_zone 'SILLY1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY4' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR4' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR5' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'EASB1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'EASB2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'ESPE1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'LINDEN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YELLOW' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'BFC1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BFC2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'RIE' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'LDM' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'RSW1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSW2' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSE' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'LDS' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'SRY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JTS1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTS2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LVA1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'LVA3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'VAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LVBAG' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'GGC1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'GGC2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'BFLD1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BFLD2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'WWE' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'WWE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PINT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YBELL2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'YBELL1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'JTW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN5' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN6' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN8' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'HGP' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SPIN' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'BINT1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PRP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'REDE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'REDW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'REDW4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ROCE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'ROCE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'OVS' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CREE' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'STRIP1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP2' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STRIP3' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP4' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'PILL1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PILL2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'RING' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'ISLE' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STAR1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STAR2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'ROY' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CAM' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'LOT' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PIRA' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'VISA1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'VISA2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'DRAG' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PINK' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'HIGH' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CONST1' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'ANGPI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'SHACA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BACKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BEACO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FARM' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'PALO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT1' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MTCHI1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI2' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI3' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI4' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'HBARNS' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'DILLI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'PANOP' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUAC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MAKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FERN' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'NROCK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'HANKY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'LEAFY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'RED' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FLINTC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'WHET' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BIGE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELQUE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BARRA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'CARSO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PAYAS' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PROBE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELCA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTR' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ARCO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'VALLE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTI' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'MONINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'TOM' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ALDEA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BRUJA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBAD' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BONE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'HAUL' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'QUARY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'OCTAN' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'PALMS' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'DAM' popcycle_group_for_peds_and_cars_to 18
fade 1 0
create_thread @SAVE 
create_thread @MODEL 
end_thread 

:SAVE
thread 'SAVE'
wait 0
if AND
$ONMISSION == 0
0AB0: key_pressed 115
then
03D8: show_save_screen 
wait 250
end
jump @SAVE

:MODEL
thread 'MODEL'
wait 0
if
0AB0: key_pressed 8
then
gosub @MODEL_1
$IVAN = actor.Create(4, #BMYPOL1, 2506.8359, -1669.4536, 12.3772)
actor.Angle($IVAN) = 88.2883 
model.Destroy(#BMYPOL1)
jump @MODEL_3
end
jump @MODEL

:MODEL_3
wait 0
end_thread

:MODEL_1
wait 0
model.Load(#BMYPOL1)
038B: load_requested_models 

:MODEL_2
wait 0
if
model.Available(#BMYPOL1)
jf @MODEL_2
return
```

После этого скомпилируем код, и начнём "новую игру". В результате мы получим что то, вроде этого:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/01058076.jpg)

Трамплин готов! Он всегда будет в этом месте! Наша задача выполнена!!! Вы можете экспериментировать с моделями, координатами. Без этого никак :)

Есть так же и другие объекты, которые не указаны в базе данных, но об этом я вам расскажу в следующих уроках.|1017|1|0|01058076`jpg`640`400`400\`250\`\`||sozdanie\_obekta|1498576590


# 000142. Метание объектов

Метание объектов|Всем привет! В этом уроке я хотел бы поделится новой информацией для меня - метание объектов.|wmysterio|wmysterio||||Что бы бросить объект в нужную сторону, достаточно воспользоваться опкодом:

```
0381: throw_object 0@ velocity_in_direction 10.0 0.0 4.0
```

Раньше я думал, что последние параметры это координаты куда нужно бросать объект, но, как оказалось, это далеко не так. Рассмотрим сами параметры:

Здесь:\
0@ - хэндл объекта, которого нужно бросать\
10.0 - сила "удала" по объекту, будет двигаться по оси X, объект отлетит на 10.0 метров\
0.0 - аналогично, только для оси Y.\
4.0 - аналогично, только для оси Z. Как только объект достигнет высоты в 4.0, он начнёт падать на землю

При применении этого опкода объект, как правило, ничего не делает: просто стоит на месте. Чтобы объект мог метаться нужно внести его в список движений:

```
0392: make_object 0@ moveable 1
```

Теперь объект можно метать. Давайте напишем скрипт "Шарик", в котором можно метать бильярдный шар:

```
{$CLEO}
thread 'SCHARIK'
04C4: store_coords_to 1@ 2@ 3@ from_actor $PLAYER_ACTOR with_offset 0.0 5.0 0.0
model.Load(3002)
038B: load_requested_models
object.Create(0@, 3002, 1@, 2@, 3@)
Object.SetImmunities(0@, 1, 1, 1, 1, 1)
marker.CreateAboveObject(1@, 0@)
0392: make_object 0@ moveable 1

while true
 if
 0AB0: 32 // space
 then
 0381: throw_object 0@ velocity_in_direction -10.0 0.0 4.0
 end
wait 0
end

0A93: end_custom_thread
```

При нажатии Пробел\` шарик будет отскакивать от земли на нужную дистанцию:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/79905200.png)\
\
× \*\*ВАЖНО:\*\* Не все объекты могут вносится в список движений. Многое количество просто падают под текстуру земли и парят вниз× \*\*Интересно:\*\* Если задать объекту массу опкодом 0906 игровые субъекты будут получать повреждения. Например при установки на 500000.0 за несколько подходов убивает CJ при столкновениях

Другой опкод, практически идентичный, выглядит так:

```
05A7: set_object 0@ velocity_in_direction_X -10.0 direction_Y 0.0 direction_Z 4.0
```

Единственное отличие от "0381": мы указываем ускорение объекта, а не силу. Из этого выходит, что объект будет "бросаться" чуть быстрее. Как многим известно, при изменении чисел при умножении итог не изменится, но похоже GTA программисты решили потролить математиков и сделали, что "СИЛА*УСКОРЕНИЕ" не равно "УСКОРЕНИЕ*СИЛА" ( или описание не соответвует действительности ). К примеру:

```
0381: throw_object 0@ velocity_in_direction -5.0 0.0 4.0
05A7: set_object 0@ velocity_in_direction_X -5.0 direction_Y 0.0 direction_Z 4.0
```

и

```
05A7: set_object 0@ velocity_in_direction_X -5.0 direction_Y 0.0 direction_Z 4.0
0381: throw_object 0@ velocity_in_direction -5.0 0.0 4.0
```

дают разные результаты. Первый вариант идеально подходит под формулу и это визуально заметно. Второй же существенно отличается: действует как опкод "0381", но метание происходит более плавно. На скрине выше можно увидеть что-то похожее на искры. Пример убирает этот недостаток.

Также есть возможность получить текущее ускорение объекта опкодом:

```
059F: get_object 0@ velocity_in_direction 1@ 2@ 3@
```

В переменные 1@ 2@ 3@ запишутся текущие ускорения для объекта 0@ по всем 3-м осям.

× \*\*ВАЖНО:\*\* Метание происходит по глобальным координатам, что существенно усложняет вычисление нужных чисел для правильного броска

По такому принципу был написан "Пул" из оригинального мейна, но там очень сложный алгоритм, чтобы его объяснить подробнее. Надеюсь эта информация немного дала вам понять как метать объекты. С Вами был "wmysterio".|1803|1|0|79905200`png`600`337`400\`224\`\`||metanie\_obektov|1504593660


# 00027. Пикапы

Пикапы|В этом уроке Вы научитесь создавать пикапы и узнаете, что это такое.|wmysterio|wmysterio||||Думаю, когда вы прочитали название урока, то в вашей голове представилась машина, типа этой:

![](https://github.com/wmysterio/scm-scripting-lessons/blob/main/_pu/0/21948005.jpg)

Однако в ГТА пикап — это совсем другое и к транспорту он не имеет никакого отношения. Итак, что же такое пикап ( **pickup** )? Пикап — это вещь, которую можно подобрать. Например: оружие, которое разбросано по карте, броня, сердечко ( которое восстанавливает жизнь ) и даже деньги, которые падают с убитых прохожих тоже считаются пикапами. В некоторых случаях даже дерево ( или другой объект ) может быть пикапом. После того, как СЖ будет возле него он пропадёт и оказывает на него некие действия.

Есть много опкодов, которые предназначены для создания пикапов. Давайте рассмотрим все! :) Итак, первым мы можем создавать пикапи оружия дальнего боя, то есть оружие, с которого можно стрелять:

```
032B: $PICKUP_0002 = create_weapon_pickup #MINIGUN group 15 ammo 60 at 2493.0 -1685.8561 13.5107
```

Здесь:\
$PICKUP\_0002 — имя переменной, где будет храниться наше пикап\
\#MINIGUN — модель оружия ( модель можно не загружать )\
15 — группа ( тип ) пикапа\
60 — количество патронов в оружии\
2493.0 -1685.8561 13.5107 — координаты нашего пикапа

Рассмотрим таблицу групп ( типов ) пикапов:

| Таблица 1 |                                                                                                      |
| --------- | ---------------------------------------------------------------------------------------------------- |
| Тип       | Описание                                                                                             |
| 1         | за деньги, регенерируется ( восстанавливается ) почти сразу. Не знаю почему, но его невозможно взять |
| 2         | бесплатно, регенерация за 30 минут игрового времени, надо отойти недалеко                            |
| 3         | бесплатно, одноразовый                                                                               |
| 9-11      | считается как бомба ( её невозможно взять ). Иногда происходит взрыв в точке, где находится пикап    |
| 15        | эти регенерируется за 6 часов игрового времени или за 6 минут по-нормальному                         |

Итак, мы узнали как создавать пикап оружия дальнего боя. Рассмотрим пикапы для оружие ближнего боя, а так же для создания прочих важных элементов игры:

```
0213: $PICKUP_0001 = create_pickup #BODYARMOUR type 15 at 2491.0 -1685.8561 13.5107
```

Здесь:\
$PICKUP\_0001 — имя переменной для нашего пикапа\
\#BODYARMOUR — модель пикапа ( см. Таблица 2 )\
15 — группа ( тип ) пикапа ( см. Таблица 1 )\
2491.0 -1685.8561 13.5107 — координаты нашего пикапа

| Таблица 2                                                                                                         |                                                         |
| ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| Модель                                                                                                            | Описание                                                |
| #HEALTH                                                                                                           | создаёт сердце. как оно работает думаю вы знаете        |
| #BODYARMOUR                                                                                                       | создает броню. Как оно работает, тоже, думаю, вы знаете |
| #GUN\_PARA                                                                                                        | создаёт парашют                                         |
| #JETPACK                                                                                                          | создаёт ДжетПак                                         |
| #INFO                                                                                                             | значок "Инфо" ( желтая букава \*\*i\*\* )               |
| #PICKUPSAVE                                                                                                       | значок дискетки ( просто значок! )                      |
| #CLOTHESP                                                                                                         | значок одежды ( просто значок! )                        |
| #KEYCARD                                                                                                          | какая то электронная карточка                           |
| Можно также создавать другие пикапы, подменой модели. Например можно поставить 700, тогда пикап создаст дерево :) |                                                         |

Когда вы убиваете прохожего, возле него обычно появляются деньги. Давайте создадим такие-же деньги, но скриптом и без убийств. Делается это опкодом:

```
02E1: $PICKUP_0003 = create_cash_pickup 500 at 2495.0 -1685.8561 13.5107 permanence_flag 1
```

Здесь:\
$PICKUP\_0003 — имя перпеменной нашего пикапа\
500 — сумма денег ( в нашем случаи когда мы возьмем пикап нам прибавится 500$ )\
1 — флаг указывает на его постоянство, то есть пока деньги не забрал игрок они будут валятся в точке :)\
2495.0 -1685.8561 13.5107 — координаты нашего пикапа

Существуют так же и специальные пикапы. В следующих уроках мы ещё вернёмся к ним, а пока рассмотрим один из них. Пикап связан с деньгами. Думаю вы видели в ГТА крутящийся желтый доллар, который давал деньги, и чем больше времени прошло, тем больше денег можно получить. Создается такой пикап командой:

```
04A6: $PICKUP_0004 = create_asset_money_pickup_at 2497.0 -1685.8561 13.5107 money 10000 10000
```

Что значат большинство параметров думаю вы знаете. Нас интересуют последние два. Это указывается минимальная и максимальная сумма, которая будет хранить деньги.

× \*\*ВАЖНО:\*\* Оба этих параметра всегда должны быть одинаковы! Иначе привычная работа этого пикапа будет нарушена!

Итак с пикапами я вас ознакомил. Давайте добавим в наш скрипт пикапы, которые будут возле дома СЖ:

```
// WMYSTERIO, ru-script.3dn.ru
DEFINE OBJECTS 1
DEFINE OBJECT SANNY BUILDER 3.04 

DEFINE MISSIONS 0

DEFINE EXTERNAL_SCRIPTS 0

DEFINE UNKNOWN_EMPTY_SEGMENT 0

DEFINE UNKNOWN_THREADS_MEMORY 3072

{$VERSION 3.1.0027}

//-------------MAIN---------------
thread 'MAIN'
set_wb_check_to 0
set_weather 0
select_interior 0
fade 0 0
0180: set_on_mission_flag_to $ONMISSION
00C0: set_current_time_hours_to 8 minutes_to 0
04E4: unknown_refresh_game_renderer_at 2491.1572 -1670.3434
Camera.SetAtPos(2491.1572, -1670.3434, 12.3359)
$PLAYER_CHAR = Player.Create(#NULL, 2491.1572, -1670.3434, 12.3359)
$PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
Actor.Angle($PLAYER_ACTOR) = 66.3548
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
Camera.SetBehindPlayer
Player.SetClothes($PLAYER_CHAR, "WORKTRCAMOGRN", "WORKTR", 2)
Player.SetClothes($PLAYER_CHAR, "SNEAKERBINCGANG", "SNEAKER", 3)
Player.SetClothes($PLAYER_CHAR, "TSHIRTERISORN", "TSHIRT", 0)
Player.Build($PLAYER_CHAR)
Player.CanMove($PLAYER_CHAR) = True
$TRAMPLIN = object.Create(#AD_JUMP, 2480.5842, -1721.8175, 12.5488)
object.Angle($TRAMPLIN) = 180.0
object.SetImmunities($TRAMPLIN, 1, 1, 1, 1, 1)
Object.Indestructibility($TRAMPLIN) = False
Object.RemoveFromMissionCleanupList($TRAMPLIN)
0879: enable_gang_wars 1
076C: set_zone 'GAN1' gang 1 density_to 40 
076C: set_zone 'GAN2' gang 1 density_to 80 
076C: set_zone 'IWD1' gang 0 density_to 40 
076C: set_zone 'IWD2' gang 0 density_to 80 
076C: set_zone 'IWD3A' gang 2 density_to 40 
076C: set_zone 'IWD3B' gang 2 density_to 80 
0237: set_gang 0 weapons_to 22 31 14 
0237: set_gang 1 weapons_to 30 28 17 
0237: set_gang 2 weapons_to 36 15 27 
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 0
0746: set_acquaintance 0 of_actors_pedtype 8 to_actors_pedtype 0
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 0
0767: set_zone 'MARKST' popcycle_group_for_peds_and_cars_to 14
0767: set_zone 'UNITY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'LAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2A' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2B' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'BLUF1A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BLUF2' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3C' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN4' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'COM1A' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM1B' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PER1' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'CHC1A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC1B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC3' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'CHC1A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC1B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC3' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4B' popcycle_group_for_peds_to 9 
0767: set_zone 'CONF1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'CONF1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'THALL1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDOC1A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3C' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDT1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1C' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LDT5' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT6' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE3C' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'ELCO1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'ELCO2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELCO1' popcycle_group_for_peds_to 9 
0874: set_zone 'ELCO2' popcycle_group_for_peds_to 9 
0767: set_zone 'GAN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GAN2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'GAN1' popcycle_group_for_peds_to 1 
0874: set_zone 'GAN2' popcycle_group_for_peds_to 1 
0767: set_zone 'GLN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GLN2A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'IWD1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD4' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD5' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'IWD1' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD2' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3A' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3B' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD4' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD5' popcycle_group_for_peds_to 1 
0767: set_zone 'JEF1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3C' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LFL1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LFL1B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'LFL1A' popcycle_group_for_peds_to 9 
0874: set_zone 'LFL1B' popcycle_group_for_peds_to 9 
0767: set_zone 'LMEX1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LMEX1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ELS1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS1B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS4' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELS1A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS1B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS2' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS4' popcycle_group_for_peds_to 10 
0767: set_zone 'MAR1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'MAR2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MAR3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MKT1' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT2' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT3' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT4' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MUL1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL2A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL2B' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL3' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL4' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL6' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'PLS' popcycle_group_for_peds_and_cars_to 8
0767: set_zone 'RIH1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH2' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD1A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD5B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SMB1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'SMB2' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VIN2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VERO1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'VERO2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO4A' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VERO4B' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'CRANB' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CALT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'SUNMA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SUNNN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'BATTP' popcycle_group_for_peds_and_cars_to 2
0767: set_zone 'ESPN1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'BAYV' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'PARA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'JUNIHO' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JUNIHI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CIVI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CHINA' popcycle_group_for_peds_and_cars_to 9
0874: set_zone 'CHINA' popcycle_group_for_peds_to 6
0767: set_zone 'SFDWT1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT5' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT6' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'FINA' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'CITYS' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'WESTP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'THEA1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'GARC' popcycle_group_for_peds_and_cars_to 7
0767: set_zone 'HASH' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'OCEAF1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'OCEAF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'OCEAF3' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'DOH1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'DOH2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'CUNTC1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SFGLF1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF2' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF3' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF4' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'HILLP' popcycle_group_for_peds_and_cars_to 10
0767: set_zone 'SILLY1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY4' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR4' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR5' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'EASB1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'EASB2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'ESPE1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'LINDEN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YELLOW' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'BFC1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BFC2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'RIE' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'LDM' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'RSW1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSW2' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSE' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'LDS' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'SRY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JTS1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTS2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LVA1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'LVA3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'VAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LVBAG' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'GGC1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'GGC2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'BFLD1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BFLD2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'WWE' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'WWE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PINT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YBELL2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'YBELL1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'JTW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN5' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN6' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN8' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'HGP' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SPIN' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'BINT1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PRP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'REDE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'REDW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'REDW4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ROCE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'ROCE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'OVS' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CREE' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'STRIP1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP2' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STRIP3' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP4' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'PILL1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PILL2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'RING' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'ISLE' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STAR1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STAR2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'ROY' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CAM' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'LOT' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PIRA' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'VISA1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'VISA2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'DRAG' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PINK' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'HIGH' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CONST1' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'ANGPI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'SHACA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BACKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BEACO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FARM' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'PALO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT1' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MTCHI1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI2' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI3' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI4' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'HBARNS' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'DILLI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'PANOP' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUAC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MAKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FERN' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'NROCK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'HANKY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'LEAFY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'RED' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FLINTC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'WHET' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BIGE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELQUE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BARRA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'CARSO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PAYAS' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PROBE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELCA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTR' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ARCO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'VALLE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTI' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'MONINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'TOM' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ALDEA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BRUJA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBAD' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BONE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'HAUL' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'QUARY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'OCTAN' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'PALMS' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'DAM' popcycle_group_for_peds_and_cars_to 18
014B: $MY_CAR = init_parked_car_generator #BULLET color -1 -1 0 alarm 0 door_lock 0 1 10000 at 2474.2131 -1690.8783 12.1239 angle 180.0
014C: set_parked_car_generator $MY_CAR cars_to_generate_to 101
// начало нашего нового кода
0213: $PICKUP_0001 = create_pickup #BODYARMOUR type 1 at 2491.0 -1685.8561 13.5107
032B: $PICKUP_0002 = create_weapon_pickup #MINIGUN group 15 ammo 60 at 2493.0 -1685.8561 13.5107 
02E1: $PICKUP_0003 = create_cash_pickup 500 at 2495.0 -1685.8561 13.5107 permanence_flag 1
04A6: $PICKUP_0004 = create_asset_money_pickup_at 2497.0 -1685.8561 13.5107 money 10000 10000
// конец нашего нового кода
fade 1 0
create_thread @SAVE 
create_thread @MODEL 
end_thread 

:SAVE
thread 'SAVE'
wait 0
if AND
$ONMISSION == 0
0AB0: key_pressed 115
then
03D8: show_save_screen 
wait 250
end
jump @SAVE

:MODEL
thread 'MODEL'
wait 0
if
0AB0: key_pressed 8
then
gosub @MODEL_1
$CAR_001 = car.Create(#INFERNUS, 2485.2769, -1652.943, 11.8878)
car.Angle($CAR_001) = 90.0
model.Destroy(#INFERNUS)
jump @MODEL_3
end
jump @MODEL

:MODEL_3
wait 0
end_thread

:MODEL_1
wait 0
model.Load(#INFERNUS)
038B: load_requested_models 

:MODEL_2
wait 0
if
model.Available(#INFERNUS)
jf @MODEL_2
return
```

В результате у меня вышло такое:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/53712079.png)

Попробуйте создать свои пикапы, меняйте модели и координаты.|2703|1|0|53712079`png`640`400`400`250``\|21948005`jpg`224`128

```
`\||pikapy|1498587658
```


# 00031. Маркеры и сферы

Маркеры и сферы|В этом уроке мы поговорим о маркерах и сферах.|wmysterio|wmysterio||||В каждой миссии оригинальной GTA SA не обошлось без маркеров. Думаю во время миссий вы видели такие стрелки над персонажами, которых нужно убить ( следовать за ними ). Эти стрелки называются маркерами. Каждый маркер имеет своё имя и обладает некоторыми свойствами, таких, как цвет размер или тип. В этом уроке мы научимся создавать такие маркеры а так же узнаем о их свойствах.

Давайте создадим такой маркер над созданным актёром. Допустим, мы уже создали актёра и назвали его $ACTOR. Теперь нам нужно "пометить" его. Для этого используем опкод:

<table><thead><tr><th>Через опкод</th><th>Упрощённо через класс</th></tr></thead><tbody><tr><td><p>```</p><p>0187: $MARKER = create_marker_above_actor $ACTOR</p><pre><code>&#x3C;/td>&#x3C;td>
</code></pre><p>marker.CreateAboveActor($MARKER, $ACTOR)</p><pre><code>&#x3C;/td>&#x3C;/tr>
&#x3C;/tbody>&#x3C;/table>

Как видите есть 2 варианта. Это одно и тоже, но, думаю, намного удобнее будет использование 2-го варианта, так, как нам не нужно искать опкод в поисковике, а это экономит время. С объектом используем:

</code></pre><p>0188: $MARKER = create\_marker\_above\_object $OBJ</p><pre><code>

С транспортом ( любым ) пользуемся:

</code></pre><p>0186: $MARKER = create\_marker\_above\_car $CAR</p><pre><code>

Так же можно поставить маркер на пикап ( Pickup ). Делается это опкодом:

</code></pre><p>03DC: $MARKER = create\_marker\_above\_pickup $PIC</p><pre><code>

\<div class="panel panel-default">
\<div class="panel-body">
Здесь:\<br>
$MARKER - указываем имя переменной для маркера\<br>
$ACTOR - имя переменной для актёра, на котором должен быть маркер\<br>
$OBJ - имя переменной для объекта\<br>
$CAR - имя переменной для машины\<br>
$PIC - имя переменной для пикапа
\</div>
\</div>

Что бы отключить маркер, используйте опкод:

\<table class="table table-bordered">\<tbody>
\<tr>\<th>Через опкод\</th>\<th>Упрощённо через класс\</th>\</tr>
\<tr>\<td> </code></pre><p>0164: disable\_marker $MARKER</p><pre><code>\</td>\<td> </code></pre><p>marker.Disable($MARKER)</p><pre><code>\</td>\</tr>
\</tbody>\</table>

Опкод отключает ( уничтожает ) абсолютно любой маркер, если имя такого было найдено. Если маркер не существует, то опкод игнорируется ( пропускается ). То есть нет требования к тому, чтобы маркер был создан ранее. Так же есть проверка: "маркер включен?":

</code></pre><p>075C: marker $MARKER enabled</p><pre><code>

Проверка действует на все типы маркеров. Думаю, что при окончании какой то миссии можно его использовать, что бы после "Миссия провалена ( выполнена )" не оставалось маркеров.

Рассмотрим свойства таких маркеров:

\<table class="table table-bordered">\<tbody>
\<tr>\<th>Опкод\</th>\<th>Описание\</th>\</tr>
\<tr>\<td> </code></pre><p>0165: set\_marker $MARKER color\_to 1</p><pre><code>\</td>\<td>Устанавливает маркеру цвет ( см. ниже "Таблица1" ).\</td>\</tr>
\<tr>\<td> </code></pre><p>0168: set\_marker $MARKER size 2</p><pre><code>\</td>\<td>Устанавливает размер маркера ( размер меняется только на радаре ). По-умолчанию установлено 4\</td>\</tr>
\<tr>\<td> </code></pre><p>07E0: set\_marker $MARKER type\_to 1</p><pre><code>\</td>\<td>Устанавливает тип маркера ( есть 2 типа маркеров: если поставить 1 - дружественная цель, если 0 - вражеская цель )\</td>\</tr>
\</tbody>\</table>

\<table class="table table-bordered">\<tbody>
\<tr>\<td colspan="2" class="text-center">Таблица 1\</td>\</tr>
\<tr>\<th>Номер\</th>\<th>Цвет\</th>\</tr>
\<tr>\<td>4, 8\</td>\<td>желтый\</td>\</tr>
\<tr>\<td>0, 5, 7\</td>\<td>красный\</td>\</tr>
\<tr>\<td>1\</td>\<td>зелёный\</td>\</tr>
\<tr>\<td>2, 6\</td>\<td>белый\</td>\</tr>
\<tr>\<td>9 и выше\</td>\<td>чёрный\</td>\</tr>
\</tbody>\</table>

Есть ещё один тип маркеров. Думаю вы видели такой маркер перед входом в какой то интерьер. Создаётся такой маркер другой командой:

</code></pre><p>0A40: $MARKER = create\_entrance\_marker\_at 1685.7 -2238.9 14.0 color 14</p><pre><code>

Для отключения такого маркера нужно применять опкод:

</code></pre><p>0A41: destroy\_entrance\_marker $MARKER</p><pre><code>

\<div class="panel panel-default">
\<div class="panel-body">
Здесь:\<br >
$MARKER - указываем имя переменной для маркера\<br >
1685.7 -2238.9 14.0 - указываем координаты, где должен быть маркер ( такой маркер называют ещё "входным маркером" ( от слова "вход" ) )\<br >
14 - думаю несложно дагадаться, что параметр указывает цвет входного маркера ( см. ниже "Таблица 1" ).
\</div>
\</div>

\<div class="alert alert-warning alert-dismissible" role="alert">
\<button type="button" class="close" data-dismiss="alert" aria-label="Close">\<span aria-hidden="true">\&times;\</span>\</button>
**Примечание:** Если в игре уже существует большое количество входных маркеров, то цвет новых чаще всего будет белым.
\</div>

Рассмотрим ещё один тип маркеров - чекпоинты ( контрольные точки ). Такой маркер используется когда сказано СЖ ехать в какую то точку и на радаре показывается куда ( появляется желтый квадратик ). Этот квадратик называется чекпоинтом, но я его отношу к маркерам, так как удаляется он как обычный маркер ( опкодом 0164 ). Создать такой квадратик можно опкодом:

</code></pre><p>018A: $MARKER = create\_checkpoint\_at 147.0 16.0 75.5</p><pre><code>

\<div class="panel panel-default">
\<div class="panel-body">
Здесь:\<br>
$MARKER - указываем имя переменной для маркера\<br>
147.0 16.0 75.5 - заданные координаты координаты
\</div>
\</div>

Также можно установить тип чекпоинта:

</code></pre><p>08FB: set\_checkpoint $MARKER type\_to 2</p><pre><code>

Ваше задание: проверить типы, узнать что будет если поставить другие числа.

Рассмотрим опкоды для создания сфер. Сферы - это красные цилиндры(можно увидеть возле стартера миссии, когда входишь в него начинается миссия или в самой миссии). Сферы, конечно, не относятся к маркерам, но они очень часто применяются вместе. Создать такую сферу можно многими способами. Вот первый пример:

</code></pre><p>03BC: $SPHERE = create\_sphere\_at 2596.589 2758.158 22.862 radius 1.0</p><pre><code>

Чтобы уничтожить сферу используйте команду:

</code></pre><p>03BD: destroy\_sphere $SPHERE</p><pre><code>

\<div class="panel panel-default">
\<div class="panel-body">
Здесь:\<br>
$SPHERE - имя переменной для сферы\<br>
2596.589 2758.158 22.862 - координаты сферы\<br>
1.0 - радиус сферы
\</div>
\</div>

Обычно используют такую команду вместе с чекпоинтами. Вот простой пример:

</code></pre><p>018A: $MARKER = create\_checkpoint\_at 147.0 16.0 75.5 03BC: $SPHERE = create\_sphere\_at 147.0 16.0 75.5 radius 2.0</p><pre><code>

Координаты должны быть одинаковые, что бы указать точное место положение сферы. Рассмотрим ещё один тип маркеров: иконки на радаре ( или радарные маркеры ). В качестве примера сойдёт иконка CJ ( на радаре показывается место положение старта миссии ). Создаётся такая иконка командой:

</code></pre><p>marker.CreateIconAndSphere($Icon, 15, 1024.0, 768.0, 128.0)</p><pre><code>

Так же есть равносильная команда для создания такого маркера:

</code></pre><p>0570: $Icon = create\_asset\_radar\_marker\_with\_icon 15 at 1024.0 768.0 128.0</p><pre><code>

\<div class="panel panel-default">
\<div class="panel-body">
Здесь:\<br>
$Icon - имя переменной для маркера\<br>
1024.0, 768.0, 128.0 - координаты маркера\<br>
15 - номер иконки маркера ( см. \<a href="/dir/gta\_sa/ikonki\_radara\_dlja\_gta\_san\_andreas/1-1-0-12">Иконки радара\</a> )
\</div>
\</div>

Единственное отличие в том, что во втором примере иконка будет появляться только тогда, когда рядом СЖ . Если СЖ уходит с зоны действия маркера, то иконка пропадает. Примером может быть парикмахерская или "Выстрел Бургера".

Давайте сделаем небольшой скрипт с маркерами:

</code></pre><p>:MODEL thread 'MODEL' wait 0 gosub @MODEL\_1</p><p>$ACTOR = actor.Create(4, #WMYCLOT, 2479.9438, -1710.5344, 12.5385) actor.Angle($ACTOR) = 357.2524</p><p>$MARKER = marker.CreateAboveActor($ACTOR) 07E0: set\_marker $MARKER type\_to 0 0168: set\_marker $MARKER size 2</p><p>$MARKER\_1 = marker.CreateIconAndSphere(34, 2421.8186, -1761.4199, 12.5391)</p><p>$MARKER\_2 = marker.CreateAboveObject($TRAMPLIN) 07E0: set\_marker $MARKER\_2 type\_to 0 0168: set\_marker $MARKER\_2 size 2 0165: set\_marker $MARKER\_2 color\_to 1</p><p>$CAR = car.Create(#INFERNUS, 2481.1675, -1705.0773, 13.5298) car.Angle($CAR) = 86.6491</p><p>$MARKER\_3 = marker.CreateAboveCar($CAR) 07E0: set\_marker $MARKER\_3 type\_to 1 0168: set\_marker $MARKER\_3 size 4</p><p>03BC: $SPHERE = create\_sphere\_at 2482.6885 -1701.198 13.527 radius 1.0 018A: $MARKER\_4 = create\_checkpoint\_at 2482.6885 -1701.198 13.527 end\_thread</p><p>:MODEL\_1 wait 0 model.Load(#WMYCLOT) model.Load(#INFERNUS) 038B: load\_requested\_models</p><p>:MODEL\_2 wait 0 if AND model.Available(#WMYCLOT) model.Available(#INFERNUS) jf @MODEL\_2 return</p><pre><code>

В примере мы создали машину и актёра а так же использовали существующий объект, что бы обозначить и его. Давайте вставим этот скрипт с наш код, заменив поток. Должно выйти это:

</code></pre><p>// WMYSTERIO, ru-script.3dn.ru DEFINE OBJECTS 1 DEFINE OBJECT SANNY BUILDER 3.04</p><p>DEFINE MISSIONS 0</p><p>DEFINE EXTERNAL\_SCRIPTS 0</p><p>DEFINE UNKNOWN\_EMPTY\_SEGMENT 0</p><p>DEFINE UNKNOWN\_THREADS\_MEMORY 3072</p><p>{$VERSION 3.1.0027}</p><p>//-------------MAIN--------------- thread 'MAIN' set\_wb\_check\_to 0 set\_weather 0 select\_interior 0 fade 0 0 0180: set\_on\_mission\_flag\_to $ONMISSION 00C0: set\_current\_time\_hours\_to 8 minutes\_to 0 04E4: unknown\_refresh\_game\_renderer\_at 2491.1572 -1670.3434 Camera.SetAtPos(2491.1572, -1670.3434, 12.3359) $PLAYER\_CHAR = Player.Create(#NULL, 2491.1572, -1670.3434, 12.3359) $PLAYER\_ACTOR = Actor.EmulateFromPlayer($PLAYER\_CHAR) Actor.Angle($PLAYER\_ACTOR) = 66.3548 07AF: $PLAYER\_GROUP = player $PLAYER\_CHAR group Camera.SetBehindPlayer Player.SetClothes($PLAYER\_CHAR, "WORKTRCAMOGRN", "WORKTR", 2) Player.SetClothes($PLAYER\_CHAR, "SNEAKERBINCGANG", "SNEAKER", 3) Player.SetClothes($PLAYER\_CHAR, "TSHIRTERISORN", "TSHIRT", 0) Player.Build($PLAYER\_CHAR) Player.CanMove($PLAYER\_CHAR) = True $TRAMPLIN = object.Create(#AD\_JUMP, 2480.5842, -1721.8175, 12.5488) object.Angle($TRAMPLIN) = 180.0 object.SetImmunities($TRAMPLIN, 1, 1, 1, 1, 1) Object.Indestructibility($TRAMPLIN) = False Object.RemoveFromMissionCleanupList($TRAMPLIN) 0879: enable\_gang\_wars 1 076C: set\_zone 'GAN1' gang 1 density\_to 40 076C: set\_zone 'GAN2' gang 1 density\_to 80 076C: set\_zone 'IWD1' gang 0 density\_to 40 076C: set\_zone 'IWD2' gang 0 density\_to 80 076C: set\_zone 'IWD3A' gang 2 density\_to 40 076C: set\_zone 'IWD3B' gang 2 density\_to 80 0237: set\_gang 0 weapons\_to 22 31 14 0237: set\_gang 1 weapons\_to 30 28 17 0237: set\_gang 2 weapons\_to 36 15 27 0746: set\_acquaintance 4 of\_actors\_pedtype 7 to\_actors\_pedtype 6 0746: set\_acquaintance 4 of\_actors\_pedtype 8 to\_actors\_pedtype 6 0746: set\_acquaintance 4 of\_actors\_pedtype 9 to\_actors\_pedtype 6 0746: set\_acquaintance 4 of\_actors\_pedtype 6 to\_actors\_pedtype 7 0746: set\_acquaintance 4 of\_actors\_pedtype 6 to\_actors\_pedtype 8 0746: set\_acquaintance 4 of\_actors\_pedtype 6 to\_actors\_pedtype 9 0746: set\_acquaintance 4 of\_actors\_pedtype 7 to\_actors\_pedtype 8 0746: set\_acquaintance 4 of\_actors\_pedtype 7 to\_actors\_pedtype 9 0746: set\_acquaintance 4 of\_actors\_pedtype 8 to\_actors\_pedtype 7 0746: set\_acquaintance 4 of\_actors\_pedtype 8 to\_actors\_pedtype 9 0746: set\_acquaintance 4 of\_actors\_pedtype 9 to\_actors\_pedtype 7 0746: set\_acquaintance 4 of\_actors\_pedtype 9 to\_actors\_pedtype 8 0746: set\_acquaintance 4 of\_actors\_pedtype 7 to\_actors\_pedtype 0 0746: set\_acquaintance 0 of\_actors\_pedtype 8 to\_actors\_pedtype 0 0746: set\_acquaintance 4 of\_actors\_pedtype 9 to\_actors\_pedtype 0 0767: set\_zone 'MARKST' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'UNITY' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'LAIR1' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'LAIR2A' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'LAIR2B' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'LBAG1' popcycle\_group\_for\_peds\_and\_cars\_to 19 0767: set\_zone 'LBAG2' popcycle\_group\_for\_peds\_and\_cars\_to 19 0767: set\_zone 'LBAG3' popcycle\_group\_for\_peds\_and\_cars\_to 19 0767: set\_zone 'BLUF1A' popcycle\_group\_for\_peds\_and\_cars\_to 10 0767: set\_zone 'BLUF2' popcycle\_group\_for\_peds\_and\_cars\_to 10 0767: set\_zone 'SUN1' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'SUN1' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'SUN3A' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'SUN3B' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'SUN3C' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'SUN4' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'COM1A' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'COM1B' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'COM2' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'COM3' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'COM4' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'PER1' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'CHC1A' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'CHC1B' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'CHC2A' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'CHC2B' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'CHC3' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'CHC4A' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'CHC4B' popcycle\_group\_for\_peds\_and\_cars\_to 7 0874: set\_zone 'CHC1A' popcycle\_group\_for\_peds\_to 9 0874: set\_zone 'CHC1B' popcycle\_group\_for\_peds\_to 9 0874: set\_zone 'CHC2A' popcycle\_group\_for\_peds\_to 9 0874: set\_zone 'CHC2B' popcycle\_group\_for\_peds\_to 9 0874: set\_zone 'CHC3' popcycle\_group\_for\_peds\_to 9 0874: set\_zone 'CHC4A' popcycle\_group\_for\_peds\_to 9 0874: set\_zone 'CHC4B' popcycle\_group\_for\_peds\_to 9 0767: set\_zone 'CONF1A' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'CONF1B' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'THALL1' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'LDOC1A' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LDOC1B' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LDOC2' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LDOC3A' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LDOC3B' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LDOC3C' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LDOC4' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LDT1A' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'LDT1B' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'LDT1C' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'LDT3' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'LDT4' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'LDT5' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'LDT6' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'LDT7' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'EBE1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'EBE2A' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'EBE2B' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'EBE3C' popcycle\_group\_for\_peds\_and\_cars\_to 8 0767: set\_zone 'ELCO1' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'ELCO2' popcycle\_group\_for\_peds\_and\_cars\_to 7 0874: set\_zone 'ELCO1' popcycle\_group\_for\_peds\_to 9 0874: set\_zone 'ELCO2' popcycle\_group\_for\_peds\_to 9 0767: set\_zone 'GAN1' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'GAN2' popcycle\_group\_for\_peds\_and\_cars\_to 7 0874: set\_zone 'GAN1' popcycle\_group\_for\_peds\_to 1 0874: set\_zone 'GAN2' popcycle\_group\_for\_peds\_to 1 0767: set\_zone 'GLN1' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'GLN2A' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'LIND1A' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'LIND1B' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LIND2A' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LIND2B' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LIND3' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'IWD1' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'IWD2' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'IWD3A' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'IWD3B' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'IWD4' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'IWD5' popcycle\_group\_for\_peds\_and\_cars\_to 7 0874: set\_zone 'IWD1' popcycle\_group\_for\_peds\_to 1 0874: set\_zone 'IWD2' popcycle\_group\_for\_peds\_to 1 0874: set\_zone 'IWD3A' popcycle\_group\_for\_peds\_to 1 0874: set\_zone 'IWD3B' popcycle\_group\_for\_peds\_to 1 0874: set\_zone 'IWD4' popcycle\_group\_for\_peds\_to 1 0874: set\_zone 'IWD5' popcycle\_group\_for\_peds\_to 1 0767: set\_zone 'JEF1A' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JEF1B' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JEF2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JEF3A' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JEF3B' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JEF3C' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'LFL1A' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'LFL1B' popcycle\_group\_for\_peds\_and\_cars\_to 7 0874: set\_zone 'LFL1A' popcycle\_group\_for\_peds\_to 9 0874: set\_zone 'LFL1B' popcycle\_group\_for\_peds\_to 9 0767: set\_zone 'LMEX1A' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'LMEX1B' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'ELS1A' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'ELS1B' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'ELS2' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'ELS3A' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'ELS3B' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'ELS4' popcycle\_group\_for\_peds\_and\_cars\_to 7 0874: set\_zone 'ELS1A' popcycle\_group\_for\_peds\_to 10 0874: set\_zone 'ELS1B' popcycle\_group\_for\_peds\_to 10 0874: set\_zone 'ELS2' popcycle\_group\_for\_peds\_to 10 0874: set\_zone 'ELS3A' popcycle\_group\_for\_peds\_to 10 0874: set\_zone 'ELS3B' popcycle\_group\_for\_peds\_to 10 0874: set\_zone 'ELS4' popcycle\_group\_for\_peds\_to 10 0767: set\_zone 'MAR1' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'MAR2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'MAR3' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'MKT1' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'MKT2' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'MKT3' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'MKT4' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'MUL1A' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL1B' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL1C' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL2A' popcycle\_group\_for\_peds\_and\_cars\_to 10 0767: set\_zone 'MUL2B' popcycle\_group\_for\_peds\_and\_cars\_to 10 0767: set\_zone 'MUL3' popcycle\_group\_for\_peds\_and\_cars\_to 10 0767: set\_zone 'MUL4' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL5A' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL5B' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL5C' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL6' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL7A' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL7B' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'PLS' popcycle\_group\_for\_peds\_and\_cars\_to 8 0767: set\_zone 'RIH1A' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'RIH1B' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'RIH2' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'RIH3A' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'RIH3B' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'RIH4' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'RIH5A' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'RIH6B' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'RIH5A' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'RIH6B' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'ROD1A' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD1B' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD1C' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD2A' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD2B' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD3A' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD3B' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD4A' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD4B' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD4C' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD5A' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'ROD5B' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'SMB1' popcycle\_group\_for\_peds\_and\_cars\_to 8 0767: set\_zone 'SMB2' popcycle\_group\_for\_peds\_and\_cars\_to 8 0767: set\_zone 'VIN2' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'VIN3' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'VIN1A' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'VIN1B' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'VERO1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'VERO2' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'VERO3' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'VERO4A' popcycle\_group\_for\_peds\_and\_cars\_to 8 0767: set\_zone 'VERO4B' popcycle\_group\_for\_peds\_and\_cars\_to 8 0767: set\_zone 'CRANB' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'CALT' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'SUNMA' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'SUNNN' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'BATTP' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'ESPN1' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'ESPN2' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'ESPN3' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'BAYV' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'PARA' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'JUNIHO' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JUNIHI' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'CIVI' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'CHINA' popcycle\_group\_for\_peds\_and\_cars\_to 9 0874: set\_zone 'CHINA' popcycle\_group\_for\_peds\_to 6 0767: set\_zone 'SFDWT1' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'SFDWT2' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'SFDWT3' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'SFDWT4' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'SFDWT5' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'SFDWT6' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'FINA' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'CITYS' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'WESTP1' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'WESTP2' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'WESTP3' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'THEA1' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'THEA2' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'THEA3' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'GARC' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'HASH' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'OCEAF1' popcycle\_group\_for\_peds\_and\_cars\_to 8 0767: set\_zone 'OCEAF2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'OCEAF3' popcycle\_group\_for\_peds\_and\_cars\_to 8 0767: set\_zone 'DOH1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'DOH2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'CUNTC1' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'CUNTC2' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'CUNTC3' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'SFGLF1' popcycle\_group\_for\_peds\_and\_cars\_to 17 0767: set\_zone 'SFGLF2' popcycle\_group\_for\_peds\_and\_cars\_to 17 0767: set\_zone 'SFGLF3' popcycle\_group\_for\_peds\_and\_cars\_to 17 0767: set\_zone 'SFGLF4' popcycle\_group\_for\_peds\_and\_cars\_to 17 0767: set\_zone 'HILLP' popcycle\_group\_for\_peds\_and\_cars\_to 10 0767: set\_zone 'SILLY1' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'SILLY2' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'SILLY3' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'SILLY4' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'SFAIR1' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'SFAIR2' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'SFAIR3' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'SFAIR4' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'SFAIR5' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'SFBAG1' popcycle\_group\_for\_peds\_and\_cars\_to 19 0767: set\_zone 'SFBAG2' popcycle\_group\_for\_peds\_and\_cars\_to 19 0767: set\_zone 'SFBAG3' popcycle\_group\_for\_peds\_and\_cars\_to 19 0767: set\_zone 'EASB1' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'EASB2' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'ESPE1' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'ESPE2' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'ESPE3' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'LINDEN' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'YELLOW' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'BFC1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'BFC2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'RIE' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'LDM' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'RSW1' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'RSW2' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'RSE' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'LDS' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'SRY' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTS1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTS2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'LVA1' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LVA2' popcycle\_group\_for\_peds\_and\_cars\_to 18 0767: set\_zone 'LVA3' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LVA4' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'VAIR1' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'VAIR2' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'VAIR3' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'LVBAG' popcycle\_group\_for\_peds\_and\_cars\_to 19 0767: set\_zone 'GGC1' popcycle\_group\_for\_peds\_and\_cars\_to 10 0767: set\_zone 'GGC2' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'BFLD1' popcycle\_group\_for\_peds\_and\_cars\_to 10 0767: set\_zone 'BFLD2' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'WWE' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'WWE1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'PINT' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'YBELL2' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'YBELL1' popcycle\_group\_for\_peds\_and\_cars\_to 17 0767: set\_zone 'JTW1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTW2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTN1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTN2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTN3' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTN4' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTN5' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTN6' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTN7' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTN8' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTE1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTE2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTE3' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTE4' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'HGP' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'SPIN' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'BINT1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'BINT2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'BINT3' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'BINT4' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'PRP1' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'PRP2' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'PRP3' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'PRP4' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'REDE1' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'REDE2' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'REDE3' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'REDW1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'REDW2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'REDW3' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'REDW4' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'ROCE1' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'ROCE2' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'OVS' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'CREE' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'STRIP1' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'STRIP2' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'STRIP3' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'STRIP4' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'PILL1' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'PILL2' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'RING' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'ISLE' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'STAR1' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'STAR2' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'ROY' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'CAM' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'LOT' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'PIRA' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'VISA1' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'VISA2' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'CALI1' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'CALI2' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'DRAG' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'PINK' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'HIGH' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'CONST1' popcycle\_group\_for\_peds\_and\_cars\_to 18 0767: set\_zone 'ANGPI' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'SHACA' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'BACKO' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'BEACO' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'FARM' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'PALO' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'MONT' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'MONT1' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'MTCHI1' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'MTCHI2' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'MTCHI3' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'MTCHI4' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'HBARNS' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'DILLI' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'TOPFA' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'BLUEB' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'BLUEB1' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'PANOP' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'BLUAC' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'CREEK' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'CREEK1' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'MAKO' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'TOPFA' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'FERN' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'NROCK' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'HANKY' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'LEAFY' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'RED' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'FLINTC' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'WHET' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'BIGE' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'ELQUE' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'BARRA' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'CARSO' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'PAYAS' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'PROBE' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'ELCA' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'FLINTR' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'ARCO' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'VALLE' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'FLINTI' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'MONINT' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'ROBINT' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'TOM' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'ALDEA' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'BRUJA' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'ROBAD' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'BONE' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'HAUL' popcycle\_group\_for\_peds\_and\_cars\_to 18 0767: set\_zone 'QUARY' popcycle\_group\_for\_peds\_and\_cars\_to 18 0767: set\_zone 'OCTAN' popcycle\_group\_for\_peds\_and\_cars\_to 18 0767: set\_zone 'PALMS' popcycle\_group\_for\_peds\_and\_cars\_to 18 0767: set\_zone 'EBAY' popcycle\_group\_for\_peds\_and\_cars\_to 18 0767: set\_zone 'EBAY2' popcycle\_group\_for\_peds\_and\_cars\_to 18 0767: set\_zone 'DAM' popcycle\_group\_for\_peds\_and\_cars\_to 18 014B: $MY\_CAR = init\_parked\_car\_generator #BULLET color -1 -1 0 alarm 0 door\_lock 0 1 10000 at 2474.2131 -1690.8783 12.1239 angle 180.0 014C: set\_parked\_car\_generator $MY\_CAR cars\_to\_generate\_to 101 0213: $PICKUP\_0001 = create\_pickup #BODYARMOUR type 1 at 2491.0 -1685.8561 13.5107 032B: $PICKUP\_0002 = create\_weapon\_pickup #MINIGUN group 15 ammo 60 at 2493.0 -1685.8561 13.5107 02E1: $PICKUP\_0003 = create\_cash\_pickup 500 at 2495.0 -1685.8561 13.5107 permanence\_flag 1 04A6: $PICKUP\_0004 = create\_asset\_money\_pickup\_at 2497.0 -1685.8561 13.5107 money 10000 10000 fade 1 0 create\_thread @SAVE create\_thread @MODEL end\_thread</p><p>:SAVE thread 'SAVE' wait 0 if AND $ONMISSION == 0 0AB0: key\_pressed 115 then 03D8: show\_save\_screen wait 250 end jump @SAVE</p><p>// старт нового кода :MODEL thread 'MODEL' wait 0 gosub @MODEL\_1</p><p>$ACTOR = actor.Create(4, #WMYCLOT, 2479.9438, -1710.5344, 12.5385) actor.Angle($ACTOR) = 357.2524</p><p>$MARKER = marker.CreateAboveActor($ACTOR) 07E0: set\_marker $MARKER type\_to 0 0168: set\_marker $MARKER size 2</p><p>$MARKER\_1 = marker.CreateIconAndSphere(34, 2421.8186, -1761.4199, 12.5391)</p><p>$MARKER\_2 = marker.CreateAboveObject($TRAMPLIN) 07E0: set\_marker $MARKER\_2 type\_to 0 0168: set\_marker $MARKER\_2 size 2 0165: set\_marker $MARKER\_2 color\_to 1</p><p>$CAR = car.Create(#INFERNUS, 2481.1675, -1705.0773, 13.5298) car.Angle($CAR) = 86.6491</p><p>$MARKER\_3 = marker.CreateAboveCar($CAR) 07E0: set\_marker $MARKER\_3 type\_to 1 0168: set\_marker $MARKER\_3 size 4</p><p>03BC: $SPHERE = create\_sphere\_at 2482.6885 -1701.198 13.527 radius 1.0 018A: $MARKER\_4 = create\_checkpoint\_at 2482.6885 -1701.198 13.527 end\_thread</p><p>:MODEL\_1 wait 0 model.Load(#WMYCLOT) model.Load(#INFERNUS) 038B: load\_requested\_models</p><p>:MODEL\_2 wait 0 if AND model.Available(#WMYCLOT) model.Available(#INFERNUS) jf @MODEL\_2 return // конец нового кода</p><pre><code>

В результате мы получим:

\<!--IMG1-->\<img src="<https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/53285247.png>" />\<!--IMG1-->

Как видите, особо сложного нету. Главное помнить имена маркеров и применять их к существующим актёрам ( объектам ).|3178|1|0|53285247`png`640`400`400\`250\`\`||markery\_i\_sfery|1506063221 </code></pre></td><td></td></tr></tbody></table>


# 000122. Типы чекпоинтов, маркеров. Детальный обзор

Типы чекпоинтов, маркеров. Детальный обзор|Всем привет! Этот урок я полностью посвятил чекпоинтам и маркерам.|wmysterio|wmysterio||||Сами маркеры можно образно разделить на две большие группы: статические и плавающие. Статические маркеры - это объекты, которые прикреплены на карте, то есть не могут перемещаться. Плавающие - на оборот: свободно двигаются за игровыми субъектами. Как правило создаются они опкодами с описанием "AboveTo"( над чем-то ). Статичные же имеют разделение примерно на три ветви: чекпоинты, радарные и входные. Входные маркеры являют собою желтую "стрелку", идентичную плавающим маркерам, только не перемещается. Как правило их ставят при входе в какой-то интерьер.

Радарные маркеры являют собою сферу в игре с иконкой на карте. Такие маркеры обычно используют для обозначения важных мест, таких как закусочных, миссий и т.п.

Чекпоинты - это маркеры пути, то есть указатели места, куда нужно добраться. Они делятся также на два вида - обычные и гоночные. Последний вид используется, как правило, в гоночных миссиях. Они имеют точку позиции и точку, куда будет смотреть маркер.

Чтобы лучше понять эту классификацию я нарисовал картинку:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/86296398.png)

Существует несколько вариантов отображения плавающих маркеров на радаре. Для этого используется опкод:

```
018B: set_marker 0@ radar_mode 2
```

Здесь:\
0@ - хэндл маркера\
2 - режим отображения. Режимы указаны в таблице ниже

| Режим | Описание                                                       |
| ----- | -------------------------------------------------------------- |
| 0     | На радаре показывается маркер и стрелка ( он же по-умолчанию ) |
| 1     | Есть стрелка над субъектом, но на радаре ничего не показано    |
| 2     | На радаре ничего не показано и нет стрелки                     |

Так же мы можем указать тип чекпоинта:

```
08FB: set_checkpoint 1@ type_to 0
```

Здесь:\
0@ - хэндл чекпоинта\
0 - тип чекпоинта. Типы указаны в таблице ниже

| Тип | Описание          |
| --- | ----------------- |
| 0   | Желтый квадратик  |
| 1   | Синий квадратик   |
| 2   | Красный квадратик |

Гоночные чекпоинты имеют свою особенность. Дело в том, что их можно перемещать. Если обычные прикреплены к месту, то другое дело с ГЧ ( они же гоночные чекпоинты ). К тому же мы можем задать размер. Создаются ГЧ следующим образом:

```
06D5: 0@ = create_racing_checkpoint_at -2699.3767 95.7964 4.3359 point_to -2699.5322 74.057 4.3359 type 0 radius 4.0
```

Здесь:\
0@ - хэндл чекпоинта\
-2699.3767 95.7964 4.3359 - место, где должна разместится контрольная точка\
-2699.5322 74.057 4.3359 - координаты, куда будет смотреть ГЧ\
0 - тип ГЧ\
4.0 - размер гоночного чекпоинта

Отключается гоночные чекпоинты следующим опкодом:

```
06D6: disable_racing_checkpoint 0@
```

Переместить ГЧ можно следующим образом:

```
07F3: move_racing_checkpoint 0@ to -2710.7253 74.4686 4.1797
```

Здесь:\
0@ - хэндл чекпоинта\
-2710.7253 74.4686 4.1797 - новая позиция гоночного чекпоинта.

Можно ещё задать угол разворота ГЧ:

```
0996: set_racing_checkpoint 0@ Z_angle_to 179.2693
```

× \*\*ВАЖНО:\*\* Гоночные чекпоинты не отображаются на экране!

Давайте напишем небольшую миссию, где игроку нужно на "кукурузнике" облетать часть города Лос Сантос:

```
{$CLEO .cm}

//------------- Mission ---------------

:MISSION
thread 'MISSION'
gosub @MISSION_29_57 
if 
wasted_or_busted 
jf @MISSION_29_46 
gosub @MISSION_29_144 

:MISSION_29_46
$ONMISSION = 0 
mission_cleanup 
end_thread 

:MISSION_29_57
increment_mission_attempts 
$ONMISSION = 1 
00C0: set_current_time 4 0
03DE: set_pedestrians_density_multiplier_to 0.0
01EB: set_traffic_density_multiplier_to 0.0
0395: clear_area 0 at 2244.7144 -1851.5718 -0.1345 radius 300.0
Model.Load(#CROPDUST)
038B: load_requested_models
0@ = Car.Create(#CROPDUST, 2244.7144, -1851.5718, -0.1345)
Car.Angle(0@) = 269.8951
Model.Destroy(#CROPDUST)
072A: put_actor $PLAYER_ACTOR into_car 0@ driverseat
wait 2000
Camera.Restore_WithJumpCut
fade 1 1000
wait 1000
0ACF: show_formatted_styled_text "3" time 1000 style 4
097A: at 0.0 0.0 0.0 play_sound 1056
wait 1000
0ACF: show_formatted_styled_text "2" time 1000 style 4 
097A: at 0.0 0.0 0.0 play_sound 1056
wait 1000
0ACF: show_formatted_styled_text "1" time 1000 style 4 
097A: at 0.0 0.0 0.0 play_sound 1056
wait 1000
0ACF: show_formatted_styled_text "G0!" time 1000 style 4
097A: at 0.0 0.0 0.0 play_sound 1057
Player.CanMove(0) = true
Actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
Car.SetImmunities(0@, 1, 1, 1, 1, 1)
0423: set_car 0@ improved_handling_to 2.0 // (float)
1@ = 0 // Index Point
9@ = 4 // Type Race Chackpoint

:MISSION_C
wait 0
06D6: disable_racing_checkpoint 8@
marker.Disable(10@)
if
1@ == 0
then
2@ = 2413.0439 
3@ = -1841.1782
5@ = 2413.2087
6@ = -2048.9414
end
if
1@ == 1
then
2@ = 2413.2087 
3@ = -2048.9414 
5@ = 2394.0317 
6@ = -2267.0752 
end
if
1@ == 2
then
2@ = 2394.0317 
3@ = -2267.0752 
5@ = 2225.1492 
6@ = -2451.5432 
end
if
1@ == 3
then
2@ = 2225.1492 
3@ = -2451.5432 
5@ = 2221.7722 
6@ = -2627.5698 
end
if
1@ == 4
then
2@ = 2221.7722 
3@ = -2627.5698 
5@ = 2380.2559 
6@ = -2664.9453 
end
if
1@ == 5
then
2@ = 2380.2559 
3@ = -2664.9453 
5@ = 2407.147 
6@ = -2510.7278 
end
if
1@ == 6
then
2@ = 2407.147 
3@ = -2510.7278 
5@ = 2489.533 
6@ = -2308.1719 
end
if
1@ == 7
then
2@ = 2489.533 
3@ = -2308.1719 
5@ = 2579.6653 
6@ = -2235.9314 
end
if
1@ == 8
then
2@ = 2579.6653 
3@ = -2235.9314 
5@ = 2582.5527 
6@ = -2116.0264 
end
if
1@ == 9
then
2@ = 2582.5527 
3@ = -2116.0264 
5@ = 2583.7729 
6@ = -2082.8301 
9@ = 1 // Finish!
end
if
1@ == 10
then
jump @MISSION_A
end
06D5: 8@ = create_racing_checkpoint_at 2@ 3@ 100.0 point_to 5@ 6@ 100.0 type 9@ radius 4.0
018A: 10@ = create_checkpoint_at 2@ 3@ 50.0

:MISSION_B
wait 0
if OR
Car.Wrecked(0@)
02BF: car 0@ sunk
then
jump @MISSION_29_144_END_CAR
end
if
not actor.InCar($PLAYER_ACTOR, 0@)
then
jump @MISSION_29_144_PLAYER_NOT_CAR
end
if
00EC: actor $PLAYER_ACTOR sphere 0 near_point 2@ 3@ radius 4.5 4.5
then
1@ += 1
097A: at 0.0 0.0 0.0 play_sound 1056
jump @MISSION_C
end
jump @MISSION_B

:MISSION_A
wait 2000
gosub @MISSION_END
Player.Money(0) += 10000
0394: play_music 1
01E3: show_text_1number_styled GXT 'M_PASS' number 10000 time 5000 style 1 // MISSION PASSED + MONEY
return 

:MISSION_29_144
wait 0 
gosub @MISSION_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 // MISSION FAILED
return

:MISSION_29_144_END_CAR
wait 0 
gosub @MISSION_END
0AD0: show_formatted_text_lowpriority "Џpa®cЈop¦ y®њ¤¦o›e®!" time 5000 // Car Wrecked!
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 // MISSION FAILED
return

:MISSION_29_144_PLAYER_NOT_CAR
wait 0 
gosub @MISSION_END
0AD0: show_formatted_text_lowpriority "‹Ё Јokњ®yћњ ¦pa®cЈop¦!" time 5000 // You not in car!
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 // MISSION FAILED
return

:MISSION_END
wait 0
03DE: set_pedestrians_density_multiplier_to 1.0
01EB: set_traffic_density_multiplier_to 1.0
06D6: disable_racing_checkpoint 8@
marker.Disable(10@)
return
```

А также стартер к нему:

```
{$CLEO}
0000:

while 8AB0: not key_pressed 9 // Tab
wait 0
end

fade 0 1000
0ACF: show_formatted_styled_text "Fly in City" time 4000 style 2
Player.CanMove(0) = false
Actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
wait 1000
0A94: start_custom_mission "Miss"
0A93: end_custom_thread
```

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/96220810.png)

Таким образом сюда ещё можно добавить таймер, что бы игрок живее летел к точке :) На этом урок окончен. Спасибо всем за время, которое вы уделили этой статье!|3133|1|0|96220810`png`600`337`400`224``\|86296398`png`507`263`400`207\`\`||tipy\_chekpointov\_markerov\_detalnyj\_obzor|1504591681


# 00055. Cleo. Основные понятия, отличия от main'а, простые примеры

Cleo. Основные понятия, отличия от main'а, простые примеры|Здравствуйте, уважаемые пользователи сайта. Пришло время немного оставить скриптить main.scm и перейти к Cleo.|wmysterio|wmysterio||||Большинство приёмов и возможностей мы рассмотрели, и дальше нет смысла писать их в мейне, так как постоянное начало новой игры думаю достаёт. Поэтому уроки дальше будут на Cleo.

Действуют Cleo-скрипты также, как и внешние скрипты из main.scm, только загружать их не нужно. Они сами загружаются в начале игры. Особенностью этих скриптов в том, что не нужно начинать новую игру, как это было в мейне. Так же важно, что в клео нельзя создавать новые потоки. То есть "create\_thread" здесь не пройдёт. Один скрипт - один поток. Рассмотрим написание простейшего скрипта:

```
{$CLEO}
0000:

:POTOK
thread 'POTOK'
wait 5000
0A93: end_custom_thread
```

Здесь:\
{$CLEO} - указываем компилятору, что это будет cleo-скрипт ( обязательно ставьте эту строку, иначе компилятор скомпилирует его как "\*.scm" и закинет его папку игры "data/script", указанной в настройке СБ ). Такую конструкцию принято называть директивой.\
0000: - опкод, который устраняет ошибку "Переход на нулевой оффсет". Эта ошибка возникает, когда идёт переход на первую метку потока. В нашем случаи такого перехода нет, но я всегда его пишу, что бы не приходилось его добавлять в будущем. Эта ошибка унаследовалась от внешних скриптов, которые также не поддерживают переход на первую метку потока.\
0A93: end\_custom\_thread - именно этим опкодом завершаются клео-скрипты. Это очень важно, потому что end\_thread вызывает ошибку при загрузке ( сохранении ) игры.

В Cleo-скриптах не рекомендуется использовать глобальные переменные. Это нужно, как минимум, для того, что бы случайно не изменить переменную в main.scm. То есть глобальные переменные действуют и на CLEO. Однако некоторые переменные всё же можно ( и нужно :) ) используются в CLEO. Это такие, как "$PLAYER\_CHAR", "$PLAYER\_ACTOR", "$ONMISSION" и "$PLAYER\_GROUP". Если всё-же можно использовать собственные глобальные переменные, создавайте как можно длинные и запутанные имена или такие, каких нет в main.scm. Например: "$KOLICHESTVO".

Но всё же рекомендую использовать локальные переменные. Переменные от "0@" до "31@" Вы можете свободно использовать для хранения даных. А переменные "32@" и "33@" - использовать в качестве таймера, которые, кстати ( как написано в справке ), не запускаются опкодом "03C3", также не рекомендовано использовать опкоды "03C4" и "04F7" ( статус-тексты ). У меня, например, постоянные проблемы с ней, хотя в других ничего плохого не происходит. Можете протестировать. Если у вас в всё окей, то юзайте на здоровье :) Особенности потоков те же, что и в мейне. Можно использовать циклы, переходы, массивы и т.п.

Скрипт мы написали. Когда мы компилируем его в первый раз, то компилятор предложит нам сохранить его. Указываем папку CLEO ( что в папке с игрой ). Другой способ - создать текстовый файл в папке "Cleo" и переместить его на санник, затем скомпилировать. Имя файла может быть любое, но обычно его называют так же, как и поток. Потоки, кстати, можно и не называть, то есть сразу писать скрипт без "thread".

Раз мы будем писать на CLEO , то полностью отредактируем мейн, сделаем его минимальным и работоспособным. Немного позже я скажу зачем мы это сделали. Вот код нашего мейна:

```
// by WMYSTERIO, http://www.ru-script.3dn.ru

DEFINE OBJECTS 1
DEFINE OBJECT SANNY BUILDER 3.04 

DEFINE MISSIONS 0

DEFINE EXTERNAL_SCRIPTS 0

DEFINE UNKNOWN_EMPTY_SEGMENT 0

DEFINE UNKNOWN_THREADS_MEMORY 3072

{$VERSION 3.1.0027}

//-------------MAIN---------------
thread 'MAIN'
set_wb_check_to 0
set_weather 0
select_interior 0
fade 0 0
0180: set_on_mission_flag_to $ONMISSION // Note: your missions have to use the variable defined here
00C0: set_current_time_hours_to 8 minutes_to 0
04E4: unknown_refresh_game_renderer_at 2491.157 -1670.343
Camera.SetAtPos(2491.157, -1670.343, 12.3359)
$PLAYER_CHAR = Player.Create(#NULL, 2491.157, -1670.343, 12.3359)
$PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
Actor.Angle($PLAYER_ACTOR) = 66.3548
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
Camera.SetBehindPlayer
Player.SetClothes($PLAYER_CHAR, "WORKTRCAMOGRN", "WORKTR", Legs)
Player.SetClothes($PLAYER_CHAR, "SNEAKERBINCGANG", "SNEAKER", Shoes)
Player.SetClothes($PLAYER_CHAR, "TSHIRTERISORN", "TSHIRT", Torso)
Player.Build($PLAYER_CHAR)
Player.CanMove($PLAYER_CHAR) = True
0629: change_integer_stat 181 to 4
016C: restart_if_wasted_at 2027.77 -1420.52 15.99 angle 137.0 town_number 0
016C: restart_if_wasted_at 1180.85 -1325.57 12.58 angle 271.4 town_number 0
016D: restart_if_busted_at 1550.68 -1675.49 14.51 angle 90.0 town_number 0
016C: restart_if_wasted_at 1244.437 331.2261 18.5547 angle 7.5465 town_number 1
016D: restart_if_busted_at 632.2344 -571.7104 15.3515 angle 267.2 town_number 1
016C: restart_if_wasted_at -2199.719 -2308.075 29.6181 angle 322.8928 town_number 1
016D: restart_if_busted_at -2163.829 -2387.817 29.625 angle 134.2066 town_number 1
016C: restart_if_wasted_at -2670.285 616.4364 13.4531 angle 183.1042 town_number 1
016D: restart_if_busted_at -1605.792 716.8598 11.0241 angle 355.2978 town_number 1
016C: restart_if_wasted_at -316.3832 1056.045 18.7344 angle 1.6017 town_number 2
016D: restart_if_busted_at -212.1889 979.4168 18.3219 angle 278.0478 town_number 2
016C: restart_if_wasted_at -1514.823 2527.119 54.7443 angle 2.3546 town_number 2
016D: restart_if_busted_at -1393.072 2633.116 54.9491 angle 86.0424 town_number 2
016C: restart_if_wasted_at 1578.446 1770.682 9.8358 angle 99.7567 town_number 2
016D: restart_if_busted_at 2337.083 2453.802 13.9765 angle 90.7643 town_number 2
fade 1 0
create_thread @SAVE
end_thread

:SAVE
thread 'SAVE'
wait 0
if AND
not actor.Dead($PLAYER_ACTOR)
8741: not actor $PLAYER_ACTOR busted
then
 if AND
 $ONMISSION == 0
 8A0C: not player $PLAYER_CHAR on_jetpack 
 then
 if AND
 8818: not actor $PLAYER_ACTOR in_air
 8965: not actor $PLAYER_ACTOR swimming
 then
 if AND
 not actor.Driving($PLAYER_ACTOR)
 0AB0: key_pressed 115 // F4
 then
 03D8: show_save_screen
 end
 end
 end
end 
jump @SAVE
```

Компилируем его и запускаем новую игру. Как видим, никаких ошибок не возникало. По этому смело закрываем мейн и начинаем писать Cleo-скрипты ;)

Прежде всего напишем скрипт спавна транспорта. Создаем в папке CLEO текстовый файл и называем его, например, "CAR.txt". Дальше запускаем ярлык санника и ожидаем запуска программы. После этого перемещаем файл в окно программы:

![](https://github.com/wmysterio/scm-scripting-lessons/blob/main/_pu/0/01129892.png)

Как видим появилось поле редактора :) Дальше уже пишем сам скрипт:

```
{$CLEO}
0000:

:car
thread 'car'
wait 0
if
0AB0: key_pressed 50 // Кнопка 2
then
0ADD: spawn_car_with_model #BULLET at_player_location
end
jump @car
```

Суть скрипта проста - нажимаем кнопку 2\` и перед СЖ появится кар "Bullet". Как видите, мы не использовали опкод "0A93" в нашем скрипте, так как мы возвращаемся постоянно на метку "@CAR". В таких случаях обычно не пишут опкод завершения потока, так как он никогда не выполнится :) Компилируем. Думаю вы заметите, что в папке создался и "\*.cs"-файл, так что клео-скрипт создан :)

Давайте удалим опкод "0000" и попробуем скомпилировать. Как видите, в нас ошибка: "Переход на нулевой оффсет". Как уже было написано выше, это случается когда идёт переход на первую метку. Именно для этого создан опкод "0000" - он делает небольшое смещение от начала потока, что позволяет избежать перехода нулевой оффсет. Также можно написать вместо него задержку "wait 0" или любой другой опкод, не влияющий на процесс игры. Это тоже помогает ;)

Давайте протестируем скрипт. Результат виден на лицо - тачка отлично "спавнится" возле Карла:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/43780319.png)

В нас ещё есть много материала, поэтому в ближайшие дня напишу ещё парочку уроков.|3456|1|0|43780319`png`600`375`400`250``\|01129892`png`393`270

```
`\||cleo_osnovnye_ponjatija_otlichija_ot_main_39_a_prostye_primery|1499524917
```


# 00061. Cleo-миссии

Cleo-миссии|В этом уроке мы рассмотрим как создавать миссии, используя CLEO.|wmysterio|wmysterio||||Как и в main.scm в Cleo можно создавать миссии. Преимущество в Cleo в том, что количество миссий неограниченное! То есть если в мейне максимум 200, то в Cleo может быть 500, 600 и так дальше. Сегодня мы напишем первую Cleo-миссию ;)

Что бы компилятор сделал Cleo-миссию, нужно указать ему в директиве расширение "\*.cm" ( custom mission ):

```
{$cleo .cm}
```

Дальше указать код миссии. Вот очень стабильный код миссий:

```
{$CLEO .cm}
//------------- Mission ---------------

:MISSION
thread 'MISSION'
gosub @MISSION_29_57
if
wasted_or_busted
jf @MISSION_29_46
gosub @MISSION_29_144

:MISSION_29_46
$ONMISSION = 0
mission_cleanup
end_thread

:MISSION_29_57
increment_mission_attempts
$ONMISSION = 1

//
{ Код миссии }
//


gosub @MISSION_END
00BA: show_text_styled GXT 'M_PASS' time 5000 style 1 // MISSION PASSED
0318: set_latest_mission_passed 'MISS_01' // GXT mission name
return

:MISSION_29_144
wait 0
gosub @MISSION_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 // MISSION FAILED
return

:MISSION_END
wait 0
return
```

Обратите внимание, что завершается поток командой "end\_thread"! После компиляции, SB создаст файл "\*.cm" в папке Cleo. Вы можете поместить его и в другую директорию, например в папку "CLEO\MISSIONS", что бы отделить написанные миссии от Cleo-скриптов.

Давайте напишем миссию, что бы на CJ-я нападали три тела и нужно их убить. После убийства мы получим 1000$.

```
{$CLEO .cm}
//------------- Mission ---------------

:MISSION
thread 'MISSION'
gosub @MISSION_29_57
if
wasted_or_busted
jf @MISSION_29_46
gosub @MISSION_29_144

:MISSION_29_46
$ONMISSION = 0
mission_cleanup
end_thread

:MISSION_29_57
increment_mission_attempts
$ONMISSION = 1
model.Load(#BALLAS1)
038B: load_requested_models

:MISSION_1
wait 0
if
model.Available(#BALLAS1)
jf @MISSION_1
actor.PutAt($PLAYER_ACTOR, 2488.8188, -1678.9363, 12.3361)
actor.Angle($PLAYER_ACTOR) = 7.1576
0@ = actor.Create(7, #BALLAS1, 2484.7991, -1660.7439, 12.3359)
actor.Angle(0@) = 199.2093
077A: set_actor 0@ acquaintance 4 to_actors_pedtype 0
1@ = actor.Create(7, #BALLAS1, 2480.4097, -1661.7654, 12.3437)
actor.Angle(1@) = 207.3561
077A: set_actor 1@ acquaintance 4 to_actors_pedtype 0
2@ = actor.Create(7, #BALLAS1, 2490.8955, -1661.2186, 12.3359)
actor.Angle(2@) = 167.8757
077A: set_actor 2@ acquaintance 4 to_actors_pedtype 0
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer
wait 2000
fade 1 1000
wait 1000
05E2: AS_actor 0@ kill_actor $PLAYER_ACTOR
05E2: AS_actor 1@ kill_actor $PLAYER_ACTOR
05E2: AS_actor 2@ kill_actor $PLAYER_ACTOR
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
player.CanMove($PLAYER_CHAR) = true
3@ = marker.CreateAboveActor(0@)
4@ = marker.CreateAboveActor(1@)
5@ = marker.CreateAboveActor(2@)
07E0: set_marker 3@ type_to 0
07E0: set_marker 4@ type_to 0
07E0: set_marker 5@ type_to 0

:MISSION_2
wait 0
if
actor.Dead(0@)
then
marker.Disable(3@)
end
if
actor.Dead(1@)
then
marker.Disable(4@)
end
if
actor.Dead(2@)
then
marker.Disable(5@)
end
if AND
actor.Dead(0@)
actor.Dead(1@)
actor.Dead(2@)
then
jump @MISSION_3
end
jump @MISSION_2

:MISSION_3
wait 0
gosub @MISSION_END
01E3: show_text_1number_styled GXT 'M_PASS' number 1000 time 5000 style 1
Player.Money($PLAYER_CHAR) += 1000
return

:MISSION_29_144
wait 0
gosub @MISSION_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 // MISSION FAILED
return

:MISSION_END
wait 0
if
056D: actor 0@ defined
then
actor.RemoveReferences(0@)
actor.DestroyInstantly(0@)
end
if
056D: actor 1@ defined
then
actor.RemoveReferences(1@)
actor.DestroyInstantly(1@)
end
if
056D: actor 2@ defined
then
actor.RemoveReferences(2@)
actor.DestroyInstantly(2@)
end
marker.Disable(3@)
marker.Disable(4@)
marker.Disable(5@)
return
```

Компилируем файл. В нас получился файл "MISSION.cm". Отлично! Мы создали миссию!

Как и в мейне, нам необходимо написать стартер для миссии - набор условий для запуска. Кстати, что бы запустить Cleo-миссию, необходимо использовать опкод:

```
0A94: start_custom_mission "MISSION"
```

Здесь:\
"MISSION" - имя миссии ( название файла! ). Обратите внимание, что расширение "\*.cm" писать не надо!

Давайте напишем простой стартер. Для этого создадим Cleo-скрипт с таким содержимым:

```
{$CLEO}
0000:

:STARTER
thread 'STARTER'
wait 0
if
$ONMISSION == 0
jf @STARTER
02A7: 0@ = create_icon_marker_and_sphere 15 at 2496.6348 -1684.6963 12.3935

:STARTER_1
wait 0
if
$ONMISSION == 1
then
marker.Disable(0@)
jump @STARTER
end

if AND
not actor.Dead($PLAYER_ACTOR)
not actor.Driving($PLAYER_ACTOR)
8A0C: not player $PLAYER_CHAR on_jetpack
8741: not actor $PLAYER_ACTOR busted
then
 if
 0102: actor $PLAYER_ACTOR in_sphere 2496.6348 -1684.6963 12.3935 radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 jump @STARTER_2
 end
end
jump @STARTER_1
 
:STARTER_2
wait 0
player.CanMove($PLAYER_CHAR) = false
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
Marker.Disable(0@)
00BE: text_clear_all
03E6: remove_text_box
00BA: show_text_styled GXT 'MISS_01' time 1000 style 2
fade 0 1000
wait 2000
0A94: start_custom_mission "MISSION"
jump @STARTER
```

Таким образом мы сделали полноценный стартер и миссия запустилась без проблем:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/01068717.png)

Обратите внимание на последний "jump". Мы перейдём на начало потока, что даёт возможность пройти миссию ещё раз. Если поставить в место неё опкод "0A93: end\_custom\_thread", то пройти миссию мы сможем только 1 раз за загрузку игры ( в том числе когда миссия провалена ), так что оставляем "jump".

Так по-немножку, мы подошли к стартерам. В следующем уроке мы подробнее рассмотрим стартеры, а именно будем учится запускать миссии по-очереди, делать что бы при завершении одной миссии открывались две новых и в таком духе. Материал достаточно сложный в освоении, так как нужно всегда всё держать в своей памяти.

Думаю основу создания cleo-миссий мы рассмотрели. Создайте несколько своих миссий. Тестируйте на здоровье :)|4071|1|0|01068717`png`600`375`400\`250\`\`||cleo\_missii|1499616943


# 00064. Работа со стартерами ( Cleo - Часть 1 )

Работа со стартерами ( Cleo - Часть 1 )|Мы продолжаем изучать стартеры и сегодня мы будем делать их для Cleo-миссий.|wmysterio|wmysterio||||Стартера отличаются от тех, что мы писали в мейне, так как мы не будем использовать глобальные переменные в качестве счетчика. Есть один опкод, который позволяет хранить потоки:

```
0A95: enable_thread_saving
```

Но я их не использую, так как он у меня не работает так как нужно. Где же выход? Как заставить миссии запускаться в каком-то порядке? Думаю вы видели мой старый мод "NFS GTA RACE". Там всегда миссии не повторялись после прохождения. Что бы и мы сделали подобное, нам необходимо хранить данные в файле. Давайте создадим ini-файл "MISSION.ini" в папке CLEO с таким содержимым:

```
ini
[MISSION_CJ]
markerID = 15 ; Здесь будет хранится номер иконки
MARKER_X_CJ = 2498.2966 ; Координата X сферы
MARKER_Y_CJ = -1684.5094 ; Координата Y сферы
MARKER_Z_CJ = 12.41 ; Координата Z сферы
MISSION_CJ_TOTAL = 0 ; Здесь будет хранится текущее количество пройденных миссий
```

Это необходимые данные для стартовой миссии. Как нам сделать, что бы при завершении одной миссии, начиналась вторая, третья и т.п? Ответ прост. Давайте сначала напишем простой код Cleo-миссии:

```
{$CLEO .CM}
//------------- mission ---------------
:mission
thread 'mission'
gosub @mission_29_57
if
wasted_or_busted
jf @mission_29_46
gosub @mission_29_144

:mission_29_46
$ONMISSION = 0
mission_cleanup
end_thread

:mission_29_57
increment_mission_attempts
$ONMISSION = 1
fade 1 1000
wait 1000
gosub @mission_END
00BA: show_text_styled GXT 'M_PASS' time 5000 style 1 // MISSION PASSED
0318: set_latest_mission_passed 'MISS_00' // GXT MISSION name
return

:mission_29_144
wait 0
gosub @mission_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 // MISSION FAILED
return

:mission_END
wait 0
return
```

Преимущество cleo-миссий ещё в том, что нам необязательно называть потоки разными именами, как это было в мейне. Можно всегда называть одним именем. Всёравно запуск идёт по названию файла :)

Как вы помните, в мейне мы использовали "$MISSION\_CJ\_TOTAL += 1", что бы указывать стартеру какую миссию запускать. В cleo-миссии нам предстоит запись в созданный ini-файл. Давайте сделаем запись в блоке, где миссия будет считаться пройденной:

```
//...
:mission_29_57
increment_mission_attempts
$ONMISSION = 1
fade 1 1000
wait 1000
gosub @mission_END
00BA: show_text_styled GXT 'M_PASS' time 5000 style 1 // MISSION PASSED
0318: set_latest_mission_passed 'MISS_00' // GXT MISSION name

0AF0: 0@ = get_int_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"
0@ += 1
0AF1: write_int 0@ to_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"

return

:mission_29_144
//...
```

Сначала мы считываем текущее количество пройденных миссий. Потом прибавляем ей 1 и в конце запишем новое значение в ту же секцию. Естественно мы могли бы напрямую записать значение, но тогда бы нам пришлось бы постоянно менять число ( количество пройденных миссий ), а это лишний геморрой. Так что оставляем именно такой вариант. Кроме этого в блоке провала миссии мы ничего не пишем, так как при провале данные ini-файла не изменятся.

Если вы хотите, что бы при выполнении миссии, позиция маркера переместилась, то используем запись в файл:

```
//...
:mission_29_57
increment_mission_attempts
$ONMISSION = 1
fade 1 1000
wait 1000
gosub @mission_END
00BA: show_text_styled GXT 'M_PASS' time 5000 style 1 // MISSION PASSED
0318: set_latest_mission_passed 'MISS_00' // GXT MISSION name
0AF0: 0@ = get_int_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"
0@ += 1
0AF1: write_int 0@ to_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"

0AF3: write_float -1446.6484 to_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MARKER_X_CJ"
0AF3: write_float 1502.4534 to_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MARKER_Y_CJ"
0AF3: write_float 1.7366 to_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MARKER_Z_CJ"

return

:mission_29_144
//...
```

"-1446.6484 1502.4534 1.7366" - наша новая точка и теперь маркер будет создаваться именно в этих координатах. Думаю вы заметили запись в ini-файле:

```
ini
markerID = 15 ; Здесь будет хранится номер иконки
```

Как вы думаете, зачем я добавил эту строчку в ини-файл? Правильно! Что бы мы могли менять иконки радара, то есть если мы прошли 3 миссии и хотим, что бы дальше появилась иконка незнакомца, то мы можем в коде выполнения третьей миссии записать новое значение номера меркера:

```
//...
:mission_3_29_57
increment_mission_attempts
$ONMISSION = 1
fade 1 1000
wait 1000
gosub @mission_3_END
00BA: show_text_styled GXT 'M_PASS' time 5000 style 1 // MISSION PASSED
0318: set_latest_mission_passed 'MISS_00' // GXT MISSION name
0AF0: 0@ = get_int_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"
0@ += 1
0AF1: write_int 0@ to_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"

0AF1: write_int 37 to_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "markerID"

return

:mission_3_29_144
//...
```

37 - наша новая иконка радара ( см. номера в [Иконки радара](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/ikonki_radara_dlja_gta_san_andreas/1-1-0-12/README.md)). Теперь осталось компилировать миссию и дать ей какое то имя. Допустим, её название будет "MIS\_001". Вы можете переместить её в папку "Cleo\Missions" или оставить так. В примерах я оставляю её в папке Cleo а вы уже можете перемещать их куда Вам нужно. Это дело вашей личной индивидуальности :)

Используя шаблон, давайте создадим ещё 4 Cleo-миссий ( их имена ,будут "MIS\_002", "MIS\_003", "MIS\_004" и "MIS\_005" ). Мы будем по очереди запускать миссии.

С миссиями разобрались. Нам осталось написать стартер. Он немного отличается от стартера в мейне, так как мы используем файл для хранения данных. Начнём! :)

Прежде всего нам нужно проверить - есть ли файл "MISSION.ini". Если его нет, то завершаем поток, так как без него будут сплошные проблемы и вылеты! Дальше проверим "Находится ли игрок на миссии?". Если да, то прыгаем на начало потока. Иначе создаём маркер, используя опкоды для ini-файлов. Так же здесь нужно проверить "Существует ли маркер?". Это нужно для того, что бы после прохождении миссии маркер удалялся. Вот текущий код:

```
{$CLEO}
0000:

:NAME
thread 'NAME'
wait 0
if
0AAB: file_exists "CLEO&#92;MISSION.ini"
jf @NAME_END
if
$ONMISSION == 0
jf @NAME
if
075C: marker 0@ enabled // проверка: "Маркер включен?"
then
marker.Disable(0@)
end

:NAME_1
wait 0
0AF0: 1@ = get_int_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "markerID"
0AF2: 2@ = get_float_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MARKER_X_CJ"
0AF2: 3@ = get_float_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MARKER_Y_CJ"
0AF2: 4@ = get_float_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MARKER_Z_CJ"
0@ = marker.CreateIconAndSphere(1@, 2@, 3@, 4@)

:NAME_END
wait 0
0A93: end_custom_thread
```

Дальше нам необходимо написать простенький цикл, в котором будут условия запуска миссий. Так же мы должны считать количество пройденных миссий CJ:

```
//...
:NAME_2
wait 0
// Считываем текущее количество пройденных миссий миссий:
0AF0: 5@ = get_int_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"
if AND
not actor.Dead($PLAYER_ACTOR)
not actor.Driving($PLAYER_ACTOR)
8A0C: not player $PLAYER_CHAR on_jetpack
8741: not actor $PLAYER_ACTOR busted // Это, наверное, самые используемые проверки в стартере :)
then
 if AND
 $ONMISSION == 0
 0102: actor $PLAYER_ACTOR in_sphere 2@ 3@ 4@ radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 00BE: text_clear_all
 03E6: remove_text_box
 fade 0 1000
 if
 5@ == 0 // проверяем: "количество пройденных миссий равно 0?"
 then
 00BA: show_text_styled GXT 'MISS_01' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_001"
 jump @NAME
 end
 if
 5@ == 1
 then
 00BA: show_text_styled GXT 'MISS_02' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_002"
 jump @NAME
 end 
 if
 5@ == 2
 then
 00BA: show_text_styled GXT 'MISS_03' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_003"
 jump @NAME
 end
 if
 5@ == 3
 then
 00BA: show_text_styled GXT 'MISS_04' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_004"
 jump @NAME
 end
 if
 5@ == 4
 then
 00BA: show_text_styled GXT 'MISS_05' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_005"
 jump @NAME
 end
 end 
end
jump @NAME_2
//...
```

Давайте взгяним на полную картину:

```
{$CLEO}
0000:

:NAME
thread 'NAME'
wait 0
if
0AAB: file_exists "CLEO&#92;MISSION.ini"
jf @NAME_END
if
$ONMISSION == 0
jf @NAME
if
075C: marker 0@ enabled
then
marker.Disable(0@)
end

:NAME_1
wait 0
0AF0: 1@ = get_int_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "markerID"
0AF2: 2@ = get_float_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MARKER_X_CJ"
0AF2: 3@ = get_float_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MARKER_Y_CJ"
0AF2: 4@ = get_float_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MARKER_Z_CJ"
0@ = marker.CreateIconAndSphere(1@, 2@, 3@, 4@)

:NAME_2
wait 0
0AF0: 5@ = get_int_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"
if AND
not actor.Dead($PLAYER_ACTOR)
not actor.Driving($PLAYER_ACTOR)
8A0C: not player $PLAYER_CHAR on_jetpack
8741: not actor $PLAYER_ACTOR busted
then
 if AND
 $ONMISSION == 0
 0102: actor $PLAYER_ACTOR in_sphere 2@ 3@ 4@ radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 00BE: text_clear_all
 03E6: remove_text_box
 fade 0 1000
 if
 5@ == 0
 then
 00BA: show_text_styled GXT 'MISS_01' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_001"
 jump @NAME
 end
 if
 5@ == 1
 then
 00BA: show_text_styled GXT 'MISS_02' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_002"
 jump @NAME
 end 
 if
 5@ == 2
 then
 00BA: show_text_styled GXT 'MISS_03' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_003"
 jump @NAME
 end
 if
 5@ == 3
 then
 00BA: show_text_styled GXT 'MISS_04' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_004"
 jump @NAME
 end
 if
 5@ == 4
 then
 00BA: show_text_styled GXT 'MISS_05' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_005"
 jump @NAME
 end
 end 
end
jump @NAME_2

:NAME_END
wait 0
0A93: end_custom_thread
```

Наш стартер готов! Теперь будут идти последовательно пять Cleo-миссий. :) Но есть один глюк. Когда игрок пройдет последнюю миссию, то появится иконка, став на которую ничего не произойдет. Что бы избежать появления такой "настойчивой" иконки нам жужно проверить количество пройденных миссий. Если пройдены все, то завершаем поток:

```
:NAME
thread 'NAME'
wait 0
if
0AAB: file_exists "CLEO&#92;MISSION.ini"
jf @NAME_END
if
$ONMISSION == 0
jf @NAME
if
075C: marker 0@ enabled
then
marker.Disable(0@)
end

0AF0: 5@ = get_int_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"
if
5@ > 4 // Это число должно быть равно количеству пройденных миссий. В нашем случаи 1+1+1+1=4
then
jump @NAME_END
end

:NAME_1
wait 0
//...
```

Теперь при прохождении последней миссии маркер появляться не будет. :) Если Вы написали ещё одну миссию, то добавить её в стартер не составляет проблем! Используйте этот шаблон:

```
if
5@ == 6 // 7, 8, 9 и так, пока не будет номер последней миссии
then
00BA: show_text_styled GXT 'MISS_06' time 1000 style 2 // 'MISS_07', 'MISS_08', 'MISS_09' указывайте названия для новых миссий
wait 1000
0A94: start_custom_mission "MIS_006" // MISS_07, MISS_08, MISS_09 указывайте имена миссий для запуска
jump @NAME
end
```

Этот кусок вставляйте сразу после завершения блока с подобными записями ( после "fade 0 1000" ). В следующем уроке мы рассмотрим запуск нескольких стартеров в Cleo.|1311|1|0||rabota\_so\_starterami\_cleo\_chast\_1|1499620646


# 00065. Работа со стартерами ( Cleo - Часть 2 )

Работа со стартерами ( Cleo - Часть 2 )|Очередная статья о том, как делать стартеры для Cleo-миссий. В ней мы научимся делать несколько стартеров, что бы в игрока был выбор миссий. Отличий от предыдущего урока немного, но всё же рассмотрим подробнее.|wmysterio|wmysterio||||Чтобы создать другой стартер, нам понадобится ini-файл из предыдущего урока. Допустим мы хотим добавить миссии OG-лока, которые можно выполнять параллельно с миссиями CJ. Открываем наш файл "MISSION.ini" и делаем новые сведения ( стартовые данные ):

```
ini
[MISSION_CJ]
markerID = 15
MARKER_X_CJ = 2498.2966
MARKER_Y_CJ = -1684.5094
MARKER_Z_CJ = 12.41
MISSION_CJ_TOTAL = 0

; Новые данные
[MISSION_OG]
markerID = 28
MARKER_X_OG = 2486.7156
MARKER_Y_OG = -1651.3683
MARKER_Z_OG = 12.4841
MISSION_OG_TOTAL = 0
```

Дальше мы должны написать сами миссии. Как и в предыдущем уроке мы, рассмотрим код миссии:

```
{$CLEO .CM}
//------------- mission ---------------
:mission
thread 'mission'
gosub @mission_29_57
if
wasted_or_busted
jf @mission_29_46
gosub @mission_29_144

:mission_29_46
$ONMISSION = 0
mission_cleanup
end_thread

:mission_29_57
increment_mission_attempts
$ONMISSION = 1
fade 1 1000
wait 1000
gosub @mission_END
00BA: show_text_styled GXT 'M_PASS' time 5000 style 1 // MISSION PASSED
0318: set_latest_mission_passed 'MISS_00' // GXT MISSION name

0AF0: 0@ = get_int_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_OG" key "MISSION_OG_TOTAL" //
0@ += 1 //
0AF1: write_int 0@ to_ini_file "CLEO&#92;MISSION.ini" section "MISSION_OG" key "MISSION_OG_TOTAL" //

return

:mission_29_144
wait 0
gosub @mission_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 // MISSION FAILED
return

:mission_END
wait 0
return
```

Пустыми комментариями выделено прибавление единицы к общему количеству пройденных миссий. Думаю вы заметили отличия: в место слова "CJ" написано "OG". Значит запись будет происходить в блок с информацией о "OG" в ini-файле. По-аналогии:

```
//Изменить положение маркера для миссий OG:
0AF3: write_float -1446.6484 to_ini_file "CLEO&#92;MISSION.ini" section "MISSION_OG" key "MARKER_X_OG"
0AF3: write_float 1502.4534 to_ini_file "CLEO&#92;MISSION.ini" section "MISSION_OG" key "MARKER_Y_OG"
0AF3: write_float 1.7366 to_ini_file "CLEO&#92;MISSION.ini" section "MISSION_OG" key "MARKER_Z_OG"
//Изменить номер маркера:
0AF1: write_int 37 to_ini_file "CLEO&#92;MISSION.ini" section "MISSION_OG" key "markerID"
```

Как видите, команды точно те же, что и для миссий CJ. И для этого стоило только поменять две буквы. Со стартерами точно также! Нам осталось поменять названия миссий:

```
{$CLEO}
0000:

:NAME_OG
thread 'NAME_OG'
wait 0
if
0AAB: file_exists "CLEO&#92;MISSION.ini"
jf @NAME_OG_END
if
$ONMISSION == 0
jf @NAME_OG
if
075C: marker 0@ enabled
then
marker.Disable(0@)
end
0AF0: 5@ = get_int_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_OG" key "MISSION_OG_TOTAL"
if
5@ > 4
then
jump @NAME_OG_END
end

:NAME_OG_1
wait 0
0AF0: 1@ = get_int_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_OG" key "markerID"
0AF2: 2@ = get_float_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_OG" key "MARKER_X_OG"
0AF2: 3@ = get_float_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_OG" key "MARKER_Y_OG"
0AF2: 4@ = get_float_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_OG" key "MARKER_Z_OG"
0@ = marker.CreateIconAndSphere(1@, 2@, 3@, 4@)

:NAME_OG_2
wait 0
0AF0: 5@ = get_int_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_OG" key "MISSION_OG_TOTAL"
if AND
not actor.Dead($PLAYER_ACTOR)
not actor.Driving($PLAYER_ACTOR)
8A0C: not player $PLAYER_CHAR on_jetpack
8741: not actor $PLAYER_ACTOR busted
then
 if AND
 $ONMISSION == 0
 0102: actor $PLAYER_ACTOR in_sphere 2@ 3@ 4@ radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 00BE: text_clear_all
 03E6: remove_text_box
 fade 0 1000
 if
 5@ == 0
 then
 00BA: show_text_styled GXT 'MISS_06' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_006"
 jump @NAME_OG
 end
 if
 5@ == 1
 then
 00BA: show_text_styled GXT 'MISS_07' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_007"
 jump @NAME_OG
 end 
 if
 5@ == 2
 then
 00BA: show_text_styled GXT 'MISS_08' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_008"
 jump @NAME_OG
 end
 if
 5@ == 3
 then
 00BA: show_text_styled GXT 'MISS_09' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_009"
 jump @NAME_OG
 end
 if
 5@ == 4
 then
 00BA: show_text_styled GXT 'MISS_10' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_010"
 jump @NAME_OG
 end
 end 
end
jump @NAME_OG_2

:NAME_OG_END
wait 0
0A93: end_custom_thread
```

Естественно стартер рассчитан на 5 миссий ( "MIS\_006", "MIS\_007", "MIS\_008", "MIS\_009" и "MIS\_010" ). Компилируем код под названием, например, "ST\_OG.CS". Скрипт со стартером для СЖ пусть будет "ST\_CJ.CS". Что бы появились оба маркера, нужно что бы эти скрипты были в папке "CLEO" вместе. Если всё правильно сделано, то старетры готовы. Можно выбирать миссию! :)

Но что, если нужно сделать так, что бы при прохождении 2-х миссий СЖ открывались миссии ОГ-лока?. Ответ очень просто. Нам нужно в стартере ОГ считать количество пройденных миссий СЖ и проверить больше ли это количество за нужное. Давайте сделаем написанное:

```
//...
:NAME_OG
thread 'NAME_OG'
wait 0
if
0AAB: file_exists "CLEO&#92;MISSION.ini"
jf @NAME_OG_END
if
$ONMISSION == 0
jf @NAME_OG
if
075C: marker 0@ enabled
then
marker.Disable(0@)
end

0AF0: 6@ = get_int_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"
if
6@ > 2 // проверяем "количество пройденных миссий CJ больше чем две?". Если нет, то прыгаем на начало потока
jf @NAME_OG

0AF0: 5@ = get_int_from_ini_file "CLEO&#92;MISSION.ini" section "MISSION_OG" key "MISSION_OG_TOTAL"
if
5@ > 4
then
jump @NAME_OG_END
end
//...
```

Готово! Теперь пока не будут пройдены две миссии СЖ, маркер OG не будет появляться. Если пройденны, то мы свободно можем проходить миссии Джефри. Вот такой не хитроумный способ. :) Как добавить в стартер новые миссии читайте в предыдущем уроке. Я напишу ещё один урок по стартерам, он будет не очень большой, но думаю будет полезен каждому новичку.|976|1|0||rabota\_so\_starterami\_cleo\_chast\_2|1499621277


# 00083. Запуск другого потока с Cleo-скрипта

Запуск другого потока с Cleo-скрипта|Сегодня мы научимся запускать Cleo-скрипты с других скриптов. Хотя точнее было бы сказать - запуск других потоков с Cleo-срипта.|wmysterio|wmysterio||||Всем привет! Начнём очередной урок по скриптингу. Наверное, Вы видели в файловом архиве мой скрипт "[Универсальная стрелка](https://github.com/wmysterio/scm-scripting-lessons/blob/main/load/gta_sa/cleo_i_asi_skripty/universalnaja_strelka_v1_0/68-1-0-528/README.md)", суть которого было облегчить жизнь скриптерам с удалением маркеров. Сегодня мы напишем похожий скрипт.

Начнём с того, что нам потребуется написать скрипт-запуск. Для примера, мы напишем скрипт "Бомба". Когда СЖ садится в машину и нажимает клавишу J`, то автомобиль будет заминирован. Когда игрок нажмёт клавишу <kbd>K` - произойдёт взрыв! Начнём с простенького - проверим находится ли игрок в машине и т.п.

```
{$CLEO}
0000:

while true
 if AND
 actor.Driving($PLAYER_ACTOR)
 0AB0: key_pressed 74 // J
 then
 // ... &#92;&#92;
 wait 2500
 end 
wait 0
end
```

Скрипт готов на 99%! Нам осталось написать только сам скрипт бомбы. Это значит нам нужно написать ещё один Cleo-скрипт, который будет имитировать взрыв, поэтому напишем его:

```
{$CLEO .s}
0000:

:BOMB
thread 'BOMB'
wait 0
1@ = 0

while car.Defined(0@)
 if
 0AB0: key_pressed 75 // K
 then
 1@ = 1
 break
 end 
wait 0
end

if
1@ == 1
then
car.StorePos(0@, 2@, 3@, 4@)
0565: create_soundless_explosion_at 2@ 3@ 4@ type 0 
0948: create_explosion_at 2@ 3@ 4@ type 0 camera_shake 1.0 
end

0A93: end_custom_thread
```

Обратите внимание на выражение:

```
{$CLEO .s}
```

В этом случае санник скомпилирует скрипт с расширением "\*.s" и загружатся скрипт вместе с игрой не будет. Назовём его "BOMB", что бы файл соответствовал названию файла ( для удобства ).

Суть скрипта проста: когда нажимаем кнопку K\` - переменной "1@" задаётся значение 1 и будет осуществлён выход с цикла командой "break". После этого обязательно ставим проверку на то, что переменная действительно равна единице, что бы выполнить блок со взрывом. Если это условие не выполняется, значит машина не существует и переменная "1@" никак не сможет изменить своё первоначальное значение.

От сюда и главный вопрос: как скрипт будет знать, что эта машина существует, если в скрипте нигде не создавалась она? Ответ кроется в запуске нашего скрипта бомбы. Чтобы запустить его, нужно воспользоваться опкодом.

```
0A92: create_custom_thread "BOMB.s"
```

Здесь:\
BOMB.s" - имя файла, что мы скомпилировали. Этот файл обязательно должен находится в папке "CLEO", иначе игра вылетит при попытке запуска

Так как же наш скрипт бомбы узнает о машине? Всё очень просто! К опкоду "0A92" нужно добавить параметр с переменной нашей машины. Для этого мы должны в скрипте-стартере получить машину игрока и передать эту переменную в опкод "0A92":

```
{$CLEO}
0000:
 
while true
 if AND
 actor.Driving($PLAYER_ACTOR)
 0AB0: key_pressed 74 // J
 then
 03C0: $CAR = actor $PLAYER_ACTOR car // получили хэндл тачки
 0A92: create_custom_thread "BOMB.s" $CAR // передаём её в другой поток
 0ACE: show_formatted_text_box "BOMB DETECTED!"
 wait 2500
 end 
wait 0
end
```

Из этого можно сделать вывод, что запуск нового потока осуществляется за принципом с scm-функциями. Передать можно до 34 параметров. Впрочем, эта возможность доступна и обычному "create\_thread" из "main.scm", но есть главная проблема...

Самое интересное то, что вызывать один и тот же поток можно очень много раз. В нашем скрипте-стартере доступна такая возможность. Мы можем сесть в машину и нажать кнопку J`, затем сесть в другую машину и снова нажать кнопку <kbd>J`. Обе машины будут "заминированы". После этого нужно нажать всего 1 раз кнопку K\`, как все машины, которые заминированы, будут взорваны! Но не всё так будет в мейне. Это и есть проблема. С запуском всё получится, но если сохраниться с активными двумя и больше потоками приведёт к вылету игры при загрузке, так как в мейне можно сохранять только 1 активный поток с тем же именем.

Вот вам небольшое задание: написать скрипт-стартер, который будет узнавать текущую машину игрока и написать скрипт, который будет осуществлять перекраску автомобиля. В качестве параметров должно быть машина и два параметра цвета, в который машина будет окрашена. Тоесть, нужно будет реализовать такой код запуска:

```
0A92: create_custom_thread "CARCOLOR.s" $CAR $CAR_CLOR1 $CAR_COLOR_2
```

|2059|1|0||zapusk\_drugogo\_potoka\_s\_cleo\_skripta|1499844974


# 00079. Немного о глобальных CLEO-переменных

Немного о глобальных CLEO-переменных|Всем привет! Сегодня мы поговорим о недавно сделанном обновлении - использование глобальных CLEO-переменных. Такие переменные используются в для обмена информации между CLEO-скриптами.|wmysterio|wmysterio||||Читать и записывать значения можно через их номера с помощью таких опкодов:

```
0AB3: var 0 = 10
0AB4: 0@ = var 0
```

Первый опкод указывает в какую переменную будет записано значение. В данном случаи в переменную 0 будет записано "10". Второй опкод, наоборот, получает значение переменной 0 и записывает результат в локальную переменную "0@". Диапазон номеров для переменных от 0 до 1023. Нужно учесть, что в номер можно записать с любого скрипта, поэтому нужно учесть и сторонние разработки, чтобы ваши скрипты нормально работали. Можно написать простые примеры скриптов с их использованием. Допустим первый скрипт будет в цикле записывать значения переменных. Второй их считывать и выводить на экран результат:

```
{$CLEO}
thread 'ONE'
wait 1500

for 0@ = 0 to 2000
0AB3: var 0 = 0@
wait 1000
end

0AB3: var 0 = -1
0A93: end_custom_thread
```

Второй скрипт:

```
{$CLEO}
thread 'TWO'
wait 2000

repeat
wait 0
0AB4: 0@ = var 0
0AD1: show_formatted_text_highpriority "%d" time 1 0@
until 0@ == -1

0A93: end_custom_thread
```

Наш результат таков: каждую итерацию глобальная переменная 0 прибавляет 1.

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/71903502.png)

Это достаточно полезная вещь, так как мы можем взаимодействовать между скриптами и менять их поведение. Вы можем обмениваться практически любыми данными ( не тестировал правда строки ). На этом всё, ждите новых уроков :)|2935|1|0|71903502`png`800`480`400\`240\`\`||nemnogo\_o\_globalnykh\_cleo\_peremennykh|1504600162


# 00066. Работа со стартерами ( Дополнительные условия )

Работа со стартерами ( Дополнительные условия )|Как вы уже догадались, речь пойдет опять о стартерах. Но на этот раз мы рассмотрим некоторые проверки, что бы разнообразить игру.|wmysterio|wmysterio||||Например проверки, связанные со временем или когда СЖ стоит на маркере, то ему пишет "Приходи с 17:00 до 20:00". Сделать эту проверку не очень сложно, но для начала нам необходимо создать GXT-запись с нужным текстом. Вот я например создал такую:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/44808415.png)

Обратите внимание на код "~~1~~". Такая запись значит, что в тексте будет число, которые указывается в опкоде. Как видите таких кодов у нас два, то есть из опкодов будет взято два числа и выведено их на экран. Числа естественно будут наши :)

Сохраняем нашу GXT-запись и начинаем писать стартер. Я возьму самый простой, на одну миссию, но можете использовать пример в своих "больших стартерах":

```
{$CLEO}
0000:

:NAME_OG
thread 'NAME_OG'
wait 0
if
$ONMISSION == 0
jf @NAME_OG
0@ = marker.CreateIconAndSphere(15, 2486.9573, -1656.5065, 13.3479)

:NAME_OG_2
wait 0
if AND
not actor.Dead($PLAYER_ACTOR)
not actor.Driving($PLAYER_ACTOR)
8A0C: not player $PLAYER_CHAR on_jetpack
8741: not actor $PLAYER_ACTOR busted
then
 if AND
 $ONMISSION == 0
 0102: actor $PLAYER_ACTOR in_sphere 2486.9573 -1656.5065 13.3479 radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 00BF: $TIME_HOURS = current_time_hours, $TIME_MINS = current_time_minutes
 if AND
 $TIME_HOURS > 16
 21 > $TIME_HOURS
 then 
 00BE: text_clear_all
 03E6: remove_text_box
 fade 0 1000
 00BA: show_text_styled GXT 'MISS_01' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_001"
 jump @NAME_OG
 else
 02FD: show_text_2numbers_lowpriority GXT 'GAM_TIM' numbers 17 20 time 1 flag 1 // Приходи с ~1~:00 по ~1~:00
 end
 end 
end
jump @NAME_OG_2
```

Вот, что в нас вышло:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/88216873.png)

Рассмотрим опкод:

```
00BF: $TIME_HOURS = current_time_hours, $TIME_MINS = current_time_minutes
```

Он запиcывает в переменную "$TIME\_HOURS" текущий час а в "$TIME\_MINS" - текущую минуту. Так, как нужен только час, проверяем его: если час больше за 16 и если он меньше за 21, то мы получим диапазон допустимого времени: с 17 до 20. Если условия срабатывают, то запускаем миссию. Иначе пишем, что что нужно придти в нужное время опкодом:

```
02FD: show_text_2numbers_lowpriority GXT 'GAM_TIM' numbers 17 20 time 1 flag 1 // Приходи с ~1~:00 по ~1~:00
```

Здесь:\
GAM\_TIM' - указываем GXT-запись с текстом\
17 20 - указываем номера для кода теста с \~1\~ \~1\~. Как видите опкод выводит на экран 2 числа - те, что мы указали в поле "numbers"\
1 - указываем время. Если мы укажем больше, то когда СЖ выйдет за пределы маркера, текст всё равно будет указывать на нужное время, а это естественно будет раздражать\
1 - флаг так и оставляйте. Я точно не знаю за что он отвечает

Как видите мы можем использовать здесь 2 числа ( **2numbers** ). Максимальное количество выводимых чисел в опкодах я видел **6**:

```
0308: show_text_6numbers GXT 'HJSTAT' numbers 1 2 3 4 5 6 time 5000 flag 5 // Distance: ~1~.~1~m Height: ~1~.~1~m Flips: ~1~ Rotation: ~1~
```

Важно запомнить, что числа мы пишем в опкоде, а GXT-записи указываем код ~~**1**~~. Со временем, думаю, разберётесь. Давайте ещё напишем условие, что бы миссия запускалась в определённый день! Начнем с создании GXT-записи:

![](https://github.com/wmysterio/scm-scripting-lessons/blob/main/_pu/0/33970220.png)

То есть, миссия будет запускаться только в воскресенье. Считаем текущий день недели, и пишем условие:

```
{$CLEO}
0000:

:NAME_OG
thread 'NAME_OG'
wait 0
if
$ONMISSION == 0
jf @NAME_OG
0@ = marker.CreateIconAndSphere(15, 2486.9573, -1656.5065, 13.3479)

:NAME_OG_2
wait 0
if AND
not actor.Dead($PLAYER_ACTOR)
not actor.Driving($PLAYER_ACTOR)
8A0C: not player $PLAYER_CHAR on_jetpack
8741: not actor $PLAYER_ACTOR busted
then
 if AND
 $ONMISSION == 0
 0102: actor $PLAYER_ACTOR in_sphere 2486.9573 -1656.5065 13.3479 radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 07D0: $WEEKDAY = weekday
 if
 $WEEKDAY == 1
 then 
 00BE: text_clear_all
 03E6: remove_text_box
 fade 0 1000
 00BA: show_text_styled GXT 'MISS_01' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_001"
 jump @NAME_OG
 else
 00BB: show_text_lowpriority GXT 'GAM_WEE' time 3000 flag 1 // Приходи в воскресенье!
 end
 end 
end
jump @NAME_OG_2
```

Как вы уже догадались, опкод "07D0" заносит переменную текущий день недели. Дальше мы проверяем "День недели == воскресенье?" Если да, то начинаем миссию, иначе пишем, что нужно придти в нужный день. Как видите, номера дней обозначаются номерами. Вот список всех номеров дней:

| ID | День        |
| -- | ----------- |
| 1  | воскресенье |
| 2  | понедельник |
| 3  | вторник     |
| 4  | среда       |
| 5  | четверг     |
| 6  | пятница     |
| 7  | суббота     |

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/79261097.png)

Эти условие будут действовать как main.scm, так и Cleo. Мы рассмотрели только некоторые условия, но вы можете добавить свои. Я, например, в одном скрипте видел условие: "Если СЖ в танке и находится на высоте больше 300.0 то запустить миссию". Даже такие бывают )))

Думаю цикл по стартерам можно завершать. Я вам дал необходимую информацию по запуску. Возможно я ещё вернусь к стартерам в ближайшем будущем.|944|1|0|88216873`png`600`360`400`240``\|33970220`png`343`192

```
`\|79261097`png`600`375`400`250``\|44808415`png`441`348`400`315``\||rabota_so_starterami_dopolnitelnye_uslovija|1499622692
```


# 000137. Группы в GTA San Andreas

Группы в GTA San Andreas|Всем привет! В этот юбилейный, сотый урок по скриптингу GTA SA от меня, я хотел-бы посвятить группам, известные Вам ещё как банды.|wmysterio|wmysterio||||Максимальное количество людей в банде составляет 8 человек. Создаётся группа следующим опкодом:

```
062F: 0@ = create_group_type 0
```

Здесь:\
0@ - имя группы\
0 - тип группы. Я пока не разобрался что значит этот параметр

Группа всегда состоит из её лидера и людей, слушающихся его. Для добавления лидера в группу существует опкод:

```
0630: put_actor 1@ in_group 0@ as_leader
```

Здесь:\
1@ - актёр, который будет лидером\
0@ - имя группы

Чтобы добавить члена группы, нужно использовать опкод:

```
0631: put_actor 2@ in_group 0@
```

Здесь:\
2@ - актёр, который подчиняется лидеру\
0@ - имя группы

Дать группе соответствующие команды:

```
07B3: set_group 0@ give_command 2
```

Здесь:\
0@ - имя группы\
2 - команда группе ( см. таблицу ниже )

| Номер | Описание                                                                                                                                                                                                               |
| ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 0, 1  | Следовать за лидером, пока не знаю чем отличаются типы 0 и 1                                                                                                                                                           |
| 2, 4  | Тупо стоят                                                                                                                                                                                                             |
| 3     | Члены группы будут жестикулировать руками, общаються в общем между собой                                                                                                                                               |
| 5     | Самая интересная на мой взгляд команда - лидер начинает набирать ближайших пешеходов себе в банду. Собирает примерно 6-7 человек, но не больше и подбирает, я так заметил людей, которые имеют одинаковый тип пешехода |

Также можно приказать группе садится в транспорт лидера группы:

```
0940: set_group 0@ enters_leaders_vehicle 1
```

Здесь:\
0@ - имя группы\
1 - будут садится, 0 - запретить садится

Чтобы выгнать актёра из группы, используем:

```
06C9: remove_actor 1@ from_group
```

Можно распустить группу опкодом:

```
0632: release_group 0@
```

Обычно ещё задают группе максимальный лимит дистанции от лидера:

```
06F0: set_group 0@ distance_limit_to 30.0
```

Здесь:\
0@ - имя группы\
30.0 - максимальная дистанция<br>

Среди проверок можно отметить следующие:

```
06EE: actor 1@ in_group 0@ // Актёр 1@ в группе 0@?
06EF: actor 1@ leading_group 0@ // Актёр является лидером группы?
07FD: group 0@ alive // Группа существует?
```

Давайте напишем простенький скрипт, где возле игрока будет создаваться группа. Лидер будет набирать людей к себе в банду.

```
{$CLEO}
04C4: store_coords_to 10@ 11@ 12@ from_actor $PLAYER_ACTOR with_offset -2.0 2.0 0.0
04C4: store_coords_to 13@ 14@ 15@ from_actor $PLAYER_ACTOR with_offset 0.0 2.0 0.0
04C4: store_coords_to 16@ 17@ 18@ from_actor $PLAYER_ACTOR with_offset 2.0 2.0 0.0
0376: 1@ = create_random_actor_at 10@ 11@ 12@
0376: 2@ = create_random_actor_at 13@ 14@ 15@
0376: 3@ = create_random_actor_at 16@ 17@ 18@
062F: 0@ = create_group_type 0
0630: put_actor 1@ in_group 0@ as_leader
0631: put_actor 2@ in_group 0@
0631: put_actor 3@ in_group 0@
07B3: set_group 0@ give_command 5 // даём группе команду
0A93: end_custom_thread
```

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/95563313.png)

На этом урок окончен. Спасибо, что не поленились почитать этой материал :)|1615|1|0|95563313`png`500`281`400\`224\`\`||gruppy\_v\_gta\_san\_andreas|1504593040


# 00098. Последовательность в анимации

Последовательность в анимации|Всем привет! С вами wmysterio! Сейчас поговорим детальнее об анимации. Существует целый ряд опоков, связанных с ними, но остановлюсь я на последовательностях или так называемых AS-паках ( action sequences ).|wmysterio|wmysterio||||Перейдём к опкодам.

```
0615: define_AS_pack_begin $ActSeq // Создаёт начало экшн-пака
0616: define_AS_pack_end $ActSeq // Создаёт конец экшн-пака
```

Заставить выполнять актёра последовательность анимации можно с помощью опкода:

```
0618: assign_actor $0@ to_AS_pack $ActSeq
```

Здесь:\
0@ - хендл, актёра\
$ActSeq - естественно имя AS-пака

Заставить выполнять последовательность анимации целую группу можно с помощью опкода:

```
087D: assign_group $PLAYER_GROUP to_AS_pack $ActSeq
```

Здесь:\
$PLAYER\_GROUP - группа, что будет вкалывать :)\
$ActSeq - имя AS-пака<br>

Следующий опкод выгружает последовательность:

```
061B: remove_references_to_AS_pack $ActSeq
```

Между опкодами "0615" и "0616" пишутся списки анимаций, которые будут выполняться последовательно. Для примера, я взял "3" анимации, которые актёр будет выполнять:

```
0605: actor -1 perform_animation_sequence "BOM_PLANT_IN" from_file "BOMBER" 4.0 loop 0 0 0 1 -1
0605: actor -1 perform_animation_sequence "BOM_PLANT_LOOP" from_file "BOMBER" 4.0 loop 0 0 0 0 -1
0605: actor -1 perform_animation_sequence "BOM_Plant_2Idle" from_file "BOMBER" 4.0 loop 0 0 0 0 -1
```

× \*\*Примечание:\*\* нужно именовать актёра именно как -1, так как мы будем передавать указатель актёра опкодом 0618. Если нужно более длительно выполнять анимацию, то пишут время в место -1

В этот список можно указывать анимации с любых IFP-файлов ( даже разных ), главное их загрузить перед процессом выполнения. Перейдём к скриптам. Давайте создадим экшн-пак, и заставим актёра выполнять его:

```
{$CLEO}
0000:

:SEQ
thread 'SEQ'
wait 5000
04ED: load_animation "BOMBER"
model.Load(#WMYDRUG)
038B: load_requested_models

:SEQ_1
wait 0
if and
04EE: animation "BOMBER" loaded
model.Available(#WMYDRUG)
jf @SEQ_1

0615: define_AS_pack_begin $ActSeq
0605: actor -1 perform_animation_sequence "BOM_PLANT_IN" from_file "BOMBER" 4.0 loop 0 0 0 1 -1
0605: actor -1 perform_animation_sequence "BOM_PLANT_LOOP" from_file "BOMBER" 4.0 loop 0 0 0 0 8000
0605: actor -1 perform_animation_sequence "BOM_Plant_2Idle" from_file "BOMBER" 4.0 loop 0 0 0 0 -1
0616: define_AS_pack_end $ActSeq

04C4: store_coords_to 1@ 2@ 3@ from_actor $PLAYER_ACTOR with_offset 0.0 5.0 -1.0
4@ = actor.Angle($PLAYER_ACTOR)
4@ += 180.0
0@ = actor.Create(5, #WMYDRUG, 1@, 2@, 3@)
model.destroy(#WMYDRUG)
actor.Angle(0@) = 4@
0618: assign_actor $0@ to_AS_pack $ActSeq
0AD0: show_formatted_text_lowpriority "ežo¢ek ¢¨£ož®¬e¦ £ocžešo¢a¦ež©®oc¦© a®œ¯a œœ." time 4000
wait 4000
0AD0: show_formatted_text_lowpriority "­eže™ko e¯y :)" time 4000
wait 4000
061B: remove_references_to_AS_pack $ActSeq
04EF: release_animation "BOMBER"
0A93: end_custom_thread
```

В результате наш актёр выполняет указанные анимации:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/64667491.png)

Если вы искали в поисковике опкодов воспроизведение анимации актёра, то наверняка вы сталкивались с сутуацией, когда находило целых три опкода. Вот эти:

```
0605: actor $PLAYER_ACTOR perform_animation_sequence "phone_talk" IFP_file "PED" 4.0 loop 0 0 0 0 time 2000 // versionA
0812: AS_actor $PLAYER_ACTOR perform_animation "phone_talk" IFP_file "PED" 4.0 loopA 0 lockX 0 lockY 0 lockF 0 time 2000 // versionB
0A1A: actor $PLAYER_ACTOR perform_animation "phone_talk" IFP_file "PED" 4.0 loopA 0 lockX 0 lockY 0 lockF 0 2000 ms // versionC
```

Возникают вопросы: Почему? С какой целью разработчики сделали это? В чем разница? Я покопался и интернете и, кажется, нашел ответ: эти версии создавались для различных ситуаций с актёрами и вела себя, соответственно, от состояния актёра.

| Версия | Описание                                                                                                                                                                                                      |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| A      | Анимация будет останавливаться, когда актёра ударили, выстрелили в него или когда нужно выполнять анимации, запрограммированных в EXE-шнике.                                                                  |
| B      | Анимация будет проигрываться, в независимо от ситуации. Чаще используется в AS-паках. Вообще все опкоды с приставкой AS используются в основном в последовательностях, причем не только анимационные команды. |
| C      | Позволяет актёру двигаться, выполняя анимацию. Прерывается, когда актёр прыгает, падает, плывёт.                                                                                                              |

Я, правда, остаюсь верным опкоду "0605" :)

Рассмотрим так же опкоды, которые привлекли моё внимание:

```
0611: actor $PLAYER_ACTOR performing_animation "phone_talk"
```

Проверка: "Выполняет ли актёр $PLAYER\_ACTOR анимацию 'phone\_talk'?".

```
0613: 26@ = actor $PLAYER_ACTOR animation "phone_talk" time
```

Заносит в переменную "26@" время выполнения актёром "$PLAYER\_ACTOR" анимации "phone\_talk".

```
0614: set_actor $PLAYER_ACTOR animation "phone_talk" progress_to 2@ // 0.0 to 1.0
```

Устанавливает прогресс выполения актёром "$PLAYER\_ACTOR" анимации "phone\_talk".

Здесь:\
2@ - дробное число от 0.0 до 1.0. Например, если нам нужно, что бы актёр начал выполнять анимацию не сначала а с середины, то устанавливают анимации прогресс в 0.5.

Пример использования:

```
0605: actor $PLAYER_ACTOR perform_animation_sequence "phone_talk" IFP_file "PED" 4.0 loop 0 0 0 0 time 2000 // versionA
0614: set_actor $PLAYER_ACTOR animation "phone_talk" progress_to 0.5
```

Опкод записывает общее время воспроизведения актёром "$PLAYER\_ACTOR" анимации "phone\_talk" в переменную "23@":

```
061A: get_actor $PLAYER_ACTOR animation "phone_talk" total_time_to 23@
```

Есть ещё этот:

```
0612: set_actor $PLAYER_ACTOR animation "phone_talk" paused 0
```

По-идеи, опкод должен ставить анимацию на паузу и продолжать воспроизведение, однако он у меня как-то неадекватно ведёт себя, а точнее, вообще никакой реакции :) Что-же, урок подошел к концу. Надеюсь мои находки будут для вас новыми и интересными ;)|2170|1|0|64667491`png`600`337`400\`224\`\`||posledovatelnost\_v\_animacii|1504463144


# 000120. Пути пешеходов и анимационные пути

Пути пешеходов и анимационные пути|Всем хай! С вами wmysterio! Относительно недавно мне удалось разобраться в путях пешеходов и научить актёров ходить по нужным точкам.|wmysterio|wmysterio||||Как я понял, есть несколько вариантов это организовать. Во-первых, через scm-пути. Следующие опкоды делают это:

```
05D6: clear_scmpath // Очищает ранее созданные scm-пути
05D7: add_point_to_scmpath 372.0 -120.1 1000.5 // Добавляет новую точку в scm-путь
05D8: AS_assign_scmpath to_actor 0@ flags 6 0 // Заставляет актёра двигаться по маршруту
07E7: AS_assign_scmpath_to_actor -1 in_car 0@ speed 25.0 flags 1 0 1 // Заставляет актёра двигаться по маршруту в транспорте
```

Как правило, указывают несколько точек, чтобы построить маршрут. Флаги для опкодов 05D8 и 07E7 мне пока не известны.

Во-вторых: через анимационные пути. Это вариант мне понравился больше, так как предыдущий как-то некорректно работает ( актёры двигаются стразу в последнюю точку, игнорируя остальные, во всяком случаи это было так раньше ). Давайте знакомится! Первый опкод создаёт новый анимационный путь, очищая все остальные:

```
0754: define_new_animation_path
```

Дальше идёт перечисление точек маршрута и анимации воспроизведения:

```
0755: add_animation_path_3D_coord -2699.4812 92.5335 4.3359 animation "NONE" IFP_file "NONE"
```

Здесь:\
-2699.4812 92.5335 4.3359 - координаты новой точки\
"NONE" - название IFP-файла и имени анимации. Если нам не нужно ничего воспроизводить, то оставляем "NONE"

Чтобы заставить актёра идти по этому пути, нужно использовать следующий опкод:

```
0817: assign_actor 0@ to_animation_path_with_walk_mode 4 route_mode 3
```

Здесь:\
0@ - хэндл актёра\
4 - режим походки актёра\
3 - режим маршрута

Я не вникал в параметры режимов, поэтому оставляю те, что были. Особенность этих параметров в том, что они заставляют актёра идти по кругу. Как только актёр достиг последней точки, он возвращается в первую и начинает маршрут сначала. Таким образом, можно использовать это в миссиях: актёры могут выступают в качестве охранников территории. Вот простой пример:

```
{$CLEO}
0000: NOP
actor.PutAt($PLAYER_ACTOR, -2706.4333, 101.8569, 4.1797)
Model.Load(#WBDYG1)
038B: load_requested_models
01EB: set_traffic_density_multiplier_to 0.0
03DE: set_pedestrians_density_multiplier_to 0.0
0395: clear_area 0 at -2699.7943 116.97724.336 radius 300.0
3@ = Actor.Create(Mission1, #WBDYG1, -2699.4812, 92.5335, 4.3359)
model.Destroy(#WBDYG1)
Actor.Angle(3@) = 358.83
0754: define_new_animation_path
0755: add_animation_path_3D_coord -2699.4812 92.5335 4.3359 animation "NONE" IFP_file "NONE"
0755: add_animation_path_3D_coord -2712.856 92.3864 4.3359 animation "NONE" IFP_file "NONE" 
0755: add_animation_path_3D_coord -2712.6179 116.1146 4.3359 animation "NONE" IFP_file "NONE"
0755: add_animation_path_3D_coord -2699.7942 116.9771 4.3359 animation "NONE" IFP_file "NONE" 
0817: assign_actor 3@ to_animation_path_with_walk_mode 4 route_mode 3
0A93: end_custom_thread
```

Результат: актёр двигается по нужным координатам:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/04086996.png)

Вот такой неожиданный для меня урок сочинился. Надеюсь, Вам он пригодится в Ваших модах :)|1944|1|0|04086996`png`600`337`400\`224\`\`||puti\_peshekhodov|1504589559


# 000178. RRR-файлы в GTA SA. Как их делать и использовать-

RRR-файлы в GTA SA. Как их делать и использовать?|В этом уроке мы познакомимся с очередным типом файлов. Научимся их создавать и использовать в игре.|wmysterio|wmysterio||||Привет, друзья! Сегодня мы будем изучать файлы путей автомобилей, которые имеют расширение "RRR". Эти файлы являются бинарными и обычно хранятся в IMG-архиве за адресом:

X:\GTA SA\data\Paths\carrec.img

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

Вот для таких случаев часто и создают RRR-файлы, которые хранят все точки маршрута со всеми углами машины, параметрами двигателя, моменты когда она притормаживает и всё в таком духе. В итоге мы имеем так называемый "Playback record", который мы будем называть маршрутом.

Главный недостаток ( а иногда и преимущество ), что автомобиль теряет физические свойства. Иными словами будет выполнять воспроизведение маршрута в таком виде, в котором он был записан. Если между точками находятся автомобили или другие объекты, то машина будет проходить сквозь них, а другой транспорт будет отскакивать, как от поезда.

Для начала научимся создавать путь. Для этого часто используют старенький скрипт от Seemann'а, который имеет название [Carrec.cs](https://github.com/wmysterio/scm-scripting-lessons/blob/main/data_base/sa/carrec.rar). Его желательно открыть ( исходники прилагаются ) и настроить под себя. В основном нужно настраивать 3 параметра:

| Константа         | Значение                                                                                                                    |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------- |
| REC\_INTERVAL\_MS | Отвечает за то, как часто будет делаться новая запись точки маршрута. Чем значение меньше, тем чаще будет добавлятся точка. |
| FILE\_PATH        | Путь к выходному файлу.                                                                                                     |
| KEY\_REC          | Код клавиши, которая запускает и останавливает запись маршрута ( в сочетании с клавишей Shift\` )                           |

Скрипт работает по следующему принципу: садимся в нужный транспорт, нажимаем клавиши Shift`+<kbd>R`. Далее начинаем ехать как и куда Вам угодно. Скрипт будет записывать точки маршрута. Когда нужно остановится, нажимаем эту комбинацию клавиш ещё раз и путь готов!

× \*\*ВАЖНО:\*\* имя файла обязательно должно содержать числа, больше за ноль! Рекомендую сначала проверить доступность имени в архиве ( нужно, чтобы такого файла небыло ), чтобы случайно не перезаписать существующий файл.× \*\*Примечание:\*\* рекомендую для записи маршрута использовать тот же транспорт, что Вы планируете создавать в скрипте. Иначе могут быть нестыковки.

Для успешной загрузки такого пути, нам необходимо добавить его в "carrec.img" спомощью любого IMG-редактора. Ну и с конце писать скрипт. Рассмотрим базовые опкоды для работы с RRR-путями:

```
// Загружает путь
07C0: load_path 908

// Проверка: путь загрузился?
07C1: path 908 available

// Выгружает путь с памяти
0873: release_path 908
```

908 в этом случае является именем файла, поэтому всегда сохраняйте файлы с числовым именем, как уже было сказано выше. После этого мы можем заставить транспорт воспроизвести наш путь следующими опкодами:

```
// Машина будет ехать по загруженному пути:
05EB: assign_car $hCar to_path 908

// Машина будет ехать по загруженному пути.
// Как только путь достигнет конца, воспроизведение начнётся сначала
085E: assign_car $hCar to_looped_path 908

// Проверка: транспорт едет по какому-то пути?
060E: car $hCar assigned_to_path

// Установить скорость воспроизведения пути. Значения могут быть от 0.0 до 1.0!
// Увы, маршрут по времени выполнения будет чуть быстрее, поэтому лучше устанавливать
// скорость, которая будет более-менее соответствовать скорости в момент записи пути.
06FD: set_car $hCar speed_on_path_to 1.0

// Пропускает маршрут. Я не тестировал этот опкод, но догадываюсь, что значение 1.0
// отвечает за позицию, в которой остановить машину ( по времени выполнения ).
// Значения могут быть от 0.0 до 1.0!
0706: advance_car $hCar further_along_path 1.0

// Останавливает воспроизведение маршрута и устанавливает его в конец пути по времени.
06C5: release_car $hCar from_path
```

Поскольку маршрут сам по себе является "записью воспроизведения", скорость мы приравниваем к общей длительности маршрута. Это дополнительно позволяет нам использовать опкоды, которые бывают пелезными при определённых обстоятельствах:

```
// Окончательно останавливает воспроизведение маршрута
05EC: release_car $hCar from_path

// Приостанавливает воспроизведение маршрута ( ставит на паузу )
05ED: freeze_car $hCar while_on_path

// Продолжает воспроизведение маршрута ( отмена паузы )
05EE: unfreeze_car $hCar while_on_path
```

Следующие опкоды я не тестировал, поэтому их описания могут быть неточными:

```
// Воспроизводит путь, но управление осуществляется с помощью искусственного интеллекта
0705: car $hCar assign_to_path 908 and_drive_normal

// Изменяет способ воспроизведения со строгого на искусственный интеллект
099B: unknown_enable_car $hCar collision_on_path
```

Здесь важно отметить, что воспроизведение маршрута перемещает машину в позицию первой точки пути, поэтому для более плавного перехода лучше создавать машину в тех же координатах.

Ну и, наконец, пример скрипта, где машина будет ехать по записанному маршруту:

```
{$CLEO}

// ! Нужно создать путь 900

:PATH
thread 'PATH'
wait 5000
Model.Load(#COMET) 
07C0: load_path 900
038B: load_requested_models

:PATH_CHECK1
wait 0
if and 
Model.Available(#COMET) 
07C1: path 900 available
jf @PATH_CHECK1 
0@ = Car.Create(#COMET, -1596.8551, -1604.5587, 35.8839)
Car.Angle(0@) = 293.6649 
0430: put_actor $PLAYER_ACTOR into_car 0@ passenger_seat 0 
Model.Destroy(#COMET)
05EB: assign_car 0@ to_path 900
06FD: set_car 0@ speed_on_path_to 0.97

:PATH_CHECK2
wait 0
if
8256: not player $PLAYER_CHAR defined
then
jump @PATH_CAR_CLEAR
end
if
856E: not car 0@ defined
then
jump @PATH_RELEASE
end
if or
00DB: actor $PLAYER_ACTOR in_car 0@
01C1: car 0@ stopped
then
jump @PATH_CAR_CLEAR
end
jump @PATH_CHECK2 

:PATH_CAR_CLEAR
if
056E: car 0@ defined
then 
06C5: release_car 0@ from_path
Car.RemoveReferences(0@)
end

:PATH_RELEASE
0873: release_path 900
0A93: end_custom_thread
```

Этим способом я делал гонки для мода '[Проект "Неизвестный": Чёрный список](https://github.com/wmysterio/scm-scripting-lessons/blob/main/load/gta_sa/globalnye_mody/proekt_neizvestnyj_chjornyj_spisok/82-1-0-695/README.md)', где соперник использовал путь, тем самым его "интеллект" был намного выше, чем могли бы быть без такого маршрута:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/38913452.png)

Надеюсь, этот материал был для Вас полезным. На этом у меня всё. С Вами попрежднему - wmysterio.|1125|1|0|38913452`png`640`359`320\`180\`\`||rrr\_fajly\_v\_gta\_sa\_kak\_ikh\_delat\_i\_ispolzovat|1510794350


# 000180. Длинные последовательности в анимации

Длинные последовательности в анимации|В этом уроке мы продолжим изучение AS Pack-ов и рассмотрим ситуацию когда последовательность анимаций нужно сделать более длинной.|wmysterio|wmysterio||||Привет, друзья! Из названия и описания ясно, что речь пойдёт о последовательности анимаций. Ранее уже был создан урок о [AS Pack-ах](https://github.com/wmysterio/scm-scripting-lessons/blob/main/publ/gta_sa/obucheniye_skriptinga/posledovatelnost_v_animacii/34-1-0-156/README.md), но некоторая часть информации ещё не рассказана.

В другом уроке я не упомянул, что есть определённый лимит на количество действий, способных воспроизводится AS Pack-ом. А точнее, что там нет конкретно-установленного лимита. В одному случае всё выполняется как надо. В другом - останавливается в каком-то моменте. Из за этого нельзя однозначно сказать сколько анимаций или действий можно выполнить в одном экшн-паке.

Из за этой неопределённости делать длинные последовательности не рекомендуется. Но что делать, если нам действительно нужна длинная последовательность?

На самом деле мы можем сделать огромную последовательность и зависеть она будет разве что от количества переменных. Принцип работы заключается в том, что мы можем запускать другую последовательность прямо внутри текущей последовательности. Этот приём использовался в оригинальном MIAN.SCM. Пора и нам научится его использовать!

Алгоритм действий таков: мы пишем всю последовательность целиком. Например: вот такую последовательность я написал:

```
07CD: AS_actor -1 walk_to 2467.3425 -1650.9974 13.4712 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2465.1921 -1667.502 13.4712 stop_with_angle 167.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2432.071 -1666.8909 13.5352 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2393.261 -1666.8276 13.478 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2351.2043 -1667.8103 13.5469 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2350.5696 -1695.3361 13.4435 stop_with_angle 180.0 within_radius 1.0 
07CD: AS_actor -1 walk_to 2467.3425 -1650.9974 13.4712 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2465.1921 -1667.502 13.4712 stop_with_angle 167.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2432.071 -1666.8909 13.5352 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2393.261 -1666.8276 13.478 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2351.2043 -1667.8103 13.5469 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2350.5696 -1695.3361 13.4435 stop_with_angle 180.0 within_radius 1.0 
07CD: AS_actor -1 walk_to 2506.5393 -1682.7019 13.5469 stop_with_angle 308.3229 within_radius 1.0 
07CD: AS_actor -1 walk_to 2511.791 -1662.2334 13.5868 stop_with_angle 36.3705 within_radius 1.0
07CD: AS_actor -1 walk_to 2496.2747 -1651.3385 13.4905 stop_with_angle 78.3575 within_radius 1.0
05BE: AS_actor -1 die
```

Если мы попытаемся "запихнуть" всё это в один пак, то есть вероятность, что актёр так и не выполнит все действия и остановится в некий момент. Это происходит не всегда, но часто.

Чтобы всё работало как надо и перестраховаться, мы должны разделить анимации по группам, например, по 6 задач:

```
// START BLOCK #1
07CD: AS_actor -1 walk_to 2467.3425 -1650.9974 13.4712 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2465.1921 -1667.502 13.4712 stop_with_angle 167.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2432.071 -1666.8909 13.5352 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2393.261 -1666.8276 13.478 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2351.2043 -1667.8103 13.5469 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2350.5696 -1695.3361 13.4435 stop_with_angle 180.0 within_radius 1.0 
// END BLOCK #1

// START BLOCK #2
07CD: AS_actor -1 walk_to 2467.3425 -1650.9974 13.4712 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2465.1921 -1667.502 13.4712 stop_with_angle 167.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2432.071 -1666.8909 13.5352 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2393.261 -1666.8276 13.478 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2351.2043 -1667.8103 13.5469 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2350.5696 -1695.3361 13.4435 stop_with_angle 180.0 within_radius 1.0 
// START BLOCK #2

// START BLOCK #3
07CD: AS_actor -1 walk_to 2506.5393 -1682.7019 13.5469 stop_with_angle 308.3229 within_radius 1.0 
07CD: AS_actor -1 walk_to 2511.791 -1662.2334 13.5868 stop_with_angle 36.3705 within_radius 1.0
07CD: AS_actor -1 walk_to 2496.2747 -1651.3385 13.4905 stop_with_angle 78.3575 within_radius 1.0
05BE: AS_actor -1 die
// START BLOCK #3
```

Далее нужно поместить эти блоки в обратном порядке, соблюдая порядок действий:

```
// START BLOCK #3
07CD: AS_actor -1 walk_to 2506.5393 -1682.7019 13.5469 stop_with_angle 308.3229 within_radius 1.0 
07CD: AS_actor -1 walk_to 2511.791 -1662.2334 13.5868 stop_with_angle 36.3705 within_radius 1.0
07CD: AS_actor -1 walk_to 2496.2747 -1651.3385 13.4905 stop_with_angle 78.3575 within_radius 1.0
05BE: AS_actor -1 die
// START BLOCK #3 

// START BLOCK #2
07CD: AS_actor -1 walk_to 2467.3425 -1650.9974 13.4712 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2465.1921 -1667.502 13.4712 stop_with_angle 167.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2432.071 -1666.8909 13.5352 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2393.261 -1666.8276 13.478 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2351.2043 -1667.8103 13.5469 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2350.5696 -1695.3361 13.4435 stop_with_angle 180.0 within_radius 1.0 
// START BLOCK #2
 
// START BLOCK #1
07CD: AS_actor -1 walk_to 2467.3425 -1650.9974 13.4712 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2465.1921 -1667.502 13.4712 stop_with_angle 167.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2432.071 -1666.8909 13.5352 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2393.261 -1666.8276 13.478 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2351.2043 -1667.8103 13.5469 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2350.5696 -1695.3361 13.4435 stop_with_angle 180.0 within_radius 1.0 
// END BLOCK #1
```

Далее вместо комментариев указывает начало и конец AS-пака:

```
0615: define_AS_pack_begin 3@
07CD: AS_actor -1 walk_to 2506.5393 -1682.7019 13.5469 stop_with_angle 308.3229 within_radius 1.0 
07CD: AS_actor -1 walk_to 2511.791 -1662.2334 13.5868 stop_with_angle 36.3705 within_radius 1.0
07CD: AS_actor -1 walk_to 2496.2747 -1651.3385 13.4905 stop_with_angle 78.3575 within_radius 1.0
05BE: AS_actor -1 die 
0616: define_AS_pack_end 3@

0615: define_AS_pack_begin 2@
07CD: AS_actor -1 walk_to 2467.3425 -1650.9974 13.4712 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2465.1921 -1667.502 13.4712 stop_with_angle 167.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2432.071 -1666.8909 13.5352 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2393.261 -1666.8276 13.478 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2351.2043 -1667.8103 13.5469 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2350.5696 -1695.3361 13.4435 stop_with_angle 180.0 within_radius 1.0 
0616: define_AS_pack_end 2@
 
0615: define_AS_pack_begin 1@
07CD: AS_actor -1 walk_to 2467.3425 -1650.9974 13.4712 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2465.1921 -1667.502 13.4712 stop_with_angle 167.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2432.071 -1666.8909 13.5352 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2393.261 -1666.8276 13.478 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2351.2043 -1667.8103 13.5469 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2350.5696 -1695.3361 13.4435 stop_with_angle 180.0 within_radius 1.0 
0616: define_AS_pack_end 1@
```

Последовательности есть. Теперь нам нужно из 1@ запустить пак 2@, чтобы действия продолжались, как будто они выполняются в одном блоке. И , аналогично, в конце блока 2@ запустить блок 3@:

```
0615: define_AS_pack_begin 3@ 
07CD: AS_actor -1 walk_to 2506.5393 -1682.7019 13.5469 stop_with_angle 308.3229 within_radius 1.0 
07CD: AS_actor -1 walk_to 2511.791 -1662.2334 13.5868 stop_with_angle 36.3705 within_radius 1.0
07CD: AS_actor -1 walk_to 2496.2747 -1651.3385 13.4905 stop_with_angle 78.3575 within_radius 1.0
05BE: AS_actor -1 die 
0616: define_AS_pack_end 3@ 
 
0615: define_AS_pack_begin 2@
07CD: AS_actor -1 walk_to 2373.5601 -1695.8665 13.4922 stop_with_angle 270.0 within_radius 1.0 
07CD: AS_actor -1 walk_to 2416.0393 -1696.1923 13.7953 stop_with_angle 270.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2416.7607 -1724.1533 13.7296 stop_with_angle 180.0 within_radius 1.0 
07CD: AS_actor -1 walk_to 2445.157 -1724.7465 13.7372 stop_with_angle 270.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2480.4011 -1726.1528 13.5547 stop_with_angle 0.0 within_radius 1.0 
07CD: AS_actor -1 walk_to 2482.4336 -1686.9985 13.5078 stop_with_angle 0.0 within_radius 1.0 
0618: assign_actor -1 to_AS_pack 3@
061B: remove_references_to_AS_pack 3@ 
0616: define_AS_pack_end 2@
 
0615: define_AS_pack_begin 1@
07CD: AS_actor -1 walk_to 2467.3425 -1650.9974 13.4712 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2465.1921 -1667.502 13.4712 stop_with_angle 167.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2432.071 -1666.8909 13.5352 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2393.261 -1666.8276 13.478 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2351.2043 -1667.8103 13.5469 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2350.5696 -1695.3361 13.4435 stop_with_angle 180.0 within_radius 1.0
0618: assign_actor -1 to_AS_pack 2@
061B: remove_references_to_AS_pack 2@ 
0616: define_AS_pack_end 1@
```

Здесь прослеживается причина почему нам нужно делать AS-Pack-и в обратном порядке: чтобы мы имели ссылки на последовательности для их запуска. Нам осталось только создать актёра и заставить его выполнять последовательность 1@:

```
{$CLEO}
wait 5000
0376: 31@ = create_random_actor_at 2498.5095 -1651.5884 12.5096
0187: 30@ = create_marker_above_actor 31@
0168: set_marker 30@ size 2
 
0615: define_AS_pack_begin 3@ 
07CD: AS_actor -1 walk_to 2506.5393 -1682.7019 13.5469 stop_with_angle 308.3229 within_radius 1.0 
07CD: AS_actor -1 walk_to 2511.791 -1662.2334 13.5868 stop_with_angle 36.3705 within_radius 1.0
07CD: AS_actor -1 walk_to 2496.2747 -1651.3385 13.4905 stop_with_angle 78.3575 within_radius 1.0
05BE: AS_actor -1 die 
0616: define_AS_pack_end 3@ 
 
0615: define_AS_pack_begin 2@
07CD: AS_actor -1 walk_to 2373.5601 -1695.8665 13.4922 stop_with_angle 270.0 within_radius 1.0 
07CD: AS_actor -1 walk_to 2416.0393 -1696.1923 13.7953 stop_with_angle 270.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2416.7607 -1724.1533 13.7296 stop_with_angle 180.0 within_radius 1.0 
07CD: AS_actor -1 walk_to 2445.157 -1724.7465 13.7372 stop_with_angle 270.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2480.4011 -1726.1528 13.5547 stop_with_angle 0.0 within_radius 1.0 
07CD: AS_actor -1 walk_to 2482.4336 -1686.9985 13.5078 stop_with_angle 0.0 within_radius 1.0 
0618: assign_actor -1 to_AS_pack 3@
061B: remove_references_to_AS_pack 3@ 
0616: define_AS_pack_end 2@
 
0615: define_AS_pack_begin 1@
07CD: AS_actor -1 walk_to 2467.3425 -1650.9974 13.4712 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2465.1921 -1667.502 13.4712 stop_with_angle 167.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2432.071 -1666.8909 13.5352 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2393.261 -1666.8276 13.478 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2351.2043 -1667.8103 13.5469 stop_with_angle 90.0 within_radius 1.0
07CD: AS_actor -1 walk_to 2350.5696 -1695.3361 13.4435 stop_with_angle 180.0 within_radius 1.0
0618: assign_actor -1 to_AS_pack 2@
061B: remove_references_to_AS_pack 2@ 
0616: define_AS_pack_end 1@
 
0618: assign_actor 31@ to_AS_pack 1@
061B: remove_references_to_AS_pack 1@
 
0A93: end_custom_thread
```

Такой способ только в редких случаях даёт сбой, но вероятность, что кто-то (что-то) помешает актёру выполить все действия всё же есть. Поэтому здесь лучше отключать трафик актёров и транспорта.

Ну и сам результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/59027446.png)|42|1|0|59027446\`png\`640\`384\`320\`192\`\`\\||dlinnye\_posledovatelnosti\_v\_animacii|1567358078


# 00022. Типы зон. Аудио-зоны

Типы зон. Аудио-зоны|В этом уроке Вы узнаете о типах зон и аудио-зонах.|wmysterio|wmysterio||||Рассмотрим опкоды, с помощью которых мы можем установить какие люди и транспорт будут появляться в той или иной зоне. Все известные мне типы описаны. Вот команда, которая указывает тип зоны:

```
0767: set_zone 'MARKST' type 14
```

Так же мы можем указать какой транспорт и люди будут существовать в той или иной зоне. Делается это опкодом:

```
0767: set_zone 'MARKST' popcycle_group_for_peds_and_cars_to 14
```

Вот опкод, который указывает в кокой зоне будут ходить только люди:

```
0874: set_zone 'MARKST' popcycle_group_for_peds_to 14
```

В опкодах:\
'MARKST' — имя зоны ( см. [Имена игровых зон](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/nazvanie_zon_dlja_gta_san_andreas/1-1-0-16/README.md) )\
14 — тип зоны ( см. в [базе данных](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/tipy_zon/1-1-0-39/README.md) )

Я взял с оригинально main.scm все зоны. Добавим их в ниш скрипт:

```
// This file was decompiled using sascm.ini published by Seemann (http://sannybuilder.com/files/SASCM.rar) on 13.10.2007
// WMYSTERIO, ru-script.3dn.ru
DEFINE OBJECTS 1
DEFINE OBJECT SANNY BUILDER 3.04 

DEFINE MISSIONS 0

DEFINE EXTERNAL_SCRIPTS 0

DEFINE UNKNOWN_EMPTY_SEGMENT 0

DEFINE UNKNOWN_THREADS_MEMORY 3072

{$VERSION 3.1.0027}

//-------------MAIN---------------
thread 'MAIN'
set_wb_check_to 0
set_weather 0
select_interior 0
fade 0 0
0180: set_on_mission_flag_to $ONMISSION
00C0: set_current_time_hours_to 8 minutes_to 0
04E4: unknown_refresh_game_renderer_at 2491.1572 -1670.3434
Camera.SetAtPos(2491.1572, -1670.3434, 12.3359)
$PLAYER_CHAR = Player.Create(#NULL, 2491.1572, -1670.3434, 12.3359)
$PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
Actor.Angle($PLAYER_ACTOR) = 66.3548
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
Camera.SetBehindPlayer
Player.SetClothes($PLAYER_CHAR, "WORKTRCAMOGRN", "WORKTR", 2)
Player.SetClothes($PLAYER_CHAR, "SNEAKERBINCGANG", "SNEAKER", 3)
Player.SetClothes($PLAYER_CHAR, "TSHIRTERISORN", "TSHIRT", 0)
Player.Build($PLAYER_CHAR)
Player.CanMove($PLAYER_CHAR) = True
fade 1 0
0879: enable_gang_wars 1
076C: set_zone 'GAN1' gang 1 density_to 40 
076C: set_zone 'GAN2' gang 1 density_to 80 
076C: set_zone 'IWD1' gang 0 density_to 40 
076C: set_zone 'IWD2' gang 0 density_to 80 
076C: set_zone 'IWD3A' gang 2 density_to 40 
076C: set_zone 'IWD3B' gang 2 density_to 80 
0237: set_gang 0 weapons_to 22 31 14 
0237: set_gang 1 weapons_to 30 28 17 
0237: set_gang 2 weapons_to 36 15 27 
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 0
0746: set_acquaintance 0 of_actors_pedtype 8 to_actors_pedtype 0
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 0
// конец нового кода
0767: set_zone 'MARKST' popcycle_group_for_peds_and_cars_to 14
0767: set_zone 'UNITY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'LAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2A' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2B' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'BLUF1A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BLUF2' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3C' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN4' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'COM1A' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM1B' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PER1' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'CHC1A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC1B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC3' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'CHC1A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC1B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC3' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4B' popcycle_group_for_peds_to 9 
0767: set_zone 'CONF1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'CONF1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'THALL1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDOC1A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3C' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDT1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1C' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LDT5' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT6' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE3C' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'ELCO1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'ELCO2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELCO1' popcycle_group_for_peds_to 9 
0874: set_zone 'ELCO2' popcycle_group_for_peds_to 9 
0767: set_zone 'GAN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GAN2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'GAN1' popcycle_group_for_peds_to 1 
0874: set_zone 'GAN2' popcycle_group_for_peds_to 1 
0767: set_zone 'GLN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GLN2A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'IWD1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD4' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD5' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'IWD1' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD2' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3A' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3B' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD4' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD5' popcycle_group_for_peds_to 1 
0767: set_zone 'JEF1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3C' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LFL1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LFL1B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'LFL1A' popcycle_group_for_peds_to 9 
0874: set_zone 'LFL1B' popcycle_group_for_peds_to 9 
0767: set_zone 'LMEX1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LMEX1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ELS1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS1B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS4' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELS1A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS1B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS2' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS4' popcycle_group_for_peds_to 10 
0767: set_zone 'MAR1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'MAR2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MAR3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MKT1' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT2' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT3' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT4' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MUL1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL2A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL2B' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL3' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL4' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL6' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'PLS' popcycle_group_for_peds_and_cars_to 8
0767: set_zone 'RIH1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH2' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD1A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD5B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SMB1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'SMB2' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VIN2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VERO1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'VERO2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO4A' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VERO4B' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'CRANB' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CALT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'SUNMA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SUNNN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'BATTP' popcycle_group_for_peds_and_cars_to 2
0767: set_zone 'ESPN1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'BAYV' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'PARA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'JUNIHO' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JUNIHI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CIVI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CHINA' popcycle_group_for_peds_and_cars_to 9
0874: set_zone 'CHINA' popcycle_group_for_peds_to 6
0767: set_zone 'SFDWT1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT5' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT6' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'FINA' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'CITYS' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'WESTP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'THEA1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'GARC' popcycle_group_for_peds_and_cars_to 7
0767: set_zone 'HASH' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'OCEAF1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'OCEAF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'OCEAF3' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'DOH1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'DOH2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'CUNTC1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SFGLF1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF2' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF3' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF4' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'HILLP' popcycle_group_for_peds_and_cars_to 10
0767: set_zone 'SILLY1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY4' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR4' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR5' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'EASB1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'EASB2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'ESPE1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'LINDEN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YELLOW' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'BFC1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BFC2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'RIE' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'LDM' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'RSW1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSW2' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSE' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'LDS' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'SRY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JTS1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTS2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LVA1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'LVA3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'VAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LVBAG' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'GGC1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'GGC2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'BFLD1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BFLD2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'WWE' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'WWE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PINT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YBELL2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'YBELL1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'JTW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN5' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN6' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN8' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'HGP' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SPIN' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'BINT1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PRP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'REDE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'REDW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'REDW4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ROCE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'ROCE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'OVS' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CREE' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'STRIP1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP2' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STRIP3' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP4' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'PILL1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PILL2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'RING' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'ISLE' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STAR1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STAR2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'ROY' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CAM' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'LOT' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PIRA' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'VISA1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'VISA2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'DRAG' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PINK' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'HIGH' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CONST1' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'ANGPI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'SHACA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BACKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BEACO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FARM' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'PALO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT1' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MTCHI1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI2' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI3' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI4' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'HBARNS' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'DILLI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'PANOP' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUAC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MAKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FERN' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'NROCK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'HANKY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'LEAFY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'RED' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FLINTC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'WHET' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BIGE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELQUE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BARRA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'CARSO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PAYAS' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PROBE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELCA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTR' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ARCO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'VALLE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTI' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'MONINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'TOM' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ALDEA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BRUJA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBAD' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BONE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'HAUL' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'QUARY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'OCTAN' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'PALMS' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'DAM' popcycle_group_for_peds_and_cars_to 18
// конец нового кода
end_thread
```

Теперь скомпилируем и проверим всё в игре. Думаю вы заметили ( хотя скорее вы не замечали ), что в аэропорту теперь ездят тачки, которые тами должны ездить. Раньше по аэропорту ездили все машины, как по обычному шоссе. Теперь стало всё на свои места.

Как видим, наш скрипт постепенно начинает расти :) Вскоре он станет большим, очень большим и гигантским! :)

Мне многие пишут о том, что бы сделать аудио-зону, то есть зону, в которой будет играть музыка. Вот опкод, который включает аудио-зоны:

```
0917: audio_zone 'LOWRIDE' enable_sound 1
```

Здесь:\
'LOWRIDE' — аудио-зона\
1 - включить аудио-зону ( если 0 - то выключить )<br>

Учтите, что аудио-зоны и игровые зоны ( обычные ) — это совсем разные вещи. Список известных мне аудио-зон вы можете найти в нашей [базе данных](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/audio_zony/1-1-0-40/README.md). Рассмотрим подробнее, что находится в файле "Игра\data\maps\\**Audiozon.ipl**":

```
OTB, 24, 1, 817.121, -2.78276, 1001.62, 838.373, 12.6744, 1009.04
```

Здесь:\
OTB - имя аудио-зоны ( именно это нужно писать в опкод \*\*0917\*\* )\
24 - номер музыки, которая будет играть в зоне. Известные мне номера Вы найдёте в таблице ниже\
Остальные параметры - координаты самих зон.

| Таблица номеров музыки в аудио-зонах |                  |
| ------------------------------------ | ---------------- |
| Номер                                | Музыка           |
| 52                                   | Playback FM      |
| 53                                   | K-ROSE           |
| 54                                   | K-DST            |
| 55                                   | Bounce FM        |
| 56                                   | SFUR             |
| 57                                   | Radio Los Santos |
| 58                                   | Radio X          |
| 59                                   | CSR              |
| 60                                   | K-JAH West       |
| 61                                   | MasterSounds     |
| 62                                   | WCTR             |

Я не буду останавливаться на аудио-зонах, потому что их не очень часто используют в скрипте. Если будут уроки по скриптам, с использованием аудио-зон мы ещё вернёмся к этому вопросу.|1139|1|0||tipy\_zon\_i\_audio\_zonu|1498568976


# 00023. Работа с клавишами. Делаем сохранение

Работа с клавишами. Делаем сохранение|Мы продолжаем изучать скриптинг и написание мейна с нуля. В этом уроке мы напишем скрипт, который будет сохранять нашу игру при нажатии конкретной клавиши.|wmysterio|wmysterio||||Я даже не знаю таких игр, в которых не было возможности сохранение игры. Рассмотрим два опкода, которые назначены для работы с клавишами:

```
0AB0: key_pressed 115
00E1: player 0 pressed_key 19
```

Первый опкод я, например, практически всегда использую. Это проверка на нажатие конкретной клавиши Windows. Здесь:

115 - номер клавиши ( см. [Номера клавиш. Таблица 2](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/nomera_klavish_gta_san_andreas/1-1-0-13/README.md) ). В нашем случае это кнопка F4.

Второй опкод - это проверка на нажатие игровой клавиши ( см. [Номера клавиш. Таблица 1](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/nomera_klavish_gta_san_andreas/1-1-0-13/README.md) ). Здесь:

0 - номер игрока. Это для $PLAYER\_CHAR. Используйте всегда 0\
19 - номер игровой клавиши. Здесь уже идёт зависимость от того находится игрок в транспорте или идёт пешком

Меня очень часто спрашивают о том, как я отличаю условные опкоды, то есть проверки, от других опкодов. Всё довольно просто. Рассмотрим простой пример, даже с темеми опкодами, что написаны выше:

| Опкод                              | Описание                               |
| ---------------------------------- | -------------------------------------- |
| \*\*0\*\*AB0: key\_pressed 115     | проверка на нажатие клавиши            |
| \*\*8\*\*AB0: not key\_pressed 115 | проверка на \*\*не\*\* нажатие клавиши |

Обратите внимание на первый символ опкодов. Если мы нашли какой то интересующий нас опкод и мы не знаем проверка это или нет, то просто в место 0 поставим 8. Если опкод нашелся в поисковике, то это проверка.

С клавишами разобрались, рассмотрим опкод, который отвечает за сохранение игры. Делается это опкодом:

```
03D8: show_save_screen
```

Осталось определить только условия, при котором будет сохранена игра. В первую очередь нельзя сохраняться во время миссий, поэтому переменная **$ONMISSION** должна быть равна нулю ( режим миссии выключен ). Это одно из главных условий, но их может быть несколько. Давайте напишем самый примитивный скрипт:

```
:SAVE
thread 'SAVE'
wait 0
if AND
$ONMISSION == 0
0AB0: key_pressed 115
then
03D8: show_save_screen
wait 250
end
jump @SAVE
```

Всё что нам осталось - это вставить этот скрипт в наш мейн. Сделаем это:

```
// WMYSTERIO, ru-script.3dn.ru
DEFINE OBJECTS 1
DEFINE OBJECT SANNY BUILDER 3.04 

DEFINE MISSIONS 0

DEFINE EXTERNAL_SCRIPTS 0

DEFINE UNKNOWN_EMPTY_SEGMENT 0

DEFINE UNKNOWN_THREADS_MEMORY 3072

{$VERSION 3.1.0027}

//-------------MAIN---------------
thread 'MAIN'
set_wb_check_to 0
set_weather 0
select_interior 0
fade 0 0
0180: set_on_mission_flag_to $ONMISSION
00C0: set_current_time_hours_to 8 minutes_to 0
04E4: unknown_refresh_game_renderer_at 2491.1572 -1670.3434
Camera.SetAtPos(2491.1572, -1670.3434, 12.3359)
$PLAYER_CHAR = Player.Create(#NULL, 2491.1572, -1670.3434, 12.3359)
$PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
Actor.Angle($PLAYER_ACTOR) = 66.3548
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
Camera.SetBehindPlayer
Player.SetClothes($PLAYER_CHAR, "WORKTRCAMOGRN", "WORKTR", 2)
Player.SetClothes($PLAYER_CHAR, "SNEAKERBINCGANG", "SNEAKER", 3)
Player.SetClothes($PLAYER_CHAR, "TSHIRTERISORN", "TSHIRT", 0)
Player.Build($PLAYER_CHAR)
Player.CanMove($PLAYER_CHAR) = True
fade 1 0
0879: enable_gang_wars 1
076C: set_zone 'GAN1' gang 1 density_to 40 
076C: set_zone 'GAN2' gang 1 density_to 80 
076C: set_zone 'IWD1' gang 0 density_to 40 
076C: set_zone 'IWD2' gang 0 density_to 80 
076C: set_zone 'IWD3A' gang 2 density_to 40 
076C: set_zone 'IWD3B' gang 2 density_to 80 
0237: set_gang 0 weapons_to 22 31 14 
0237: set_gang 1 weapons_to 30 28 17 
0237: set_gang 2 weapons_to 36 15 27 
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 0
0746: set_acquaintance 0 of_actors_pedtype 8 to_actors_pedtype 0
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 0
0767: set_zone 'MARKST' popcycle_group_for_peds_and_cars_to 14
0767: set_zone 'UNITY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'LAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2A' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2B' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'BLUF1A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BLUF2' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3C' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN4' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'COM1A' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM1B' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PER1' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'CHC1A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC1B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC3' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'CHC1A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC1B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC3' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4B' popcycle_group_for_peds_to 9 
0767: set_zone 'CONF1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'CONF1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'THALL1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDOC1A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3C' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDT1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1C' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LDT5' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT6' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE3C' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'ELCO1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'ELCO2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELCO1' popcycle_group_for_peds_to 9 
0874: set_zone 'ELCO2' popcycle_group_for_peds_to 9 
0767: set_zone 'GAN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GAN2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'GAN1' popcycle_group_for_peds_to 1 
0874: set_zone 'GAN2' popcycle_group_for_peds_to 1 
0767: set_zone 'GLN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GLN2A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'IWD1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD4' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD5' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'IWD1' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD2' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3A' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3B' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD4' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD5' popcycle_group_for_peds_to 1 
0767: set_zone 'JEF1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3C' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LFL1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LFL1B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'LFL1A' popcycle_group_for_peds_to 9 
0874: set_zone 'LFL1B' popcycle_group_for_peds_to 9 
0767: set_zone 'LMEX1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LMEX1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ELS1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS1B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS4' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELS1A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS1B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS2' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS4' popcycle_group_for_peds_to 10 
0767: set_zone 'MAR1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'MAR2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MAR3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MKT1' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT2' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT3' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT4' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MUL1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL2A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL2B' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL3' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL4' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL6' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'PLS' popcycle_group_for_peds_and_cars_to 8
0767: set_zone 'RIH1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH2' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD1A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD5B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SMB1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'SMB2' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VIN2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VERO1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'VERO2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO4A' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VERO4B' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'CRANB' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CALT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'SUNMA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SUNNN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'BATTP' popcycle_group_for_peds_and_cars_to 2
0767: set_zone 'ESPN1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'BAYV' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'PARA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'JUNIHO' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JUNIHI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CIVI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CHINA' popcycle_group_for_peds_and_cars_to 9
0874: set_zone 'CHINA' popcycle_group_for_peds_to 6
0767: set_zone 'SFDWT1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT5' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT6' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'FINA' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'CITYS' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'WESTP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'THEA1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'GARC' popcycle_group_for_peds_and_cars_to 7
0767: set_zone 'HASH' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'OCEAF1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'OCEAF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'OCEAF3' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'DOH1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'DOH2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'CUNTC1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SFGLF1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF2' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF3' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF4' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'HILLP' popcycle_group_for_peds_and_cars_to 10
0767: set_zone 'SILLY1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY4' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR4' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR5' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'EASB1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'EASB2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'ESPE1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'LINDEN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YELLOW' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'BFC1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BFC2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'RIE' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'LDM' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'RSW1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSW2' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSE' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'LDS' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'SRY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JTS1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTS2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LVA1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'LVA3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'VAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LVBAG' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'GGC1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'GGC2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'BFLD1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BFLD2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'WWE' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'WWE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PINT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YBELL2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'YBELL1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'JTW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN5' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN6' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN8' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'HGP' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SPIN' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'BINT1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PRP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'REDE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'REDW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'REDW4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ROCE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'ROCE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'OVS' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CREE' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'STRIP1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP2' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STRIP3' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP4' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'PILL1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PILL2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'RING' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'ISLE' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STAR1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STAR2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'ROY' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CAM' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'LOT' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PIRA' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'VISA1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'VISA2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'DRAG' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PINK' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'HIGH' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CONST1' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'ANGPI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'SHACA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BACKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BEACO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FARM' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'PALO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT1' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MTCHI1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI2' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI3' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI4' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'HBARNS' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'DILLI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'PANOP' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUAC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MAKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FERN' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'NROCK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'HANKY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'LEAFY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'RED' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FLINTC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'WHET' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BIGE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELQUE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BARRA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'CARSO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PAYAS' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PROBE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELCA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTR' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ARCO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'VALLE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTI' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'MONINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'TOM' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ALDEA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BRUJA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBAD' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BONE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'HAUL' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'QUARY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'OCTAN' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'PALMS' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'DAM' popcycle_group_for_peds_and_cars_to 18
create_thread @SAVE // Наш новый код!
end_thread 

// начало нового кода
:SAVE
thread 'SAVE'
wait 0
if AND
$ONMISSION == 0
0AB0: key_pressed 115
then
03D8: show_save_screen 
wait 250
end
jump @SAVE
// конец нового кода
```

Компилируем и начинаем новую игру! Начинаем, потому, что мы добавили новый поток. Когда мы во время игры нажмём клавишу F4, появится окно сохранения:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/81463968.png)

Таким образом наша задача выполнена!|1292|1|0|81463968`png`640`400`400\`250\`\`||rabota\_s\_klavishami\_delaem\_sokhranenie|1498570494


# 00037. Анимация. Основные команды и примеры их использования

Анимация. Основные команды и примеры их использования|Мы продолжаем изучать скриптинг. Этот урок посвящен анимациям. Мы научимся основным командам для проигрывания анимаций а так-же сделаем третью миссию с использованием анимацией.|wmysterio|wmysterio||||Если вы не читали урок о GTA Animation Manager, то советую прочитать [руководство к этой программе](https://github.com/wmysterio/scm-scripting-lessons/blob/main/publ/gta_sa/dokumentacii_k_programmam/rukovodstvo_po_ispolzovaniju_programmy_gta_animation_maneger/54-1-0-6/README.md).

Для начала научимся загружать анимации. Сделать это можно командой:

```
04ED: load_animation "LOWRIDER"
```

Здесь:\
"LOWRIDER" — название ifp-файла ( см. рисунок ниже )![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/15513934.png)

После этого нам обязательно нужно проверить: "загружена ли она?". Эта проверка осуществляется опкодом:

```
04EE: animation "LOWRIDER" loaded
```

После загрузки можно использовать анимации, что содержаться в ifp-файлах ( см. рисунок ниже ):

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/77197739.png)

Теперь, что бы какой то актёр проиграл эту анимацию, нужно использовать опкод:

```
0605: actor 0@ perform_animation "M_SMKLEAN_LOOP" IFP "LOWRIDER" framedelta 4.0 loop 0 lockX 0 lockY 0 lockF 0 time 670
```

Здесь:\
0@ — Имя переменной для актёра\
"prtial\_gngtlkB" — название анимации\
"LOWRIDER" — название IFP-файла\
4.0 и 0 0 0 0 — оставляйте так, далее мы детально изучим эти параметры\
670 — время воспроизведения. Если поставить больше, то анимация будет повторяться. Длина любой анимации на рисунку выше выделено зелёным цветом

Если мы загрузили анимацию, то естественно нам её нужно выгрузить с памяти когда она не нужна. Делается это опкодом:

```
04EF: release_animation "LOWRIDER"
```

Рассмотрим анимации, которые НЕ нужно загружать и НЕ нужно выгружать. Это анимации "PED.IFP", так как она загружается вместе с игрой и постоянно используется:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/84390702.png)

Рассмотрим другую анимацию - анимация телефона ( когда СЖ достаёт или прячет телефон ). Что бы актёр доставал телефон, используйте опкод:

```
0729: AS_actor $PLAYER_ACTOR hold_cellphone 1
```

Здесь:\
$PLAYER\_ACTOR - имя переменной актёра\
1 - достать телефон, 0 - спрятать

После этого опкода обычно делают задержку в 2000 милисекунд, чтобы актёр окончательно взял телефон и приложил его к уху, или спрятал его в карман.

× \*\*Примечание:\*\* Сначала нужно загрузить модель телефона #CELLPHONE, иначе актёр приставит к уху только свою руку ;)

Так же актёра можно заставить говорить:

```
0967: actor 0@ move_mouth 4000 ms
```

Здесь:\
0@ - хендл актёра\
4000 - время, сколько нужно шевелить губами

И опкод, который заставляет прекратить актёра шевелить губами:

```
0968: actor 0@ stop_mouth
```

Есть ещё похожий опкод, который заставляет актёра шевелить губами, но это имеет вид больше жевания, нежели разговора:

```
05BA: AS_actor 2@ move_mouth 4000 ms
```

Так же актёров можно заставить сидеть. Делается это опкодом:

```
06B0: AS_actor 41@ sit_down 4000 ms
```

Здесь:\
41@ - имя переменной для актёра\
4000 - указывается время, то есть сколько времени должен сидеть актёр

Так же актёра можно заставить прыгать:

```
05BC: AS_actor 1@ jump 1
```

Здесь:\
1@ - имя переменной для актёра\
1 - стиль прыжка. Так и оставляйте единицу, так как разницы между стилями не заметил

Что бы заставить актёра присесть, используйте опкод:

```
04EB: AS_actor 65@ crouch 1
```

Здесь:\
65@ - имя переменной для актёра\
1 - заставляет актёра присесть, если поставить 0 - то заставляет актёра встать

Существует ещё проверка на приседание актёра:

```
0597: actor $PLAYER_ACTOR crouching
```

Так же есть полезная проверка на выполнение актёром какой-то анимации:

```
0611: actor 2@ performing_animation "LRGIRL_IDLE_TO_L0"
```

Здесь:\
2@ - хэндл актёра\
"LRGIRL\_IDLE\_TO\_L0" - имя анимации ( не IFP )

Вот мы рассмотрели основные команды для работы с анимациями. Давайте теперь напишем миссию и сделаем ролик, в котором СЖ-ю звонят, он берет трубку и ему сообщают, что возле Гроув есть Баллас и его нужно убить:

```
// WMYSTERIO, ru-script.3dn.ru

DEFINE OBJECTS 1
DEFINE OBJECT SANNY BUILDER 3.04 

DEFINE MISSIONS 3
DEFINE MISSION 0 AT @MISSION_0 // 1 
DEFINE MISSION 1 AT @MISSION_1 // 2
DEFINE MISSION 2 AT @MISSION_2 // 3 -- наш новый скрипт
 
DEFINE EXTERNAL_SCRIPTS 0

DEFINE UNKNOWN_EMPTY_SEGMENT 0

DEFINE UNKNOWN_THREADS_MEMORY 3072

{$VERSION 3.1.0027}

//-------------MAIN---------------
thread 'MAIN'
set_wb_check_to 0
set_weather 0
select_interior 0
fade 0 0
0180: set_on_mission_flag_to $ONMISSION
00C0: set_current_time_hours_to 8 minutes_to 0
04E4: unknown_refresh_game_renderer_at 2491.1572 -1670.3434
Camera.SetAtPos(2491.1572, -1670.3434, 12.3359)
$PLAYER_CHAR = Player.Create(#NULL, 2491.1572, -1670.3434, 12.3359)
$PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
Actor.Angle($PLAYER_ACTOR) = 66.3548
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
Camera.SetBehindPlayer
Player.SetClothes($PLAYER_CHAR, "WORKTRCAMOGRN", "WORKTR", 2)
Player.SetClothes($PLAYER_CHAR, "SNEAKERBINCGANG", "SNEAKER", 3)
Player.SetClothes($PLAYER_CHAR, "TSHIRTERISORN", "TSHIRT", 0) 
Player.Build($PLAYER_CHAR)
Player.CanMove($PLAYER_CHAR) = True
$TRAMPLIN = object.Create(#AD_JUMP, 2480.5842, -1721.8175, 12.5488)
object.Angle($TRAMPLIN) = 180.0
object.SetImmunities($TRAMPLIN, 1, 1, 1, 1, 1)
Object.Indestructibility($TRAMPLIN) = False
Object.RemoveFromMissionCleanupList($TRAMPLIN)
0879: enable_gang_wars 1
076C: set_zone 'GAN1' gang 1 density_to 40 
076C: set_zone 'GAN2' gang 1 density_to 80 
076C: set_zone 'IWD1' gang 0 density_to 40 
076C: set_zone 'IWD2' gang 0 density_to 80 
076C: set_zone 'IWD3A' gang 2 density_to 40 
076C: set_zone 'IWD3B' gang 2 density_to 80 
0237: set_gang 0 weapons_to 22 31 14 
0237: set_gang 1 weapons_to 30 28 17 
0237: set_gang 2 weapons_to 36 15 27 
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 0
0746: set_acquaintance 0 of_actors_pedtype 8 to_actors_pedtype 0
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 0
0767: set_zone 'MARKST' popcycle_group_for_peds_and_cars_to 14
0767: set_zone 'UNITY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'LAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2A' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2B' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'BLUF1A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BLUF2' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3C' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN4' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'COM1A' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM1B' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PER1' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'CHC1A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC1B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC3' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'CHC1A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC1B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC3' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4B' popcycle_group_for_peds_to 9 
0767: set_zone 'CONF1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'CONF1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'THALL1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDOC1A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3C' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDT1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1C' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LDT5' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT6' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE3C' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'ELCO1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'ELCO2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELCO1' popcycle_group_for_peds_to 9 
0874: set_zone 'ELCO2' popcycle_group_for_peds_to 9 
0767: set_zone 'GAN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GAN2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'GAN1' popcycle_group_for_peds_to 1 
0874: set_zone 'GAN2' popcycle_group_for_peds_to 1 
0767: set_zone 'GLN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GLN2A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'IWD1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD4' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD5' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'IWD1' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD2' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3A' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3B' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD4' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD5' popcycle_group_for_peds_to 1 
0767: set_zone 'JEF1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3C' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LFL1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LFL1B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'LFL1A' popcycle_group_for_peds_to 9 
0874: set_zone 'LFL1B' popcycle_group_for_peds_to 9 
0767: set_zone 'LMEX1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LMEX1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ELS1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS1B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS4' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELS1A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS1B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS2' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS4' popcycle_group_for_peds_to 10 
0767: set_zone 'MAR1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'MAR2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MAR3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MKT1' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT2' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT3' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT4' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MUL1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL2A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL2B' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL3' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL4' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL6' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'PLS' popcycle_group_for_peds_and_cars_to 8
0767: set_zone 'RIH1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH2' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD1A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD5B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SMB1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'SMB2' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VIN2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VERO1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'VERO2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO4A' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VERO4B' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'CRANB' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CALT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'SUNMA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SUNNN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'BATTP' popcycle_group_for_peds_and_cars_to 2
0767: set_zone 'ESPN1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'BAYV' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'PARA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'JUNIHO' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JUNIHI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CIVI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CHINA' popcycle_group_for_peds_and_cars_to 9
0874: set_zone 'CHINA' popcycle_group_for_peds_to 6
0767: set_zone 'SFDWT1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT5' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT6' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'FINA' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'CITYS' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'WESTP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'THEA1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'GARC' popcycle_group_for_peds_and_cars_to 7
0767: set_zone 'HASH' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'OCEAF1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'OCEAF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'OCEAF3' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'DOH1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'DOH2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'CUNTC1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SFGLF1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF2' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF3' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF4' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'HILLP' popcycle_group_for_peds_and_cars_to 10
0767: set_zone 'SILLY1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY4' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR4' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR5' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'EASB1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'EASB2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'ESPE1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'LINDEN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YELLOW' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'BFC1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BFC2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'RIE' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'LDM' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'RSW1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSW2' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSE' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'LDS' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'SRY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JTS1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTS2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LVA1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'LVA3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'VAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LVBAG' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'GGC1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'GGC2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'BFLD1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BFLD2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'WWE' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'WWE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PINT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YBELL2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'YBELL1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'JTW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN5' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN6' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN8' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'HGP' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SPIN' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'BINT1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PRP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'REDE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'REDW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'REDW4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ROCE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'ROCE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'OVS' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CREE' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'STRIP1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP2' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STRIP3' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP4' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'PILL1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PILL2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'RING' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'ISLE' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STAR1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STAR2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'ROY' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CAM' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'LOT' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PIRA' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'VISA1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'VISA2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'DRAG' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PINK' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'HIGH' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CONST1' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'ANGPI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'SHACA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BACKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BEACO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FARM' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'PALO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT1' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MTCHI1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI2' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI3' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI4' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'HBARNS' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'DILLI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'PANOP' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUAC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MAKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FERN' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'NROCK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'HANKY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'LEAFY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'RED' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FLINTC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'WHET' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BIGE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELQUE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BARRA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'CARSO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PAYAS' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PROBE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELCA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTR' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ARCO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'VALLE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTI' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'MONINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'TOM' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ALDEA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BRUJA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBAD' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BONE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'HAUL' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'QUARY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'OCTAN' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'PALMS' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'DAM' popcycle_group_for_peds_and_cars_to 18
014B: $MY_CAR = init_parked_car_generator #BULLET color -1 -1 0 alarm 0 door_lock 0 1 10000 at 2474.2131 -1690.8783 12.1239 angle 180.0
014C: set_parked_car_generator $MY_CAR cars_to_generate_to 101
0213: $PICKUP_0001 = create_pickup #BODYARMOUR type 15 at 2491.0 -1685.8561 13.5107
032B: $PICKUP_0002 = create_weapon_pickup #MINIGUN group 15 ammo 60 at 2493.0 -1685.8561 13.5107 
02E1: $PICKUP_0003 = create_cash_pickup 500 at 2495.0 -1685.8561 13.5107 permanence_flag 1 
04A6: $PICKUP_0004 = create_asset_money_pickup_at 2497.0 -1685.8561 13.5107 money 10000 10000
016C: restart_if_wasted_at 2027.77 -1420.52 15.99 angle 137.0 town_number 0 
016C: restart_if_wasted_at 1180.85 -1325.57 12.58 angle 271.4 town_number 0
016D: restart_if_busted_at 1550.68 -1675.49 14.51 angle 90.0 town_number 0
016C: restart_if_wasted_at 1244.437 331.2261 18.5547 angle 7.5465 town_number 1
016D: restart_if_busted_at 632.2344 -571.7104 15.3515 angle 267.2 town_number 1
016C: restart_if_wasted_at -2199.719 -2308.075 29.6181 angle 322.8928 town_number 1
016D: restart_if_busted_at -2163.829 -2387.817 29.625 angle 134.2066 town_number 1
016C: restart_if_wasted_at -2670.285 616.4364 13.4531 angle 183.1042 town_number 1
016D: restart_if_busted_at -1605.792 716.8598 11.0241 angle 355.2978 town_number 1
016C: restart_if_wasted_at -316.3832 1056.045 18.7344 angle 1.6017 town_number 2
016D: restart_if_busted_at -212.1889 979.4168 18.3219 angle 278.0478 town_number 2
016C: restart_if_wasted_at -1514.823 2527.119 54.7443 angle 2.3546 town_number 2
016D: restart_if_busted_at -1393.072 2633.116 54.9491 angle 86.0424 town_number 2
016C: restart_if_wasted_at 1578.446 1770.682 9.8358 angle 99.7567 town_number 2
016D: restart_if_busted_at 2337.083 2453.802 13.9765 angle 90.7643 town_number 2
fade 1 0
create_thread @SAVE 
create_thread @STARTER
create_thread @STARTER_NEW
create_thread @STARTER_3 // наш новый код
end_thread 

:SAVE
thread 'SAVE'
wait 0
if AND
$ONMISSION == 0
0AB0: key_pressed 115
then
03D8: show_save_screen 
wait 250
end
jump @SAVE

:STARTER 
thread 'STARTER'
wait 0
$ICON = marker.CreateIconAndSphere(15, 2287.793, -1667.109, 15.0317)

:STARTER_1
wait 0
if AND
$ONMISSION == 0
00EC: actor $PLAYER_ACTOR 0 near_point 2287.793 -1667.109 radius 15.0317 3.0 
jf @STARTER_1
marker.Disable($ICON)
00BA: show_text_styled GXT 'MIS_01' time 1000 style 2 
start_mission 0
end_thread

:STARTER_NEW 
thread 'STARTER_NEW'
wait 0
$ICON_NEW = marker.CreateIconAndSphere(38, 2510.8367, -1672.7837, 12.442)

:STARTER_NEW_1
wait 0
if AND
$ONMISSION == 0
0102: actor $PLAYER_ACTOR in_sphere 2510.8367 -1672.7837 12.442 radius 2.0 2.0 2.0 sphere 0 stopped_on_foot 
jf @STARTER_NEW_1
if AND
8741: not actor $PLAYER_ACTOR busted 
not actor.Dead($PLAYER_ACTOR)
jf @STARTER_NEW_1
if
not actor.Driving($PLAYER_ACTOR)
jf @STARTER_NEW_1
marker.Disable($ICON_NEW)
00BA: show_text_styled GXT 'MIS_02' time 1000 style 2 
start_mission 1
end_thread

:STARTER_3 
thread 'STARTER_3'
wait 0
$ICON3 = marker.CreateIconAndSphere(28, 2486.7761, -1650.9607, 12.4845)

:STARTER_3_1
wait 0
if AND
$ONMISSION == 0
0102: actor $PLAYER_ACTOR in_sphere 2486.7761 -1650.9607 12.4845 radius 2.0 2.0 2.0 sphere 0 stopped_on_foot 
jf @STARTER_3_1
if AND
8741: not actor $PLAYER_ACTOR busted 
not actor.Dead($PLAYER_ACTOR)
jf @STARTER_3_1
if
not actor.Driving($PLAYER_ACTOR)
jf @STARTER_3_1
marker.Disable($ICON3)
player.CanMove($PLAYER_CHAR) = false
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
00BA: show_text_styled GXT 'MIS_03' time 1000 style 2 
fade 0 2000
wait 2000
start_mission 2
end_thread

//-------------Mission 0---------------
// Originally: MISSION_0

:MISSION_0
thread 'MISSION_0'
gosub @MISSION_0_29_57 
if 
wasted_or_busted 
jf @MISSION_0_29_46 
gosub @MISSION_0_29_144 

:MISSION_0_29_46
$ONMISSION = 0 
mission_cleanup 
end_thread 

:MISSION_0_29_57
increment_mission_attempts 
$ONMISSION = 1 
018A: 1@ = create_checkpoint_at 2184.3604 -1774.8608 12.3665
03BC: 2@ = create_sphere_at 2184.3604 -1774.8608 12.3665 radius 2.0 
00BB: show_text_lowpriority GXT 'MS_0101' time 3000 flag 1

:MISSION_0_A
wait 0
if
00EC: actor $PLAYER_ACTOR 0 near_point 2184.3604 -1774.8608 radius 12.3665 3.0
jf @MISSION_0_A
marker.Disable(1@)
03BD: destroy_sphere 2@ 
model.Load(#BARREL4)
038B: load_requested_models 

:MISSION_0_B
wait 0
if
model.Available(#BARREL4)
jf @MISSION_0_B
0@ = object.Create(#BARREL4, 2153.9919, -1796.8591, 12.5507)
object.Angle(0@) = 277.5201
model.Destroy(#BARREL4)
3@ = marker.CreateAboveObject(0@)
00BB: show_text_lowpriority GXT 'MS_0102' time 3000 flag 1

:MISSION_0_C
wait 0
if
0366: object 0@ damaged
jf @MISSION_0_C
0318: set_latest_mission_passed 'MIS_01' 
01E3: show_text_1number_styled GXT 'M_PASS' number 5000 time 4000 style 1 
Player.Money($PLAYER_CHAR) += 5000
play_music 1
gosub @MISSION_0_END
create_thread @STARTER
return 

:MISSION_0_29_144
wait 0 
gosub @MISSION_0_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 
create_thread @STARTER
return

:MISSION_0_END
wait 0
if
03CA: object 0@ exists
then
object.RemoveReferences(0@)
object.Destroy(0@)
end 
marker.Disable(1@)
marker.Disable(3@)
03BD: destroy_sphere 2@ 
return 

//-------------Mission 1---------------
// Originally: MISSION_1

:MISSION_1
thread 'MISSION_1'
gosub @MISSION_1_29_57 
if 
wasted_or_busted 
jf @MISSION_1_29_46 
gosub @MISSION_1_29_144 

:MISSION_1_29_46
$ONMISSION = 0 
mission_cleanup 
end_thread 

:MISSION_1_29_57
increment_mission_attempts 
$ONMISSION = 1 
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
player.CanMove($PLAYER_CHAR) = false
0169: set_fade_color_RGB 0 128 128 
016A: fade 0 time 1000 
wait 3000
03DE: set_pedestrians_density_multiplier_to 0.0 
01EB: set_traffic_density_multiplier_to 0.0 
0395: clear_area 0 at 2506.3228 -1666.5116 12.3863 radius 300.0 
0826: enable_hud 0 
02A3: enable_widescreen 1 
model.Load(#GREENWOO)
038B: load_requested_models 

:MISSION_1_A
wait 0
if
model.Available(#GREENWOO)
jf @MISSION_1_A
0@ = car.Create(#GREENWOO, 2506.3228, -1666.5116, 12.3863)
car.Angle(0@) = 90.795
car.SetImmunities(0@, 1, 1, 1, 1, 1)
model.Destroy(#GREENWOO)
05CB: AS_actor $PLAYER_ACTOR enter_car 0@ as_driver 0 ms 

:MISSION_1_B
wait 0
if
actor.InCar($PLAYER_ACTOR, 0@)
jf @MISSION_1_B
04E4: unknown_refresh_game_renderer_at 2501.5085 -1669.8973
Camera.SetAtPos(2501.5085, -1669.8973, 13.3562)
Camera.SetPosition(2501.5085, -1669.8973, 13.3562, 0.0, 0.0, 0.0)
Camera.PointAt(2506.3228, -1666.5116, 12.3863, 2)
wait 2000
03E6: remove_text_box 
00BE: text_clear_all 
016A: fade 1 time 1000
wait 1000
00BC: show_text_highpriority GXT 'MS01_01' time 4000 flag 1 
wait 4000
0936: set_camera 2501.5085 -1669.8973 13.3562 position_to 2501.0186 -1665.4775 13.3554 time 7000 drop_mode 1 
0920: point_camera 2506.3228 -1666.5116 12.3863 transverse_to 2506.3228 -1666.5116 12.3863 time 7000 mode 1 
wait 6990 
Camera.SetPosition(2501.0186, -1665.4775, 13.3554, 0.0, 0.0, 0.0)
Camera.PointAt(2506.3228, -1666.5116, 12.3863, 2) 
00BC: show_text_highpriority GXT 'MS01_02' time 5000 flag 1 
wait 5000
0169: set_fade_color_RGB 0 128 128 
016A: fade 0 time 1000 
wait 1000
car.RemoveReferences(0@)
03DE: set_pedestrians_density_multiplier_to 1.0 
01EB: set_traffic_density_multiplier_to 1.0 
0826: enable_hud 1 
02A3: enable_widescreen 0 
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer 
03E6: remove_text_box 
00BE: text_clear_all 
wait 2000
0169: set_fade_color_RGB 0 128 128 
016A: fade 1 time 1000 
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
player.CanMove($PLAYER_CHAR) = true
0318: set_latest_mission_passed 'MIS_02' 
01E3: show_text_1number_styled GXT 'M_PASS' number 5000 time 4000 style 1 
Player.Money($PLAYER_CHAR) += 5000
play_music 1
gosub @MISSION_1_END
create_thread @STARTER_NEW
return 

:MISSION_1_29_144
wait 0 
gosub @MISSION_1_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 
create_thread @STARTER_NEW 
return

:MISSION_1_END
wait 0 
return 

// код новой миссии
//-------------Mission 2---------------
// Originally: MISSION_2

:MISSION_2
thread 'MISSION_2'
gosub @MISSION_2_29_57 
if 
wasted_or_busted 
jf @MISSION_2_29_46 
gosub @MISSION_2_29_144 

:MISSION_2_29_46
$ONMISSION = 0 
mission_cleanup 
end_thread 

:MISSION_2_29_57
increment_mission_attempts 
$ONMISSION = 1 
03DE: set_pedestrians_density_multiplier_to 0.0 
01EB: set_traffic_density_multiplier_to 0.0 
0395: clear_area 0 at 2478.7612 -1651.6365 13.4687 radius 300.0 
0826: enable_hud 0 
02A3: enable_widescreen 1 
model.Load(#CELLPHONE)
038B: load_requested_models 

:MISSION_2_A
wait 0
if
model.Available(#CELLPHONE)
jf @MISSION_2_A
actor.PutAt($PLAYER_ACTOR, 2478.7612, -1651.6365, 13.4687)
actor.Angle($PLAYER_ACTOR) = 108.0285
04E4: unknown_refresh_game_renderer_at 2476.7725 -1655.647
Camera.SetAtPos(2476.7725, -1655.647, 13.3275)
Camera.SetPosition(2476.7725, -1655.647, 13.3275, 0.0, 0.0, 0.0)
Camera.PointAt(2478.7612, -1651.6365, 13.4687, 2)
wait 2000
03E6: remove_text_box 
00BE: text_clear_all 
016A: fade 1 time 1000
wait 1000
0729: AS_actor $PLAYER_ACTOR hold_cellphone 1 
wait 2000
00BC: show_text_highpriority GXT 'MS03_01' time 6000 flag 1 
wait 6000
0967: actor $PLAYER_ACTOR move_mouth 4000 ms 
00BC: show_text_highpriority GXT 'MS03_02' time 4000 flag 1
wait 4000 
0968: actor $PLAYER_ACTOR stop_mouth 
0729: AS_actor $PLAYER_ACTOR hold_cellphone 0 
wait 2000
016A: fade 0 time 1000
wait 2000
03DE: set_pedestrians_density_multiplier_to 1.0 
01EB: set_traffic_density_multiplier_to 1.0 
0826: enable_hud 1 
02A3: enable_widescreen 0 

:MISSION_2_B
wait 0
model.Load(#BALLAS1)
038B: load_requested_models 

:MISSION_2_C
wait 0
if
model.Available(#BALLAS1)
jf @MISSION_2_C
0@ = actor.Create(8, #BALLAS1, 2419.8154, -1687.3512, 13.7861)
actor.SetImmunities(0@, 1, 1, 1, 1, 1) 
actor.Angle(0@) = 359.3008
actor.Health(0@) = 500
1@ = marker.CreateAboveActor(0@)
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer 
03E6: remove_text_box 
00BE: text_clear_all
016A: fade 1 time 1000 
wait 1000
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
player.CanMove($PLAYER_CHAR) = true
00BC: show_text_highpriority GXT 'MS03_03' time 3000 flag 1 

:MISSION_2_D
wait 0
if
00F2: actor $PLAYER_ACTOR near_actor 0@ radius 4.0 4.0 0 
jf @MISSION_2_D
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
player.CanMove($PLAYER_CHAR) = false
016A: fade 0 time 1000
wait 1000
actor.PutAt($PLAYER_ACTOR, 2419.7251, -1683.7125, 13.7646)
actor.Angle($PLAYER_ACTOR) = 180.0
actor.PutAt(0@, 2419.8154, -1687.3512, 13.7861)
actor.Angle(0@) = 0.0
04E4: unknown_refresh_game_renderer_at 2419.7251 -1683.7125
Camera.SetAtPos(2419.7251, -1683.7125, 14.7626)
Camera.SetPosition(2419.7251, -1683.7125, 14.7626, 0.0, 0.0, 0.0)
Camera.PointAt(2420.2771, -1686.0566, 13.7886, 2)
0826: enable_hud 0 
02A3: enable_widescreen 1
04ED: load_animation "BAR" 

:MISSION_2_E
wait 0
if
04EE: animation "BAR" loaded 
jf @MISSION_2_E
wait 1500
016A: fade 1 time 1000
wait 1000
0967: actor 0@ move_mouth 3500 ms 
0605: actor 0@ perform_animation_sequence "Barcustom_order" IFP_file "BAR" 4.0 loop 0 0 0 0 time 3500 
00BC: show_text_highpriority GXT 'MS03_04' time 3500 flag 1
wait 3500
0968: actor 0@ stop_mouth 
0967: actor $PLAYER_ACTOR move_mouth 2330 ms 
0605: actor $PLAYER_ACTOR perform_animation_sequence "Barserve_loop" IFP_file "BAR" 4.0 loop 0 0 0 0 time 2330
00BC: show_text_highpriority GXT 'MS03_05' time 2330 flag 1
wait 2330
0968: actor $PLAYER_ACTOR stop_mouth 
016A: fade 0 time 1000
wait 1000 
04EF: release_animation "BAR" 
0826: enable_hud 1 
02A3: enable_widescreen 0
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer 
03E6: remove_text_box 
00BE: text_clear_all
wait 1500
016A: fade 1 time 1000
wait 1000 
05E2: AS_actor 0@ kill_actor $PLAYER_ACTOR 
actor.SetImmunities(0@, 0, 0, 0, 0, 0)
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
player.CanMove($PLAYER_CHAR) = true

:MISSION_2_F
wait 0
if
actor.Dead(0@)
jf @MISSION_2_F
marker.Disable(1@)
wait 2000
0318: set_latest_mission_passed 'MIS_03' 
01E3: show_text_1number_styled GXT 'M_PASS' number 10000 time 4000 style 1 
Player.Money($PLAYER_CHAR) += 10000
play_music 1
gosub @MISSION_2_END
create_thread @STARTER_3
return 

:MISSION_2_29_144
wait 0 
gosub @MISSION_2_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 
create_thread @STARTER_3 
return

:MISSION_2_END
wait 0 
if
075C: marker 1@ enabled 
then
marker.Disable(1@)
end
if
056D: actor 0@ defined
then
actor.RemoveReferences(0@)
actor.DestroyInstantly(0@)
end
return
```

Неплохо вышло, только камера во втором ролике не совсем корректно стоит. Ваша задача - сделать её нормальной :)|1294|1|0|15513934`png`731`445`400`243``\|77197739`png`729`445`400`244``\|84390702`png`478`127`400`106``||animacija\_osnovnye\_komandy\_i\_primery\_ikh\_ispolzovanija|1498919369


# 00041. Работа с интерьерами

Работа с интерьерами|Всем привет! Давненько в нас не было обновлений и вот, решил написать новый урок. Как вы уже догадались, речь пойдёт об интерьерах. Вы узнаете какие есть интерьеры и что с ними можно делать.|wmysterio|||||В игре есть много интерьеров. Некоторые из них были не доступны для CJ, но путём скриптинга мы сделаем возможность входить в них, например в дом Райдера или Свита. Заглянув базу данных, вы сможете узнать все интерьеры и их номера ( см. [Интерьеры](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/interery_v_gta_san_andreas/1-1-0-23/README.md) ). Как видите, несколько интерьеров имеют одинаковый номер.

Перейдём к делу. В первую очередь, нужно активировать нужный интерьер. Делается это опкодом:

```
04BB: select_interior 1
```

Здесь:\
1 - номер интерьера

Дальше нам следует переместить актёра в этот интерьер:

```
0860: link_actor $PLAYER_ACTOR to_interior 1
```

Для автомобилей:

```
0840: link_car 379@ to_interior 1
```

Для объектов:

```
0566: link_object $2703 to_interior 1
```

Здесь:\
$PLAYER\_ACTOR - хендл актёра\
379@ - хендл машины\
$2703 - хендл объекта\
1 - номер интерьера

После этой операции нужно уже перемещать актёра/транспорт/объект в координаты интерьера. Увы, я не знаю координаты всех интерьеров, но несколько из них я постараюсь вам предоставить.

Также можно отключать интерьеры, то есть CJ не сможет входить в них. Делается опкодом:

```
07FB: set_interior 'CARLS' access 0
```

Здесь:\
'CARLS' - имя интерьера\
0 - отключить интерьер ( если поставить 1 - включить )

В этом примере зайти в дом CJ на Гроув будет невозможно. Также есть опкод, который редко используется - указать цвет интерьера:

```
04F9: set_interior 1 color_to 4
```

Здесь:\
1 - номер интерьера\
4 - номер цвета

Также можно записать в переменную номер текущего интерьера:

```
09E8: 1@ = actor $PLAYER_ACTOR active_interior
077E: get_active_interior_to 1@
```

Первый опкод получает интерьер, в котором находится актёр. Второй - интерьер, который сейчас активный.

Здесь:\
1@ - переменная, в которую будет записан номер интерьера\
$PLAYER\_ACTOR - актёр, номер интерьера которого будет считано

Также, как и номер интерьера, можно записать в переменную, имя интерьера:

```
094B: v$ACTIVE_INTERIOR_NAME = get_active_interior_name_from_actor $PLAYER_ACTOR
```

Здесь:\
v$ACTIVE\_INTERIOR\_NAME - строковая переменная, в которой будет хранится имя интерьера\
$PLAYER\_ACTOR - актёр, имя интерьера которого будет прочитано

Основные опкоды для работы с интерьерами мы рассмотрели. Давайте напишем теперь скрипт, что бы был входной маркер у дома свита. И когда СЖ возле него, нас телепортировало в интерьер Свита.

```
:ITERIOR
thread 'ITERIOR'
wait 0
0A40: $MARKER_SWEER = create_entrance_marker_at 2522.3816 -1679.3961 16.497 color 4 
0A40: $MARKER_SWEER_1 = create_entrance_marker_at 2524.7561 -1679.386 1016.4986 color 4 

:ITERIOR_1
wait 0 
if
00FF: actor $PLAYER_ACTOR sphere 0 in_sphere 2522.3816 -1679.3961 15.497 radius 1.5 1.5 1.5 on_foot 
jf @ITERIOR 
player.CanMove($PLAYER_CHAR) = false
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
fade 0 1000
wait 1000
04BB: select_interior 1 
0860: link_actor $PLAYER_ACTOR to_interior 1 
actor.PutAt($PLAYER_ACTOR, 2527.5676, -1679.5599, 1015.4986)
actor.Angle($PLAYER_ACTOR) = 270.9803
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer 
wait 2000
fade 1 1000
wait 1000
player.CanMove($PLAYER_CHAR) = true
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)

:ITERIOR_2
wait 0 
if
actor.Dead($PLAYER_ACTOR)
then
jump @ITERIOR_1
end
00FF: actor $PLAYER_ACTOR sphere 0 in_sphere 2524.8591 -1679.4088 1015.4986 radius 1.5 1.5 1.5 on_foot 
jf @ITERIOR_2 
player.CanMove($PLAYER_CHAR) = false
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
fade 0 1000
wait 1000
04BB: select_interior 0 
0860: link_actor $PLAYER_ACTOR to_interior 0 
actor.PutAt($PLAYER_ACTOR, 2518.9583, -1678.6345, 14.596)
actor.Angle($PLAYER_ACTOR) = 64.7881
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer 
wait 2000
fade 1 1000
wait 1000
player.CanMove($PLAYER_CHAR) = true
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
jump @ITERIOR_1
```

Конечно, это не самый идеальный интерьер, так как местами можно провалится :D Но зато Вы сможете входить в интерьер Свита. Кстати, улица так же является одним большим интерьером и имеет номер 0. Давайте добавим этот кусок скрипта в наш main.scm:

```
// WMYSTERIO, ru-script.3dn.ru

DEFINE OBJECTS 1
DEFINE OBJECT SANNY BUILDER 3.04 

DEFINE MISSIONS 3
DEFINE MISSION 0 AT @MISSION_0 // 1 
DEFINE MISSION 1 AT @MISSION_1 // 2
DEFINE MISSION 2 AT @MISSION_2 // 3
 
DEFINE EXTERNAL_SCRIPTS 0

DEFINE UNKNOWN_EMPTY_SEGMENT 0

DEFINE UNKNOWN_THREADS_MEMORY 3072

{$VERSION 3.1.0027}

//-------------MAIN---------------
thread 'MAIN'
set_wb_check_to 0
set_weather 0
select_interior 0
fade 0 0
0180: set_on_mission_flag_to $ONMISSION
00C0: set_current_time_hours_to 8 minutes_to 0
04E4: unknown_refresh_game_renderer_at 2491.1572 -1670.3434
Camera.SetAtPos(2491.1572, -1670.3434, 12.3359)
$PLAYER_CHAR = Player.Create(#NULL, 2491.1572, -1670.3434, 12.3359)
$PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
Actor.Angle($PLAYER_ACTOR) = 66.3548
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
Camera.SetBehindPlayer
Player.SetClothes($PLAYER_CHAR, "WORKTRCAMOGRN", "WORKTR", 2)
Player.SetClothes($PLAYER_CHAR, "SNEAKERBINCGANG", "SNEAKER", 3)
Player.SetClothes($PLAYER_CHAR, "TSHIRTERISORN", "TSHIRT", 0) 
Player.Build($PLAYER_CHAR)
Player.CanMove($PLAYER_CHAR) = True
$TRAMPLIN = object.Create(#AD_JUMP, 2480.5842, -1721.8175, 12.5488)
object.Angle($TRAMPLIN) = 180.0
object.SetImmunities($TRAMPLIN, 1, 1, 1, 1, 1)
Object.Indestructibility($TRAMPLIN) = False
Object.RemoveFromMissionCleanupList($TRAMPLIN)
0879: enable_gang_wars 1
076C: set_zone 'GAN1' gang 1 density_to 40 
076C: set_zone 'GAN2' gang 1 density_to 80 
076C: set_zone 'IWD1' gang 0 density_to 40 
076C: set_zone 'IWD2' gang 0 density_to 80 
076C: set_zone 'IWD3A' gang 2 density_to 40 
076C: set_zone 'IWD3B' gang 2 density_to 80 
0237: set_gang 0 weapons_to 22 31 14 
0237: set_gang 1 weapons_to 30 28 17 
0237: set_gang 2 weapons_to 36 15 27 
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 6
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 6 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 8 to_actors_pedtype 9
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 7
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 8
0746: set_acquaintance 4 of_actors_pedtype 7 to_actors_pedtype 0
0746: set_acquaintance 0 of_actors_pedtype 8 to_actors_pedtype 0
0746: set_acquaintance 4 of_actors_pedtype 9 to_actors_pedtype 0
0767: set_zone 'MARKST' popcycle_group_for_peds_and_cars_to 14
0767: set_zone 'UNITY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'LAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2A' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LAIR2B' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'LBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'BLUF1A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BLUF2' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN3C' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'SUN4' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'COM1A' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM1B' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'COM4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PER1' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'CHC1A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC1B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2A' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC2B' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'CHC3' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'CHC4B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'CHC1A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC1B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC2B' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC3' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4A' popcycle_group_for_peds_to 9 
0874: set_zone 'CHC4B' popcycle_group_for_peds_to 9 
0767: set_zone 'CONF1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'CONF1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'THALL1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDOC1A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC3C' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDOC4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LDT1A' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1B' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT1C' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LDT5' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT6' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'LDT7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE2B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'EBE3C' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'ELCO1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'ELCO2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELCO1' popcycle_group_for_peds_to 9 
0874: set_zone 'ELCO2' popcycle_group_for_peds_to 9 
0767: set_zone 'GAN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GAN2' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'GAN1' popcycle_group_for_peds_to 1 
0874: set_zone 'GAN2' popcycle_group_for_peds_to 1 
0767: set_zone 'GLN1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'GLN2A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LIND1B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2A' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND2B' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LIND3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'IWD1' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD4' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'IWD5' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'IWD1' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD2' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3A' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD3B' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD4' popcycle_group_for_peds_to 1 
0874: set_zone 'IWD5' popcycle_group_for_peds_to 1 
0767: set_zone 'JEF1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JEF3C' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LFL1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'LFL1B' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'LFL1A' popcycle_group_for_peds_to 9 
0874: set_zone 'LFL1B' popcycle_group_for_peds_to 9 
0767: set_zone 'LMEX1A' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LMEX1B' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ELS1A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS1B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS2' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3A' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS3B' popcycle_group_for_peds_and_cars_to 7 
0767: set_zone 'ELS4' popcycle_group_for_peds_and_cars_to 7 
0874: set_zone 'ELS1A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS1B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS2' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3A' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS3B' popcycle_group_for_peds_to 10 
0874: set_zone 'ELS4' popcycle_group_for_peds_to 10 
0767: set_zone 'MAR1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'MAR2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MAR3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'MKT1' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT2' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT3' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MKT4' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'MUL1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL1C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL2A' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL2B' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL3' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'MUL4' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL5C' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL6' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'MUL7B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'PLS' popcycle_group_for_peds_and_cars_to 8
0767: set_zone 'RIH1A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH1B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH2' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3A' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH3B' popcycle_group_for_peds_and_cars_to 15 
0767: set_zone 'RIH4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'RIH6B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD1A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD1C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD2B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD3B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4A' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4B' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD4C' popcycle_group_for_peds_and_cars_to 14 
0767: set_zone 'ROD5A' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'ROD5B' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SMB1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'SMB2' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VIN2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1A' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VIN1B' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'VERO1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'VERO2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'VERO4A' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'VERO4B' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'CRANB' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CALT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'SUNMA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SUNNN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'BATTP' popcycle_group_for_peds_and_cars_to 2
0767: set_zone 'ESPN1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPN3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'BAYV' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'PARA' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'JUNIHO' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JUNIHI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CIVI' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'CHINA' popcycle_group_for_peds_and_cars_to 9
0874: set_zone 'CHINA' popcycle_group_for_peds_to 6
0767: set_zone 'SFDWT1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFDWT4' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT5' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'SFDWT6' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'FINA' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'CITYS' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'WESTP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'WESTP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'THEA1' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'THEA3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'GARC' popcycle_group_for_peds_and_cars_to 7
0767: set_zone 'HASH' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'OCEAF1' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'OCEAF2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'OCEAF3' popcycle_group_for_peds_and_cars_to 8 
0767: set_zone 'DOH1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'DOH2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'CUNTC1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'CUNTC3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'SFGLF1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF2' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF3' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'SFGLF4' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'HILLP' popcycle_group_for_peds_and_cars_to 10
0767: set_zone 'SILLY1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY3' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SILLY4' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'SFAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR4' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFAIR5' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'SFBAG1' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG2' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'SFBAG3' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'EASB1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'EASB2' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'ESPE1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'ESPE3' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'LINDEN' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YELLOW' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'BFC1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BFC2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'RIE' popcycle_group_for_peds_and_cars_to 0
0767: set_zone 'LDM' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'RSW1' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSW2' popcycle_group_for_peds_and_cars_to 6 
0767: set_zone 'RSE' popcycle_group_for_peds_and_cars_to 6
0767: set_zone 'LDS' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'SRY' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'JTS1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTS2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'LVA1' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'LVA3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'LVA4' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'VAIR1' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR2' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'VAIR3' popcycle_group_for_peds_and_cars_to 16 
0767: set_zone 'LVBAG' popcycle_group_for_peds_and_cars_to 19 
0767: set_zone 'GGC1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'GGC2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'BFLD1' popcycle_group_for_peds_and_cars_to 10 
0767: set_zone 'BFLD2' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'WWE' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'WWE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PINT' popcycle_group_for_peds_and_cars_to 5
0767: set_zone 'YBELL2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'YBELL1' popcycle_group_for_peds_and_cars_to 17 
0767: set_zone 'JTW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN5' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN6' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN7' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTN8' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'JTE4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'HGP' popcycle_group_for_peds_and_cars_to 4
0767: set_zone 'SPIN' popcycle_group_for_peds_and_cars_to 11
0767: set_zone 'BINT1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT3' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'BINT4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'PRP1' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP2' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP3' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'PRP4' popcycle_group_for_peds_and_cars_to 4 
0767: set_zone 'REDE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'REDE3' popcycle_group_for_peds_and_cars_to 2 
0767: set_zone 'REDW1' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW2' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'REDW3' popcycle_group_for_peds_and_cars_to 11 
0767: set_zone 'REDW4' popcycle_group_for_peds_and_cars_to 5 
0767: set_zone 'ROCE1' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'ROCE2' popcycle_group_for_peds_and_cars_to 0 
0767: set_zone 'OVS' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CREE' popcycle_group_for_peds_and_cars_to 9
0767: set_zone 'STRIP1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP2' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STRIP3' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STRIP4' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'PILL1' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'PILL2' popcycle_group_for_peds_and_cars_to 9 
0767: set_zone 'RING' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'ISLE' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'STAR1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'STAR2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'ROY' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CAM' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'LOT' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PIRA' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'VISA1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'VISA2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI1' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'CALI2' popcycle_group_for_peds_and_cars_to 12 
0767: set_zone 'DRAG' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'PINK' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'HIGH' popcycle_group_for_peds_and_cars_to 12
0767: set_zone 'CONST1' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'ANGPI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'SHACA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BACKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BEACO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FARM' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'PALO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MONT1' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'MTCHI1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI2' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI3' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MTCHI4' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'HBARNS' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'DILLI' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUEB1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'PANOP' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BLUAC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'CREEK1' popcycle_group_for_peds_and_cars_to 3 
0767: set_zone 'MAKO' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'TOPFA' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FERN' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'NROCK' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'HANKY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'LEAFY' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'RED' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'FLINTC' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'WHET' popcycle_group_for_peds_and_cars_to 3
0767: set_zone 'BIGE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELQUE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BARRA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'CARSO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PAYAS' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'PROBE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ELCA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTR' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ARCO' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'VALLE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'FLINTI' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'MONINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBINT' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'TOM' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ALDEA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BRUJA' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'ROBAD' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'BONE' popcycle_group_for_peds_and_cars_to 1
0767: set_zone 'HAUL' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'QUARY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'OCTAN' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'PALMS' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY' popcycle_group_for_peds_and_cars_to 18
0767: set_zone 'EBAY2' popcycle_group_for_peds_and_cars_to 18 
0767: set_zone 'DAM' popcycle_group_for_peds_and_cars_to 18
014B: $MY_CAR = init_parked_car_generator #BULLET color -1 -1 0 alarm 0 door_lock 0 1 10000 at 2474.2131 -1690.8783 12.1239 angle 180.0
014C: set_parked_car_generator $MY_CAR cars_to_generate_to 101
0213: $PICKUP_0001 = create_pickup #BODYARMOUR type 15 at 2491.0 -1685.8561 13.5107
032B: $PICKUP_0002 = create_weapon_pickup #MINIGUN group 15 ammo 60 at 2493.0 -1685.8561 13.5107 
02E1: $PICKUP_0003 = create_cash_pickup 500 at 2495.0 -1685.8561 13.5107 permanence_flag 1 
04A6: $PICKUP_0004 = create_asset_money_pickup_at 2497.0 -1685.8561 13.5107 money 10000 10000
016C: restart_if_wasted_at 2027.77 -1420.52 15.99 angle 137.0 town_number 0 
016C: restart_if_wasted_at 1180.85 -1325.57 12.58 angle 271.4 town_number 0
016D: restart_if_busted_at 1550.68 -1675.49 14.51 angle 90.0 town_number 0
016C: restart_if_wasted_at 1244.437 331.2261 18.5547 angle 7.5465 town_number 1
016D: restart_if_busted_at 632.2344 -571.7104 15.3515 angle 267.2 town_number 1
016C: restart_if_wasted_at -2199.719 -2308.075 29.6181 angle 322.8928 town_number 1
016D: restart_if_busted_at -2163.829 -2387.817 29.625 angle 134.2066 town_number 1
016C: restart_if_wasted_at -2670.285 616.4364 13.4531 angle 183.1042 town_number 1
016D: restart_if_busted_at -1605.792 716.8598 11.0241 angle 355.2978 town_number 1
016C: restart_if_wasted_at -316.3832 1056.045 18.7344 angle 1.6017 town_number 2
016D: restart_if_busted_at -212.1889 979.4168 18.3219 angle 278.0478 town_number 2
016C: restart_if_wasted_at -1514.823 2527.119 54.7443 angle 2.3546 town_number 2
016D: restart_if_busted_at -1393.072 2633.116 54.9491 angle 86.0424 town_number 2
016C: restart_if_wasted_at 1578.446 1770.682 9.8358 angle 99.7567 town_number 2
016D: restart_if_busted_at 2337.083 2453.802 13.9765 angle 90.7643 town_number 2
07FB: set_interior 'SWEETS' access 1 // Наш новый скрипт!
fade 1 0
create_thread @SAVE 
create_thread @STARTER
create_thread @STARTER_NEW
create_thread @STARTER_3
create_thread @ITERIOR // Наш новый скрипт!
end_thread 

:ITERIOR
thread 'interior'
wait 0
0A40: $MARKER_SWEER = create_entrance_marker_at 2522.3816 -1679.3961 16.497 color 4 
0A40: $MARKER_SWEER_1 = create_entrance_marker_at 2524.7561 -1679.386 1016.4986 color 4 

:ITERIOR_1
wait 0 
if
00FF: actor $PLAYER_ACTOR sphere 0 in_sphere 2522.3816 -1679.3961 15.497 radius 1.5 1.5 1.5 on_foot 
jf @ITERIOR 
player.CanMove($PLAYER_CHAR) = false
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
fade 0 1000
wait 1000
04BB: select_interior 1 
0860: link_actor $PLAYER_ACTOR to_interior 1 
actor.PutAt($PLAYER_ACTOR, 2527.5676, -1679.5599, 1015.4986)
actor.Angle($PLAYER_ACTOR) = 270.9803
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer 
wait 2000
fade 1 1000
wait 1000
player.CanMove($PLAYER_CHAR) = true
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)

:ITERIOR_2
wait 0 
if
actor.Dead($PLAYER_ACTOR)
then
jump @ITERIOR_1
end
00FF: actor $PLAYER_ACTOR sphere 0 in_sphere 2524.8591 -1679.4088 1015.4986 radius 1.5 1.5 1.5 on_foot 
jf @ITERIOR_2 
player.CanMove($PLAYER_CHAR) = false
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
fade 0 1000
wait 1000
04BB: select_interior 0 
0860: link_actor $PLAYER_ACTOR to_interior 0 
actor.PutAt($PLAYER_ACTOR, 2518.9583, -1678.6345, 14.596)
actor.Angle($PLAYER_ACTOR) = 64.7881
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer 
wait 2000
fade 1 1000
wait 1000
player.CanMove($PLAYER_CHAR) = true
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
jump @ITERIOR_1

:SAVE
thread 'SAVE'
wait 0
if AND
$ONMISSION == 0
0AB0: key_pressed 115
then
03D8: show_save_screen 
wait 250
end
jump @SAVE

:STARTER 
thread 'STARTER'
wait 0
$ICON = marker.CreateIconAndSphere(15, 2287.793, -1667.109, 15.0317)

:STARTER_1
wait 0
if AND
$ONMISSION == 0
00EC: actor $PLAYER_ACTOR 0 near_point 2287.793 -1667.109 radius 15.0317 3.0 
jf @STARTER_1
marker.Disable($ICON)
00BA: show_text_styled GXT 'MIS_01' time 1000 style 2 
start_mission 0
end_thread

:STARTER_NEW 
thread 'STARTER_NEW'
wait 0
$ICON_NEW = marker.CreateIconAndSphere(38, 2510.8367, -1672.7837, 12.442)

:STARTER_NEW_1
wait 0
if AND
$ONMISSION == 0
0102: actor $PLAYER_ACTOR in_sphere 2510.8367 -1672.7837 12.442 radius 2.0 2.0 2.0 sphere 0 stopped_on_foot 
jf @STARTER_NEW_1
if AND
8741: not actor $PLAYER_ACTOR busted 
not actor.Dead($PLAYER_ACTOR)
jf @STARTER_NEW_1
if
not actor.Driving($PLAYER_ACTOR)
jf @STARTER_NEW_1
marker.Disable($ICON_NEW)
00BA: show_text_styled GXT 'MIS_02' time 1000 style 2 
start_mission 1
end_thread

:STARTER_3 
thread 'STARTER_3'
wait 0
$ICON3 = marker.CreateIconAndSphere(28, 2486.7761, -1650.9607, 12.4845)

:STARTER_3_1
wait 0
if AND
$ONMISSION == 0
0102: actor $PLAYER_ACTOR in_sphere 2486.7761 -1650.9607 12.4845 radius 2.0 2.0 2.0 sphere 0 stopped_on_foot 
jf @STARTER_3_1
if AND
8741: not actor $PLAYER_ACTOR busted 
not actor.Dead($PLAYER_ACTOR)
jf @STARTER_3_1
if
not actor.Driving($PLAYER_ACTOR)
jf @STARTER_3_1
marker.Disable($ICON3)
player.CanMove($PLAYER_CHAR) = false
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
00BA: show_text_styled GXT 'MIS_03' time 1000 style 2 
fade 0 2000
wait 2000
start_mission 2
end_thread

//-------------Mission 0---------------
// Originally: MISSION_0

:MISSION_0
thread 'MISSION_0'
gosub @MISSION_0_29_57 
if 
wasted_or_busted 
jf @MISSION_0_29_46 
gosub @MISSION_0_29_144 

:MISSION_0_29_46
$ONMISSION = 0 
mission_cleanup 
end_thread 

:MISSION_0_29_57
increment_mission_attempts 
$ONMISSION = 1 
018A: 1@ = create_checkpoint_at 2184.3604 -1774.8608 12.3665
03BC: 2@ = create_sphere_at 2184.3604 -1774.8608 12.3665 radius 2.0 
00BB: show_text_lowpriority GXT 'MS_0101' time 3000 flag 1

:MISSION_0_A
wait 0
if
00EC: actor $PLAYER_ACTOR 0 near_point 2184.3604 -1774.8608 radius 12.3665 3.0
jf @MISSION_0_A
marker.Disable(1@)
03BD: destroy_sphere 2@ 
model.Load(#BARREL4)
038B: load_requested_models 

:MISSION_0_B
wait 0
if
model.Available(#BARREL4)
jf @MISSION_0_B
0@ = object.Create(#BARREL4, 2153.9919, -1796.8591, 12.5507)
object.Angle(0@) = 277.5201
model.Destroy(#BARREL4)
3@ = marker.CreateAboveObject(0@)
00BB: show_text_lowpriority GXT 'MS_0102' time 3000 flag 1

:MISSION_0_C
wait 0
if
0366: object 0@ damaged
jf @MISSION_0_C
0318: set_latest_mission_passed 'MIS_01' 
01E3: show_text_1number_styled GXT 'M_PASS' number 5000 time 4000 style 1 
Player.Money($PLAYER_CHAR) += 5000
play_music 1
gosub @MISSION_0_END
create_thread @STARTER
return 

:MISSION_0_29_144
wait 0 
gosub @MISSION_0_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 
create_thread @STARTER
return

:MISSION_0_END
wait 0
if
03CA: object 0@ exists
then
object.RemoveReferences(0@)
object.Destroy(0@)
end 
marker.Disable(1@)
marker.Disable(3@)
03BD: destroy_sphere 2@ 
return 

//-------------Mission 1---------------
// Originally: MISSION_1

:MISSION_1
thread 'MISSION_1'
gosub @MISSION_1_29_57 
if 
wasted_or_busted 
jf @MISSION_1_29_46 
gosub @MISSION_1_29_144 

:MISSION_1_29_46
$ONMISSION = 0 
mission_cleanup 
end_thread 

:MISSION_1_29_57
increment_mission_attempts 
$ONMISSION = 1 
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
player.CanMove($PLAYER_CHAR) = false
0169: set_fade_color_RGB 0 128 128 
016A: fade 0 time 1000 
wait 3000
03DE: set_pedestrians_density_multiplier_to 0.0 
01EB: set_traffic_density_multiplier_to 0.0 
0395: clear_area 0 at 2506.3228 -1666.5116 12.3863 radius 300.0 
0826: enable_hud 0 
02A3: enable_widescreen 1 
model.Load(#GREENWOO)
038B: load_requested_models 

:MISSION_1_A
wait 0
if
model.Available(#GREENWOO)
jf @MISSION_1_A
0@ = car.Create(#GREENWOO, 2506.3228, -1666.5116, 12.3863)
car.Angle(0@) = 90.795
car.SetImmunities(0@, 1, 1, 1, 1, 1)
model.Destroy(#GREENWOO)
05CB: AS_actor $PLAYER_ACTOR enter_car 0@ as_driver 0 ms 

:MISSION_1_B
wait 0
if
actor.InCar($PLAYER_ACTOR, 0@)
jf @MISSION_1_B
04E4: unknown_refresh_game_renderer_at 2501.5085 -1669.8973
Camera.SetAtPos(2501.5085, -1669.8973, 13.3562)
Camera.SetPosition(2501.5085, -1669.8973, 13.3562, 0.0, 0.0, 0.0)
Camera.PointAt(2506.3228, -1666.5116, 12.3863, 2)
wait 2000
03E6: remove_text_box 
00BE: text_clear_all 
016A: fade 1 time 1000
wait 1000
00BC: show_text_highpriority GXT 'MS01_01' time 4000 flag 1 
wait 4000
0936: set_camera 2501.5085 -1669.8973 13.3562 position_to 2501.0186 -1665.4775 13.3554 time 7000 drop_mode 1 
0920: point_camera 2506.3228 -1666.5116 12.3863 transverse_to 2506.3228 -1666.5116 12.3863 time 7000 mode 1 
wait 6990 
Camera.SetPosition(2501.0186, -1665.4775, 13.3554, 0.0, 0.0, 0.0)
Camera.PointAt(2506.3228, -1666.5116, 12.3863, 2) 
00BC: show_text_highpriority GXT 'MS01_02' time 5000 flag 1 
wait 5000
0169: set_fade_color_RGB 0 128 128 
016A: fade 0 time 1000 
wait 1000
car.RemoveReferences(0@)
03DE: set_pedestrians_density_multiplier_to 1.0 
01EB: set_traffic_density_multiplier_to 1.0 
0826: enable_hud 1 
02A3: enable_widescreen 0 
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer 
03E6: remove_text_box 
00BE: text_clear_all 
wait 2000
0169: set_fade_color_RGB 0 128 128 
016A: fade 1 time 1000 
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
player.CanMove($PLAYER_CHAR) = true
0318: set_latest_mission_passed 'MIS_02' 
01E3: show_text_1number_styled GXT 'M_PASS' number 5000 time 4000 style 1 
Player.Money($PLAYER_CHAR) += 5000
play_music 1
gosub @MISSION_1_END
create_thread @STARTER_NEW
return 

:MISSION_1_29_144
wait 0 
gosub @MISSION_1_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 
create_thread @STARTER_NEW 
return

:MISSION_1_END
wait 0 
return 

//-------------Mission 1---------------
// Originally: MISSION_2

:MISSION_2
thread 'MISSION_2'
gosub @MISSION_2_29_57 
if 
wasted_or_busted 
jf @MISSION_2_29_46 
gosub @MISSION_2_29_144 

:MISSION_2_29_46
$ONMISSION = 0 
mission_cleanup 
end_thread 

:MISSION_2_29_57
increment_mission_attempts 
$ONMISSION = 1 
03DE: set_pedestrians_density_multiplier_to 0.0 
01EB: set_traffic_density_multiplier_to 0.0 
0395: clear_area 0 at 2478.7612 -1651.6365 13.4687 radius 300.0 
0826: enable_hud 0 
02A3: enable_widescreen 1 
model.Load(#CELLPHONE)
038B: load_requested_models 

:MISSION_2_A
wait 0
if
model.Available(#CELLPHONE)
jf @MISSION_2_A
actor.PutAt($PLAYER_ACTOR, 2478.7612, -1651.6365, 13.4687)
actor.Angle($PLAYER_ACTOR) = 108.0285
04E4: unknown_refresh_game_renderer_at 2476.7725 -1655.647
Camera.SetAtPos(2476.7725, -1655.647, 13.3275)
Camera.SetPosition(2476.7725, -1655.647, 13.3275, 0.0, 0.0, 0.0)
Camera.PointAt(2478.7612, -1651.6365, 13.4687, 2)
wait 2000
03E6: remove_text_box 
00BE: text_clear_all 
016A: fade 1 time 1000
wait 1000
0729: AS_actor $PLAYER_ACTOR hold_cellphone 1 
wait 2000
00BC: show_text_highpriority GXT 'MS03_01' time 6000 flag 1 
wait 6000
0967: actor $PLAYER_ACTOR move_mouth 4000 ms 
00BC: show_text_highpriority GXT 'MS03_02' time 4000 flag 1
wait 4000 
0968: actor $PLAYER_ACTOR stop_mouth 
0729: AS_actor $PLAYER_ACTOR hold_cellphone 0 
wait 2000
016A: fade 0 time 1000
wait 2000
03DE: set_pedestrians_density_multiplier_to 1.0 
01EB: set_traffic_density_multiplier_to 1.0 
0826: enable_hud 1 
02A3: enable_widescreen 0 

:MISSION_2_B
wait 0
model.Load(#BALLAS1)
038B: load_requested_models 

:MISSION_2_C
wait 0
if
model.Available(#BALLAS1)
jf @MISSION_2_C
0@ = actor.Create(8, #BALLAS1, 2419.8154, -1687.3512, 13.7861)
actor.SetImmunities(0@, 1, 1, 1, 1, 1) 
actor.Angle(0@) = 359.3008
actor.Health(0@) = 500
1@ = marker.CreateAboveActor(0@)
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer 
03E6: remove_text_box 
00BE: text_clear_all
016A: fade 1 time 1000 
wait 1000
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
player.CanMove($PLAYER_CHAR) = true
00BC: show_text_highpriority GXT 'MS03_03' time 3000 flag 1 

:MISSION_2_D
wait 0
if
00F2: actor $PLAYER_ACTOR near_actor 0@ radius 4.0 4.0 0 
jf @MISSION_2_D
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
player.CanMove($PLAYER_CHAR) = false
016A: fade 0 time 1000
wait 1000
actor.PutAt($PLAYER_ACTOR, 2419.7251, -1683.7125, 13.7646)
actor.Angle($PLAYER_ACTOR) = 180.0
actor.PutAt(0@, 2419.8154, -1687.3512, 13.7861)
actor.Angle(0@) = 0.0
04E4: unknown_refresh_game_renderer_at 2419.7251 -1683.7125
Camera.SetAtPos(2419.7251, -1683.7125, 14.7626)
Camera.SetPosition(2419.7251, -1683.7125, 14.7626, 0.0, 0.0, 0.0)
Camera.PointAt(2420.2771, -1686.0566, 13.7886, 2)
0826: enable_hud 0 
02A3: enable_widescreen 1
04ED: load_animation "BAR" 

:MISSION_2_E
wait 0
if
04EE: animation "BAR" loaded 
jf @MISSION_2_E
wait 1500
016A: fade 1 time 1000
wait 1000
0967: actor 0@ move_mouth 3500 ms 
0605: actor 0@ perform_animation_sequence "Barcustom_order" IFP_file "BAR" 4.0 loop 0 0 0 0 time 3500 
00BC: show_text_highpriority GXT 'MS03_04' time 3500 flag 1
wait 3500
0968: actor 0@ stop_mouth 
0967: actor $PLAYER_ACTOR move_mouth 2330 ms 
0605: actor $PLAYER_ACTOR perform_animation_sequence "Barserve_loop" IFP_file "BAR" 4.0 loop 0 0 0 0 time 2330
00BC: show_text_highpriority GXT 'MS03_05' time 2330 flag 1
wait 2330
0968: actor $PLAYER_ACTOR stop_mouth 
016A: fade 0 time 1000
wait 1000 
04EF: release_animation "BAR" 
0826: enable_hud 1 
02A3: enable_widescreen 0
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer 
03E6: remove_text_box 
00BE: text_clear_all
wait 1500
016A: fade 1 time 1000
wait 1000 
05E2: AS_actor 0@ kill_actor $PLAYER_ACTOR 
actor.SetImmunities(0@, 0, 0, 0, 0, 0)
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
player.CanMove($PLAYER_CHAR) = true

:MISSION_2_F
wait 0
if
actor.Dead(0@)
jf @MISSION_2_F
marker.Disable(1@)
wait 2000
0318: set_latest_mission_passed 'MIS_03' 
01E3: show_text_1number_styled GXT 'M_PASS' number 10000 time 4000 style 1 
Player.Money($PLAYER_CHAR) += 10000
play_music 1
gosub @MISSION_2_END
create_thread @STARTER_3
return 

:MISSION_2_29_144
wait 0 
gosub @MISSION_2_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 
create_thread @STARTER_3 
return

:MISSION_2_END
wait 0 
if
075C: marker 1@ enabled 
then
marker.Disable(1@)
end
if
056D: actor 0@ defined
then
actor.RemoveReferences(0@)
actor.DestroyInstantly(0@)
end
return
```

В результате мы получили:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/32493694.png)|1180|1|0|32493694\`png\`640\`400\`400\`250\`\`\\||rabota\_s\_intererami|1498919423


# 00036. Катсцены и всё, что необходимо для примитивного видеоролика

Катсцены и всё, что необходимо для примитивного видеоролика|Как вы уже догадались, в этом уроке речь пойдет об катсценах. Думаю в игре вы наблюдали такие катсцены, видеоролики в начале или конце миссии. Сегодня мы сделаем примитивную мини-цену.|wmysterio|wmysterio||||В первую очередь, рассмотрим опкоды для затемнения ( осветления ) экрана. Когда мы начинаем миссию, то экран станет чёрным, и когда ролик заканчивается - возвращается к обычному режиму. Что-же, вот этот опкод:

```
016A: fade 0 time 5000
```

Здесь:\
0 — экран будет затемнятся ( ставать черным ), если поставить 1 - то экран будет осветляться\
5000 — время, за которое экран полностью будет затемнённым ( чем дольше время, тем дольше будет затемнятся. Если поставить ноль, то экран будет затемнятся мгновенно )

Обычно после этого опкода ставят задержку, равную времени затемнения ( осветления ):

<table><thead><tr><th>Код затемнения:</th><th>Код осветления:</th></tr></thead><tbody><tr><td><p>```</p><p>016A: fade 0 time 5000 wait 5000</p><pre><code>&#x3C;/td>&#x3C;td>
</code></pre><p>016A: fade 1 time 5000 wait 5000</p><pre><code>&#x3C;/td>&#x3C;/tr>
&#x3C;/tbody>&#x3C;/table>

Так же мы можем указывать цвет затемнения ( осветления ). Делается это опкодом:

</code></pre><p>0169: set\_fade\_color\_RGB 0 0 0</p><pre><code>

\<div class="panel panel-default">
\<div class="panel-body">
Здесь:\<br>
0 0 0 - цвет, который задаётся в RGB канале ( 1-й параметр - количество красного, 2-й - количество зелёного, 3-й - количество синего ). Если Вы уже владели графическим редакторами, типа Фотошопа, то это для вас не должно быть новостью.
\</div>
\</div>

\<div class="alert alert-danger alert-dismissible" role="alert">
\<button type="button" class="close" data-dismiss="alert" aria-label="Close">\<span aria-hidden="true">\&times;\</span>\</button>
**ВАЖНО:** Все цвета имеют своё ограничения: число должно быть от 0 до 255! Если не указывать этот параметр, то затемнение ( осветление ) будет по-умолчанию чёрным.
\</div>

Давайте сделаем мини-скрипт осветления и затемнения. Сделаем, что бы цвет экрана был красным:

\<table class="table table-bordered">\<tbody>
\<tr>\<th>Код затемнения:\</th>\<th>Код осветления:\</th>\</tr>
\<tr>\<td> </code></pre><p>0169: set\_fade\_color\_RGB 255 0 0 016A: fade 0 time 2000 wait 2000</p><pre><code>\</td>\<td> </code></pre><p>0169: set\_fade\_color\_RGB 255 0 0 016A: fade 1 time 2000 wait 2000</p><pre><code>\</td>\</tr>
\</tbody>\</table>

Чтобы во время катсцены не было ЧП, то есть что бы в кадр не попадали лишние актёры или транспорт, нужно очищать местность. Делается это опкодом:

</code></pre><p>0395: clear\_area 0 at 681.8004 -474.1063 15.5363 radius 3.0</p><pre><code>

\<div class="panel panel-default">
\<div class="panel-body">
Здесь:\<br>
0 - очищает местность от объектов. Если поставить 1, то очищены будут так-же и эффекты\<br>
681.8004 -474.1063 15.5363- координаты, где нужно очистить местность, будет стёрты актёры, транспорт и всё, что попало в радиус действия\<br>
3.0 - указываем радиус действия, обычно я ставлю около 300.0
\</div>
\</div>

Так же очень полезными оподами для создания катсцен являются:

</code></pre><p>01EB: set\_traffic\_density\_multiplier\_to 0.0 03DE: set\_pedestrians\_density\_multiplier\_to 0.0</p><pre><code>

Первый указывает ( регулирует ) частоту появления автомобилей на дорогах. Если поставить "0.0", то машины не будут появляться на дорогах. Аналогично действует и второй опкод, только действует он на пешеходов. Если поставить "1.0", то люди и транспорт будут появляться как обычно. Думаю, правильно будет сначала задать частоту появления авто и людей а затем очищать местность:

</code></pre><p>03DE: set\_pedestrians\_density\_multiplier\_to 0.0 01EB: set\_traffic\_density\_multiplier\_to 0.0 0395: clear\_area 0 at 681.8004 -474.1063 15.5363 radius 3.0</p><pre><code>

Рассмотрим некоторые режимы интерфейса. В первую очередь обратим внимания на радар. Мы его можем убрать, что бы он нам не мешал во время просмотра ролика. Убрать радар можно опкодом:

</code></pre><p>0581: enable\_radar 0</p><pre><code>

Так же можно убрать основной интерфейс: иконки оружия, денег, здоровья и т.п. Так же этим опкодом можно убрать и радар. Рассмотрим его:

</code></pre><p>0826: enable\_hud 0</p><pre><code>

Для возврата в предыдущий режим смените 0 на 1.

Есть очень полезный для видеороликов опкод, который делает широкоформатный режим ( вверху и внизу появляются маленькие черные полоски ). Делается это опкодом:

</code></pre><p>02A3: enable\_widescreen 1</p><pre><code>

Для возврата в предыдущий режим смените 1 на 0.

Рассмотрим основные опкоды для работы с камерой. Чтобы поставить камеру в нужное место, нужно воспользоваться опкодом:

</code></pre><p>Camera.SetPosition(987.4759, -2149.3523, 13.0937, 0.0, 0.0, 0.0)</p><pre><code>

\<div class="panel panel-default">
\<div class="panel-body">
Здесь:\<br>
987.4759, -2149.3523, 13.0937 - координаты точки, где должна стоять камера\<br>
0.0, 0.0, 0.0 - эти параметры так и оставляйте. Они позволяют дополнительно настроить углы разворота камеры.
\</div>
\</div>

Следом за этой командой пишут:

</code></pre><p>Camera.PointAt(987.256, -2150.7703, 13.0937, 2)</p><pre><code>

Этот опкод указывает место, куда будет смотреть камера. Если не поставить эту команду, то камера будет смотреть вверх. Здесь:

\<div class="panel panel-default">
\<div class="panel-body">
Здесь:\<br>
987.256, -2150.7703, 13.0937 - координаты, куда будет смотреть камера\<br>
2 - режим камеры: 2 - будет перемещена мгновенно, если поставить 0 - то камера будет плавно переходить к этой точке.
\</div>
\</div>

Чтобы во время просмотра ролика не было не прорисованных текстур, то нужно освежить местность, то есть быстро прорисовать их. Полезно, когда ролик будет далеко от СЖ. Я рекомендую использовать всегда эти опкоды перед использованием катсцен:

</code></pre><p>04E4: unknown\_refresh\_game\_renderer\_at 987.4759 -2149.3523 Camera.SetAtPos(987.4759, -2149.3523, 13.0937)</p><pre><code>

Второй опкод так же делает прорисовку, но для камеры.

\<div class="panel panel-default">
\<div class="panel-body">
Здесь:\<br>
987.4759, -2149.3523, 13.0937 - координаты прорисовки. В опкоде 04E4 ось Z указывать не нужно
\</div>
\</div>

Раз можно поставить камеру, то значит её можно убрать ( точнее восстановить её в обычный режим )! Рассмотрим пару опкодов:

</code></pre><p>Camera.Restore\_WithJumpCut Camera.SetBehindPlayer</p><pre><code>

Первая команда убирает камеру. Второй - заставляет камеру двигать камеру за игроком, то есть делает камеру как обычно. Советую использовать эту пару вместе.

Так-же, как и актёра или объекта, камеру можно перемещать во время ролика! Рассмотрим два опкода:

</code></pre><p>0936: set\_camera -338.3795 -2146.4304 43.9853 position\_to -273.8923 -2192.0386 28.7383 time 5000 drop\_mode 1 0920: point\_camera -337.1891 -2147.2615 44.0234 transverse\_to -137.0 1257.0 6.0 time 5000 mode 1</p><pre><code>

1-й опкод указывает куда будет перемещаться камера. 2-й - куда будет перемещаться фокус камера. Мы можем назвать место, куда смотрит камера - поинтом. Теперь будет легче объяснить 2-й опкод: перемещает поинт с одной позиции в другую.

\<div class="panel panel-default">
\<div class="panel-body">
Здесь:\<br>
-338.3795 -2146.4304 43.9853 - место, где раньше была позиция камеры\<br>
-273.8923 -2192.0386 28.7383 - место, куда будет перемещена камера\<br>
-337.1891 -2147.2615 44.0234 - место, где раньше была позиция поинта\<br>
-137.0 1257.0 6.0 - место, куда будет перемещен поинт\<br>
5000 - время, за которое будет перемещены камера и поинт. Как правило, время ставят одинаковое\<br>
1 - режим перемещения: 1 будет перемещена плавно, если поставить 0 - то будет перемещена мгновенно
\</div>
\</div>

После этого нужно снова указывать место камеры и её поинт. Здесь важно не запутаться, на простом примере думаю будет легче вам разобраться:

</code></pre><p>Camera.SetPosition(2358.656, -1246.348, 28.7884, 0.0, 0.0, 0.0) Camera.PointAt(2359.521, -1246.843, 28.7047, 2) // ставим камеру и её поинт</p><p>0936: set\_camera 2358.656 -1246.348 28.7884 position\_to 2358.656 -1246.348 28.7884 time 7000 drop\_mode 1 0920: point\_camera 2359.521 -1246.843 28.7047 transverse\_to 2359.276 -1247.129 28.7047 time 7000 mode 1 // перемещаем камеру и поинт wait 7000 // ждём такое же время, как время перемещения камер</p><p>Camera.SetPosition(2358.656, -1246.348, 28.7884, 0.0, 0.0, 0.0) Camera.PointAt(2359.276, -1247.129, 28.7047, 2) // ставим новую камеру и поинт</p><pre><code>

Думаю основные команды для роботы с камерами мы рассмотрели. Давайте сделаем новую миссию, в которой мы будем использовать камеру. Так же напишем новый стартер для этой миссии:

</code></pre><p>// WMYSTERIO, ru-script.3dn.ru</p><p>DEFINE OBJECTS 1 DEFINE OBJECT SANNY BUILDER 3.04</p><p>DEFINE MISSIONS 2 // добавим новую миссию DEFINE MISSION 0 AT @MISSION\_0 DEFINE MISSION 1 AT @MISSION\_1 // добавим номер и метку миссии</p><p>DEFINE EXTERNAL\_SCRIPTS 0</p><p>DEFINE UNKNOWN\_EMPTY\_SEGMENT 0</p><p>DEFINE UNKNOWN\_THREADS\_MEMORY 3072</p><p>{$VERSION 3.1.0027}</p><p>//-------------MAIN--------------- thread 'MAIN' set\_wb\_check\_to 0 set\_weather 0 select\_interior 0 fade 0 0 0180: set\_on\_mission\_flag\_to $ONMISSION 00C0: set\_current\_time\_hours\_to 8 minutes\_to 0 04E4: unknown\_refresh\_game\_renderer\_at 2491.1572 -1670.3434 Camera.SetAtPos(2491.1572, -1670.3434, 12.3359) $PLAYER\_CHAR = Player.Create(#NULL, 2491.1572, -1670.3434, 12.3359) $PLAYER\_ACTOR = Actor.EmulateFromPlayer($PLAYER\_CHAR) Actor.Angle($PLAYER\_ACTOR) = 66.3548 07AF: $PLAYER\_GROUP = player $PLAYER\_CHAR group Camera.SetBehindPlayer Player.SetClothes($PLAYER\_CHAR, "WORKTRCAMOGRN", "WORKTR", 2) Player.SetClothes($PLAYER\_CHAR, "SNEAKERBINCGANG", "SNEAKER", 3) Player.SetClothes($PLAYER\_CHAR, "TSHIRTERISORN", "TSHIRT", 0) Player.Build($PLAYER\_CHAR) Player.CanMove($PLAYER\_CHAR) = True $TRAMPLIN = object.Create(#AD\_JUMP, 2480.5842, -1721.8175, 12.5488) object.Angle($TRAMPLIN) = 180.0 object.SetImmunities($TRAMPLIN, 1, 1, 1, 1, 1) Object.Indestructibility($TRAMPLIN) = False Object.RemoveFromMissionCleanupList($TRAMPLIN) 0879: enable\_gang\_wars 1 076C: set\_zone 'GAN1' gang 1 density\_to 40 076C: set\_zone 'GAN2' gang 1 density\_to 80 076C: set\_zone 'IWD1' gang 0 density\_to 40 076C: set\_zone 'IWD2' gang 0 density\_to 80 076C: set\_zone 'IWD3A' gang 2 density\_to 40 076C: set\_zone 'IWD3B' gang 2 density\_to 80 0237: set\_gang 0 weapons\_to 22 31 14 0237: set\_gang 1 weapons\_to 30 28 17 0237: set\_gang 2 weapons\_to 36 15 27 0746: set\_acquaintance 4 of\_actors\_pedtype 7 to\_actors\_pedtype 6 0746: set\_acquaintance 4 of\_actors\_pedtype 8 to\_actors\_pedtype 6 0746: set\_acquaintance 4 of\_actors\_pedtype 9 to\_actors\_pedtype 6 0746: set\_acquaintance 4 of\_actors\_pedtype 6 to\_actors\_pedtype 7 0746: set\_acquaintance 4 of\_actors\_pedtype 6 to\_actors\_pedtype 8 0746: set\_acquaintance 4 of\_actors\_pedtype 6 to\_actors\_pedtype 9 0746: set\_acquaintance 4 of\_actors\_pedtype 7 to\_actors\_pedtype 8 0746: set\_acquaintance 4 of\_actors\_pedtype 7 to\_actors\_pedtype 9 0746: set\_acquaintance 4 of\_actors\_pedtype 8 to\_actors\_pedtype 7 0746: set\_acquaintance 4 of\_actors\_pedtype 8 to\_actors\_pedtype 9 0746: set\_acquaintance 4 of\_actors\_pedtype 9 to\_actors\_pedtype 7 0746: set\_acquaintance 4 of\_actors\_pedtype 9 to\_actors\_pedtype 8 0746: set\_acquaintance 4 of\_actors\_pedtype 7 to\_actors\_pedtype 0 0746: set\_acquaintance 0 of\_actors\_pedtype 8 to\_actors\_pedtype 0 0746: set\_acquaintance 4 of\_actors\_pedtype 9 to\_actors\_pedtype 0 0767: set\_zone 'MARKST' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'UNITY' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'LAIR1' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'LAIR2A' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'LAIR2B' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'LBAG1' popcycle\_group\_for\_peds\_and\_cars\_to 19 0767: set\_zone 'LBAG2' popcycle\_group\_for\_peds\_and\_cars\_to 19 0767: set\_zone 'LBAG3' popcycle\_group\_for\_peds\_and\_cars\_to 19 0767: set\_zone 'BLUF1A' popcycle\_group\_for\_peds\_and\_cars\_to 10 0767: set\_zone 'BLUF2' popcycle\_group\_for\_peds\_and\_cars\_to 10 0767: set\_zone 'SUN1' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'SUN1' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'SUN3A' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'SUN3B' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'SUN3C' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'SUN4' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'COM1A' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'COM1B' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'COM2' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'COM3' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'COM4' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'PER1' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'CHC1A' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'CHC1B' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'CHC2A' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'CHC2B' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'CHC3' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'CHC4A' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'CHC4B' popcycle\_group\_for\_peds\_and\_cars\_to 7 0874: set\_zone 'CHC1A' popcycle\_group\_for\_peds\_to 9 0874: set\_zone 'CHC1B' popcycle\_group\_for\_peds\_to 9 0874: set\_zone 'CHC2A' popcycle\_group\_for\_peds\_to 9 0874: set\_zone 'CHC2B' popcycle\_group\_for\_peds\_to 9 0874: set\_zone 'CHC3' popcycle\_group\_for\_peds\_to 9 0874: set\_zone 'CHC4A' popcycle\_group\_for\_peds\_to 9 0874: set\_zone 'CHC4B' popcycle\_group\_for\_peds\_to 9 0767: set\_zone 'CONF1A' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'CONF1B' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'THALL1' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'LDOC1A' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LDOC1B' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LDOC2' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LDOC3A' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LDOC3B' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LDOC3C' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LDOC4' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LDT1A' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'LDT1B' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'LDT1C' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'LDT3' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'LDT4' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'LDT5' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'LDT6' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'LDT7' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'EBE1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'EBE2A' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'EBE2B' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'EBE3C' popcycle\_group\_for\_peds\_and\_cars\_to 8 0767: set\_zone 'ELCO1' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'ELCO2' popcycle\_group\_for\_peds\_and\_cars\_to 7 0874: set\_zone 'ELCO1' popcycle\_group\_for\_peds\_to 9 0874: set\_zone 'ELCO2' popcycle\_group\_for\_peds\_to 9 0767: set\_zone 'GAN1' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'GAN2' popcycle\_group\_for\_peds\_and\_cars\_to 7 0874: set\_zone 'GAN1' popcycle\_group\_for\_peds\_to 1 0874: set\_zone 'GAN2' popcycle\_group\_for\_peds\_to 1 0767: set\_zone 'GLN1' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'GLN2A' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'LIND1A' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'LIND1B' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LIND2A' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LIND2B' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LIND3' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'IWD1' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'IWD2' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'IWD3A' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'IWD3B' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'IWD4' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'IWD5' popcycle\_group\_for\_peds\_and\_cars\_to 7 0874: set\_zone 'IWD1' popcycle\_group\_for\_peds\_to 1 0874: set\_zone 'IWD2' popcycle\_group\_for\_peds\_to 1 0874: set\_zone 'IWD3A' popcycle\_group\_for\_peds\_to 1 0874: set\_zone 'IWD3B' popcycle\_group\_for\_peds\_to 1 0874: set\_zone 'IWD4' popcycle\_group\_for\_peds\_to 1 0874: set\_zone 'IWD5' popcycle\_group\_for\_peds\_to 1 0767: set\_zone 'JEF1A' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JEF1B' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JEF2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JEF3A' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JEF3B' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JEF3C' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'LFL1A' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'LFL1B' popcycle\_group\_for\_peds\_and\_cars\_to 7 0874: set\_zone 'LFL1A' popcycle\_group\_for\_peds\_to 9 0874: set\_zone 'LFL1B' popcycle\_group\_for\_peds\_to 9 0767: set\_zone 'LMEX1A' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'LMEX1B' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'ELS1A' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'ELS1B' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'ELS2' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'ELS3A' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'ELS3B' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'ELS4' popcycle\_group\_for\_peds\_and\_cars\_to 7 0874: set\_zone 'ELS1A' popcycle\_group\_for\_peds\_to 10 0874: set\_zone 'ELS1B' popcycle\_group\_for\_peds\_to 10 0874: set\_zone 'ELS2' popcycle\_group\_for\_peds\_to 10 0874: set\_zone 'ELS3A' popcycle\_group\_for\_peds\_to 10 0874: set\_zone 'ELS3B' popcycle\_group\_for\_peds\_to 10 0874: set\_zone 'ELS4' popcycle\_group\_for\_peds\_to 10 0767: set\_zone 'MAR1' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'MAR2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'MAR3' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'MKT1' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'MKT2' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'MKT3' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'MKT4' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'MUL1A' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL1B' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL1C' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL2A' popcycle\_group\_for\_peds\_and\_cars\_to 10 0767: set\_zone 'MUL2B' popcycle\_group\_for\_peds\_and\_cars\_to 10 0767: set\_zone 'MUL3' popcycle\_group\_for\_peds\_and\_cars\_to 10 0767: set\_zone 'MUL4' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL5A' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL5B' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL5C' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL6' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL7A' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'MUL7B' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'PLS' popcycle\_group\_for\_peds\_and\_cars\_to 8 0767: set\_zone 'RIH1A' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'RIH1B' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'RIH2' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'RIH3A' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'RIH3B' popcycle\_group\_for\_peds\_and\_cars\_to 15 0767: set\_zone 'RIH4' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'RIH5A' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'RIH6B' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'RIH5A' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'RIH6B' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'ROD1A' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD1B' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD1C' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD2A' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD2B' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD3A' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD3B' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD4A' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD4B' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD4C' popcycle\_group\_for\_peds\_and\_cars\_to 14 0767: set\_zone 'ROD5A' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'ROD5B' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'SMB1' popcycle\_group\_for\_peds\_and\_cars\_to 8 0767: set\_zone 'SMB2' popcycle\_group\_for\_peds\_and\_cars\_to 8 0767: set\_zone 'VIN2' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'VIN3' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'VIN1A' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'VIN1B' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'VERO1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'VERO2' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'VERO3' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'VERO4A' popcycle\_group\_for\_peds\_and\_cars\_to 8 0767: set\_zone 'VERO4B' popcycle\_group\_for\_peds\_and\_cars\_to 8 0767: set\_zone 'CRANB' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'CALT' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'SUNMA' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'SUNNN' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'BATTP' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'ESPN1' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'ESPN2' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'ESPN3' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'BAYV' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'PARA' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'JUNIHO' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JUNIHI' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'CIVI' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'CHINA' popcycle\_group\_for\_peds\_and\_cars\_to 9 0874: set\_zone 'CHINA' popcycle\_group\_for\_peds\_to 6 0767: set\_zone 'SFDWT1' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'SFDWT2' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'SFDWT3' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'SFDWT4' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'SFDWT5' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'SFDWT6' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'FINA' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'CITYS' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'WESTP1' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'WESTP2' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'WESTP3' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'THEA1' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'THEA2' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'THEA3' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'GARC' popcycle\_group\_for\_peds\_and\_cars\_to 7 0767: set\_zone 'HASH' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'OCEAF1' popcycle\_group\_for\_peds\_and\_cars\_to 8 0767: set\_zone 'OCEAF2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'OCEAF3' popcycle\_group\_for\_peds\_and\_cars\_to 8 0767: set\_zone 'DOH1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'DOH2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'CUNTC1' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'CUNTC2' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'CUNTC3' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'SFGLF1' popcycle\_group\_for\_peds\_and\_cars\_to 17 0767: set\_zone 'SFGLF2' popcycle\_group\_for\_peds\_and\_cars\_to 17 0767: set\_zone 'SFGLF3' popcycle\_group\_for\_peds\_and\_cars\_to 17 0767: set\_zone 'SFGLF4' popcycle\_group\_for\_peds\_and\_cars\_to 17 0767: set\_zone 'HILLP' popcycle\_group\_for\_peds\_and\_cars\_to 10 0767: set\_zone 'SILLY1' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'SILLY2' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'SILLY3' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'SILLY4' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'SFAIR1' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'SFAIR2' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'SFAIR3' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'SFAIR4' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'SFAIR5' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'SFBAG1' popcycle\_group\_for\_peds\_and\_cars\_to 19 0767: set\_zone 'SFBAG2' popcycle\_group\_for\_peds\_and\_cars\_to 19 0767: set\_zone 'SFBAG3' popcycle\_group\_for\_peds\_and\_cars\_to 19 0767: set\_zone 'EASB1' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'EASB2' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'ESPE1' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'ESPE2' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'ESPE3' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'LINDEN' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'YELLOW' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'BFC1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'BFC2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'RIE' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'LDM' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'RSW1' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'RSW2' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'RSE' popcycle\_group\_for\_peds\_and\_cars\_to 6 0767: set\_zone 'LDS' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'SRY' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTS1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTS2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'LVA1' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LVA2' popcycle\_group\_for\_peds\_and\_cars\_to 18 0767: set\_zone 'LVA3' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'LVA4' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'VAIR1' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'VAIR2' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'VAIR3' popcycle\_group\_for\_peds\_and\_cars\_to 16 0767: set\_zone 'LVBAG' popcycle\_group\_for\_peds\_and\_cars\_to 19 0767: set\_zone 'GGC1' popcycle\_group\_for\_peds\_and\_cars\_to 10 0767: set\_zone 'GGC2' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'BFLD1' popcycle\_group\_for\_peds\_and\_cars\_to 10 0767: set\_zone 'BFLD2' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'WWE' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'WWE1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'PINT' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'YBELL2' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'YBELL1' popcycle\_group\_for\_peds\_and\_cars\_to 17 0767: set\_zone 'JTW1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTW2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTN1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTN2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTN3' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTN4' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTN5' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTN6' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTN7' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTN8' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTE1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTE2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTE3' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'JTE4' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'HGP' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'SPIN' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'BINT1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'BINT2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'BINT3' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'BINT4' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'PRP1' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'PRP2' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'PRP3' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'PRP4' popcycle\_group\_for\_peds\_and\_cars\_to 4 0767: set\_zone 'REDE1' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'REDE2' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'REDE3' popcycle\_group\_for\_peds\_and\_cars\_to 2 0767: set\_zone 'REDW1' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'REDW2' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'REDW3' popcycle\_group\_for\_peds\_and\_cars\_to 11 0767: set\_zone 'REDW4' popcycle\_group\_for\_peds\_and\_cars\_to 5 0767: set\_zone 'ROCE1' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'ROCE2' popcycle\_group\_for\_peds\_and\_cars\_to 0 0767: set\_zone 'OVS' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'CREE' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'STRIP1' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'STRIP2' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'STRIP3' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'STRIP4' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'PILL1' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'PILL2' popcycle\_group\_for\_peds\_and\_cars\_to 9 0767: set\_zone 'RING' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'ISLE' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'STAR1' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'STAR2' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'ROY' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'CAM' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'LOT' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'PIRA' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'VISA1' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'VISA2' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'CALI1' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'CALI2' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'DRAG' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'PINK' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'HIGH' popcycle\_group\_for\_peds\_and\_cars\_to 12 0767: set\_zone 'CONST1' popcycle\_group\_for\_peds\_and\_cars\_to 18 0767: set\_zone 'ANGPI' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'SHACA' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'BACKO' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'BEACO' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'FARM' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'PALO' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'MONT' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'MONT1' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'MTCHI1' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'MTCHI2' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'MTCHI3' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'MTCHI4' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'HBARNS' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'DILLI' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'TOPFA' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'BLUEB' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'BLUEB1' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'PANOP' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'BLUAC' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'CREEK' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'CREEK1' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'MAKO' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'TOPFA' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'FERN' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'NROCK' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'HANKY' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'LEAFY' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'RED' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'FLINTC' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'WHET' popcycle\_group\_for\_peds\_and\_cars\_to 3 0767: set\_zone 'BIGE' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'ELQUE' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'BARRA' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'CARSO' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'PAYAS' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'PROBE' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'ELCA' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'FLINTR' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'ARCO' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'VALLE' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'FLINTI' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'MONINT' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'ROBINT' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'TOM' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'ALDEA' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'BRUJA' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'ROBAD' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'BONE' popcycle\_group\_for\_peds\_and\_cars\_to 1 0767: set\_zone 'HAUL' popcycle\_group\_for\_peds\_and\_cars\_to 18 0767: set\_zone 'QUARY' popcycle\_group\_for\_peds\_and\_cars\_to 18 0767: set\_zone 'OCTAN' popcycle\_group\_for\_peds\_and\_cars\_to 18 0767: set\_zone 'PALMS' popcycle\_group\_for\_peds\_and\_cars\_to 18 0767: set\_zone 'EBAY' popcycle\_group\_for\_peds\_and\_cars\_to 18 0767: set\_zone 'EBAY2' popcycle\_group\_for\_peds\_and\_cars\_to 18 0767: set\_zone 'DAM' popcycle\_group\_for\_peds\_and\_cars\_to 18 014B: $MY\_CAR = init\_parked\_car\_generator #BULLET color -1 -1 0 alarm 0 door\_lock 0 1 10000 at 2474.2131 -1690.8783 12.1239 angle 180.0 014C: set\_parked\_car\_generator $MY\_CAR cars\_to\_generate\_to 101 0213: $PICKUP\_0001 = create\_pickup #BODYARMOUR type 15 at 2491.0 -1685.8561 13.5107 032B: $PICKUP\_0002 = create\_weapon\_pickup #MINIGUN group 15 ammo 60 at 2493.0 -1685.8561 13.5107 02E1: $PICKUP\_0003 = create\_cash\_pickup 500 at 2495.0 -1685.8561 13.5107 permanence\_flag 1 04A6: $PICKUP\_0004 = create\_asset\_money\_pickup\_at 2497.0 -1685.8561 13.5107 money 10000 10000 016C: restart\_if\_wasted\_at 2027.77 -1420.52 15.99 angle 137.0 town\_number 0 016C: restart\_if\_wasted\_at 1180.85 -1325.57 12.58 angle 271.4 town\_number 0 016D: restart\_if\_busted\_at 1550.68 -1675.49 14.51 angle 90.0 town\_number 0 016C: restart\_if\_wasted\_at 1244.437 331.2261 18.5547 angle 7.5465 town\_number 1 016D: restart\_if\_busted\_at 632.2344 -571.7104 15.3515 angle 267.2 town\_number 1 016C: restart\_if\_wasted\_at -2199.719 -2308.075 29.6181 angle 322.8928 town\_number 1 016D: restart\_if\_busted\_at -2163.829 -2387.817 29.625 angle 134.2066 town\_number 1 016C: restart\_if\_wasted\_at -2670.285 616.4364 13.4531 angle 183.1042 town\_number 1 016D: restart\_if\_busted\_at -1605.792 716.8598 11.0241 angle 355.2978 town\_number 1 016C: restart\_if\_wasted\_at -316.3832 1056.045 18.7344 angle 1.6017 town\_number 2 016D: restart\_if\_busted\_at -212.1889 979.4168 18.3219 angle 278.0478 town\_number 2 016C: restart\_if\_wasted\_at -1514.823 2527.119 54.7443 angle 2.3546 town\_number 2 016D: restart\_if\_busted\_at -1393.072 2633.116 54.9491 angle 86.0424 town\_number 2 016C: restart\_if\_wasted\_at 1578.446 1770.682 9.8358 angle 99.7567 town\_number 2 016D: restart\_if\_busted\_at 2337.083 2453.802 13.9765 angle 90.7643 town\_number 2 fade 1 0 create\_thread @SAVE create\_thread @STARTER create\_thread @STARTER\_NEW // создаём новый поток со стартером end\_thread</p><p>:SAVE thread 'SAVE' wait 0 if AND $ONMISSION == 0 0AB0: key\_pressed 115 then 03D8: show\_save\_screen wait 250 end jump @SAVE</p><p>:STARTER thread 'STARTER' wait 0 $ICON = marker.CreateIconAndSphere(15, 2287.793, -1667.109, 15.0317)</p><p>:STARTER\_1 wait 0 if AND $ONMISSION == 0 00EC: actor $PLAYER\_ACTOR 0 near\_point 2287.793 -1667.109 radius 15.0317 3.0 jf @STARTER\_1 marker.Disable($ICON) 00BA: show\_text\_styled GXT 'MIS\_01' time 1000 style 2 start\_mission 0 end\_thread</p><p>:STARTER\_NEW // наш новый стартер thread 'STARTER\_NEW' wait 0 $ICON\_NEW = marker.CreateIconAndSphere(38, 2510.8367, -1672.7837, 12.442)</p><p>:STARTER\_NEW\_1 wait 0 if AND $ONMISSION == 0 0102: actor $PLAYER\_ACTOR in\_sphere 2510.8367 -1672.7837 12.442 radius 2.0 2.0 2.0 sphere 0 stopped\_on\_foot jf @STARTER\_NEW\_1 if AND 8741: not actor $PLAYER\_ACTOR busted not actor.Dead($PLAYER\_ACTOR) jf @STARTER\_NEW\_1 if not actor.Driving($PLAYER\_ACTOR) jf @STARTER\_NEW\_1 marker.Disable($ICON\_NEW) 00BA: show\_text\_styled GXT 'MIS\_02' time 1000 style 2 start\_mission 1 end\_thread</p><p>//-------------Mission 0--------------- // Originally: MISSION\_0</p><p>:MISSION\_0 thread 'MISSION\_0' gosub @MISSION\_0\_29\_57 if wasted\_or\_busted jf @MISSION\_0\_29\_46 gosub @MISSION\_0\_29\_144</p><p>:MISSION\_0\_29\_46 $ONMISSION = 0 mission\_cleanup end\_thread</p><p>:MISSION\_0\_29\_57 increment\_mission\_attempts $ONMISSION = 1 018A: 1@ = create\_checkpoint\_at 2184.3604 -1774.8608 12.3665 03BC: 2@ = create\_sphere\_at 2184.3604 -1774.8608 12.3665 radius 2.0 00BB: show\_text\_lowpriority GXT 'MS\_0101' time 3000 flag 1</p><p>:MISSION\_0\_A wait 0 if 00EC: actor $PLAYER\_ACTOR 0 near\_point 2184.3604 -1774.8608 radius 12.3665 3.0 jf @MISSION\_0\_A marker.Disable(1@) 03BD: destroy\_sphere 2@ model.Load(#BARREL4) 038B: load\_requested\_models</p><p>:MISSION\_0\_B wait 0 if model.Available(#BARREL4) jf @MISSION\_0\_B 0@ = object.Create(#BARREL4, 2153.9919, -1796.8591, 12.5507) object.Angle(0@) = 277.5201 model.Destroy(#BARREL4) 3@ = marker.CreateAboveObject(0@) 00BB: show\_text\_lowpriority GXT 'MS\_0102' time 3000 flag 1</p><p>:MISSION\_0\_C wait 0 if 0366: object 0@ damaged jf @MISSION\_0\_C 0318: set\_latest\_mission\_passed 'MIS\_01' 01E3: show\_text\_1number\_styled GXT 'M\_PASS' number 5000 time 4000 style 1 Player.Money($PLAYER\_CHAR) += 5000 play\_music 1 gosub @MISSION\_0\_END create\_thread @STARTER return</p><p>:MISSION\_0\_29\_144 wait 0 gosub @MISSION\_0\_END 00BA: show\_text\_styled GXT 'M\_FAIL' time 5000 style 1 create\_thread @STARTER return</p><p>:MISSION\_0\_END wait 0 if 03CA: object 0@ exists then object.RemoveReferences(0@) object.Destroy(0@) end marker.Disable(1@) marker.Disable(3@) 03BD: destroy\_sphere 2@ return</p><p>// наша новая миссия!!! //-------------Mission 1--------------- // Originally: MISSION\_1</p><p>:MISSION\_1 thread 'MISSION\_1' gosub @MISSION\_1\_29\_57 if wasted\_or\_busted jf @MISSION\_1\_29\_46 gosub @MISSION\_1\_29\_144</p><p>:MISSION\_1\_29\_46 $ONMISSION = 0 mission\_cleanup end\_thread</p><p>:MISSION\_1\_29\_57 increment\_mission\_attempts $ONMISSION = 1 actor.SetImmunities($PLAYER\_ACTOR, 1, 1, 1, 1, 1) player.CanMove($PLAYER\_CHAR) = false 0169: set\_fade\_color\_RGB 0 128 128 016A: fade 0 time 1000 wait 3000 03DE: set\_pedestrians\_density\_multiplier\_to 0.0 01EB: set\_traffic\_density\_multiplier\_to 0.0 0395: clear\_area 0 at 2506.3228 -1666.5116 12.3863 radius 300.0 0826: enable\_hud 0 02A3: enable\_widescreen 1 model.Load(#GREENWOO) 038B: load\_requested\_models</p><p>:MISSION\_1\_A wait 0 if model.Available(#GREENWOO) jf @MISSION\_1\_A 0@ = car.Create(#GREENWOO, 2506.3228, -1666.5116, 12.3863) car.Angle(0@) = 90.795 car.SetImmunities(0@, 1, 1, 1, 1, 1) model.Destroy(#GREENWOO) 05CB: AS\_actor $PLAYER\_ACTOR enter\_car 0@ as\_driver 0 ms</p><p>:MISSION\_1\_B wait 0 if actor.InCar($PLAYER\_ACTOR, 0@) jf @MISSION\_1\_B 04E4: unknown\_refresh\_game\_renderer\_at 2501.5085 -1669.8973 Camera.SetAtPos(2501.5085, -1669.8973, 13.3562) Camera.SetPosition(2501.5085, -1669.8973, 13.3562, 0.0, 0.0, 0.0) Camera.PointAt(2506.3228, -1666.5116, 12.3863, 2) wait 2000 03E6: remove\_text\_box 00BE: text\_clear\_all 016A: fade 1 time 1000 wait 1000 00BC: show\_text\_highpriority GXT 'MS01\_01' time 4000 flag 1 // Я oбычный гaнгcтep, кoтopый дoлжeн yбивaть вpaгoв! wait 4000 0936: set\_camera 2501.5085 -1669.8973 13.3562 position\_to 2501.0186 -1665.4775 13.3554 time 7000 drop\_mode 1 0920: point\_camera 2506.3228 -1666.5116 12.3863 transverse\_to 2506.3228 -1666.5116 12.3863 time 7000 mode 1 wait 6990 Camera.SetPosition(2501.0186, -1665.4775, 13.3554, 0.0, 0.0, 0.0) Camera.PointAt(2506.3228, -1666.5116, 12.3863, 2) 00BC: show\_text\_highpriority GXT 'MS01\_02' time 5000 flag 1 // Хорошо, я знаю место, где их можно найти! Одного легче убить... wait 5000 0169: set\_fade\_color\_RGB 0 128 128 016A: fade 0 time 1000 wait 1000 car.RemoveReferences(0@) 03DE: set\_pedestrians\_density\_multiplier\_to 1.0 01EB: set\_traffic\_density\_multiplier\_to 1.0 0826: enable\_hud 1 02A3: enable\_widescreen 0 Camera.Restore\_WithJumpCut Camera.SetBehindPlayer 03E6: remove\_text\_box 00BE: text\_clear\_all wait 2000 0169: set\_fade\_color\_RGB 0 128 128 016A: fade 1 time 1000 actor.SetImmunities($PLAYER\_ACTOR, 0, 0, 0, 0, 0) player.CanMove($PLAYER\_CHAR) = true 0318: set\_latest\_mission\_passed 'MIS\_02' 01E3: show\_text\_1number\_styled GXT 'M\_PASS' number 5000 time 4000 style 1 Player.Money($PLAYER\_CHAR) += 5000 play\_music 1 gosub @MISSION\_1\_END create\_thread @STARTER\_NEW return</p><p>:MISSION\_1\_29\_144 wait 0 gosub @MISSION\_1\_END 00BA: show\_text\_styled GXT 'M\_FAIL' time 5000 style 1 create\_thread @STARTER\_NEW return</p><p>:MISSION\_1\_END wait 0 return</p><pre><code>

Сюжет миссии: Карл сидит в машине и говорит сам с собой о том, как он не любит врагов. Тем временем камера снимает его.

\<!--IMG1-->\<img src="<https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/68320138.png>" />\<!--IMG1-->\<br>\<br>\<!--IMG2-->\<img src="<https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/94318394.png>" />\<!--IMG2-->

Рассмотрим наш новый стартер. Как вы уже, наверное заметили, он немного усложнён. Теперь что бы начать миссию, СЖ не должен быть в машине. Так же он не должен быть арестован или убит. И главное - мы изменили условие, когда СЖ в точке на:

</code></pre><p>0102: actor $PLAYER\_ACTOR in\_sphere 2510.8367 -1672.7837 12.442 radius 2.0 2.0 2.0 sphere 0 stopped\_on\_foot</p><pre><code>

Этот опкод проверяет: "Находится ли СЖ в точке 2510.8367 -1672.7837 12.442 радиусами 2.0 2.0 2.0", при этом он должен быть пешим. Это более универсальный вариант, чем опкод 00EC.

Думаю основные команды для работы с камерой вы усвоили. Но если есть вопросы - обращайтесь на форум! :)

\<div class="alert alert-warning alert-dismissible" role="alert">
\<button type="button" class="close" data-dismiss="alert" aria-label="Close">\<span aria-hidden="true">\&times;\</span>\</button>
**Примечание:** в некоторых широкоформатных экранах полоски могут не появляться.
\</div>|1713|1|0|68320138`png`640`400`400`250``\|94318394`png`640`400`400`250\`\`||katsceny\_i\_chto\_neobkhodimo\_dlja\_primitivnogo\_videorolika|1498863917 </code></pre></td><td></td></tr></tbody></table>


# 000174. Снова статистика игрока

Снова статистика игрока|В этом уроке мы узнаем некоторые не очевидные возможности статистики игрока.|wmysterio|wmysterio||||Всем привет! Думаю вы помните [этот урок](https://github.com/wmysterio/scm-scripting-lessons/blob/main/publ/uroki_skriptinga/gta_sa/statistika_igroka/34-1-0-134/README.md), в котором мы рассматривали статистику игрока и могли менять его статы. Сегодня я сделал некоторый эксперимент и он оправдал свои ожидания. На самом деле, мимо стандартной статистики, мы можем создавать свои собственные. Игра их не будет отображать в меню "Статистика", но в скрипте это очень даже реально сделать, при этом используя те опкоды, которые использовались в статье выше.

С выходом оригинальных названий опкодов, можно делать всякие эксперименты. Этот один из них. Начинаем порядок создания статистики:

```
0627: update_integer_stat 1000 to 0
```

Этот опкод ( или **0628** ) регистрирует новую статистику. В нашем случаи её ID равен 1000 а стартовое значение - 0.

Далее, по ходу дела, мы можем менять значение статистики на нужное. Как показали мои тесты - всё работает как надо. Вот, для примера, скрипт, который увеличивает статистику 1000 до 1000 и выводит её текущее значение или использовать как счётчик миссий для Cleo-миссий:

```
{$CLEO}
:STAT_NEW
03A4: name_thread 'STAT_NEW'
0627: update_integer_stat 1000 to 0 

for 1@ = 1 to 100
0623: add 1 to_integer_stat 1000 // увеличиваем стат 1000 на 1
0652: 0@ = integer_stat 1000 // получаем текущее значение стата 1000
0AD1: show_formatted_text_highpriority "Stat 1000: %d" time 100 0@ // выводим текущее значение
wait 100
end

0A93: end_custom_thread
```

Таким образом мы можем создавать и отслеживать сколько угодно статистик, что бывает очень помогает в сложных миссиях, где нужно что-то подсчитывать и хранить значения, при этом экономить переменные :)

× \*\*Примечание:\*\* Подбирать свободные ID статистики - это то ещё занятие. Часть из них иногда ведёт себя непредсказуемо, изменяя значения без вызова опкода|1412|1|0||snova\_statistika\_igroka|1509827017


# 00040. Как создать свой чит-

Как создать свой чит?|Очень многим помогают читы в игре, хотя и без них можно пройти игру. Сегодня мы научимся делать простые читы для GTA SA с помощью скриптинга.|wmysterio|wmysterio||||Есть неплохой опкод, который позволяет нам проверить текст, который пользователь ввёл с клавиатуры. :

```
0ADC: test_cheat "STRING"
```

Давайте напишем чит на редкое оружие, чтобы, например, нам давали миниган. Вот такой код получится:

```
:MINIGUN
thread 'MINIGUN'
wait 0
if
0ADC: test_cheat "MINIGUN"
jf @MINIGUN
model.Load(#MINIGUN)
038B: load_requested_models

:MINIGUN_1
wait 0
if
model.Available(#MINIGUN)
jf @MINIGUN_1
01B2: give_actor $PLAYER_ACTOR weapon 38 ammo 1000
model.Destroy(#MINIGUN)
jump @MINIGUN
```

Теперь, если ввести в игре фразу "MINIGUN", то нам дадут миниган. Используя этот шаблон, можно написать много примитивных читов, например поставить тачку возле игрока и так дальше.

Здесь важно помнить, что это не те читы, которые используются в игре, а скрипты, которые написаны в main.scm или Cleo-скриптах, и иммитируют работу читов. Даже и не знаю, что можно ещё написать об опкоде 0ADC, так что напишу ещё один пример, что бы при вводе строки "PLAYER", игрок одевал костюм копа:

```
:PLAYER
thread 'PLAYER'
wait 0
if
0ADC: test_cheat "PLAYER"
jf @PLAYER
087B: set_player $PLAYER_CHAR clothes_texture "policetr" model "policetr" body_part 17
jump @PLAYER
```

Удачи Вам в создании читов :)|9022|1|0||kak\_sozdat\_svoj\_chit|1498917460


# 00090. Работа с гаражами

Работа с гаражами|В этом уроке мы будем работать с гаражами.|wmysterio|wmysterio||||Всем привет! Ещё один материал, который относится к курсу "базовый", я что то забыл о них =) Ну, ничего страшного, выложу в курсе "Продвинутый". Думаю нет смысла объяснять что такое гараж, по этому перейдём сразу к делу.

Для начала рассмотрим типы гаражей. Всего их восемь. Вот таблица типов:

| Таблица 1. |                                                                            |
| ---------- | -------------------------------------------------------------------------- |
| Тип        | Описание                                                                   |
| 1          | Заготовка для гаража ( не открывается ).                                   |
| 2          | 8-ball ( бомба, которая взрывается через некоторое время, после зарядки ). |
| 3          | 8-ball ( бомба, которая взрывается, если кто-то сядет в машину).           |
| 4          | 8-ball ( бомба на радиоуправлении ).                                       |
| 5          | Перекраска.                                                                |
| 32         | Обыкновенный гараж на 4 машины.                                            |
| 33         | Гараж с дверью, сквозь которую можно передвигаться :)                      |
| 38         | Гараж, который не закрывается, если в нём есть машина.                     |

Все остальные скорее всего повторяются или не работают. Каждый гараж в игре имеет свой ID или, правильнее, название. Подробно о них вы можете посмотреть в нашей [базе данных](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/gta_san_andreas_nazvanija_garazhej/1-1-0-24/README.md). Рассмотрим опкоды для работы с гаражами:

```
0299: activate_garage 'VECMOD'
02B9: deactivate_garage 'VECMOD'
```

Опкоды активируют и деактивируют гараж с названием "VECMOD".

```
0360: open_garage 'VECMOD'
0361: close_garage 'VECMOD'
```

Опкоды открывают или закрывают гараж "VECMOD".

```
03B0: garage 'VECMOD' door_open
03B1: garage 'VECMOD' door_closed
```

Проверки для гаража "VECMOD": **03B0** - "Гараж открыт?", **03B1** - "Гараж закрыт?". Не понимаю только зачем было два опкода, ведь опкод "83B0" аналогичный опкоду "03B1".

```
02FA: set_garage 'VECMOD' type 5
```

Опкод задаёт гаражу "VECMOD" тип, тип смотрите в таблице 1.

```
021B: set_garage 'VECMOD' to_accept_only_car #MANANA
```

Гараж "VECMOD" будет принимать только автомобиль с моделью #MANANA.

Давайте напишем простой скрипт, который запрещает перекраску автомобиля в районе Аилдвуда:

```
{$CLEO}
0000:

:NAME
thread 'NAME'
wait 0
Garage.Close('SPRLAE')
Garage.Deactivate('SPRLAE')
0A93: end_custom_thread
```

Для начала нужно закрыть гараж, что бы не было возможности заезжать туда. Так как если деактивировать его и не закрыть, то перекраска осуществится, но выехать с гаража не получится. Результат не заставил себя долго ждать:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/46914387.jpg)

Давайте изменим тип гаража. Что бы в место перекраски, нам ставили бомбу:

```
{$CLEO}
0000:

:NAME
thread 'NAME'
wait 0
garage.ChangeType('SPRLAE', 2)
0A93: end_custom_thread
```

Думаю, с этого краткого урока Вы сделали для себя полезные выводы и можете использовать гаражи для своих миссий или скриптов.|1288|1|0|46914387`jpg`500`300`400\`240\`\`||rabota\_s\_garazhami|1503135012


# 000176. Выделение памяти

Всем привет! В этом уроке мы ознакомимся с функцией выделения памяти и рассмотрим подробный пример работы этой фишки.

Иногда при проектировании больших скриптов возникают проблемы с хранением каких-либо значений в CLEO-скриптах:

* Количество локальных переменных мало;
* Глобальные переменные не рекомендовано использовать в CLEO;
* Глобальные CLEO-переменные могут привести к конфликтам между скриптами;

Проблемы очевидны и решить их можно несколькими способами. Сегодня мы рассмотрим способ с выделением динамической памяти.

Допустим, у нас стоит задача: создать 100 актёров. Их нужно где-то хранить, и буфер является очень привлекательным вариантом. Рассмотрим опкоды, для работы с ними:

```
0AC8: 0@ = allocate_memory_size 120
0AC9: free_allocated_memory 0@
```

Первый опкод выделяет память под буфер, где `120` — это размер (в байтах), а `0@` — переменная, которая будет хранить указатель на начало области памяти (он же совпадает с началом буфера). Второй опкод освобождает выделенную память.

Возникает вопрос: как узнать размер выделяемой памяти, чтобы нам хватило места для записи этих актёров? Поскольку переменные для создания/записи актёров являются ссылками, то размер одного сегмента этой памяти будут равняться 4 байтам, а общий размер выделяемой памяти — `100 × 4 = 400` байт.

Для того, чтобы получить 1 элемент этого буфера, легче всего сделать несколько SCM-функций, которые делали бы навигацию по этой области памяти. Первый участок кода будет выделять память под актёров, а второй — очистка выделенной памяти:

```
goto @SKIP_FUNCTIONS

:CREATE_ARRAY
0A90: 2@ = 4 * 0@ // 4 * size
0AC8: 1@ = allocate_memory_size 2@
0AB2: ret 1 1@

:DESTROY_ARRAY
0AC9: free_allocated_memory 0@
0AB2: ret 0

:SKIP_FUNCTIONS
```

Я назвал SCM-функции "создать массив" и "удалить массив" согласно принципам, по которым они работают. Теперь добавим возможность читать/записывать в ячейку памяти нужное значение по индексу. Индекс будет определятся как `Номер × размер`, размер ссылки естественно 4 байта:

```
:SET_ARRAY_ITEM
0A90: 3@ = 4 * 1@ // 4 * size
0A8E: 4@ = 0@ + 3@ // Buffer + offset
0A8C: write_memory 4@ size 4 value 2@ virtual_protect 0
0AB2: ret 0

:GET_ARRAY_ITEM
0A90: 3@ = 4 * 1@ // 4 * size
0A8E: 4@ = 0@ + 3@ // Buffer + offset
0A8D: 2@ = read_memory 4@ size 4 virtual_protect 0
0AB2: ret 1 2@
```

Поскольку у нас идёт работа с памятью, мы обязательно применяем опкоды `0A8C` и `0A8D` для чтения и записи её участка. Адрес чтения мы получили за формулой: `Начало буфера + ( размер ссылки × индекс )`. Поэтому наши SCM-функции будут обязательно принимать ссылку на выделенный буфер:

```
0AB1: call_scm_func @CREATE_ARRAY 1 num_items 100 store_to 0@
0AB1: call_scm_func @DESTROY_ARRAY 1 array 0@
0AB1: call_scm_func @SET_ARRAY_ITEM 3 array 0@ index 0 value 0@
0AB1: call_scm_func @GET_ARRAY_ITEM 2 array 0@ index 0 value 0@
```

Итак, запишем в наш массив 100 случайных актёра, разместив их у Гроув Стрит:

```
{$CLEO}
0000:

goto @SKIP_FUNCTIONS

:CREATE_ARRAY
0A90: 2@ = 4 * 0@ // 4 * size
0AC8: 1@ = allocate_memory_size 2@
0AB2: ret 1 1@

:DESTROY_ARRAY
0AC9: free_allocated_memory 0@
0AB2: ret 0

:SET_ARRAY_ITEM
0A90: 3@ = 4 * 1@ // 4 * size
0A8E: 4@ = 0@ + 3@ // Buffer + offset
0A8C: write_memory 4@ size 4 value 2@ virtual_protect 0
0AB2: ret 0

:GET_ARRAY_ITEM
0A90: 3@ = 4 * 1@ // 4 * size
0A8E: 4@ = 0@ + 3@ // Buffer + offset
0A8D: 2@ = read_memory 4@ size 4 virtual_protect 0
0AB2: ret 1 2@

:SKIP_FUNCTIONS

{ !!! НАШ КОД !!! }

0AB1: call_scm_func @CREATE_ARRAY 1 num_items 100 store_to 0@
3@ = 2500.0

for 2@ = 0 to 100 step 1
 0376: 1@ = create_random_actor_at 3@ -1659.0 12.3437
 0AB1: call_scm_func @SET_ARRAY_ITEM 3 array 0@ index 2@ value 1@
 3@ -= 1.0
 wait 0
end

0A93: end_custom_thread
```

Результат:

![100 актёров на Гроу](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/24368649.png)

Как видим, в скрипте использовалась всего 1 переменная `1@` и мы не потеряли полный доступ ко всем остальным актёрам. Давайте теперь удалим созданных актёров и посмотрим работают ли наши функции удаления и очищения памяти:

```
{$CLEO}
0000:

goto @SKIP_FUNCTIONS

:CREATE_ARRAY
0A90: 2@ = 4 * 0@ // 4 * size
0AC8: 1@ = allocate_memory_size 2@
0AB2: ret 1 1@

:DESTROY_ARRAY
0AC9: free_allocated_memory 0@
0AB2: ret 0

:SET_ARRAY_ITEM
0A90: 3@ = 4 * 1@ // 4 * size
0A8E: 4@ = 0@ + 3@ // Buffer + offset
0A8C: write_memory 4@ size 4 value 2@ virtual_protect 0
0AB2: ret 0

:GET_ARRAY_ITEM
0A90: 3@ = 4 * 1@ // 4 * size
0A8E: 4@ = 0@ + 3@ // Buffer + offset
0A8D: 2@ = read_memory 4@ size 4 virtual_protect 0
0AB2: ret 1 2@

:SKIP_FUNCTIONS
0AB1: call_scm_func @CREATE_ARRAY 1 num_items 100 store_to 0@
3@ = 2500.0

for 2@ = 0 to 100 step 1
 0376: 1@ = create_random_actor_at 3@ -1659.0 12.3437
 0AB1: call_scm_func @SET_ARRAY_ITEM 3 array 0@ index 2@ value 1@
 3@ -= 1.0
 wait 0
end

{ !!! НАШ НОВЫЙ КОД !!! }

for 2@ = 0 to 100 step 1
 0AB1: call_scm_func @GET_ARRAY_ITEM 2 array 0@ index 2@ value 1@
 if 
 056D: actor 1@ defined
 then
 01C2: remove_references_to_actor 1@ 
 009B: destroy_actor 1@
 end
 wait 0
end 
 
0AB1: call_scm_func @DESTROY_ARRAY 1 array 0@ 

0A93: end_custom_thread
```

Результат:

![Актёров уже нет Гроу](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/57559530.png)

Улица снова пуста! Интересно понаблюдать за самим процессом создания/удаления этих актёров: видно сколько примерно времени занимает одна итерация цикла.

Думаю, многие заметили, что в цикл я добавил нетипичную для него задержку в 0 милисекунд. В нашем случае без задержки игра вылетит, что конечно не радует. Надеюсь, что этот пример пригодится вашим проектам, где есть смысл хранить данные именно таким способом.

{% hint style="danger" %}
Чтобы не превышать лимиты, не создавайте слишком много сущностей за один раз!
{% endhint %}

{% hint style="danger" %}
Не используйте этот способ для хранения данных, которые нужно восстанавливать после перезагрузки игры!
{% endhint %}

{% hint style="warning" %}
В `main.scm` этот способ нужно использовать с осторожностью, но там ситуация с переменными более благосклонна к нам.
{% endhint %}

Кроме актёров, таким вот образом можно записать и другие сущности, а также целые и/или вещественные числа. Также нет привязки к конкретному типу данных: мы можем в разные ячейки записать разные значения. Главное не забыть что и куда было записано :)

На этом, пожалуй, всё. С Вами был wmysterio!


# 00076. Статистика игрока

Статистика игрока|Сегодня мы рассмотрим опкоды для изменения статистики игрока.|wmysterio|wmysterio||||Всем привет! Статистика - это то, чего достиг игрок за игровое время. Например: уровень стрельбы с АК-47, насколько от сыт и т.п. Для изменения какой то статистики, обычно используют 2 опкода:

```
0629: change_integer_stat 181 to 0
062A: change_float_stat 21 to 800.0
```

Опкоды устанавливают значения для ID статистики игрока.

Здесь:\
21 и 181 - ID статистики ( см. [Статистика игрока](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/statistika_igroka_staty/1-1-0-32/README.md) )\
0 и 800.0 - соответственно значения, которые принимает статистика

Давайте напишем скрипт, который стразу даёт максимальные навыки оружия, максимальная жизнь - 1450.0 ( в такой настройке полоска выход даже за пределы обычного ):

```
{$CLEO}
0000:

:STAT_PL
thread 'STAT_PL'
wait 0
062A: change_float_stat 165 to 2000.0
062A: change_float_stat 23 to 1000.0
062A: change_float_stat 21 to 0.0
0629: change_float_stat 22 to 1000
062A: change_float_stat 80 to 2000.0
062A: change_float_stat 225 to 2000.0
062A: change_float_stat 223 to 1000.0
062A: change_float_stat 229 to 1000.0
062A: change_float_stat 230 to 2000.0
062A: change_float_stat 24 to 1450.0
062A: change_float_stat 69 to 1000.0
062A: change_float_stat 70 to 1000.0
062A: change_float_stat 71 to 1000.0
062A: change_float_stat 72 to 1000.0
062A: change_float_stat 73 to 1000.0
062A: change_float_stat 74 to 1000.0
062A: change_float_stat 75 to 1000.0
062A: change_float_stat 76 to 1000.0
062A: change_float_stat 77 to 1000.0
062A: change_float_stat 78 to 1000.0
062A: change_float_stat 160 to 1000.0
0A93: end_custom_thread
```

В результате игрок станет "прокачанным" в любой момент. Обратите внимание на полоску жизни:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/63682838.png)

Так же мы можем узнать текущее значение статистики, используя опкоды:

```
0653: 0@ = float_stat 21
0652: 0@ = integer_stat 181
```

Здесь:\
0@ - переменная, в которую будет записано значение\
21 - ID статистики ( дробное )\
181 - ID статистики ( целое )

Полученный результат можно использовать в проверках:

```
0653: 0@ = float_stat 21
if
0@ > 300.0
then
 // выполнять какие то действие, например написать "Нужно есть больше или меньше"
end
```

Статистика 181: при установке следующих значений будут "открыты" такие территории ( города ):

| ID | Местность                                                     |
| -- | ------------------------------------------------------------- |
| 0  | Лос Сантос                                                    |
| 1  | Сельская местность возле Лос Сантос                           |
| 2  | Сан Фиеро и всё вышеперечисленное                             |
| 3  | Сельская местность возле Лас Вентурас и всё вышеперечисленное |
| 4  | Лас Вентурас и всё вышеперечисленное                          |

Если установить значение 0, то при попадании за территории Лос Сантоса Вы получите 5 звёзд.

Можно так же выполнять прямые записи к существующему значению статистики:

```
0623: add 1 to_integer_stat 214
0624: add 1.0 to_float_stat 160
0628: add 1@ to_float_stat 2
0625: decrease_integer_stat 184 by 1
0626: decrease_float_stat 21 by 1.0
0627: update_integer_stat 215 to $1922
0A10: increase_integer_stat 161 by 1
0A1F: increase_float_stat 24 by 196@
042E: downdate_integer_stat 212 to 448@
0582: downdate_integer_stat 175@($RACE_INDEX,30i) to 450@
```

Тоесть, чтобы не писать такой код:

```
0653: 0@ = float_stat 21
0@ += 100.0
062A: change_float_stat 21 to 0@
```

можно сразу прибавить к значению статистики своё число: "0624: add 100.0 to\_float\_stat 21". С остальными уже поэкспериментируйте, там можно сложить, вычитать делить и умножать значения статов.

Мимо этого существуют опкоды для узнавания значений некоторых ID статистики:

```
08E1: 0@ = total_tags_sprayed // Целое число
```

В переменную "0@" будет записано к-во закрашенных граффити.

```
08E2: 0@ = territories_controlled_percentage // Целое число
```

В переменную"0@" будет записано процент владения территориями. Если все территории принадлежат вам, то в переменную будет занесено 100.

Так же есть возможность отключить функцию показа статистики. Когда нажимаем "Действие" ( по-умолчанию кнопка TAB\` ) статистика не будет показана:

```
0960: enable_player $PLAYER_CHAR stats_box 0 // если поставить 1 - то будет
```

Этот опкод рекомендовано использовать в цикле.

× \*\*Примечание:\*\* Если изменить мышцы игрока или полноту, то визуально результат ничего не покажет. Что бы изменения были видны нужно зайти в какой то интерьер.|2653|1|0|63682838\`png\`500\`300\`400\`240\`\`\\||statistika\_igroka|1499752446


# 00094. Пропуск видеороликов

Пропуск видеороликов|Думаю многим знаком урок скриптинга в main.scm, где рассматривалось создание примитивного видеоролика. Этот урок будет так же посвящен созданию катсцены, но тема отличается тем, что мы будем делать возможность её пропуска.|wmysterio|wmysterio||||Всем привет. Я видел много скриптов, где использовались цикли с проверкой на нажатие клавиши, однако я планирую использовать намного лучший способ. Для таких целей используется два опкода:

```
0707: start_scene_skip_to @INTRO
0701: end_scene_skip
```

Первый опкод - делает мгновенный переход к метке "@INTRO". Особенность в том, что переход будет выполнен при нажатии клавиши ( пробел, шифт и т.п. ) не используя условия в коде, расположенного ниже, вплоть, до опкода "0701", что завершает сцену. Используя эти данные, давайте напишем скрипт, который делает ролик, который легко можно пропустить:

```
{$CLEO}
0000:
thread 'SCENE'
03BC: 0@ = create_sphere_at 2476.0601 -1681.2487 13.3413 radius 2.0

while 80EC: not actor $PLAYER_ACTOR 0 near_point 2476.0601 -1681.2487 radius 1.0 1.0
wait 0
end

03BD: destroy_sphere 0@
player.CanMove($PLAYER_CHAR) = false
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
fade 0 1000
wait 1000
04E4: unknown_refresh_game_renderer_at 2486.915 -1673.9196
Camera.SetAtPos(2486.915, -1673.9196, 13.3359)
Camera.SetPosition(2486.915, -1673.9196, 13.3359, 0.0, 0.0, 0.0)
Camera.PointAt(2485.3206, -1676.1002, 13.3382, 2)
actor.PutAt($PLAYER_ACTOR, 2484.4446, -1678.1494, 12.3367)
actor.Angle($PLAYER_ACTOR) = 54.63
0376: 1@ = create_random_actor_at 2483.2427 -1677.151 12.3374
actor.Angle(1@) = 232.9327
0826: enable_hud 0
02A3: enable_widescreen 1
wait 1000
03E6: remove_text_box
00BE: text_clear_all
fade 1 1000
0707: start_scene_skip_to @SCENE { Вызов ролика, которого можно пропустить }
wait 1000
//сам ролик:
0AD0: show_formatted_text_lowpriority "C£pa¢a cžy¤a®¨ ak¦ep" time 5000 // Справа случайный актер
wait 5000
0AD0: show_formatted_text_lowpriority "A cže¢a - CJ" time 5000 // А слева - CJ
wait 5000
0AD0: show_formatted_text_lowpriority ""¦o ¦ec¦o¢¨ požœk" time 5000 // Это тестовый ролик
wait 5000

:SCENE { Метка окончания ролика }
wait 0
fade 0 1000
0701: end_scene_skip
wait 1000
0826: enable_hud 1
02A3: enable_widescreen 0
03E6: remove_text_box
00BE: text_clear_all
actor.RemoveReferences(1@)
actor.DestroyInstantly(1@)
actor.PutAt($PLAYER_ACTOR, 2480.1101, -1678.0629, 13.3401)
actor.Angle($PLAYER_ACTOR) = 303.6017
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer
wait 1000
fade 1 1000
wait 1000
player.CanMove($PLAYER_CHAR) = true
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
0A93: end_custom_thread
```

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/88031612.png)

Если вы нажмёте пробел во время ролика, то вы увидите, как экран начнёт темнеть и в скорее Вы перейдёте в режим игры. То есть, всё, что находится в блоке между опкодами "0707" и "0701" можно пропускать. Здесь я могу сделать несколько советов, которые могут предотвратить вылет игры, так как новички часто забывают о проверках.

Начну с того, что рекомендовано создавать всех используемых субъектов в ролике ещё до объявления опкода "0707". Приведу пример: примерно в середине ролика вы создали актёра, который будет выполнять какие то функции в нём. Нужно учесть, что если нужно будет удалить его с игры или использовать в дальнейшем, то после пропуска ролика нужно обязательно проверить на существование, так как играющий может пропустить ролик ещё до создания актёра.

Так как актёр не создан и идёт уничтожение актёра после ролика, то естественно будет вылет. Для примера, давайте усовершенствуем наш скрипт, сделаем, что бы во время диалога приходил 2-й созданный актёр и вступал в диалог. После катсцены, делаем проверки. Вот код примера:

```
{$CLEO}
0000:
thread 'SCENE'
03BC: 0@ = create_sphere_at 2476.0601 -1681.2487 13.3413 radius 2.0

while 80EC: not actor $PLAYER_ACTOR 0 near_point 2476.0601 -1681.2487 radius 1.0 1.0
wait 0
end

03BD: destroy_sphere 0@
player.CanMove($PLAYER_CHAR) = false
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
fade 0 1000
wait 1000
04E4: unknown_refresh_game_renderer_at 2486.915 -1673.9196
Camera.SetAtPos(2486.915, -1673.9196, 13.3359)
Camera.SetPosition(2486.915, -1673.9196, 13.3359, 0.0, 0.0, 0.0)
Camera.PointAt(2485.3206, -1676.1002, 13.3382, 2)
actor.PutAt($PLAYER_ACTOR, 2484.4446, -1678.1494, 12.3367)
actor.Angle($PLAYER_ACTOR) = 54.63
0376: 1@ = create_random_actor_at 2483.2427 -1677.151 12.3374
actor.Angle(1@) = 232.9327
0826: enable_hud 0
02A3: enable_widescreen 1
wait 1000
03E6: remove_text_box
00BE: text_clear_all
fade 1 1000
0707: start_scene_skip_to @SCENE
wait 1000
0AD0: show_formatted_text_lowpriority "C£pa¢a cžy¤a®¨ ak¦ep" time 5000
wait 5000
0AD0: show_formatted_text_lowpriority "A cže¢a - CJ" time 5000
wait 5000
0AD0: show_formatted_text_lowpriority ""¦o ¦ec¦o¢¨ požœk" time 5000
wait 5000

0376: 2@ = create_random_actor_at 2488.4609 -1671.9213 12.3359
actor.Angle(2@) = 145.077
07CD: AS_actor 2@ walk_to 2484.9302 -1676.5956 13.3378 stop_with_angle 139.4369 within_radius 1.0
wait 250
Camera.SetPosition(2482.2092, -1680.7852, 13.3318, 0.0, 0.0, 0.0)
Camera.PointAt(2485.3206, -1676.1002, 13.3382, 2)

while 80EC: not actor 2@ 0 near_point 2484.9302 -1676.5956 radius 1.0 1.0
wait 0
end
0AD0: show_formatted_text_lowpriority "Œpœ¥ež ¦pe¦œ ak¦ep" time 5000
wait 5000 //этот блок создаёт случайного актёра и заставляет его подойти к точке

:SCENE
wait 0
fade 0 1000
0701: end_scene_skip
wait 1000
if
actor.Defined(2@)
then
marker.CreateAboveActor(3@, 2@)
end // если мы планируем поставить маркер над актёром, то обязательно нужно делать проверку!
0826: enable_hud 1
02A3: enable_widescreen 0
03E6: remove_text_box
00BE: text_clear_all
actor.RemoveReferences(1@)
actor.DestroyInstantly(1@)
actor.PutAt($PLAYER_ACTOR, 2480.1101, -1678.0629, 13.3401)
actor.Angle($PLAYER_ACTOR) = 303.6017
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer
wait 1000
fade 1 1000
wait 1000
player.CanMove($PLAYER_CHAR) = true
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
0A93: end_custom_thread
```

В случае, если нам актёр нужен для дальнейшей манипуляции, то нам необходимо заново создать его ( если пропуск ролика был до самого создания ). Из этого делаем вывод, что лучше создать необходимые субъекты до ролика, что бы потом не играться со всякими проверками.

Но всё же иногда ситуация вынуждает нас делать проверки, что бы улучшить мод. Например: при завершении ролика 3 актёра садились в машину. Если пропустить ролик, то актёры естественно никуда не сядут =) Давайте нашим ещё один пример, что бы эти актёры в любом случаи сели в автомобиль. Создавать все субъекты мы будем до ролика, что уменьшает количество условий:

```
{$CLEO}
0000:
thread 'SCENE'
03BC: 0@ = create_sphere_at 2476.0601 -1681.2487 13.3413 radius 2.0

while 80EC: not actor $PLAYER_ACTOR 0 near_point 2476.0601 -1681.2487 radius 1.0 1.0
wait 0
end
model.Load(#ADMIRAL)
038B: load_requested_models

while not model.Available(#ADMIRAL)
wait 0
end

03BD: destroy_sphere 0@
player.CanMove($PLAYER_CHAR) = false
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
fade 0 1000
wait 1000
04E4: unknown_refresh_game_renderer_at 2486.915 -1673.9196
Camera.SetAtPos(2486.915, -1673.9196, 13.3359)
Camera.SetPosition(2486.915, -1673.9196, 13.3359, 0.0, 0.0, 0.0)
Camera.PointAt(2485.3206, -1676.1002, 13.3382, 2)
actor.PutAt($PLAYER_ACTOR, 2484.4446, -1678.1494, 12.3367)
actor.Angle($PLAYER_ACTOR) = 54.63
0376: 1@ = create_random_actor_at 2483.2427 -1677.151 12.3374
actor.Angle(1@) = 232.9327
0376: 2@ = create_random_actor_at 2488.4609 -1671.9213 12.3359
actor.Angle(2@) = 145.077
3@ = car.Create(#ADMIRAL, 2482.4629, -1670.8448, 13.3404)
car.Angle(3@) = 43.8693
0826: enable_hud 0
02A3: enable_widescreen 1
wait 1000
03E6: remove_text_box
00BE: text_clear_all
fade 1 1000
0707: start_scene_skip_to @SCENE
wait 1000
0AD0: show_formatted_text_lowpriority "C£pa¢a cžy¤a®¨ ak¦ep" time 5000
wait 5000
0AD0: show_formatted_text_lowpriority "A cže¢a - CJ" time 5000
wait 5000
0AD0: show_formatted_text_lowpriority ""¦o ¦ec¦o¢¨ požœk" time 5000
wait 5000
07CD: AS_actor 2@ walk_to 2484.9302 -1676.5956 13.3378 stop_with_angle 139.4369 within_radius 1.0
wait 250
Camera.SetPosition(2482.2092, -1680.7852, 13.3318, 0.0, 0.0, 0.0)
Camera.PointAt(2485.3206, -1676.1002, 13.3382, 2)

while 80EC: not actor 2@ 0 near_point 2484.9302 -1676.5956 radius 1.0 1.0
wait 0
end

0AD0: show_formatted_text_lowpriority "Œpœ¥ež ¦pe¦œ ak¦ep" time 5000
wait 5000
0AD0: show_formatted_text_lowpriority "Cežœ ¢ce ¢ ¯a¥œ®y" time 5000
Camera.SetPosition(2493.0073, -1684.394, 13.5095, 0.0, 0.0, 0.0)
Camera.PointAt(2486.0164, -1677.4105, 13.3372, 2)
05CB: AS_actor $PLAYER_ACTOR enter_car 3@ as_driver 20000 ms
05CA: AS_actor 1@ enter_car 3@ passenger_seat 0 20000 ms
05CA: AS_actor 2@ enter_car 3@ passenger_seat 1 20000 ms

:SCENE_A
wait 0
if AND
actor.InCar($PLAYER_ACTOR, 3@)
actor.InCar(1@, 3@)
actor.InCar(2@, 3@)
jf @SCENE_A // заставляем актёров сесть в тачку

:SCENE
wait 0
fade 0 1000
0701: end_scene_skip
wait 1000

if
not actor.InCar($PLAYER_ACTOR, 3@)
then
05CB: AS_actor $PLAYER_ACTOR enter_car 3@ as_driver 0 ms
end
if
not actor.InCar(1@, 3@)
then
05CA: AS_actor 1@ enter_car 3@ passenger_seat 0 0 ms
end
if
not actor.InCar(2@, 3@)
then
05CA: AS_actor 2@ enter_car 3@ passenger_seat 1 0 ms
end
{ блок условий, если игрок пропустил ролик, а актёры не в машине, то
при срабатывании проверки мгновенно перемещаем их в нужную тачку }

0826: enable_hud 1
02A3: enable_widescreen 0
03E6: remove_text_box
00BE: text_clear_all
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer
wait 1000
fade 1 1000
wait 1000
player.CanMove($PLAYER_CHAR) = true
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
0A93: end_custom_thread
```

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/66771219.png)

Рассмотрим ещё один пример. Он касается перемещения камеры с помощью опкодов "0936" и "0920". Есть один глюк, когда пропустить ролик во время перемещения камеры, то при завершении ролика команды "Camera.Restore\_WithJumpCut" и "Camera.SetBehindPlayer" не срабатывают и камера перемещается дальше, игнорируя их. С этой проблемой я соткнулся при разработке мода "GTA SA - Карьерист" и сейчас я расскажу как избавится от этой зависимости.

А избавился довольно просто - дублировал перемещения, изменив только вемя на "0" и тип перемещения поставил "0". Таким образом мы заставяем камеру мгновенно переместится в нужную точку и при пропуске ролика ненужный эффект перехода камеры будет анулирован. Давайте к нашему скрипту допишем ещё и перемещения камеры, что бы всё было как "нужно":

```
{$CLEO}
0000:
thread 'SCENE'
03BC: 0@ = create_sphere_at 2476.0601 -1681.2487 13.3413 radius 2.0

while 80EC: not actor $PLAYER_ACTOR 0 near_point 2476.0601 -1681.2487 radius 1.0 1.0
wait 0
end
model.Load(#ADMIRAL)
038B: load_requested_models

while not model.Available(#ADMIRAL)
wait 0
end

03BD: destroy_sphere 0@
player.CanMove($PLAYER_CHAR) = false
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
fade 0 1000
wait 1000
04E4: unknown_refresh_game_renderer_at 2486.915 -1673.9196
Camera.SetAtPos(2486.915, -1673.9196, 13.3359)
Camera.SetPosition(2486.915, -1673.9196, 13.3359, 0.0, 0.0, 0.0)
Camera.PointAt(2485.3206, -1676.1002, 13.3382, 2)
actor.PutAt($PLAYER_ACTOR, 2484.4446, -1678.1494, 12.3367)
actor.Angle($PLAYER_ACTOR) = 54.63
0376: 1@ = create_random_actor_at 2483.2427 -1677.151 12.3374
actor.Angle(1@) = 232.9327
0376: 2@ = create_random_actor_at 2488.4609 -1671.9213 12.3359
actor.Angle(2@) = 145.077
3@ = car.Create(#ADMIRAL, 2482.4629, -1670.8448, 13.3404)
car.Angle(3@) = 43.8693
0826: enable_hud 0
02A3: enable_widescreen 1
wait 1000
03E6: remove_text_box
00BE: text_clear_all
fade 1 1000
0707: start_scene_skip_to @SCENE
wait 1000
0AD0: show_formatted_text_lowpriority "C?pa?a c?y¤a?®?? ak¦ep" time 5000
wait 5000
0AD0: show_formatted_text_lowpriority "A c?e?a - CJ" time 5000
wait 5000
0AD0: show_formatted_text_lowpriority ""¦o ¦ec¦o??? po??k" time 5000
wait 5000
07CD: AS_actor 2@ walk_to 2484.9302 -1676.5956 13.3378 stop_with_angle 139.4369 within_radius 1.0
wait 250
Camera.SetPosition(2482.2092, -1680.7852, 13.3318, 0.0, 0.0, 0.0)
Camera.PointAt(2485.3206, -1676.1002, 13.3382, 2)

while 80EC: not actor 2@ 0 near_point 2484.9302 -1676.5956 radius 1.0 1.0
wait 0
end

0AD0: show_formatted_text_lowpriority "?p??e? ¦pe¦?? ak¦ep" time 5000
wait 5000
0AD0: show_formatted_text_lowpriority "Ce?? ?ce ? ?a??®y" time 5000
Camera.SetPosition(2493.0073, -1684.394, 13.5095, 0.0, 0.0, 0.0)
Camera.PointAt(2486.0164, -1677.4105, 13.3372, 2)
wait 200
0936: set_camera 2493.0073 -1684.394 13.5095 position_to 2478.6345 -1677.7593 13.3396 time 12000 drop_mode 1
0920: point_camera 2486.0164 -1677.4105 13.3372 transverse_to 2480.2334 -1675.2882 13.3393 time 12000 mode 1 // перемещаем камеру во время ролика
05CB: AS_actor $PLAYER_ACTOR enter_car 3@ as_driver 20000 ms
05CA: AS_actor 1@ enter_car 3@ passenger_seat 0 20000 ms
05CA: AS_actor 2@ enter_car 3@ passenger_seat 1 20000 m

:SCENE_A
wait 0
if AND
actor.InCar($PLAYER_ACTOR, 3@)
actor.InCar(1@, 3@)
actor.InCar(2@, 3@)
jf @SCENE_A

:SCENE
wait 0
fade 0 1000
0701: end_scene_skip
wait 1000
0936: set_camera 2493.0073 -1684.394 13.5095 position_to 2478.6345 -1677.7593 13.3396 time 0 drop_mode 0
0920: point_camera 2486.0164 -1677.4105 13.3372 transverse_to 2480.2334 -1675.2882 13.3393 time 0 mode 0 // перемещам камеру в окончательную точку игновенно
if
not actor.InCar($PLAYER_ACTOR, 3@)
then
05CB: AS_actor $PLAYER_ACTOR enter_car 3@ as_driver 0 ms
end
if
not actor.InCar(1@, 3@)
then
05CA: AS_actor 1@ enter_car 3@ passenger_seat 0 0 ms
end
if
not actor.InCar(2@, 3@)
then
05CA: AS_actor 2@ enter_car 3@ passenger_seat 1 0 ms
end
0826: enable_hud 1
02A3: enable_widescreen 0
wait 2000
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer
03E6: remove_text_box
00BE: text_clear_all 
fade 1 1000
wait 1000
player.CanMove($PLAYER_CHAR) = true
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
0A93: end_custom_thread
```

Вот это и есть одна из возможностей устранения глюка перемещения камеры.

Думаю, этот урок станет полезныи при создании ваших роликов. Следующий урок будет про миссии. А точнее мы будем учится делать "нервометры". С Вами был wmysterio.|1013|1|0|88031612`png`500`300`400`240``\|66771219`png`500`300`400`240\`\`||propusk\_videorolikov|1504427719


# 00072. Работа со светом. Прожектор

Работа со светом. Прожектор|В этом уроке мы рассмотрим базовые опкоды для работы со светом.|wmysterio|wmysterio||||Думаю с название этого краткого урока вы догадались, что речь пойдёт о свете ( это не имя девушки :D ). Это небольшой источник света и используется в качестве слабого освещения. Примером света можно назвать фары автомобиля и прожекторы на вертолётах. Начнём с опкодов:

```
06B1: 0@ = create_searchlight_at -1200.0 500.0 20.0 radius 5.0 target -1300.0 490.0 13.0 radius 25.0
```

Здесь:\
0@ - переменная, в которую записывается источник света\
-1200.0 500.0 20.0 - координаты создания света\
5.0 - начальный радиус света\
-1300.0 490.0 13.0 - координаты цели, то есть место, куда будет направлен этот источник\
25.0 - соответственно радиус возле цели

```
06C1: create_searchlight 0@ on_car 1@ with_offset 0.0 1.0 -0.5 radius 0.4 target 2228.36 -1171.48 25.82 radius 5.0
```

Создаёт источник света и цепляет его к автомобилю.

Здесь:\
0@ - переменная, в которую записывается источник света\
1@ - хендл машины, к которой будет прицеплен свет\
0.0 1.0 -0.5 - координаты размещения света относительно машины\
0.4 - начальный радиус света\
2228.36 -1171.48 25.82 - координаты, куда будет направлен свет\
5.0 - радиус возле цели

```
06C4: create_marker_above_searchlight 0@ handle_as 1@
```

Создаёт маркер над источником света.

Здесь:\
0@ - указатель на свет\
1@ - переменная маркера

```
06B6: set_searchlight 0@ follow_actor $PLAYER_ACTOR speed 0.2
```

Заставляет следовать свет за актёром.

Здесь:\
0@ - указатель на свет\
$PLAYER\_ACTOR - актёр, за которым будет двигаться свет\
0.2 - скорость перемещения координат направление света

```
06B4: set_searchlight 0@ path_between 2228.36 -1171.48 25.82 and 2215.41 -1142.51 25.5 speed 0.5
```

Заставляет прожектор следовать с одной точки в другую.

Здесь:\
0@ - указатель на свет\
2228.36 -1171.48 25.82 - изначальная точка перемещения\
2215.41 -1142.51 25.5 - конечная точка перемещения\
0.5 - соответственно скорость перемещения света

```
06CA: attach_searchlight 0@ to_tower 1@ to_housing 2@ to_bulb 3@ with_offset 0.0 1.181 0.768
```

Опкод цепляет свет к прожектору.

Здесь:\
0@ - указатель на свет\
1@ - указатель на основание прожектора\
2@ - указатель на сам прожектора\
3@ - указатель на стекло прожектора\
0.0 1.181 0.768 - координаты сцепления света, относительно прожектора

```
06B2: destroy_searchlight 0@
```

Уничтожает источник света.

Так же есть проверки для света:

```
06B3: searchlight 0@ active // активный ( существует ) источник света?
06B7: searchlight 0@ spotted_actor $PLAYER_ACTOR // Актёра находится в источнике света? ( актёр замечен источником света? )
```

Для примера напишем самый простой скрипт:

```
{$CLEO}
0000:

:LIGHT
thread 'LIGHT'
wait 0
06B1: 0@ = create_searchlight_at 2480.4573 -1754.0773 24.2714 radius 4.0 target 2481.6211 -1748.3218 13.5469 radius 15.0
0A93: end_custom_thread
```

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/18774195.png)

Думаю, о источнике света я вам рассказал всё необходимое =)|1084|1|0|18774195`png`600`360`400\`240\`\`||rabota\_so\_svetom|1499707648


# 00092. Работа с файлами ( форматированное чтение )

Работа с файлами ( форматированное чтение )|В этом уроке мы вернёмся к файлам, а точнее будет записывать и считывать форматированный текст.|wmysterio|wmysterio||||Привет всем пользователям нашего сайта! Пришло время для очередного урока! Этот способ отличается от работы с ini-файлами по всем статьям, но прочтя этот урок вы многое узнаете и, надеюсь, будете активно использовать в своих скриптах.

Прежде всего нам нужно настроить наш Санник, так как именно настройка ( а точнее не полная настройка ) не давала мне писать скрипты изучаемым сегодня методом. Как оказалось, всё дело в регистре букв, который компилятор использует по-умолчанию. Давайте откроем настройки и перейдём во вкладку "Форматирование" и обратим внимание на радио-кнопку "Регист букв":

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/25511210.png)

Как видим, по-умолчанию у нас стоит ВЕРХНИЙ регист. Так, как режим открытия файла должен обязательно компилироваться в нижнем регистре, то меняет радиокнопку на **Как есть** ( **нижний** - тоже неплохой вариант, это уже наш вкус, но главное, что бы не стоял верхний регистр ). После этого нажимаем "ОК".

В отличии от ini-режима, в этом режиме нет никаких ключевых слов или секций. Как и Cleo - считывание происходит построчно. Существует 6 основных режимов открытия файла:

| Таблица 1       |                                                                                                                                                         |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Текстовый режим |                                                                                                                                                         |
| Режим           | Описание                                                                                                                                                |
| rt              | Режим открытия файла для чтения. Файл должен существовать.                                                                                              |
| wt              | Режим создания пустого файла для записи. Если файл с таким именем уже существует его содержимое стирается, и файл рассматривается как новый пустой файл |
| at              | Дописать в файл. Операция добавления данных в конец файла. Файл создается, если он не существует.                                                       |
| Бинарный режим  |                                                                                                                                                         |
| Режим           | Описание                                                                                                                                                |
| rb              | Режим открытия файла для чтения. Файл должен существовать.                                                                                              |
| wb              | Режим создания пустого файла для записи. Если файл с таким именем уже существует его содержимое стирается, и файл рассматривается как новый пустой файл |
| ab              | Дописать в файл. Операция добавления данных в конец файла. Файл создается, если он не существует.                                                       |

Рассмотрим опкод, для открытия файла:

```
0A9A: $hFILE = openfile "Cleo&#92;config.txt" mode "rb" // IF and SET
```

Здесь:\
$hFILE - хендл нашего файла\
"Cleo\config.txt" - путь у нашему файлу относительно директории GTA SA\
"rb" - режим открытия ( см. Таблица 1 )

Этот опокод является так же явлется условным, поэтому советую использовать его в блоке условий "if...jf". После того, так работа с файлом завершена, обязательно нужно закрыть его опкодом:

```
0A9B: closefile $hFILE
```

Обращаю Ваше внимание, что прежде чем открывать файл, нужно убедится в том, что он не открыт в каком-то другом приложении. Если в ini-файле можно было динамически менять значения, то этим методом так не получится.

Так, так тема нашего урока "форматированное считывание и запись", то мы обязаны рассмотреть какие идентификаторы есть, которые пишутся в опкод в зависимости от типа принимаемых значений:

| Таблица 2     |                                                                                                |
| ------------- | ---------------------------------------------------------------------------------------------- |
| Идентификатор | Описание                                                                                       |
| %d            | Идентификатор целого числа                                                                     |
| %f            | Идентификатор дробного числа ( по-умолчанию число и остаток с шестью символами после запятой ) |
| %s            | Идентификатор строки                                                                           |
| %c            | Идентификатор символа (номер символа)                                                          |

Здесь:\
% - специальный идентификатор, который указывает компилятору какой тип данных нужно записывать или читать. Они стоят в том порядке, который мы задали в файле, или планируем записать.\
d, f, c, s - собственно и есть типы

Давайте рассмотрим 2 опкода, которые позволяют осуществлять запись и чтение:

```
0AD9: write_formatted_text "Записать %d значений" in_file $hFILE 2
0ADA: 0@ = scan_file $hFile format "Считать %d" 1@
```

Опкод "0AD9" записует форматированный текст в файл "$hFILE". Будет записан текст, с таким содержимым: "Записать 2 значений". Как видите, в поле строки указываются только идентификаторы, а после опкода идёт перечисление всех значений. То есть, если мы хотим, что бы в файл записало стоку с содержимым "Бокал пива вмещает 0.5 литра" и хотим в скрипте задать объём пива, то наш скрипт приобретёт следующий вид:

```
0@ = 0.5
0AD9: write_formatted_text "Бокал пива вмещает %.1f литра" in_file $hFILE 0@
```

Таким образом мы сами задаём в переменную значение, а за тем размещаем в нужном нам месте текста. Но не нужно забывать, что не все числа нужно объявлять через идентификаторы. Можно обойтись и без них, если он не содержит нужной нам информации:

```
0@ = 1.25
0AD9: write_formatted_text "В 2 бокала пива вмещается %.2f литра" in_file $hFILE 0@
```

Соответственно в файл будет записан текст: "В 2 бокала пива вмещается 1.25 литра". То есть, если не задать параметр как идентификатор, то он воспринимается как символ. Давайте на этом же примере, напишем текст, с использованием 2-х параметров:

```
0@ = 1.25
1@ = 2
0AD9: write_formatted_text "В %d бокала пива вмещается %.2f литра" in_file $hFILE 1@ 0@
```

Думаю вы обратили внимание на "%.2f". Собственно для чего мы поставили это? Дело в том, что при такой установке в файл будет записываться только 2 символа после запятой. Если мы поставим "%.3f", то в файл будет записано 3 символа. Если этого не сделать ( напишем просто "%f" ), то число в файл запишет число "1.250000". Эти идентификаторы уже нужно ставить на своё усмотрение, но как минимум "%.1f". Иначе если дробное число не будет иметь остатка ( например, "1.0"), то во многих случаях в файл запишется просто "1", что вызывает проблемы при считывании. Данные выражения с точкой действуют только на дробные цисла!

Что касается записи строк, то здесь всё тоже самое. Указываем стринговую переменную и задаём ей значение. После этого записуем в файл:

```
1@v = "Привет"
0AD9: write_formatted_text "text %s" in_file $hFILE 1@v
```

Содержимое файла: "text Привет". Вот пример простейшего скрипта, который запишет в файл данные:

```
{$CLEO}
0000:
thread 'WRITE_TEXT'

:WRITE_TEXT
wait 0
if
file.Open(0@, "cleo&#92;text.txt", "wt")
jf @WRITE_TEXT
1@ = 2
2@v = "пива"
3@ = 1.25
0AD9: write_formatted_text "в %d бакалах %s вмещается %.2f литра" in_file 0@ 1@ 2@v 3@
file.Close(0@)
0A93: end_custom_thread
```

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/39936709.png)\
\
× \*\*ВАЖНО:\*\* Если файл имеет какие то записи, то при открытии его режимом "wt" или "wb" его содержимое теряется ( файл перезапишеться ).

Опкод "0ADA" осуществляет считывание файла и очень похож на запись, но здесь есть одно примечание, что содержимое строки файла должно точно совпадать с содержимым строки опкода! Если строка файла "Сейчас 16:21 часов", то содержимое строки опкода будет "Сейчас %d:%d часов" ( планируется считать 2 значения из файла ). Следовательно в конце опкода нужно дописать необходимые параметры:

```
0ADA: 0@ = scan_file $hFile format "Сейчас %d:%d часов" 1@ 2@
```

Таким образом в переменные "1@" и "2@" будут записаны числа, считанные из файла. В переменную "0@" запишется количество удачных преобразований. Если оно не совпадёт с параметрами файла, то выражение вернёт **false** и в переменные "1@" и "2@" нифига не запишется =) Это условный опкод, поэтому используйте его в условных конструкциях с "if". Старайтесь правильно указывать идентификаторы. Во многих случаях это и есть решение проблем.

Давайте напишем простой пример скрипта, который будет считывать цвета для автомобиля а за тем задавать их транспорту, в который мы сели:

```
{$CLEO}
0000:
thread 'READ_TEXT'

:READ_TEXT
wait 0
if
file.Open(0@, "cleo&#92;text.txt", "rt")
jf @READ_TEXT

:READ_TEXT_1
wait 0
if 
0ADA: 1@ = scan_file 0@ format "Color car: %d, %d" 2@ 3@
jf @READ_TEXT_1
file.Close(0@)

:READ_TEXT_2
wait 0
if
actor.Driving($PLAYER_ACTOR)
jf @READ_TEXT_2
03C0: 5@ = actor $PLAYER_ACTOR car
0229: set_car 5@ primary_color_to 2@ secondary_color_to 3@
0A93: end_custom_thread
```

В результате наш скрипт прекрасно перекрашивает наш транспорт на заданный в файле цвет.

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/52341360.png)

В большинстве случаев файлы используют для хранения одинаковой по-структуре информации. Затем считывают весь файл и задают параметры для разных субъектов. К примеру, в файле в нас будет хранится информация о транспорте. Считая её мы создадим несколько машин в генераторе транспорта. Сначала рассмотрим опкод для определения количества параметров в строке:

```
014B: $CAR = init_parked_car_generator #RHINO color -1 -1 1 alarm 0 door_lock 0 0 10000 at 2435.302 -1671.848 12.8007 angle 90.0
```

Первый параметр будет у нас модель транспорта. Второй параметр пусть будет цена автомобиля. А следующие четыре: координаты спавна и угол поворота. Остальные пусть будут по-умолчанию. Что бы не терять ваше время, я создал файл с уже готовыми параметрами:

445 5000 2483.021 -1659.0421 12.94315 180.0\
446 7000 2477.022 -1659.0422 12.9432 180.0\
447 4000 2471.023 -1659.0423 12.9431 180.0\
448 8000 2465.024 -1659.0424 12.94321 180.0\
491 10000 2459.025 -1659.0425 12.94322 180.0\
471 13000 2453.026 -1659.0426 12.94311 180.0\
455 20000 2447.027 -1659.0427 12.94314 180.0\
438 8000 2441.028 -1659.0428 12.94321 180.0

Дальше уже напишем скрипт:

```
{$CLEO}
0000:
thread 'READ_TEXT'

var
$CARS: array 8 of car
end

:READ_TEXT
wait 0
if
file.Open(0@, "cleo&#92;text.txt", "rt")
jf @READ_TEXT
$INDEX = 0

while not file.EOF(0@)
 if 
 0ADA: 1@ = scan_file 0@ format "%d %d %f %f %f %f" 2@ 3@ 4@ 5@ 6@ 7@ // IF AND SET
 then
 014B: $CARS[$INDEX] = init_parked_car_generator 2@ color -1 -1 1 alarm 0 door_lock 0 0 3@ at 4@ 5@ 6@ angle 7@
 014C: set_parked_car_generator $CARS[$INDEX] cars_to_generate_to 101
 $INDEX += 1
 end
wait 0
end
file.Close(0@)
0A93: end_custom_thread
```

Так как в нас файл состоит из 8 строк, то и в массиве автомобилей тоже будет 8 машин. Дальше считывая файл мы подставляем считанные значения в опкод, тем самым создаём новый элемент генератора транспорта.

Думаю, Вы обратили внимание на опкод "0AD6: end\_of\_file 0@ reached" ( он же **file.EOF(0@)** ). Это проверка "Достигнут ли конец файла 0@?". Используя её мы узнаём когда прекращать чтение. В результате мы получили:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/59636185.png)

Если разобраться, то нет ничего сложного. Используйте файлы и в своих модах. В большинстве случаев, это существенно уменьшает время и код! =)|2411|1|0|52341360`png`500`388`400`310``\|59636185`png`500`300`400`240``\|25511210`png`460`422`400`366``|39936709`png`403`301`400\`298\`\`||rabota\_s\_fajlami\_formatirovannoe\_schityvanie|1504425699


# 00093. Работа с файлами ( Дозапись )

Работа с файлами ( Дозапись )|В предыдущем уроке мы говорили о записи файла и него чтение. Сегодня наш урок посвящен дозаписи.|wmysterio|wmysterio||||Всем привет! Если открыть файл режимом "wt", то содержимое файла теряется. Если нужно сохранить это содержимое и в свою очередь добавить новую информацию, то нам понадобится режим "at", который и делает дозапись в конец файла.

Давайте напишем скрипт, который будет вести лог. Например, вести мониторинг координат СЖ и его угола каждую секунду и записывать в файл ( пока не будет зажата клавиша 1 ):

```
:NAME
thread 'NAME'
wait 0
if
file.Open(0@, "Cleo/log.txt", "at")
jf @NAME
wait 2000
0ACE: show_formatted_text_box "FILE IS OPEN"

while 8AB0: not key_pressed 49 // key 1
 if
 not actor.Dead($PLAYER_ACTOR)
 then
 actor.StorePos($PLAYER_ACTOR, 1@, 2@, 3@)
 4@ = actor.Angle($PLAYER_ACTOR)
 0AD9: write_formatted_text "Pos: %.4f %.4f %.4f angle: %.2f " in_file 0@ 1@ 2@ 3@ 4@
 end
wait 1000
end
file.Close(0@)
0ACE: show_formatted_text_box "FILE IS CLOSED"
0A93: end_custom_thread
```

Запускаем игру и побродим некоторые время по игровому миру. Проверяем файл и что мы видим? :

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/83210492.png)

Ура! Данные успешно занесены в файл! Но... АААА!!!! Как безобразно всё это выглядит! Неудобство чтения просто зашкаливает! От сюда и возникает вопрос "Как записать данные файла с новой строки?". Ответ дал мне пользователь **DK22Pac**. Как оказалось нужно было добавить в конце строки специальные коды, который подразумевает перенос строки ( символы окончания и переноса строки ). Следовательно, наш опкод для записы будет выглядеть следующим образом:

```
0AD9: write_formatted_text "Pos: %.4f %.4f %.4f angle: %.2f%c%c" in_file 0@ 1@ 2@ 3@ 4@ 0xD 0xA
```

0xD 0xA - это и есть те коды, которые делают переход на новою строку, в конце строки прописываются как идентификатор символа ( %c). Давайте обновим наш скрипт:

```
:NAME
thread 'NAME'
wait 0
if
file.Open(0@, "Cleo/my_text.txt", "at")
jf @NAME
0ACE: show_formatted_text_box "FILE IS OPEN"

while 8AB0: not key_pressed 49 // key 1
 if
 not actor.Dead($PLAYER_ACTOR)
 then
 actor.StorePos($PLAYER_ACTOR, 1@, 2@, 3@)
 4@ = actor.Angle($PLAYER_ACTOR)
 0AD9: write_formatted_text "Pos: %.4f %.4f %.4f angle: %.2f%c%c" in_file 0@ 1@ 2@ 3@ 4@ 0xD 0xA
 end
wait 1000
end
file.Close(0@)
0ACE: show_formatted_text_box "FILE IS CLOSED"
0A93: end_custom_thread
```

Давайте посмотрим на результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/00269069.png)

Выглядит куда удобнее! Этим методом мы можем сделать, например файл с координатами спавна случайных актёров. Давайте переделаем наш скипт:

```
:NAME
thread 'NAME'
wait 0
if
file.Open(0@, "Cleo/my_text.txt", "rt")
jf @NAME

var
$ACTORS: array 20 of actor
end
$INDEX = 0

while not file.EOF(0@)
 if
 $INDEX > 19
 then
 break
 end // если к-во строк превышает допустимый массив актёров, то выходим с цикла

 if
 0ADA: 7@ = scan_file 0@ format "Pos: %f %f %f angle: %f%c%c" 1@ 2@ 3@ 4@ 5@ 6@ //IF and SET
 then
 0376: $ACTORS[$INDEX] = create_random_actor_at 1@ 2@ 3@
 actor.Angle($ACTORS[$INDEX]) = 4@
 $INDEX += 1
 end
wait 0
end
file.Close(0@)

0A93: end_custom_thread
```

Если мы допысали код символа, то при считывании мы тоже должны считать его опкодом "0ADA", выделив 2 переменные для записи в них кодов переноса. Результат скрипта:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/60046112.png)

Создались актёры, в тех местах, где был СЖ при дозаписи файла. И, напоследок, расскажу вам о текстовых и бинарных файлах ( r**t** - r**b**, w**t** - w**b**, a**t** - a**b** ). Вообще, принципиальной разницы между текстовыми файлами и бинарными нет, но открытие бинарного файла как текстового могут наблюдаться "косяки". Например, при записи в текстовые файлы все одиночные символы "\r" ( символ перевода на новую строку в Mac OS ) или "\n" ( символ перевода на новую строку в Unix ) заменяются на 2 символа "\r\n" ( перевод на новую строку в Windows ). Поэтому, если работаете с бинарным файлом, открывайте его как бинарный, если с текстовым - открывайте его как текстовый.

Надеюсь, эта информация была для Вас полезной :) Немного позже выложу урок, как записать данные в определённое место файла.|1511|1|0|00269069`png`440`330`399`300``\|60046112`png`500`300`400`240``\|83210492`png`769`117`400`60``||rabota\_s\_fajlami\_dozapis|1504427021


# 00071. Визуальные эффекты в GTA San Andreas

Визуальные эффекты в GTA San Andreas|Всем привет! Пришло время рассмотреть визуальные эффекты в GTA San Andreas. Сами эффекты реализуются при помощи систем частиц ( particles ). Но что бы не путать всё распределим эффекты на три группы: эффекты, короны и проекции.|wmysterio|wmysterio||||**Эффекты.**

Думаю вы замечали в игре их, например взять эффект нитро из выхлопной трубы? или взять даже той огонь, что присутствует в игре. Эффекты никак не могут влиять на игрока. Тоесть, если СЖ в эффекте огня, то он не будет получать урон. Рассмотрим опкоды:

```
064B: 0@ = create_particle "EXHALE" at 2490.4514 -1674.7673 13.3359 type 1
```

Здесь:\
0@ - переменная ффекта\
"EXHALE" - имя самого эффекта ( см.[Эффекты частицы](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/ehffekty_chasticy_v_gta_sa/1-1-0-20/README.md) )\
2490.4514 -1674.7673 13.3359 - координаты создания\
1 - какой то тип. Я не знаю за что он отвечает, так что оставляем как есть

```
064C: make_particle 0@ visible
```

Делает эффект видимым. Начинает воспроизведения. А опкод

```
064E: stop_particle 0@
```

останавливает воспроизведения системы частиц.

```
064F: remove_references_to_particle 0@ // Выгружает из памяти эффект

0976: destroy_particle 139@ // mission version
0650: destroy_particle 0@ // Опкоды 0976 и 0650 уничтожают эффект
```

Также есть возможность прицепить эффект к сущностям:

```
0669: 0@ = attach_particle "EXHALE" to_actor $PLAYER_ACTOR with_offset 0.0 0.116 0.048 flag 1
066A: 0@ = attach_particle "EXHALE" to_actor $PLAYER_ACTOR with_offset 0.0 0.116 0.048 rotation 90.0 90.0 90.0 flag 1
066B: 0@ = attach_particle "EXHALE" to_car $CAR with_offset 0.0 0.116 0.048 flag 1
066C: 0@ = attach_particle "EXHALE" to_car $CAR with_offset 0.0 0.116 0.048 rotation 90.0 90.0 90.0 flag 1
066D: 0@ = attach_particle "EXHALE" to_object $OBJECT with_offset 0.0 0.116 0.048 flag 1
```

Здесь:\
0@ - переменная для эффекта\
"EXHALE" - имя самого эффекта\
$PLAYER\_ACTOR, $CAR, $OBJECT - переменные субъектов ( актёра, транспорта и объекта )\
0.0 0.116 0.048 - координаты относительно субъекта\
90.0 90.0 90.0 - ротация эффекта ( разворот на угол по осям X, Y и Z )\
1 - флаг. Зачем он я не знаю, так что ставим 1.

Можно так же прицепить эффект определённой части тела актёра:

```
0883: attach_particle 0@ to_actor $PLAYER_ACTOR mode 5
```

Здесь:\
5 - режим. Почему назвали именно режимом не знаю ![wacko](http://s49.ucoz.net/sm/15/wacko.gif) Чем ниже число, тем ниже относительно актёра будет прицеплен к актёру. Чем больше - тем выше.

Вот Вам простейший пример использования:

```
{$cleo}
0000:

:A
thread 'a'
wait 5000
0669: 0@ = attach_particle "EXHALE" to_actor $PLAYER_ACTOR with_offset 0.05 0.12 0.0 flag 1
0883: attach_particle 0@ to_actor $PLAYER_ACTOR mode 5
064C: make_particle 0@ visible
0A93: end_custom_thread
```

Эффект дыма будет прицеплен ко рту СЖ. Вот скрин:

![](https://github.com/wmysterio/scm-scripting-lessons/blob/main/_pu/1/96756408.png)

Плюсы: ничего не нужно загружать. Минусы: не все эффекты воспроизводятся постоянно. Много из них проигрываются только 1 раз. Возможно это связано как то с типом или флагом.

**Короны.**

Думаю, в большинства новичков это ассоциируется с какой-то драгоценностью, которую носят на голове короли. Однако в гта это иной термин. К коронам можно отнести всякие блики, геометрические фигуры, которые постоянно "смотрят" в камеру. Есть всего два опкода для создания корон ( хотя здесь лучше сказать "для рисования корон" ):

```
024F: create_corona_with_radius 2.0 type 9 lensflares 0 with_color 0 255 0 at 2490.4514 -1674.7673 13.3359
04D5: create_corona_at 2490.4514 -1674.7673 13.3359 radius 2.0 type 9 flare 0 RGB 0 255 0
```

Здесь:\
2490.4514 -1674.7673 13.3359 - координаты появления короны\
2.0 - радиус короны. Чем больше, тем громаднее она будет\
9 - тип короны ( см. [Короны→типы корон](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/korony_v_gta_sa/1-1-0-21/README.md) )\
lensflares 0 = flare 0 - блик короны ( см. [Короны→типы lensflares](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/korony_v_gta_sa/1-1-0-21/README.md) )\
with\_color 0 255 0 и RGB 0 255 0 - указывает цвет в цветовой схеме ( R - красный, G - зелёный, B - синий ). Диапазон значений от 0 до 255

Как видите в переменную короны не заносятся. Что бы их было видно нужно поставить опкод в цикл. Давайте напишем пример для корон:

```
{$cleo}
0000:

while 8AB0: not key_pressed 49 // 1
04D5: create_corona_at 2490.4514 -1674.7673 13.3359 radius 2.0 type 9 flare 0 RGB 0 255 0
wait 0
end

0A93: end_custom_thread
```

Пока игрок на нажмёт кнопку 1\` на Гроув будет рисоваться корона. Скрин, как всегда:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/71905228.png)

Плюсы: опять ничего дополнительно загружать не нужно. Можно указывать цвет короне, что может делать гта необычной, например можно создать скрипт, когда в СЖ есть броня, то вокруг него будет корона. Чем то будет смахивать на щит мага из игры WoW. Минусы: корону нельзя создать. Её нужно рисовать в цикле. Особенность: корона будет "смотреть" в камеру под любым углом.

**Проекции.**

Это те же эффекты. Отличие в том, что они не имеют анимации и их можно отредактировать. К примеру можно привести тени. Рассмотрим опкод для рисования проекции:

```
016F: create_particle 6 rotation_factor 180.0 size 7.0 intensity 255 flags 255 0 0 at 2490.4514 -1674.7673 13.3359
```

Здесь:\
6 - тип проекции ( см. [Типы проекций](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/proekcii_v_gta_sa/1-1-0-22/README.md) )\
180.0 - угол поворота проекции по оси Z\
7.0 - размер. чем больше, тем громаднее будет проеция\
255 - интенсивность. Если простыми словами, то прозрачность в диапазоне от 0 до 255. Если поставить 0, то проекцию не будет видно вообще\
flags 255 0 0 - цветовая схема RGB. Выше указано что это\
2490.4514 -1674.7673 13.3359 - точка рисования

Давайте сделаем огромное пятно крови на Гроув-стрит:

```
{$cleo}
0000:

while 8AB0: not key_pressed 49 // 1
016F: create_particle 6 rotation_factor 180.0 size 7.0 intensity 255 flags 255 0 0 at 2490.4514 -1674.7673 13.3359
wait 0
end

0A93: end_custom_thread
```

А вот и лужа крови:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/25623464.png)

Плюсы и минусы такие же как и в корон. Если нечем заняться, то вот вам задание: Сделать проекцию зелёного цвета ( как бы имитируя лужу кислоты ) и когда СЖ ( или какой то другой пед ) попадает в неё у него отнимается какое-то количество жизни.|4137|1|0|71905228`png`600`360`400`240``\|25623464`png`600`360`400`240\`\`|96756408`png`362\`286

```
`\||vizualnye_ehffekty_v_gta_san_andreas|1499706891
```


# 00069. Взрывы и всё, что связано с огнём.

Взрывы и всё, что связано с огнём.|В этом уроке мы рассмотрим взрывы, а также поиграем с огнём! :)|wmysterio|wmysterio||||Вы любите взрывы? Когда автомобиль взлетает на несколько метров вверх... Ммм... Я люблю! :) Чтобы узнать опкоды взрывов в поиске введите слово "explo" и Вам предоставится список опкодов для работы со взрывами. Я рассмотрю только несколько из них - которые я использую и проблем с ними не возникает.

Опкод создаёт взрыв:

```
0948: create_explosion_at 1205.0 162.0 13.0 type 11 camera_shake 5.0
```

Здесь:\
1205.0 162.0 13.0 - координаты, где должен произойти взрыв\
11 - тип взрыва ( см. [Типы взрывов](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/tipy_vzryvov_dlja_gta_san_andreas/1-1-0-30/README.md) )\
5.0 - параметр указывает как сильно будет шататься камера после взрыва. Чем больше число, тем сильнее будет шататься ( но большие значения не вводите )

Опкод воспроизводит звук взрыва:

```
0565: create_soundless_explosion_at 1205.0 162.0 13.0 type 11
```

Здесь:\
1205.0 162.0 13.0 - координаты, где должен произойти взрыв\
11 - тип взрыва. Звук будет подбираться по типу, так что используйте такой тип, который вы указали в опкоде 0948 ( обычно эти опкоды идут вместе )

Далее в нас опкод, который проверяет "Существует ли взрыв в кубе?":

```
0356: explosion_type -1 in_cube_cornerA 107@ 108@ 109@ cornerB 110@ 111@ 112@
```

Здесь:\
-1 - указывается тип взрыва ( см. [Типы взрывов](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/tipy_vzryvov_dlja_gta_san_andreas/1-1-0-30/README.md) ), которого нужно проверить. Если поставить -1, то проверятся будут любые взрывы в кубе\
107@ 108@ 109@ - координаты нижней левой точки куба ( можно использовать обычные координаты в место переменных )\
110@ 111@ 112@ - координаты верхней правой точки куба ( можно использовать обычные координаты в место переменных )

Эти опкоды заставляют транспорт "0@" взорваться:

```
020B: explode_car 0@ // versionA
070C: explode_car 0@ // versionB
```

Прикольно, правда? Давайте напишем скрипт: Когда СЖ сидит в транспорте и нажимает кнопку 8`, то в переменную заносится текущий автомобиль. Если СЖ нажмёт кнопку <kbd>9`, то этот транспорт взорвётся!

```
{$CLEO}
0000:

while true
 if AND
 actor.Driving($PLAYER_ACTOR)
 0AB0: key_pressed 56 // 8
 then
 03C0: 0@ = actor $PLAYER_ACTOR car
 0AD1: show_formatted_text_highpriority "Detonator enable!" time 3000
 end
 if AND
 car.Defined(0@)
 0AB0: key_pressed 57 // 9
 then
 if
 8119: not car 0@ wrecked
 then
 020B: explode_car 0@ // versionA
 end
 end
wait 0
end
```

По-традиции скрин:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/17423750.png)

Даю Вам задание: сделать точно такой же скрипт, только взрыв автомобиля не должен осуществляться опкодами: "020B", "070C" и "08CB". Принцип работы должен быть тем же: нажимаешь кнопку - БАХ!

Взрывы рассмотрели. Теперь рассмотрим огонь. Думаю расписывать что такое огонь не имеет смысла :D Перейдём к опкодам!

```
02CF: 0@ = create_fire_at 0.0 0.0 0.0 propagation 0 size 1
```

Одкод создаёт огонь.

Здесь:\
0@ - переменная, в которой хранится имя огня\
0.0 0.0 0.0 - указываем координаты, где должен создаться огонь\
0 - распространение огня. Чем больше параметр, тем быстрее огонь будет распространятся по площади 1 - размер огня. По-сути это размер ( радиус ) центра

```
02D1: remove_fire 0@
```

Выгружает с памяти ( тушит ) огонь.

```
031A: remove_all_fires
```

Тушит все огоньки.

```
0980: extinguish_all_fires_at -973.759 1077.152 1350.399 radius 200.0
```

Тушит все огони в определённой точке на расстоянии радиуса.

```
06F5: create_coordinate 1@ 2@ 3@ from_fire 0@
```

Записывает в переменные координаты огня "0@". Далее рассмотрим проверки для огней:

```
0973: fire 0@ exists // огонь 0@ существует?
02D0: fire 0@ extinguished // огонь 0@ потушен?
```

Есть так же два интересных опкода. Например: когда в машины мало жизней, то она начинает гореть. Мы можем заставить его гореть принудительно! Используем опкод:

```
0325: 0@ = create_car $CAR fire
```

Здесь:\
0@ - хэндл огня\
$CAR - хэндл транспорта. Если мы поставили иммунитеты к огню, то опкод может не сработать

Так же само мы можем заставить гореть актёра, используя опкод:

```
0326: 0@ = create_actor $ACTOR fire
```

Давайте напишем простейший скрипт - нажимаем кнопку 1\` и СЖ начинает гореть:

```
{$CLEO}
0000:

while true
 if
 0AB0: key_pressed 49
 then
 0326: 0@ = create_actor $PLAYER_ACTOR fire
 end
wait 0
end
```

Думаю основную ( если не полную :) ) информацию я вам предоставил. Вы можете использовать огни в своих миссиях.|1343|1|0|17423750`png`600`360`400\`240\`\`||vzryvy\_i\_vsjo\_chto\_svjazano\_s\_ognjom|1499704863


# 00086. Движения объектов и эффектов

Движения объектов и эффектов|Опять возвращаемся к объектам. На этот раз мы будем их перемещать. Всё это нужно, что бы мы могли двигать эффекты.|wmysterio|wmysterio||||Думаю во многих модах вы видели, когда к эффекты, например огня, двигаются. Отсюда и вопрос - как заставить их двигаться, ведь нет опкодов для перемещения эффектов. Именно для этого мы вернёмся к движению объектов.

Рассмотрим, уже вам известные опкоды, для перемещения объектов:

```
01BC: put_object $OBJ at 2413.5225 -1659.0372 13.3828
034E: move_object 0@ to 2413.5225 -1659.0372 20.3828 speed 0.5 1.0 1.0 flag 0
```

Опкод "034E" отличается тем, что перемещение происходит плавно. Единственный минус, что этот опкод используется, как условие и использовать нужно только в циклах, например: в "while" или в блоках условий. Здесь:

Здесь:\
0@ - хендл объекта\
2413.5225 -1659.0372 13.3828 - координаты, куда должен переместится объект\
0.5 1.0 1.0 - скорость перемещения: 1-й параметр - по оси X, 2-ой - по оси Y, 3-й - по оси Z. Если поставить все значения в 0.0, то никакого перемещения не будет, так как итерация равна нулю. Тоесть, если к координатам прибавить эти нули, то координаты не поменяют свои значения\
0 - флаг. Если 0, то объект будет перемещаться до тех пор, пока не будет в заданной точке. Если поставить 1, то перемещение может прекратится ещё до заданных координат. Чем это объянить я не знаю, поэтому используем 0

Давайте напишем пример с перемещением объекта:

```
{$CLEO}
0000:

var
0@: object
end

:NAME
thread 'NAME'
wait 0
0@.Create(1248, 2505.4763, -1677.182, 13.3773)
wait 3000

while 834E: not move_object 0@ to 2413.5225 -1659.0372 13.3828 speed 0.25 0.25 0.0 flag 0 
wait 0
end 

0A93: end_custom_thread
```

Аналогично перемещаются и эффекты. Суть в том, что мы должны прицепить эффект к объекту. Давайте допишем парочку строчек к нашему примеру:

```
{$CLEO}
0000:
 
var
0@: object
end
 
:NAME
thread 'NAME'
wait 0
0@.Create(1248, 2505.4763, -1677.182, 13.3773)
wait 3000
066E: create_particle "nitro" attached_to_object 0@ with_offset 0.0 0.0 0.0 rotation 0.0 0.0 0.0 flag 1 handle_as 1@ //
064C: make_particle 1@ visible //
 
while 834E: not move_object 0@ to 2413.5225 -1659.0372 13.3828 speed 0.25 0.25 0.0 flag 0 
wait 0
end 
 
0A93: end_custom_thread
```

Таким образом, при перемещении объекта будет перемещаться и эффект. Так как эффекта почти не видно из за объекта, нужно как то замаскировать его :) Не вопрос! Есть опкод, который делает невидимым объект:

```
0750: set_object 0@ visibility 0
```

Здесь:\
0@ - хендл объекта\
0 - установить видимость. Если 0 - невидимый, 1 - видимый

А так же сделаем немного медленнее перемещение, что бы эффект был заметнее:

```
{$CLEO}
0000:
 
var
0@: object
end
 
:NAME
thread 'NAME'
wait 0
0@.Create(1248, 2505.4763, -1677.182, 13.3773)
wait 3000 
066E: create_particle "nitro" attached_to_object 0@ with_offset 0.0 0.0 0.0 rotation 0.0 0.0 0.0 flag 1 handle_as 1@ 
064C: make_particle 1@ visible 
0750: set_object 0@ visibility 0 //
 
while 834E: not move_object 0@ to 2413.5225 -1659.0372 13.3828 speed 0.15 0.15 0.0 flag 0 
wait 0
end 
 
0A93: end_custom_thread
```

Обратите внимание на то, что делать невидимым объект нужно после того, как создали и запустили эффект. В противном случаи эффект может скрыться вместе с объектом :)

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/53422508.jpg)

Используя эти возможности вы можете как-то усовершенствовать эти знания, добавив, например, вращение объекта по осям. Ваше задание - проверить как будет лететь эффект, если задавать в цикле меняющийся угол поворота поворота объекта. Для достижения нужного результата установите в опкоде "066E" оффсет "0.0 1.0 0.0". Результат вас удивит.

P. S. Можно делать невидимыми не только объекты, но и транспорт и даже актёров!

* 0338: set\_car $CAR visibility 0&#x20;
* 0337: set\_actor $ACTOR visibility 0

Эффект действует на всех актёров, кроме СЖ.|1791|1|0|53422508`jpg`500`300`400\`240\`\`||dvizhenija\_obektov\_i\_ehffektov|1500712228


# 00068. Использование RC

Использование RC|Этот урок посвящен ещё одному режиму - режиму RC. Его чаще называют режимом удалённого управления ( управление на расстоянии ).|wmysterio|wmysterio||||Пример такого режима можно было наблюдать в миссия Зеро. Мы управляли маленьким самолётиком и уничтожали фургоны. Вот скрин с этим режимом:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/98696836.png)

Сегодня мы рассмотрим опкоды для работы с этим режимом а так же напишем простенькие примеры. Начнем, опкоды:

Помещает игрока в режиме RC в машину:

```
0715: put_player $PLAYER_CHAR in_RC_mode_in_car $CAR
```

Здесь:\
$PLAYER\_CHAR - хендл игрока\
$CAR - хендл созданной ранее машины ( лодки, вертолёта, самолёта )

Опкод считывает в переменную текущую RC-машину игрока:

```
0484: $CAR = player $PLAYER_CHAR RC_car
```

Выход игрока с режима RC:

```
04DB: exit_RC_mode
```

Для реальности разработчики сделали миниатюрные модели транспорта. Их имена начинаются с "#RC". Вот список всех доступных RC-моделей:

| Модель    |
| --------- |
| #RCBANDIT |
| #RCBARON  |
| #RCCAM    |
| #RCGOBLIN |
| #RCRAIDER |
| #RCTIGER  |

Однако возможно использовать и другие модели транспорта. Например: #INFERNUS. Вот скрин:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/89041466.png)

Если присмотреться, то заметно, что водитель отсутствует! Можно сказать, что призрак водит авто :) Нужно так же помнить, что здесь работает функция уничтожения. Она действует в любом транспорте! После детонации транспорта, возвращается контроль к самому CJ.

Минусы режима:

* Управляя транспортом, мы одновременно управляем и CJ. Поэтому его нужно перемещать в точку, где нет угрозы для жизни;
* В RC-режиме действуют номера клавиш когда СЖ идёт пешком, тоесть, чтобы ехать вперёд на транспорте, то нужно нажать пробел;

Что бы избавится от этих минусов нужно всего три шага:

* Создать автомобиль в любой точке ( желательно не далеко от RC-машинки );
* Поместить СЖ в эту машину ( "072A" ) и закрепить её в текущей позиции;
* Поместить СЖ в режим RC;

Вот образец:

```
072A: put_actor $PLAYER_ACTOR into_car 1@ driverseat
car.LockInCurrentPosition(1@) = true
0715: put_player $PLAYER_CHAR in_RC_mode_in_car 0@
```

Таким образом мы можем нормально управлять RC-транспортом. Давайте напишем скрипт, что бы возле дома СЖ стоял самолётик. Возле него так же будет стоять #INFERNUS. Если СЖ сядет в инфернус, то ему дают удалённое управление самолётиком.

```
{$CLEO}
0000:

:NAME
thread 'NAME'
wait 0
model.Load(#INFERNUS)
model.Load(#RCBARON)
038B: load_requested_models

:NAME_1
wait 0
if AND
model.available(#INFERNUS)
model.available(#RCBARON)
jf @NAME_1
0@ = car.Create(#RCBARON, 2499.4604, -1684.9598, 13.4366)
car.Angle(0@) = 19.615
car.SetImmunities(0@, 1, 1, 1, 1, 1)
1@ = car.Create(#INFERNUS, 2509.5298, -1686.9619, 13.0763)
car.Angle(1@) = 45.9011
car.SetImmunities(1@, 1, 1, 1, 1, 1)
model.destroy(#INFERNUS)
model.destroy(#RCBARON)

:NAME_2
wait 0
if AND
car.Defined(0@)
car.Defined(1@)
then
 if AND
 8119: not car 0@ wrecked
 actor.InCar($PLAYER_ACTOR, 1@)
 then
 car.LockInCurrentPosition(1@) = true
 0715: put_player $PLAYER_CHAR in_RC_mode_in_car 0@
 jump @NAME_3
 end
end
jump @NAME_2

:NAME_3
wait 0
if
0119: car 0@ wrecked
jf @NAME_3
car.LockInCurrentPosition(1@) = false
car.SetImmunities(1@, 0, 0, 0, 0, 0)
0A93: end_custom_thread
```

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/52657795.png)

Естественно скрипт одноразовый. После уничтожения RC-машинки скрипт завершит свою работу. Думаю, основную теорию я вам предоставил. Вы можете использовать её для своих миссий и скриптов :)|1248|1|0|98696836`png`600`360`400`240``\|89041466`png`600`360`400`240``\|52657795`png`600`360`400`240``||ispolzovanie\_rc|1499703465


# 00067. Использование турелей

Использование турелей|Мы продолжаем изучать скриптинг, и сегодня речь пойдет о турелях, а точнее о режиме турели.|wmysterio|wmysterio||||Что это значит? Думаю в оригинальной игре вам предоставлялись шансы пострелять как бы с места пассажира: по-центру появляется прицел и можем стрелять. Например: в миссии Зеро нам нужно было сбивать самолётики миниганом. Мы не могли сдвинуться с места, но могли вращать оружие и стрелять. Такой режим принято называть режимом турели ( от слова **turret** ). Вот как выглядит этот режим:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/50413679.png)

Знакомо, правда? Давайте рассмотрим опкоды для работы с турелью:

```
0464: put_actor $PLAYER_ACTOR into_turret_on_car $CAR at_car_offset -0.2 0.5 0.0 position 0 shooting_angle_limit 0.0 with_weapon 0 
06A7: put_actor $PLAYER_ACTOR into_turret_on_car $CAR at_car_offset -0.2 0.5 0.0 position 1 shooting_angle 110.0 70.0 with_weapon 43
```

Данные опкоды позволяют использовать турель на машине.

Здесь:\
$PLAYER\_ACTOR - хэндл актёра\
$CAR - хэндл машины, к которой будет прицеплен режим\
-0.2 0.5 0.0 - определяется позиция, с которой можно будет вести обстрел. Эти координаты берутся относительно автомобиля. Мы поговорим об этом ниже\
position 0 - выбирается позиция. Я точно не знаю что именно имеется ввиду под словом "позиция", поэтому используйте число указанное в опкодах\
shooting\_angle\_limit 0.0 - определяется лимит поворота на определённый угол\
with\_weapon 0 - указывается номер оружия, с которого будет вестись обстрел\
shooting\_angle 110.0 70.0 - Указывается лимит углов поворота. Первое число - поворот по горизонтали. Если поставить 360.0, то можно стрелять вокруг всей тачки. Второе число - поворот по вертикали ( вверх/вниз ). Советую так оставить число 70.0, так как если поставить число больше игра может вылететь. Советую вам использовать опкод 06A7, с ним у меня проблем не возникало, а вот с другим были проблемы с номером оружия

Так же есть возможность прицепить режим турели к объекту:

```
04F4: put_actor $PLAYER_ACTOR into_turret_on_object $OBJECT offset_from_object_origin -0.2 0.5 0.0 orientation 0 both_side_angle_limit 360.0 lock_weapon 38
```

Здесь:\
$PLAYER\_ACTOR - хендл актёра\
$OBJECT - хендл созданного объекта\
-0.2 0.5 0.0 - определяется позиция, с которой можно будет вести обстрел. Эти координаты берутся относительно объекта, на котором будет турель\
360.0 - угловой лимит по горизонтали\
38 - номер оружия, с которого будет обстрел

Что бы выйти с режима турели используется опкод:

```
0465: remove_actor $PLAYER_ACTOR from_turret_mode
```

Увы, я не нашел опкода, который позволит ходить с турелью. Если я что нибудь разнюхаю, выложу сюда. Если игрока поставить в режим турели, то он не будет передвигаться, а будет следовать за автомобилем или объектом.

Давайте рассмотрим координаты относительно объекта ( оффсеты ) "offset\_from\_object 0.0 0.0 0.0". Допустим в нас есть объект-звезда. Так и или иначе в неё есть перед ( место, куда "смотрит" объект ). Назовём это место "перёд объекта". Естественно у объекта есть центр. Это будет точка. На рисунке она обозначена красным цветом.

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/15433893.png)

Эта точка имеет координаты 0.0 0.0 0.0. Если мы будем увеличивать только первое число, то оффсет переместится в сторону "перёд объекта":

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/63004922.png)

Если мы будем уменьшать значение и уйдем в минус, то оффсет передвинется в противоположную сторону, то есть, как бы это интересно не звучало, в з"ад объекта" )))

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/44693461.png)

Редактирование первого числа позволяет сдвигать оффсет по желтой линии на рисунке. По зелёной линии мы сможем смещать оффсет влево ( второе число положительное ) или вправо ( второе число отрицательное ) от объекта:

| влево ( второе число положительное ) 0.0 2.0 0.0                                         | вправо ( второе число отрицательное ) 0.0 -2.0 0.0                                       |
| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| ![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/69616219.png) | ![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/25373552.png) |

Третье число указывает высоту смещения от объекта. Если оно положительное, то оффсет сместится вверх. Если отрицательное - сместится вниз. Для примера, оффсет "5.0 -5.0 0.0" будет в этой точке:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/19110219.png)

Самое главное, что координаты ведутся относительно объекта, то есть нам ничего другого вычислять не надо. Объект может быть где угодно и под любыми углами - за нас всё уже сделано! :)

Что касается оффсета автомобиля, то там есть отличия:

* Первое число - движение влево ( отрицательное число ) / вправо( положительное число );
* Второе число - движение назад ( отрицательное число ) / вперед ( положительное число );
* Третье число - движение вниз ( отрицательное число ) / вверх ( положительное число );

Как по мне, то такой вариант намного лучше, чем с объектами. Почему разработчики сделали для каждого класса свои оффсеты - не берусь предположить :) С оффсетами вроде разобрались. Переходим к скриптингу. Давайте напишем скрипт, что бы нажатии кнопки T\`, СЖ помещался в режим турели и он мог стрелять с минигана. Для разнообразия сделаем, что бы СЖ оказался возле какого то транспорта:

```
{$CLEO}
0000:

:NAME
thread 'NAME'
wait 0
model.Load(#MINIGUN)
038B: load_requested_models

:NAME_1
wait 0
if
model.Available(#MINIGUN)
jf @NAME_1

:NAME_2
wait 0
0AB5: store_actor $PLAYER_ACTOR closest_vehicle_to 0@ closest_ped_to 1@
if AND
0AB0: key_pressed 84 // T
car.Defined(0@)
then
 if AND
 83C9: not car 0@ damaged
 82BF: not car 0@ sunk
 then
 06A7: put_actor $PLAYER_ACTOR into_turret_on_car 0@ at_car_offset 1.0 0.2 0.3 position 1 shooting_angle 360.0 70.0 with_weapon 38
 wait 250
 jump @NAME_3
 end
end
jump @NAME_2

:NAME_3
wait 0
if OR
actor.Dead($PLAYER_ACTOR)
0AB0: key_pressed 84 // T
03C9: car 0@ damaged
02BF: car 0@ sunk
then
0465: remove_actor $PLAYER_ACTOR from_turret_mode
wait 250
jump @NAME_2
end
jump @NAME_3
```

Вот скрин:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/92582055.png)

Выбираем нужную тачку и нажимаем T`, помещаемся в неё и начинаем палить во всё подряд! Нажимаем ещё раз <kbd>T`, и выходим с режима турели. Интересный вышел скриптик, который можно и в миссию запихнуть ;)

Что касается других актёров, то их тоже можно ставить в режим турели. Они просто будут стоять на месте и стрелять ( нужно заставить их убить кого то опкодом "05E2" ).

Одно я точно не знаю - нужна ли загрузка нужной модели или нет, но на всякий случаи загружайте ;)|1868|1|0|92582055`png`600`375`400`250``\|15433893`png`473`486`399`410``\|63004922`png`473`486`399`410``|44693461`png`473`486`399`410``\|69616219`png`473`486`399`410``\|25373552`png`473`486`399`410``|19110219`png`473`486`399`410``\|50413679`png`600`375`400`250\`\`||ispolzovanie\_turelej|1499697357


# 00057. Работа с INI-файлами ( запись и считывание )

Работа с INI-файлами ( запись и считывание )|В этом укроке мы напишем два скрипта, которые будут использовать ini-файл. Первый будет записывать данные в файл, другой - считывать.|wmysterio|wmysterio||||Очень часто скриптеры хранят какие-то данные в файле. Например: я в моде NFS GTA RACE хранил стартера для миссий, а также текущую модель, уважение в ini-файле.

Рассмотрим основные опкоды. Сначала, обычно, проверяют на существование файла опкодом:

```
0AAB: file_exists "CLEO&#92;temp.ini"
```

Здесь:\
"CLEO\temp.ini" - путь к нужному файлу

Дальше, обычно, если файла не найден, то скриптеры завершают поток, чтобы скрипт без файла не работал. Если файл найден - то можно.

Первый наш скрипт будет записывать данные. Давайте в файле будет хранится состояние жизни и брони CЖ. Другой скрипт будет считывать с того же самого файла данные и выводить их на экран.

Но сначала рассмотрим структуру ini-файла. Обычно он делится на секции - текст, написанный в квадратных скобках:

```
ini
[SECTION]
```

Количество секций неограниченно; а могут и вовсе отсутствовать.

В каждой секции имеются ключевые слова, которым заданы значения типа "int", "float", "string" ( целое, дробное, строка ). Сначала пишем **ключевое слово**, затем символ **=**, а потом **само значение**. Каждое ключевое слово пишется с новой строки.

```
ini
key_int = 25
key_float = -0.23
key_string = WMYSTERIO
```

Сложив всё вместе, мы получим полную структуру ini-файла:

<table><thead><tr><th>Примеры INI-файлов:</th><th></th></tr></thead><tbody><tr><td>Пример 1</td><td>Пример 2</td></tr><tr><td><p>```</p><p>ini [SECTION] key_int = 25 key_float = 1.83 key_string = WMYSTERIO</p><pre><code>&#x3C;/td>&#x3C;td>
</code></pre><p>ini ; Основные данные об актёре [Coord_Actor] position_x = -190.35 position_y = 2004.2345 position_z = 39.0 actor_angle = 180.0</p><p>[Data_Actor] Health = 50 Armor = 100 Name = Smoke</p><pre><code>&#x3C;/td>&#x3C;/tr>
&#x3C;/tbody>&#x3C;/table>

Как и в Санни Билдере, в ini-файлах есть комментарии. Всё что находится после символа **;** будет игнорироваться. Вроде, с этим не должно возникнуть проблем, поэтому рассмотрим опкоды для записи значений в ini-файл:

</code></pre><p>0AF1: write\_int 25 to\_ini\_file "CLEO\temp.ini" section "SECTION" key "key\_int" 0AF3: write\_float 1.85 to\_ini\_file "CLEO\temp.ini" section "SECTION" key "key\_float" 0AF5: write\_string "MY NAME - WMYSTERIO" to\_ini\_file "CLEO\temp.ini" section "SECTION" key "key\_string"</p><pre><code>

\<div class="panel panel-default">
\<div class="panel-body">
Здесь:\<br>
0AF1 - опкод записи целого числа в файл\<br>
0AF3 - опкод записи дробного числа в файл\<br>
0AF5 - опкод записи строки в файл\<br>
"CLEO\&#92;temp.ini" - указывается полный путь к файлу\<br>
"SECTION" - указывается секция, в которую нужно записать данные\<br>
"key\_int", "key\_float", "key\_string" - указываются ключи. Именно в них будут хранится данные
\</div>
\</div>

Теперь считывание с ini-файла:

</code></pre><p>0AF0: 0@ = get\_int\_from\_ini\_file "CLEO\temp.ini" section "SECTION" key "key\_int" 0AF2: 1@ = get\_float\_from\_ini\_file "CLEO\temp.ini" section "SECTION" key "key\_float" 0AF4: 2\@v = read\_string\_from\_ini\_file "CLEO\temp.ini" section "SECTION" key "key\_string"</p><pre><code>

\<div class="panel panel-default">
\<div class="panel-body">
Здесь:\<br>
0AF0 - в переменную считываются целые значения с файла\<br>
0AF2 - в переменную считываются дробные значения с файла\<br>
0AF4 - в переменную считываются строки с файла\<br>
"CLEO\&#92;temp.ini" - указывается полный путь к файлу\<br>
"SECTION" - указывается секция, с которой будет считано значение\<br>
"key\_int", "key\_float", "key\_string" - указываются ключи. Именно из них будут передаваться данные в переменную.
\</div>
\</div>

Для строк всегда возле переменных указывайте префикс **v**. Опкоды рассмотрели, теперь к примерам :) Скрипт, который будет записывать состояние жизни и брони СЖ в ini-файл:

</code></pre><p>{$CLEO} 0000:</p><p>:WRITE thread 'WRITE' wait 0 if 0AAB: file\_exists "CLEO\TEMP.ini" // если файл не найден, то завершаем скрипт jf @WRITE\_END</p><p>:WRITE\_1 wait 0 0@ = actor.Health($PLAYER\_ACTOR) 04DD: 1@ = actor $PLAYER\_ACTOR armour 0AF1: write\_int 0@ to\_ini\_file "CLEO\TEMP.ini" section "CJ" key "Health" // запишем данные в файл 0AF1: write\_int 1@ to\_ini\_file "CLEO\TEMP.ini" section "CJ" key "Armour" jump @WRITE\_1</p><p>:WRITE\_END wait 0 0A93: end\_custom\_thread</p><pre><code>

Скрипт, которые считывает данные из файла и выводит на экран состояние жизни и брони CJ:

</code></pre><p>{$CLEO} 0000:</p><p>:READ thread 'READ' wait 0 if 0AAB: file\_exists "CLEO\TEMP.ini" // Если файл не найден - завершаем скрипт jf @READ\_END</p><p>:READ\_1 wait 0 03F0: enable\_text\_draw 1 // Включаем возможность рисования на экране 0AF0: 0@ = get\_int\_from\_ini\_file "CLEO\TEMP.ini" section "CJ" key "Health" // Считываем данные из файла 0AF0: 1@ = get\_int\_from\_ini\_file "CLEO\TEMP.ini" section "CJ" key "Armour" {-- Выводим данные на экран --} 045A: draw\_text\_1number 20.0 20.0 GXT 'HEA\_1' number 0@ // text: health <del>1</del> 045A: draw\_text\_1number 20.0 30.0 GXT 'BRO\_1' number 1@ // text: armour <del>1</del> jump @READ\_1</p><p>:READ\_END wait 0 0A93: end\_custom\_thread</p><pre><code>

Результат, как всегда, положительный :) Всё работает как часики, и на экран выводится состояние CJ:

\<!--IMG1-->\<img src="/\_pu/0/53472615.png" />\<!--IMG1-->

Интересные факты:

* ini-файл можно редактировать во время игры;
* расширение файла не обязательно должно быть "*.ini", можно и как "*.bag", "\*.fix" и т.п;

На этом урок окончен. Тестируйте ;)|3880|1|0|53472615`png`168`161 </code></pre><p>`||rabota\_s\_ini\_fajlami\_zapis\_i\_schityvanie|1499595834</p></td><td></td></tr></tbody></table>


# 00044. Работа с панелями ( таблицами )

Работа с панелями ( таблицами )|В этом уроке мы рассмотрим примеры и опкоды для работы с панелями.|wmysterio|wmysterio||||Думаю, Вы замечали панели покупок в магазине, где при выборе строки, например "Куртка с капюшоном" мы меняли скин CJ. Именно о таких панелях будет идти речь. Прежде всего создадим таблицу с двумя колонками и 4 строками:

```
08D4: $PANEL = create_panel_with_title 'GXTNAME' position 29.0 170.0 width 180.0 columns 2 interactive 1 background 1 alignment 1
08DB: set_panel $PANEL column 0 header 'GXTHED1' data 'GXTROW1' 'ЗАПИСЬ 2' 'ЗАПИСЬ 3' 'ЗАПИСЬ 4' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY'
08DB: set_panel $PANEL column 1 header 'ЗАГОЛОВОК 2' data 'ЗАПИСЬ 5' 'ЗАПИСЬ 6' 'ЗАПИСЬ 7' 'ЗАПИСЬ 8' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 
```

Здесь ( опкод 08D4 ):\
$PANEL - указывает переменную в которой будет храниться панель\
GXTNAME - указываем имя таблицы ( см. рисунок ниже: "Имя таблицы" )\
29.0 170.0 - указываем место на экране, где должна появится таблица\
180.0 - указываем длину таблицы\
columns 2 - указываем количество колонок в нашей таблице\
interactive 1 - даёт возможность выбирать строки в таблице, если поставить 0 - то только просмотр\
background 1 - обозначает цвет таблицы. Если поставить 1 - то таблица будет чёрная с небольшой прозрачностью, если поставить 0 - то будет прозрачной\
alignment 1 - указывает стиль записей. Если поставить 1 - записи будут выравниваться по левому краю, если 0, то по-центруЗдесь ( опкод 08DB ):\
$PANEL - указывает переменную в которой будет храниться панель\
column 0 - указываем номер колонки для создания строк. Номера колонок всегда начинаются с нуля!\
GXTHED1 - указываем заголовок для каждой из колонок ( см. рисунок ниже: "Заголовок 1" )\
GXTROW1 - указываем названия для строк по очереди ( см. рисунок ниже: "Запись 1" ). Тексты будут расположены именно так, в каком порядке вы их задали\
'DUMMY' - это специальный параметр. Его присутствие - знак того, что запись будет пустой. То есть её просто не выводят на экран, тем самым уменьшая высоту таблицы

Если сейчас у вас возникают трудности, то этот рисунок поможет вам представить как формируется таблица:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/48891377.png)

Как видите никакого "DUMMY" здесь нет. Но в опкодах его присутствие должно быть обязательно, если количество строк меньше 12. Пример строки обозначен зелёным цветом. Рассмотрим опкоды, связаны с панелями

Что бы изменить выравнивание текста в нужной колонке, используем:

```
08D6: set_panel $PANEL column 0 alignment 1
```

Здесь:\
$PANEL - имя панели\
0 - указываем номер строки\
1 - смотрите описание к опкоду 08D4: alignment 1<br>

Что бы записать в переменную номер выделенной ( активной ) строки, используем:

```
08D7: 0@ = panel $PANEL active_row
```

Что бы занести в переменную выбранную строку:

```
08D8: 0@ = panel $PANEL selected_row
```

Что бы запретить ( разрешить ) выбирать какую-то строку, используем опкод:

```
08D9: set_panel $PANEL row 2 enable 0
```

Здесь:\
$PANEL - хэндл панельки\
2 - номер нужной строки\
0 - запретить выбирать эту строку ( если поставить 1 - то разрешить )

Можно также указать длину выбранной колонки:

```
09DB: set_panel $PANEL column 0 width 192
```

Здесь:\
$PANEL - имя переменной панельки\
0 - указываем номер колонки\
192 - указываем длину<br>

Так же мы можем установить номер активной строки:

```
090E: set_panel $PANEL active_row 2
```

Здесь:\
$PANEL - имя панельки\
2 - указываем номер строки

Таким образом при появлении таблицы на экране, сразу будет выделена строка с номером 2.

× \*\*ВАЖНО:\*\* Никогда не используйте этот опкод в циклах, так как пользователь не сможет выбрать другую строку

Что бы убрать панель с экрана, используем:

```
08DA: remove_panel $PANEL
```

Рассмотрим опкоды для вывода чисел в панельках. Вывод целого числа в панельке:

```
08EE: set_panel $PANEL column 1 row 3 text_1number GXT 'DOLLAR' number $NUMBER // $~1~
```

Здесь:\
$PANEL - имя панельки\
1 - указываем в которой колонке вывести число\
3 - указываем в которой строке вывести число\
'DOLLAR' - GXT-запись с выводом числа. Содержание записи, для примера, смотрите в таблице ниже\
$NUMBER - переменная, которая содержит целое число, ибо можно просто указать число без перемененной

| Пример записи |
| ------------- |
| \~1\~         |
| Цена: \~1\~   |

Вывести 2-а целых чисела на панельку можно так:

```
08EF: set_panel 206@ column 2 row 34@ text_2numbers GXT 'DES1_66' numbers 48@ 49@ // ~1~ : ~1~
```

Есть ещё специальные панели, использующиеся для автомобилей, но о них мы поговорим немного позже.

Давайте напишем простой пример для вызова таблицы и её использования. Например: при нажатии кнопки K\`, появится панель одежды с её ценами, и при выборе пункта с нас будет забрано денюжку и СЖ получит одежду. Таким образом, в нас будет панель с 3-мя строками и 2-мя колонками.

Создадим необходимую GXT- или FXT-запись. Вот пример моей:

| Записи, читаемые игрой                                                                   | Перевод записей на русский                                                               |
| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| ![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/23140964.png) | ![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/40273458.png) |

Далее напишем скрипт таблицы, с необходимыми условиями и параметрами:

```
:TABLE
wait 0
08D4: $PANEL = create_panel_with_title 'TABNAME' position 20.0 20.0 width 150.0 columns 2 interactive 1 background 1 alignment 1
09DB: set_panel $PANEL column 0 width 100
09DB: set_panel $PANEL column 1 width 50
08DB: set_panel $PANEL column 0 header 'TABHEA1' data 'TABROW1' 'TABROW2' 'TABROW3' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY'
08DB: set_panel $PANEL column 1 header 'TABHEA2' data 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY'
08EE: set_panel $PANEL column 1 row 0 text_1number GXT 'TABMONE' number 1200
08EE: set_panel $PANEL column 1 row 1 text_1number GXT 'TABMONE' number 800
08EE: set_panel $PANEL column 1 row 2 text_1number GXT 'TABMONE' number 300
```

В результате получится такая панелька:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/69611556.png)

Дальше необходимо создать цикл, к котором проверяются условия выбора строки, проверка денег, а так же условия, при которых убирается паньль с экрана. Сделает это:

```
:TABLE_1
wait 0
08D7: 0@ = panel $PANEL active_row
1@ = player.Money($PLAYER_CHAR)

if OR
actor.Dead($PLAYER_ACTOR)
0741: actor $PLAYER_ACTOR busted
0AB0: key_pressed 13 // ENTER
then
jump @TABLE_2
end

if AND
0@ == 0 // Выбрана строка 0
0AB0: key_pressed 32 // SPACE
then
 if
 1@ > 1199
 then
 Player.SetClothes($PLAYER_CHAR, "WORKTRCAMOGRN", "WORKTR", 2)
 Player.Build($PLAYER_CHAR)
 player.Money($PLAYER_CHAR) += -1200
 jump @TABLE_2
 end
end

if AND
0@ == 1 // Выбрана строка 1
0AB0: key_pressed 32 // SPACE
then
 if
 1@ > 799
 then
 Player.SetClothes($PLAYER_CHAR, "TSHIRTERISORN", "TSHIRT", 0)
 Player.Build($PLAYER_CHAR)
 player.Money($PLAYER_CHAR) += -800
 jump @TABLE_2
 end
end

if AND
0@ == 2 // Выбрана строка 2
0AB0: key_pressed 32 // SPACE
then
 if
 1@ > 299
 then
 Player.SetClothes($PLAYER_CHAR, "bandred", "bandana", 16)
 Player.Build($PLAYER_CHAR)
 player.Money($PLAYER_CHAR) += -300
 jump @TABLE_2
 end
end

jump @TABLE_1

:TABLE_2
wait 0
08DA: remove_panel $PANEL
```

Таким образом при выборе строки, СЖ будет одевать одежду со списка и с его счета будет снята сумма денег, если денег хватит конечно :)

Основная часть скрипта сделана. Теперь добавим пример скрипта в мейн: [смотреть](https://github.com/wmysterio/scm-scripting-lessons/blob/main/data_base/sa/TABLE.txt).

Наша задача решена! Но вы можете ( даже должны ) экспериментировать! Создать больше строк или колонок, написать другие условия или добавить комментарии внизу панели ;)|1403|1|0|69611556`png`640`400`400`250``\|48891377`png`640`204`400`127``\|23140964`png`438`346`400`315``|40273458`png`437`347`400\`317\`\`||rabota\_s\_paneljami\_tablicami|1498996840


# 00043. Работа с аудио

Работа с аудио|Начинаем наш новый урок! Эта тема посвящена работе с аудио-файлами.|wmysterio|wmysterio||||Аудио-файлы можно "разбить" на три категории: звук, саундтрек и музыка. Зачем это нужно? Потому, что воспроизводятся они разными опкодами. Рассмотрим по очереди все категории:

**Звуки**. Отличается короткой длиной и типом файла. Обычно в игре звуки имеют тип "\*.wav". Для начала, нужно загрузить звук опкодом:

```
03CF: load_wav 23000 as 1
```

Здесь:\
23000 - номер ( ID ) звука. Все номера звуков хранятся в файле \*\*AudioEvents.txt\*\*, что в папке "data"\
1 - это, так сказать "переменная", в которой будет хранится звук

Потом нужно сделать проверку на загруженность:

```
03D0: wav 1 loaded
```

Здесь:\
1 - это та самая "переменная", в которую мы записали номер звука

После этого можно воспроизвести сам звук:

```
03D1: play_wav 1
```

Здесь:\
1 - загруженная "переменная" со звуком

Существует также проверка на окончание воспроизведения звука:

```
03D2: wav 1 ended
```

Когда звук больше не нужен, то обязательно выгружаем звук опкодом:

```
040D: unload_wav 1
```

Здесь:\
1 - загруженная "переменная" со звуком

Существует ещё опкод, который не нуждается в загрузке звука и который сразу проигрывает звук:

```
018C: play_sound 1052 at 0.0 0.0 0.0
```

Здесь:\
1052 - номер звука. Я пока знаю где найти описание всех номеров, поэтому берите то, что есть в "main.scm"\
0.0 0.0 0.0 - точно не знаю зачем эти цифры, так что оставляйте как есть× \*\*Примечание:\*\* следует помнить, что этот опкод воспроизводит не все звуки, так что приходится выбирать и тестировать наугад

**Саундтреки**. Эта категория аудио, как и звуки, отличается своей длиной и типом. Они имеют расширение "\*.ogg" и намного длиннее, чем звуки. Для примера саундтрека: когда входим в интерьер дискотеки играет музыка, на битве лоурайдеров - тоже звучик саундтрек. Саундтреки требуют загрузки:

```
0952: load_soundtrack 10 // увы, я не помню все номера саундтреков, но вы можете протестировать
0954: start_playing_loaded_soundtrack // воспроизводит саундтрек
```

× \*\*ВАЖНО:\*\* Одновременно можно проигрывать только 1 сандтрек

Так же можно занести в переменную статус саундтрека:

```
0953: get_soundtrack_status_to 17@
```

Здесь:\
17@ - переменная, в которую заносится статус.

А вот эта команда прекращает воспроизведение саундтрека:

```
0955: end_playing_loaded_soundtrack
```

**Музыка**. Музыка не требует дополнительной загрузки и её можно воспроизводить когда угодно. Она загружается вместе с игрой. Музыку можно услышать когда вы прошли миссию или купили дом. Опкод, запускающий музыку:

```
0394: play_music 2
```

Здесь:\
2 - номер музыки: 1 - миссия пройдена, 2 - дом куплен.

С выходом Cleo 4, нам добавилось несколько опкодов для работы с аудио. Теперь можно проигрывать прямо в игре любимый трек. Рассмотрим алгоритм запуска аудио-файла. Сначала кидаем в папку Cleo ( или в другую папку ) нужный трек и переименовуем его на английские символы ( без пробелов ) или числа. Вот например я кинул в папку Cleo трек с названием "1.mp3". Потом в скрипте нужно обязательно проверить: "Существует ли файл?":

```
0AAB: file_exists "CLEO&#92;1.mp3"
```

Здесь:\
"CLEO\1.mp3" - путь к аудио-файлу

После успешной проверки, загружаем аудио:

```
0AAC: $hMP3 = load_audiostream "CLEO&#92;1.mp3"
```

Здесь:\
$hMP3 - переменная, в которой будет хранится аудио\
"CLEO\1.mp3" - путь к аудио-файлу

После этого запускаем аудио:

```
0AAD: set_audiostream $hMP3 perform_action 1
```

Здесь:\
$hMP3 - переменная, в которой хранится аудио\
1 - флаг. ( 1 - запустить проигрывание сначала, 0 - остановить проигрывание, 2 - поставить на паузу, 3 - возобновить проигрывание )

Опкод, регулирующий громкость аудио в игре:

```
0ABC: set_audiostream $hMP3 volume 1.0
```

Здесь:\
$hMP3 - переменная, в которой хранится аудио\
1.0 - громкость ( от 0.0 до 1.0 )

Ещё один полезный опкод, который позволяет автоматически начать воспроизведение, если музыка была остановлена:

```
0AC0: loop_audiostream $hMP3 flag 1
```

Здесь:\
$hMP3 - переменная, в которой хранится аудио\
1 - флаг. Если поставить 1, то аудио будет повторятся после окончания, если 0 - не будет повторятся

И, наконец, выгрузка звука:

```
0AAE: release_audiostream $hMP3
```

Давайте напишем простенький скрипт, чтобы при нажатии кнопки 1\` играла музыка "1.mp3". Вот код:

```
:AUDIO
thread 'AUDIO'
wait 0
if
0AAB: file_exists "CLEO&#92;1.mp3"
jf @AUDIO_END
0AAC: $hMP3 = load_audiostream "CLEO&#92;1.mp3"
0ABC: set_audiostream $hMP3 volume 1.0
0@ = 0

:AUDIO_1
wait 0
if
0@ == 0
then
 if
 0AB0: key_pressed 49 // 1
 then
 0AC0: loop_audiostream $hMP3 flag 1
 0AAD: set_audiostream $hMP3 perform_action 1 // PLAY
 wait 250
 0@ = 1
 end
else
 if
 0AB0: key_pressed 49 // 1
 then
 0AC0: loop_audiostream $hMP3 flag 0
 0AAD: set_audiostream $hMP3 perform_action 0 // STOP
 wait 250
 0@ = 0
 end
end
jump @AUDIO

:AUDIO_END
wait 0
end_thread
```

Пока не будем кидать этот код в мейн, так как сейсач нет такой необходимости.|2782|1|0||rabota\_s\_audio|1498947823


# 00038. Рисование на экране (Часть 1 - Текст)

Рисование на экране (Часть 1 - Текст)|Начинаем наш очередной урок, и здесь вы научитесь основным командам по рисованию на экране.|wmysterio|wmysterio||||Что значит рисование? - Спросите вы. Это может быть любой текст или текстура, которые могут размещаться в любой точке экрана.

Экран как бы имеет свою координатную сетку, размер которой составляет "640.0" точек по ширине и "448.0" точек по высоте. Начальные координаты "0.0 0.0" и они находятся в правом верхнем углу. Вообще если в поисковике SB ввести слово **DRAW**, то вам выведется список всех команд, которые позволяют рисовать на экране. Рисование можно разбить на две большие группы:

* рисование текста
* рисование текстур

В этом уроке мы коснёмся только текста. Первым делом, рассмотрим опкод, который включает режим рисования:

```
03F0: enable_text_draw 1
```

Здесь:\
1 - включить режим рисования. Если поставить 0 - выключить режим рисования. При смене интерьера, этот параметр сбивается на ноль, по этому его нужно снова включать.

Рассмотрим команды для рисования текста. Самый первый опкод, это:

```
033E: set_draw_text_position 320.0 180.333 GXT 'BJ_PUSH'
```

Здесь:\
320.0 180.333 - координаты на экране. 1-й параметр - координата X ( по ширине ), 2-й - координата Y ( по высоте )\
'BJ\_PUSH' - имя GXT-записи, то есть текст, который содержится в этой записи, будет выведен на экран по координатам

С текстом можно делать разные манипуляции: изменять его цвет и размер:

```
0340: set_text_draw_RGBA 0 90 180 255
033F: set_text_draw_letter_size 1.3 3.36
```

Здесь:\
0 - количество красного цвета ( канал R, от 0 до 255 )\
90 - количество зелёного цвета ( канал G, от 0 до 255 )\
180 - количество синего цвета ( канал B, от 0 до 255 )\
255 - указывает прозрачность текста, если поставить 0, то текст не будет видно. Максимум - 255\
1.3 - размер буквы по ширине\
3.36 - размер буквы по высоте

Так же можно задать шрифт и обводку тексту опкодами:

```
0349: set_text_draw_font 0
081C: draw_text_outline 2 RGBA 10 20 30 255
```

Здесь:\
0 - номер шрифта ( см. [Стили текста - шрифт](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/stili_teksta/1-1-0-43/README.md) )\
2 - плотность обводки ( см. [Стили текста - Обводка](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/stili_teksta/1-1-0-43/README.md) )\
10 - количество красного цвета ( канал R, от 0 до 255 )\
20 - количество зелёного цвета ( канал G, от 0 до 255 )\
30 - количество синего цвета ( канал B, от 0 до 255 )\
255 - указывает прозрачность текста, если поставить 0, то текст не будет видно. Максимум - 255<br>

Кроме этого, можно указать тень текста и её цвет, установить максимальную ширину текста:

```
060D: draw_text_shadow 0 color_RGBA 0 0 0 255
0343: set_text_draw_linewidth 640.0
```

Здесь:\
0 - расстояние тени от текста\
0 0 0 255 - указываются цвета тени и её прозрачность ( См. [Стили текста - Тени](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/stili_teksta/1-1-0-43/README.md) )\
640.0 - указать новую длину строки. Пример-сравнение текста по-умолчанию и текста, которому задали длину 300 символов вы также можете найти в нашей [базе данных, внизу](https://github.com/wmysterio/scm-scripting-lessons/blob/main/dir/gta_sa/stili_teksta/1-1-0-43/README.md), внизу.

Есть возможность выравнивания текста:

```
0342: enable_text_draw_centered 1 // по-центру
03E4: enable_text_draw_align_right 1 // справа
0341: set_text_draw_align_justify 1 // расстягивает строку на максимальную длину ( пробелы кажутся более длинными )
```

И, напоследок, можно вывести какие то числовые переменные на экран:

```
045A: draw_text_1number 320.0 155.333 GXT 'ALLRACE' number 0@ // ~1~
045B: draw_text_2numbers 320.0 155.333 GXT 'TIME' numbers 0@ 0@ // ~1~ ~1~
07FC: text_draw_box_position_XY 320.0 155.333 GXT_reference 'BOAT_7' value 241@ flag 2 // value 2.43
```

Первый опкод выводит 1 переменную на экран. Второй опкод выводит 2 переменных на экран. Третий опкод выводит дробное число на экран.

Здесь:\
320.0 155.333 - место расположения текста на экране\
'ALLRACE', 'TIME', 'BOAT\_7' - GXT-записи с текстом\
0@ - переменная, в ней должно быть целое число ( можно указать и число, не обязательно переменную )\
241@ - переменная, в ней должно быть дробное число\
2 - выводит количество символов после запятой в дробном числе× \*\*ОЧЕНЬ ВАЖНО:\*\* Что бы текст смог менять размеры и прочее, то манипуляции над ним должны быть перед тем, как выводить сам текст. И такие действия должны быть перед каждой записью с текстом.

Вот пример рисования:

```
:TEXT
thread 'TEXT'
wait 0
03F0: enable_text_draw 1

0226: $TEMP_HEALTH = actor $PLAYER_ACTOR health
0343: set_text_draw_linewidth 300.0
03E4: enable_text_draw_align_right 1
060D: draw_text_shadow 1 color_RGBA 0 0 0 255
0340: set_text_draw_RGBA 255 0 0 255
045A: draw_text_1number 30.0 10.0 GXT 'MAG_4OB' number $TEMP_HEALTH //~1~

04DD: $TEMP_ARMOUR = actor $PLAYER_ACTOR armour
0343: set_text_draw_linewidth 300.0
03E4: enable_text_draw_align_right 1
060D: draw_text_shadow 1 color_RGBA 0 0 0 255
0340: set_text_draw_RGBA 0 255 0 255
045A: draw_text_1number 60.0 10.10 GXT 'MAG_4OB' number $TEMP_ARMOUR //~1~

06AC: $TEMP_SPEED = actor $PLAYER_ACTOR movement_speed
0343: set_text_draw_linewidth 300.0
03E4: enable_text_draw_align_right 1
060D: draw_text_shadow 1 color_RGBA 0 0 0 255
0340: set_text_draw_RGBA 0 0 255 255
07FC: text_draw_1float_position_XY 90.0 10.0 GXT_reference 'MAG_4OB' value $TEMP_SPEED decimal_count 2
jump @TEXT
```

Как видите, всегда перед текстом пишутся параметры а потом рисуются. Если этого не сделать,то текст выведется по-умолчанию. Вот так выглядит рисованный нами текст:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/57811439.png)\
\
× \*\*ВАЖНО:\*\* Что бы текст или текстура отображались на экране всегда, то их необходимо рисовать в циклах!|3113|1|0|57811439\`png\`640\`400\`400\`250\`\`\\||risovanie\_na\_ehkrane\_chast\_1\_tekst|1498868750


# 00039. Рисование на экране (Часть 2 - Текстуры)

Рисование на экране (Часть 2 - Текстуры)|В этом уроке Вы узнаете как выводить текстуры на экран.|wmysterio|wmysterio||||Прежде всего нужно помнить, что загружать текстуры можно только те, что находятся в папке "Игра\MODELS\TXD\\". Поэтому кидайте свои текстуры в эту папку, а только потом загружайте их.

Итак, первый делом, нужно загрузить TXD-файл, в котором есть текстуры. Делается это опкодом:

```
0390: load_txd_dictionary 'LD_POKE'
```

Здесь:\
'LD\_POKE' — имя тестуры. Обратите внимание, что расширение указывать не нужно. Также нет необходимости проверять на её загруженность ( даже проверки такой нету )

Что бы выгрузить текстуры с памяти используйте опкод:

```
0391: release_txd_dictionary
```

Следует помнить, что выгружаются абсолютно все загруженные ранее текстуры! Что бы мы могли выводить нужные текстуры, нужно указать им номер:

```
038F: load_texture "cd10c" as 1
```

Здесь:\
"cd10c" - имя картинки ( см. Картинку ниже )\
1 - присваиваем ей номер![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/30804637.png)\
\
× \*\*Примечание:\*\* номера текстур должны быть больше 0!

Так же обратите внимание на размер картинки ( в нашем случаи: 128x128 ). Он нам ещё пригодится!

Есть два опкода для рисования текстур:

```
038D: draw_texture 1 position 200.0 150.0 size 128 128 RGBA 255 255 255 255
074B: draw_texture 1 position 200.0 150.0 scale 128 128 angle 0.0 color_RGBA 255 255 255 255
```

Здесь:\
1 - номер картинки\
200.0 150.0 - координаты экрана где должна размещаться картинка\
128 128 - размер картинки\
0.0 - угол поворота картинки\
255 255 255 255 здесь указываются цвета и прозрачность. Обычно так и оставляют, но если написать так: "0 255 255 255", то в картинке пропадёт весь красный цвет и вообще картинка поменяется ( это только в игре, с самой картинкой ничего не случаться )

Так же есть полезный опкод:

```
03E3: set_texture_to_be_drawn_antialiased 1
```

Он сглаживает картинку, то есть не видно жесткой пикселизации.

Как видите, опкодов для работы с текстурами немного, но их достаточно, что бы сделать отличную модификацию, например того же спидометра. Но спидометра мы делать пока не будем, а просто выведем текстуру на экран. Так же, как и текст, текстуры рисовать нужно в цикле и с использованием опкода 03F0.

Давайте напишем простой скрипт с использованием текстур. Немного усложним скрипт, сделаем что бы картинка появлялась, когда игрок нажмёт клавишу 1\`:

```
:TEXTURE
thread 'TEXTURE'
wait 0 
if
0AB0: key_pressed 49
jf @TEXTURE
0390: load_txd_dictionary 'LD_DUAL'
038F: load_texture "light" as 1
wait 250

:TEXTURE_1
wait 0
03f0: enable_text_draw 1
03E3: set_texture_to_be_drawn_antialiased 1 
038D: draw_texture 1 position 150.0 150.0 scale 25.0 25.0 RGBA 255 255 255 255 
if
0AB0: key_pressed 49
then
0391: release_txd_dictionary
wait 250
jump @TEXTURE
end 
jump @TEXTURE_1
```

Результат говорит сам за себя:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/08727525.png)|2054|1|0|08727525\`png\`895\`656\`400\`293\`\`\\|30804637\`png\`783\`482\`400\`246\`\`\\||risovanie\_na\_ehkrane\_chast\_2\_tekstury|1498916749


# Раздел 03. MAIN.SCM


# 0009. Редактирование main.scm. Потоки и опкоды (Часть 1)

Редактирование main.scm. Потоки и опкоды (Часть 1)|В этом уроке мы ознакомимся с базовыми понятиями скриптов: потоками, командами, метками, прыжками и задержкой. Будет введено понятие опкода.|wmysterio|wmysterio||||Для начала сделаем резервную копию игровых файлов. А именно **main.scm** и\*\* script.img\*\*. Найти их можно в папке с игрой: "Игра\data\script".

Теперь открываем Санни Билдер. И нажимаем "Файл->Открыть" и указываем "main.scm" ( не забывайте в скобках указать формат "SCM", иначе нужного файла не найти ). Открыли? Хорошо. Видите сколько строк? Дух захватывает правда? А представьте, что это всё напечатали вы! Если у Вас будет упорство и терпение, то всё вполне реально, хотя как правило обходится всё меньшим количеством кода. Но раз мы хотим что то сделать самим, то давайте выделим всё и нажмем кнопку DEL\`. Чистый лист! Какое облегчение! Теперь можно делать что то своё! Но для минимальной работы скрипта, нужно указать некоторую необходимую информацию. Скопируйте эти строки:

```

// This file was decompiled using sascm.ini published by Seemann (http://sannybuilder.com/files/SASCM.rar) on 13.10.2007
// WMYSTERIO, ru-script.3dn.ru
DEFINE OBJECTS 0 

DEFINE MISSIONS 0

DEFINE EXTERNAL_SCRIPTS 0

DEFINE UNKNOWN_EMPTY_SEGMENT 0

DEFINE UNKNOWN_THREADS_MEMORY 574

//-------------MAIN---------------

thread 'MAIN'
set_wb_check_to 0
set_weather 0
select_interior 0
fade 1 0
0180: set_on_mission_flag_to $ONMISSION
00C0: set_current_time_hours_to 8 minutes_to 0
04E4: unknown_refresh_game_renderer_at 2491.1572 -1670.3434
Camera.SetAtPos(2491.1572, -1670.3434, 12.3359)
$PLAYER_CHAR = Player.Create(#NULL, 2491.1572, -1670.3434, 12.3359)
$PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
Actor.Angle($PLAYER_ACTOR) = 66.3548
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
Camera.SetBehindPlayer
Player.Build($PLAYER_CHAR)
Player.CanMove($PLAYER_CHAR) = true
end_thread
```

Затем нажмите кнопку F7`. Запустите игру ( <kbd>F8` ), обязательно нажимаем "НОВАЯ ИГРА"! Посмотрите что изменилось. Думаю большинство заметило, что нету вступительного ролика и прочего. Такой мейн называется "Чистым".

× \*\*ВАЖНО:\*\* При редактировании потоков начинать новую игру обязательно.

Начнем с потоков думаю. Я не буду выражаться какими то сложными выражениями. Скажу только несколько слов о них. Я назову это отдельным блоком, в котором делаются некоторые действия. Каждый поток имеет свое имя, как и каждый человек. Нельзя создать два потоки с одинаковыми именами и длиной больше 15 символов. Рекомендую брать пример с оригинального "main.scm", где длина потока составляет не больше 7 символов. Лучше делать так, как это делали разработчики игры.

× \*\*Примечание:\*\* Названия потоков должно состоять только с латинких символов, чисел и символа \*\*\_\*\*

Как же создать поток? Для начала изучим правила написания потока. Каждый поток начинается командой:

```
thread 'POTOK' // POTOK - это имя нашего потока
```

и заканчивается командой ( команда завершения или деактивации ):

```
end_thread // команда завершения потока
```

Это очень легкие команды, думаю за небольшой промежуток времени вы запомните их.

Что такое метка? На этот вопрос я очень легко могу ответить, и этот ответ станет основой скриптинга, поэтому запоминайте.

1. \- Как узнать метку и её создать? Создание метки очень просто. Нужно написать сначала символ \*\*:\*\* а затем ввести имя метки. Вот пример:
2. ```
   :METKA
   ```
3. Узнать метку можно за правилами написания, о котором я написал выше. Принято писать метки с теми именами, что и поток, далее уже после имени потока добавляют несколько чисел или букв. С техничекой точки зрения метка - это смещение в файле "main.scm" и представляет собой обычное число. В прочем, для нас это не важно, так как Sanny Builder все эти смещения высчитывает самостоятельно, основываясь на наших метках.
4. *
5. Пример написания потока и и его меткок:
6. ```
   :POTOK
   thread 'POTOK'

   :POTOK_1

   :POTOK_2

   :POTOK_3

   end_thread
   ```
7. Весь скриптинг основан на построчном считывании информации. То есть одна команда - одна строка. В примере показано, что сначала будет выполняться команды от метки ":POTOK\_1", затем ":POTOK\_2" и вконце ":POTOK\_3". Естественно можно изменить порядок выполнения меток, не изменяя их положения. Для этого служит команда **jump**. Если перевести дословно, то это значит прыжок. Далее мы будем использовать именно это выражение. Что же, давайте напишем пример, где используются прыжки:
8. ```
   :POTOK
   thread 'POTOK' 
   jump @POTOK_4

   :POTOK_1
   jump @POTOK_3

   :POTOK_2
   jump @POTOK_5

   :POTOK_3
   jump @POTOK_2

   :POTOK_4
   jump @POTOK_1

   :POTOK_5
   end_thread
   ```
9. Сложновато, правда? Далее будет ещё сложнее. Особенно если вы решили увидеть чужой скрипт. :) Но не будем о грустном! Разобраться не так уже и сложно. Давайте представим маленький шарик. Представили? Назовём его "Указатель". Нет, пусть будет просто "Шарик" :) Этому шарику предстоит пройти определенный путь. Начинает путь наш шарик с имени потока, то есть с команды "thread", и начинает идти вниз. Используя прыжки ( jump ) можно нарисовать путь прохождения шарика. Я уже нарисовал путь. Вот по примеру должно примерно так получится:
10. ![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/06743791.png)
11. Итак, вы увидели шарика. Оранжевым указано куда именно я направлял шарика. Я специально загрузил этот рисунок, что бы вам легче было представить себе принцип работы скриптов. Если шарик достиг места финиша, то он автоматично отправляется на заслуженную пенсию и больше использоваться в потоке не будет, пока его не вызовут опять на службу. :)
12. Как запустить поток и что нужно для его правильной работы? Хороший вопрос. Особенно интересно слово "правильной"! Что же, думаю самое время познакомиться с опкодами! Это наши верные помощники! Так и будем называть их, потому что они помогают выполнить кое-какие действия. Для правильной работы нам нужно запомнить помощника по имени **0001:**, то есть опкод:
13. ```
    0001: wait 0 ms // 0 - это задержка
    ```
14. Он обычно стоит после названия метки. Они там должны находится не всегда, а только в в случаи необходиомости, например в циклах ( будет рассматриваться в следующих уроках ). Но в целях обучения мы будем располагать опкод после каждой метки.
15. С новой версией СБ и Клео, в целях удобства, ему присвоили статус команды ( так званный кейворд ), и мы можем писать просто
16. ```
    wait 0 // 0 - это задержка
    ```
17. Технически разницы между опкодами и командами нету - команда имеет упрощённый синтаксис, но в процессе преобразования заменяется на опкод. **Опкод** - это операционная код ( команда ).
18. Что бы запустить наш поток, то есть призвать нашего шарика на старт, используется такая команда:
19. ```
    create_thread @POTOK // POTOK - имя потока, который нужно запустить
    ```
20. Она, собственно, делает поток активным. Таким образом, пишем правильный запуск потока:
21. ```
    // This file was decompiled using sascm.ini published by Seemann (http://sannybuilder.com/files/SASCM.rar) on 13.10.2007
    // WMYSTERIO, ru-script.3dn.ru
    DEFINE OBJECTS 1
    DEFINE OBJECT SANNY BUILDER 3.04 

    DEFINE MISSIONS 0

    DEFINE EXTERNAL_SCRIPTS 0

    DEFINE UNKNOWN_EMPTY_SEGMENT 0

    DEFINE UNKNOWN_THREADS_MEMORY 574

    //-------------MAIN---------------
    thread 'MAIN'
    set_wb_check_to 0
    set_weather 0
    select_interior 0
    fade 1 0
    0180: set_on_mission_flag_to $ONMISSION
    00C0: set_current_time_hours_to 8 minutes_to 0
    04E4: unknown_refresh_game_renderer_at 2491.1572 -1670.3434
    Camera.SetAtPos(2491.1572, -1670.3434, 12.3359)
    $PLAYER_CHAR = Player.Create(#NULL, 2491.1572, -1670.3434, 12.3359)
    $PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
    Actor.Angle($PLAYER_ACTOR) = 66.3548
    07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
    Camera.SetBehindPlayer
    Player.Build($PLAYER_CHAR)
    Player.CanMove($PLAYER_CHAR) = True
    create_thread @POTOK
    end_thread 

    :POTOK
    thread 'POTOK'
    wait 0 
    jump @POTOK_4

    :POTOK_1
    wait 0
    jump @POTOK_3

    :POTOK_2
    wait 0
    jump @POTOK_5

    :POTOK_3
    wait 0
    jump @POTOK_2

    :POTOK_4
    wait 0
    jump @POTOK_1

    :POTOK_5
    wait 0
    end_thread
    ```
22. Конечно, толку от нашего примера никакого, но, думаю, вы приобрели необходимый опыт в написании потоков.
23. × \*\*ВАЖНО:\*\* Команду запуска потока нужно давать в \*\*активном потоке\*\*, иначе поток не запустится!
24. В нашем случае, поток вызывается с активного потока ( "MAIN" ), а когда поток запущен командой "thread", то вызванный поток сам стает активным, так сказать вызывается тогда, когда шарик при деле :) Первый поток называется ГЛАВНЫМ, или MAIN.
25. × \*\*Примечание:\*\* пустые строки игнорируется Sanny Builder и носит только косметический характер.|4763|1|0|06743791\`png\`480\`510\`400\`425\`\`\\||redaktirovanie\_main\_scm\_potoki\_i\_opkody\_chast\_1|1498200845


# 00014. Редактирование main.scm. Потоки и опкоды (Часть 2)

Редактирование main.scm. Потоки и опкоды (Часть 2)|В этом уроке мы продолжим изучать потоки. Урок посвящен запуску нескольких потоков и описаны правила переходов между ними.|wmysterio|wmysterio||||Итак запускать поток мы научились. Давайте научимся запускать несколько потоков одновременно! В CLEO такой возможности нет ( есть аналоги, но сейчас не о этом ), поэтому я вас учу сначала редактировать именно "main.scm". Но ближе к делу. Все потоки запускаются, как уже было сказано с помощью команды **create\_thread**. Теперь в работающем потоке пишем несколько таких команд:

```
// ...
create_thread @POTOK
create_thread @POTOK_1
create_thread @POTOK_2
end_thread 

:POTOK
thread 'POTOK'
wait 0 
jump @POTOK_5

:POTOK_5
wait 0
end_thread

:POTOK_1
thread 'POTOK_1'
wait 0 
jump @POTOK_1_4

:POTOK_1_4
wait 0
end_thread

:POTOK_2
thread 'POTOK_2'
wait 0 
jump @POTOK_2_3

:POTOK_2_3
wait 0
end_thread 
```

Вот мы выполнили нашу задачу - запустили подряд три потока. Они будут выполнятся одновременно! Смысл в том, что мы "нанимаем" три наших знакомых шарика и они вкалывают на нас. Графически это можно описать так:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/74148405.png)

С рисунка видно, что работают 3 шарика. При этом потоки могут быть в разных местах, то есть если в начале мы напишем так:

```
create_thread @POTOK
create_thread @POTOK_3
create_thread @POTOK_2
```

то, работать они будут так же. Разницы нету.

× \*\*ВАЖНО:\*\* Все прыжки должны выполятся только в области своего потока! Это значит нельзя делать прыжки на метки, находящаяся в другом потоке.

Вот вам картинка:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/50899820.png)

Так что запомним: Шарик знает только себя, выполняет только свою работу. Остальные шарики ему по барабану, как и на их работу. Я бы сказал, что он имеет свою сферу влияния, которая действует только на том потоке, на котором его вызвали. Технически этот шарик к другим потокам обращаться не должен.

Но есть одна особенность в этом случае: если метка для прыжка находится в другом потоке, но от неё идёт комманда прыжка обратно в первый, то ошибки не будет! Вот картинка, что бы вы поняли о чём я:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/97405113.png)

Дело в том, что Sanny Builder автоматичеки распределяет сферы влияния, а в месте с ними и метки, которые ей принадлежат. Таким образом, метка "POTOK\_1\_4" автоматически отнесётся к потоку "POTOK", даже, если она находится в середине потока "POTOK\_1".

× \*\*ВАЖНО:\*\* Вызывать одного и того же шарика можно много раз, но никак не одновременно. То есть, пока работает поток, вызывать его ещё раз нельзя!

Вот скрин:

![](https://github.com/wmysterio/scm-scripting-lessons/blob/main/_pu/0/90162325.png)

Хоть и шарики могут вызываться подряд, но между вызовами есть крохотная задержка. А это значит, что если мы поменяем вызовы местами, то выйдет следующее:

![](https://github.com/wmysterio/scm-scripting-lessons/blob/main/_pu/0/59927369.png)

Так что нужно быть внимательным при запуске потоков.

Думаю, Вы заметили, что в последних картинках, в потоке "POTOK\_1" в место "end\_thread" стоит "jump @POTOK\_1". Это значит, что данный поток будет повторяться. Причём бесконечно! Но о бесконечности мы поговорим в следующих уроках.

В общем, если запускать потоки, которые будут работать одновременно, советую не делать "create\_thread" с разных потоков, что бы избежать все возможных ошибок и глюков.|1467|1|0|74148405`png`1117`552`400`197``\|50899820`png`934`496`400`212``\|97405113`png`406`516`393`500``|90162325`png`379\`457

```
`\|59927369`png`318`468
```

\`||redaktirovanie\_main\_scm\_potoki\_i\_opkody\_chast\_2|1498204687


# 00013. Редактирование main.scm. Потоки и опкоды (Часть 3)

Редактирование main.scm. Потоки и опкоды (Часть 3)|В этом уроке мы продолжим изучать потоки. На этот раз мы познакомимся с командами gosub и return|wmysterio|wmysterio||||Если вы владеете какими то языками программирования, то для Вас это может показаться знакомой вешью. Итак, ознакомимся с тем, как пишется команда **gosub**:

```
gosub @POTOK_1
```

Эта команда переходит на метку "POTOK\_1" так же само, как и "jump", только разница том, что шарик будет возвращаться к месту, где этот переход состоялся. Возвращаться он будет когда встретит ближайший **return**. Следовательно **return** - команда возврата. Давайте напишем небольшой скрипт, что бы вы поняли как он работает:

```
:POTOK
thread 'POTOK'
wait 0
gosub @POTOK_1
end_thread

:POTOK_1
wait 0
return
```

Графически можно представить так:

![](https://github.com/wmysterio/scm-scripting-lessons/blob/main/_pu/0/84529523.png)

Давайте проследим за тем, так будет двигаться шарик. Сначала он пройдёт 3 строчки. На 4-й он встретит "gosub", дальше идёт прыжок на 7 строку, так как именно там находится метка "@POTOK\_1". Проходит дальше 2 строки и встречает "return". Дальше шарик прыгает обратно на строку, где был "gosub" и продолжает путь, то есть переходит на 5 строку и "уходит на пенсию" =)

Напишем более сложный скрипт, где есть несколько "gosub", и посмотрим на движение шарика:

![](https://github.com/wmysterio/scm-scripting-lessons/blob/main/_pu/0/52091111.png)

Что бы вам было легче представить как работают эти 2 опкода, я наведу пример в реальной жизни:

Папа Васе:\
\- Сын, пойди в магазин.\
Вася идёт.\
По дороге ему девочка Рита:\
\- Вася, сорви для меня цветок.\
Вася идёт рвать цветы. Возвращается. Девочка благодарит. Вася идёт в магазин, покупает там, и приходит домой. Папа даёт Васе 5 рублей.

Теперь давайте рассмотрим картинку, которая "транслирует" эту историю в Sanny Builder:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/80340610.png)

Таким образом можно сказать, что поток существует, что бы выполнять одну конкретную задачу, а "gosub" - что бы выполнять вторичные. В нашем примере главная цель - заработать 5 рублей, вторичные цели - купить товар, сорвать цветок. Две вторичные задачи - два "gosub".

И, конечно, не забываем о правилах переходов, которые я написал в предыдущем уроке. Думаю основы работы с потоками и метками вы научились. Пора переходить к новому материалу. Если у вас возникли вопросы, задайте их на форуме.

× \*\*ВАЖНО:\*\* Любой "gosub" требует обязательного возврата командой "ruturn".× \*\*Примечание:\*\* В SCM скриптинге есть лимит на количество вложенных "gosub" - 8 штук. Под "вложенными" имеется ввиду те "gosub", которые вызываются внутри существующего "gosub". В последнем примере таких вложенных "gosub" было 2 ( "@POTOK\_1" и "@POTOK\_2" ). Остальные находились на одном уровне вложенности.|1360|1|0|84529523\`png\`285\`183 \`\`\`

`\|52091111`png`290`343

```
`\|80340610`png`574`379`400`264``\||redaktirovanie_main_scm_potoki_i_opkody_chast_3|1498207216
```


# 00062. Работа со стартерами ( MAIN.SCM - Часть 1 )

Работа со стартерами ( MAIN.SCM - Часть 1 )|В этом мы рассмотрим примеры запуска нескольких миссий.|wmysterio|wmysterio||||Доброго времени суток, дорогие друзья! Как Вы уже догадались, речь пойдет о стартерах. Когда я был новичком, мне никак не удавалось запускать миссии в нужном порядке. Стартер, что был в учебнике, был для меня плохим примером, так как он был в скомпилированном виде, и с помощью него я смог запустить максимум 3 миссии.

Как я решил данную проблему? Ответ оказался очень простым! Дело было в глобальных переменных, которые были в качестве счетчика, то есть за каждую выполненную миссию мы увеличиваем счетчик на 1. Вот несколько миссий в качестве примера ( Счетчиком будет переменная "$TOTAL\_MISSION" ):

```
//------------- GUN (mission 1) ---------------
:GUN
thread 'GUN'
gosub @GUN_29_57
if
wasted_or_busted
jf @GUN_29_46
gosub @GUN_29_144

:GUN_29_46
$ONMISSION = 0
mission_cleanup
end_thread

:GUN_29_57
increment_mission_attempts
$ONMISSION = 1
fade 1 1000
wait 1000
gosub @GUN_END
00BA: show_text_styled GXT 'M_PASS' time 5000 style 1 // GUN PASSED
0318: set_latest_mission_passed 'MISS_00' // GXT GUN name
$TOTAL_MISSION += 1
create_thread @STARTER
return

:GUN_29_144
wait 0
gosub @GUN_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 // GUN FAILED
create_thread @STARTER
return

:GUN_END
wait 0
return


//------------- MYS (mission 1) ---------------
:MYS
thread 'MYS'
gosub @MYS_29_57
if
wasted_or_busted
jf @MYS_29_46
gosub @MYS_29_144

:MYS_29_46
$ONMISSION = 0
mission_cleanup
end_thread

:MYS_29_57
increment_mission_attempts
$ONMISSION = 1
fade 1 1000
wait 1000
gosub @MYS_END
00BA: show_text_styled GXT 'M_PASS' time 5000 style 1 // GUN PASSED
0318: set_latest_mission_passed 'MISS_01' // GXT GUN name
$TOTAL_MISSION += 1
create_thread @STARTER
return

:MYS_29_144
wait 0
gosub @MYS_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 // GUN FAILED
create_thread @STARTER
return

:MYS_END
wait 0
return


//------------- TES (mission 2) ---------------
:TES
thread 'TES'
gosub @TES_29_57
if
wasted_or_busted
jf @TES_29_46
gosub @TES_29_144

:TES_29_46
$ONMISSION = 0
mission_cleanup
end_thread

:TES_29_57
increment_mission_attempts
$ONMISSION = 1
fade 1 1000
wait 1000
gosub @TES_END
00BA: show_text_styled GXT 'M_PASS' time 5000 style 1 // GUN PASSED
0318: set_latest_mission_passed 'MISS_02' // GXT GUN name
$TOTAL_MISSION += 1
create_thread @STARTER
return

:TES_29_144
wait 0
gosub @TES_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 // GUN FAILED
create_thread @STARTER
return

:TES_END
wait 0
return
```

В нашем арсенале есть три миссии. Как видите во всех присутствует команда "create\_thread @STARTER". Значит их запускает поток с именем ":STARTER". Давайте напишем условия перехода:

```
:STARTER
thread 'STARTER'
wait 0
$MARKER_INDEX_T = marker.CreateIconAndSphere(15, $MISSION_T_COORD_X, $MISSION_T_COORD_Y, $MISSION_T_COORD_Z)
 
:STARTER_1
wait 0
if AND
not actor.Dead($PLAYER_ACTOR)
not actor.Driving($PLAYER_ACTOR)
8A0C: not player $PLAYER_CHAR on_jetpack
8741: not actor $PLAYER_ACTOR busted
then
 if
 $ONMISSION == 0
 then
 if AND
 $TOTAL_MISSION == 0
 0102: actor $PLAYER_ACTOR in_sphere $MISSION_T_COORD_X $MISSION_T_COORD_Y $MISSION_T_COORD_Z radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 jump @STARTER_2 
 end
 if AND
 $TOTAL_MISSION == 1
 0102: actor $PLAYER_ACTOR in_sphere $MISSION_T_COORD_X $MISSION_T_COORD_Y $MISSION_T_COORD_Z radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 jump @STARTER_3 
 end 
 if AND
 $TOTAL_MISSION == 2
 0102: actor $PLAYER_ACTOR in_sphere $MISSION_T_COORD_X $MISSION_T_COORD_Y $MISSION_T_COORD_Z radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 jump @STARTER_4 
 end 
 end
end
jump @STARTER_1

:STARTER_2
wait 0
Marker.Disable($MARKER_INDEX_T)
00BE: text_clear_all
03E6: remove_text_box
00BA: show_text_styled GXT 'MISS_01' time 1000 style 2
fade 0 1000
wait 2000
start_mission 0
end_thread

:STARTER_3
wait 0
Marker.Disable($MARKER_INDEX_T)
00BE: text_clear_all
03E6: remove_text_box
00BA: show_text_styled GXT 'MISS_02' time 1000 style 2
fade 0 1000
wait 2000
start_mission 1 
end_thread

:STARTER_4
wait 0
Marker.Disable($MARKER_INDEX_T)
00BE: text_clear_all
03E6: remove_text_box
00BA: show_text_styled GXT 'MISS_03' time 1000 style 2
fade 0 1000
wait 2000
start_mission 2 
end_thread
```

Как видите, мы создаём сферу и маркер, координаты которой "$MISSION\_T\_COORD\_X", "$MISSION\_T\_COORD\_Y", "$MISSION\_T\_COORD\_Z". Значит нам нужно написать их ещё перед запуском стартера. Обычно скриптеры пишут их в первом потоке, то есть в потоке "MAIN" и тамже задают начальное значение "$TOTAL\_MISSION". Сделаем это тоже:

```
//...
fade 1 0
$TOTAL_MISSION = 0
$MISSION_T_COORD_X = 2535.1055
$MISSION_T_COORD_Y = 2148.1006
$MISSION_T_COORD_Z = 10.8203
create_thread @STARTER
end_thread
```

Теперь сфера будет появляться в этих координатах. Но очень часто нужно сделать, что бы сфера после прохождения миссии появлялась в другой точке. Не проблема! Мы пишем переменные маркера в самой миссии ( до или после $TOTAL\_MISSION += 1 ):

```
//...
$ONMISSION = 1
fade 1 1000
wait 1000
gosub @GUN_END
00BA: show_text_styled GXT 'M_PASS' time 5000 style 1 // GUN PASSED
0318: set_latest_mission_passed 'MISS_00' // GXT GUN name
$MISSION_T_COORD_X = -1446.6484
$MISSION_T_COORD_Y = 1502.4534
$MISSION_T_COORD_Z = 1.7366
$TOTAL_MISSION += 1
create_thread @STARTER
return
//...
```

Таким образом, после прохождения миссии "GUN" позиция маркера изменится.

Что делать, если нужно запустить первую миссию в начале игры? То есть нажимаем "Новая игра" и сразу показывается какой то ролик из миссии или сразу идёт миссия. Например, у миссии 0 есть ролик ( просто представим, так как я кинул код без ролика ). Ответ очень прост! Вместо "create\_thread @STARTER" в потоке "MAIN" пишем "start\_mission 0":

```
// fade 1 0 меняем
fade 0 0 // на это, что бы игра моментально затемнилась, так как в миссии идёт осветление
$TOTAL_MISSION = 0
$MISSION_T_COORD_X = 2535.1055
$MISSION_T_COORD_Y = 2148.1006
$MISSION_T_COORD_Z = 10.8203
// create_thread @STARTER в место этого
start_mission 0 // запускаем миссию
end_thread
//...
```

Даже если миссия будет провалена мы всё равно увидим маркер, так как мы указали необходимые данные в коде провала миссии. Поэтому я закомментировал строчку "// create\_thread @STARTER в место этого". Если этого не сделать, то после прохождении миссии 0 поток ":STARTER" запустится дважды, а это приведёт к нежелательным последствиям.

Я привел пример только для 3-х миссий. Что Вам нужно сделать, чтоб было больше:

* Скопируйте код одной из миссий и в ставьте её в конец скрипта. Переименуйте метки и название потока. Это займет максимум 30 секунд;
* Добавьте в стартер код запуска:<br>

```
:STARTER_n // приставку n вы поменяйте на число
wait 0
Marker.Disable($MARKER_INDEX_T)
00BE: text_clear_all
03E6: remove_text_box
00BA: show_text_styled GXT 'MISS_04' time 1000 style 2 // указывайте название новой миссии
fade 0 1000
wait 2000
start_mission n // n - номер новой миссии
end_thread
```

* Добавьте условие перехода на метку запуска:<br>

```
if AND
$TOTAL_MISSION == n // n - увеличивайте число на 1 с каждой новой миссией
0102: actor $PLAYER_ACTOR in_sphere $MISSION_T_COORD_X $MISSION_T_COORD_Y $MISSION_T_COORD_Z radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
then
jump @STARTER_n // делаем переход на метку запуска
end
```

Вставляйте этот код в условие:

```
if
$ONMISSION == 0
then
// ваш код
end
```

Так же не забывайте внести их в список миссий ( DEFINE MISSIONS ).

В следующем уроке мы рассмотрим возможность выбора миссий, то есть будет несколько маркеров и в зависимости от того, куда станет игрок запустится та или иная миссия.|853|1|0||rabota\_so\_starterami\_main\_scm\_chast\_1|1499618018


# 00063. Работа со стартерами ( MAIN.SCM - Часть 2 )

Работа со стартерами ( MAIN.SCM - Часть 2 )|В предыдущем уроке мы рассмотрели запуск миссий по очереди. Сегодня мы попытаемся сделать возможность выбора миссий. То есть нам будет предоставлено два маркера и зависимости от выбранного маркера будет запускается та или иная миссия.|wmysterio|wmysterio||||Что бы это сделать нам необходимо создать несколько стартеров. Обычно миссии делят на части: миссии Свита, миссии СЖ, миссии ОG и т.п. Мы поступим также.

Давайте у нас будут миссии СЖ и Свита. Как и в предыдущем уроке, нам понадобятся глобальные переменные для каждого стартера. Допустим это будут "$MISSION\_CJ\_TOTAL" и "$MISSION\_SWIT\_TOTAL". Они будут равны нулю в начале игры. Так же мы должны завести переменные для координат маркера. Создадим такое в потоке "MAIN":

```
//...
$MISSION_CJ_TOTAL = 0
$MARKER_X_CJ = 2498.2966
$MARKER_Y_CJ = -1684.5094
$MARKER_Z_CJ = 12.41

$MISSION_SWIT_TOTAL = 0
$MARKER_X_SWEET = 2516.5918
$MARKER_Y_SWEET = -1674.5015
$MARKER_Z_SWEET = 12.973
//...
```

Теперь нам необходимо создать стартера для каждой части. Первый поток будет стартером для миссий CJ. Допустим там будет 5 миссий ( номера 0, 1, 2, 3, 4 ):

```
:STARTER_CJ
thread 'STARTER_CJ'
wait 0
$MARKER_CJ = marker.CreateIconAndSphere(15, $MARKER_X_CJ, $MARKER_Y_CJ, $MARKER_Z_CJ)
 
:STARTER_CJ_1
wait 0
if AND
not actor.Dead($PLAYER_ACTOR)
not actor.Driving($PLAYER_ACTOR)
8A0C: not player $PLAYER_CHAR on_jetpack
8741: not actor $PLAYER_ACTOR busted
then
 if
 $ONMISSION == 0
 then
 if AND
 $MISSION_CJ_TOTAL == 0
 0102: actor $PLAYER_ACTOR in_sphere $MARKER_X_CJ $MARKER_Y_CJ $MARKER_Z_CJ radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 jump @STARTER_CJ_2 
 end
 if AND
 $MISSION_CJ_TOTAL == 1
 0102: actor $PLAYER_ACTOR in_sphere $MARKER_X_CJ $MARKER_Y_CJ $MARKER_Z_CJ radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 jump @STARTER_CJ_3 
 end 
 if AND
 $MISSION_CJ_TOTAL == 2
 0102: actor $PLAYER_ACTOR in_sphere $MARKER_X_CJ $MARKER_Y_CJ $MARKER_Z_CJ radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 jump @STARTER_CJ_4 
 end 
 if AND
 $MISSION_CJ_TOTAL == 3 
 0102: actor $PLAYER_ACTOR in_sphere $MARKER_X_CJ $MARKER_Y_CJ $MARKER_Z_CJ radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 jump @STARTER_CJ_5 
 end
 if AND
 $MISSION_CJ_TOTAL == 4
 0102: actor $PLAYER_ACTOR in_sphere $MARKER_X_CJ $MARKER_Y_CJ $MARKER_Z_CJ radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 jump @STARTER_CJ_6 
 end
 end
end
jump @STARTER_CJ_1

:STARTER_CJ_2
wait 0
Marker.Disable($MARKER_CJ)
00BE: text_clear_all
03E6: remove_text_box
00BA: show_text_styled GXT 'MISS_01' time 1000 style 2
fade 0 1000
wait 2000
start_mission 0
end_thread

:STARTER_CJ_3
wait 0
Marker.Disable($MARKER_CJ)
00BE: text_clear_all
03E6: remove_text_box
00BA: show_text_styled GXT 'MISS_02' time 1000 style 2
fade 0 1000
wait 2000
start_mission 1 
end_thread

:STARTER_CJ_4
wait 0
Marker.Disable($MARKER_CJ)
00BE: text_clear_all
03E6: remove_text_box
00BA: show_text_styled GXT 'MISS_03' time 1000 style 2
fade 0 1000
wait 2000
start_mission 2 
end_thread

:STARTER_CJ_5
wait 0
Marker.Disable($MARKER_CJ)
00BE: text_clear_all
03E6: remove_text_box
00BA: show_text_styled GXT 'MISS_04' time 1000 style 2
fade 0 1000
wait 2000
start_mission 3 
end_thread

:STARTER_CJ_6
wait 0
Marker.Disable($MARKER_CJ)
00BE: text_clear_all
03E6: remove_text_box
00BA: show_text_styled GXT 'MISS_05' time 1000 style 2
fade 0 1000
wait 2000
start_mission 4 
end_thread
```

Аналогично создаём поток для миссий Свита:

```
:STARTER_SWIT
thread 'STARTER_SWIT'
wait 0
$MARKER_SWIT = marker.CreateIconAndSphere(38, $MARKER_X_SWEET, $MARKER_Y_SWEET, $MARKER_Z_SWEET)
 
:STARTER_SWIT_1
wait 0
if AND
not actor.Dead($PLAYER_ACTOR)
not actor.Driving($PLAYER_ACTOR)
8A0C: not player $PLAYER_CHAR on_jetpack
8741: not actor $PLAYER_ACTOR busted
then
 if
 $ONMISSION == 0
 then
 if AND
 $MISSION_SWIT_TOTAL == 0
 0102: actor $PLAYER_ACTOR in_sphere $MARKER_X_SWIT $MARKER_Y_SWIT $MARKER_Z_SWIT radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 jump @STARTER_SWIT_2
 end
 if AND
 $MISSION_SWIT_TOTAL == 1
 0102: actor $PLAYER_ACTOR in_sphere $MARKER_X_SWIT $MARKER_Y_SWIT $MARKER_Z_SWIT radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 jump @STARTER_SWIT_3 
 end 
 if AND
 $MISSION_SWIT_TOTAL == 2
 0102: actor $PLAYER_ACTOR in_sphere $MARKER_X_SWIT $MARKER_Y_SWIT $MARKER_Z_SWIT radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 jump @STARTER_SWIT_4 
 end 
 if AND
 $MISSION_SWIT_TOTAL == 3
 0102: actor $PLAYER_ACTOR in_sphere $MARKER_X_SWIT $MARKER_Y_SWIT $MARKER_Z_SWIT radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 jump @STARTER_SWIT_5 
 end
 if AND
 $MISSION_SWIT_TOTAL == 4
 0102: actor $PLAYER_ACTOR in_sphere $MARKER_X_SWIT $MARKER_Y_SWIT $MARKER_Z_SWIT radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 jump @STARTER_SWIT_6 
 end
 end
end
jump @STARTER_SWIT_1

:STARTER_SWIT_2
wait 0
Marker.Disable($MARKER_SWIT)
00BE: text_clear_all
03E6: remove_text_box
00BA: show_text_styled GXT 'MISS_06' time 1000 style 2
fade 0 1000
wait 2000
start_mission 5
end_thread

:STARTER_SWIT_3
wait 0
Marker.Disable($MARKER_SWIT)
00BE: text_clear_all
03E6: remove_text_box
00BA: show_text_styled GXT 'MISS_07' time 1000 style 2
fade 0 1000
wait 2000
start_mission 6
end_thread

:STARTER_SWIT_4
wait 0
Marker.Disable($MARKER_SWIT)
00BE: text_clear_all
03E6: remove_text_box
00BA: show_text_styled GXT 'MISS_08' time 1000 style 2
fade 0 1000
wait 2000
start_mission 7
end_thread

:STARTER_SWIT_5
wait 0
Marker.Disable($MARKER_SWIT)
00BE: text_clear_all
03E6: remove_text_box
00BA: show_text_styled GXT 'MISS_09' time 1000 style 2
fade 0 1000
wait 2000
start_mission 8
end_thread

:STARTER_SWIT_6
wait 0
Marker.Disable($MARKER_SWIT)
00BE: text_clear_all
03E6: remove_text_box
00BA: show_text_styled GXT 'MISS_010' time 1000 style 2
fade 0 1000
wait 2000
start_mission 9
end_thread
```

Номера миссий для Свита будут 5, 6, 7, 8, 9. Следовательно в списке "DEFINE MISSIONS" будут номера и метки миссий. Для примера пусть будет такой список:

```
//...
DEFINE MISSIONS 10
DEFINE MISSION 0 AT @MISSION_CJ_1
DEFINE MISSION 1 AT @MISSION_CJ_2
DEFINE MISSION 2 AT @MISSION_CJ_3
DEFINE MISSION 3 AT @MISSION_CJ_4
DEFINE MISSION 4 AT @MISSION_CJ_5
DEFINE MISSION 5 AT @MISSION_SWIT_1
DEFINE MISSION 6 AT @MISSION_SWIT_2
DEFINE MISSION 7 AT @MISSION_SWIT_3
DEFINE MISSION 8 AT @MISSION_SWIT_4
DEFINE MISSION 9 AT @MISSION_SWIT_5
//...
```

Дальше нам уже нужно написать блок миссий. Они должны идти в том порядке, в котором написано в "DEFINE MISSIONS". Используя шаблон в предыдущем уроке напишем миссии для СJ и SWIT. Код блока я сохранин в текстовом файде, который можно скачать [здесь](https://github.com/wmysterio/scm-scripting-lessons/blob/main/data_base/sa/MISSION_BLOCK.txt).

И, что бы метки появлялись в начале игры, активируем метки в потоке "MAIN":

```
//...
$MISSION_CJ_TOTAL = 0
$MARKER_X_CJ = 2498.2966
$MARKER_Y_CJ = -1684.5094
$MARKER_Z_CJ = 12.41

$MISSION_SWIT_TOTAL = 0
$MARKER_X_SWEET = 2516.5918
$MARKER_Y_SWEET = -1674.5015
$MARKER_Z_SWEET = 12.973

create_thread @STARTER_CJ
create_thread @STARTER_SWIT
end_thread
//...
```

Теперь при начале новой игры появляться 2 маркера с иконкой "CJ" и "S". Если стать на одну из них, то будут запускаться миссии в зависимости от того на какую метку стал игрок.

Таким образом мы предоставили игроку выбор. Это очень важно, так как если игрок никак не может выполнить миссию, то он может свободно двигаться дальше, пройдя другие миссии а затем вернутся и завершить миссию, на которой он застрял ранее.

Как сделать, что бы при прохождении 2-х миссий CJ, открывались миссии SWIT? Это очень просто сделать. В потоке "MAIN" удаляем или закомментируем строку "create\_thread @STARTER\_SWIT":

```
//...
$MISSION_CJ_TOTAL = 0
$MISSION_SWIT_TOTAL = 0
$MARKER_X_CJ = 2498.2966
$MARKER_Y_CJ = -1684.5094
$MARKER_Z_CJ = 12.41
$MARKER_X_SWEET = 2516.5918
$MARKER_Y_SWEET = -1674.5015
$MARKER_Z_SWEET = 12.973
create_thread @STARTER_CJ
//create_thread @STARTER_SWIT удаляем эту строчку и не позволяем запустится стартеру сначала игры
end_thread
//...
```

Дальше находим в блоке миссий "MISSION\_CJ\_2" и запускаем стартер для миссий Свита в месте, где миссия CJ считается пройденной. Вот код:

```
//...
:MISSION_CJ_2_29_57
increment_mission_attempts
$ONMISSION = 1
fade 1 1000
wait 1000

//
{ mission block }
//

gosub @MISSION_CJ_2_END
030C: progress_made += 1
00BA: show_text_styled GXT 'M_PASS' time 5000 style 1 // MISSION PASSED
$MISSION_CJ_TOTAL += 1
0318: set_latest_mission_passed 'MISS_02' // GXT mission name
create_thread @STARTER_SWIT // Вставляем запуск сюда
create_thread @STARTER_CJ
return

:MISSION_CJ_2_29_144
wait 0
gosub @MISSION_CJ_2_END
//...
```

Перерь в начале игры будет только миссии CJ. После прохождения 2-й миссии CJ появится маркер Свита и можно уже выполнять миссии Свита. По аналогии вы можете создать свои стартеры и миссии, но сначала продумайте ход событий :) В следующем уроке мы погорим о стартерах в Cleo. С вами был wmysterio, спасибо за внимание!|717|1|0||rabota\_so\_starterami\_main\_scm\_chast\_2|1499618913


# 00054. Внешние скрипты в main.scm

Внешние скрипты в main.scm|Начинаем новый урок по Sanny Builder. И на этот раз мы рассмотрим внешние скрипты.|wmysterio|wmysterio||||Всем привет! Что значит"внешние"? Это те скрипты, которые загружаются из файлы "script.img". Например: скрипт авто-тюнинга, парашюта или казино. Сегодня мы создадим один такой скрипт и рассмотрим основные опкоды для загрузки таких скриптов.

Прежде всего нужно написать сам скрипт ( пишутся как и обычные потоки в мейне ). Для примера у меня будет внешний скрипт, суть которого заключается в том, что когда машина игрока перевернута, то при нажатии кнопки CTRL\` машина будет перекидываться обратно на колёса.

Прежде всего напишем поток ":NOFLIP". И переместим его в самый конец мейна ( все внешние скрипты пишутся после блока с миссиями ). Вот сам код:

```
:NOFLIP
thread 'NOFLIP'
wait 0

while actor.Driving($PLAYER_ACTOR)
wait 0
 03C0: 0@ = actor $PLAYER_ACTOR car
 if
 01F4: car 0@ flipped
 then
 if
 0AB0: key_pressed 17 // CTRL
 then
 00A0: store_actor $PLAYER_ACTOR position_to 1@ 2@ 3@
 4@ = car.Angle(0@)
 car.PutAt(0@, 1@, 2@, 3@)
 car.Angle(0@) = 4@
 end
 end
end

end_thread
```

Можно было и запустить этот поток командой "create\_thread", но раз мы учимся создавать внешние скрипты, то мы запускать его мы будем иным образом. Прежде всего нужно объявить этот поток как внешний. Находим стоку вначале мейна:

```
DEFINE EXTERNAL_SCRIPTS 0
```

Меняем значение 0 на 1, это указывается общее количество внешних скриптов. Так, как мы планируем создать новый внешний скрипт, то значение нужно прибавить. Далее нужно написать сам потом и дать имя нашему внешнему скрипту. Сразу после этого допишем строку:

```
DEFINE SCRIPT NO_FLIPPED AT @NOFLIP // 0
```

Здесь:\
NO\_FLIPPED - имя нашего внешнего скрипта\
@NOFLIP - указываем метку с которой будет начинаться сам скрипт\
// 0 - это обычный комментарий, но я специально его написал, так как каждый скрипт имеет свой номер, счёт которых начинается с нуля. Дальше вы увидите зачем я это сделал.

Таким образом мы получим:

```
DEFINE EXTERNAL_SCRIPTS 1
DEFINE SCRIPT NO_FLIPPED AT @NOFLIP // 0
```

Теперь рассмотрим основные опкоды для работы внешних скриптов. Опкод записует в переменную текущий статус внешнего скрипта:

```
0926: $SCRIPT_STATUS = external_script_status 0 (NO_FLIPPED) // return 0 if not active
```

Далее:

```
08A9: load_external_script 0 (NO_FLIPPED)
```

Опкод загружает внешний скрипт.

```
08AB: external_script 0 (NO_FLIPPED) loaded
```

Проверка: "Внешний скрипт загружен?"

```
0913: run_external_script 0 (NO_FLIPPED)
```

Опкод запускает внешний скрипт.

```
090F: end_external_script 0 (NO_FLIPPED)
```

Опкод выгружает с памяти внешний скрипт ( завершает его ).

Здесь:\
0 - номер внешнего скрипта\
NO\_FLIPPED - указываем имя нашего внешнего скрипта<br>

Это основные команды. Давайте теперь напишем поток, который будет запускать, написанный нами, внешний скрипт. Создадим поток с именем ":TRIGGER" и напишем необходимые условия:

```
:TRIGGER
thread 'TRIGGER'
wait 0
0926: $SCRIPT_STATUS = external_script_status 0 (NO_FLIPPED)
if AND
actor.Driving($PLAYER_ACTOR)
$SCRIPT_STATUS == 0
then
 if
 08AB: external_script 0 (NO_FLIPPED) loaded
 then
 0913: run_external_script 0 (NO_FLIPPED)
 else
 08A9: load_external_script 0 (NO_FLIPPED)
 jump @TRIGGER
 end
end

:TRIGGER_3_1
wait 0
090F: end_external_script 0 (NO_FLIPPED)
jump @TRIGGER
```

Как видите сначала мы запишем в переменную статус внешнего скрипта, дале мы проверяем: "СЖ в машине?" и "внешний скрипт отключен?". Если эти условие выполняются, то проверяем "Внешний скрипт загружен?". Если скрипт не загружен, то загружаем его, и так дальше, пока скрипт всё таки не загрузится. После загрузки идёт старт внешнего скрипта опкодом **0913**. Дальше игра ждёт окончания потока ":NOFLIP". То есть, когда СЖ выйдет с тачки, то поток завершится, а затем и завершится внешний скрипт опкодом **090F**.

Теперь запускаем поток ":TRIGGER" командой "create\_thread" из потока "MAIN". В результате мы получили неплохую палочку-выручалочку. Теперь машина всегда будет под вашим контролем ;) Вот код мейна: [main.txt](https://github.com/wmysterio/scm-scripting-lessons/blob/main/data_base/sa/EXTERNAL.txt). Это один из самых простых примеров, по этому разобраться в них думаю сложно не будет.

Теперь поговорим о том, зачем они нужны. Я сначала не понимал зачем они вообще нужны. Работал только с обычными потоками. Но вдруг игра начала сильно тормозить. Я не мог понять с чего это вдруг. Потом увидел статью о внешних скриптах и попробовал сделать несколько. На моё удивление, игра перестала тормозить. Как оказалось, игра выделяет дополнительную память под внешние скрипты, что значительно увеличивает быстродействие.

Особенно помогает, если в потоке идёт очень много проверок и арифметических операций. Максимальное количество внешних скриптов - 70 ( одновременно работающих ), то есть мы так же получаем дополнительный бонус в потоках ( 70+96=166 ) 166 штук!!! Однако не стоит злоупотреблять этим, поэтому старайтесь максимально снизить количество потоков. Например, не нужно делать потоки для каждого внешнего скрипта, а стараться объединять их в один.

И напоследок рассмотрим ещё несколько полезных опкодов:

```
07D3: 'HOUSE' = init_external_script_named_handle 23 (BURG_BRAINS)
0884: 'DANCER' = init_external_script_named_handle 52 (DANCER)
```

Внешние скрипты инициализируются как строки ( задают им строковые имена ( не больше 7 символов! ) ). Привязываются к интерьеру, однако точный принцип работы этих опкодов я точно не знаю.

```
0928: init_external_script_trigger 19 (DEALER) with_actor_model #BMYDRUG priority 100
08E8: assign_external_script_handle 'DEALER' to_model #BMYDRUG
```

Внешний скрипт будут выполнять актёры с определённой моделью. В оригинальном мейне эти опкоды идут в паре. Здесь:

Здесь:\
\#BMYDRUG - модель актёра, который будет выполнять действия во внешнем скрипте\
'DEALER' - строковое имя скрипта\
19 (DEALER) - номер и имя скрипта\
100 - приоритет в процентах ( целое число )<br>

```
0929: init_external_script_trigger 7 (ARCADE) with_object_model #CJ_COIN_OP_3 priority 100 radius 4.0 type -1
```

Внешний скрипт привязывается к объекту.

× \*\*Примечание:\*\* опкоды 08E8, 0928 и 0929 не требуют запуска. Они запускаются автоматически× \*\*ВАЖНО:\*\* Если Вы добавили внешний скрипт, то компилировать его нужно после выхода с игры ( полностью )!

P.S Попробуйте тоже сделать какой-то примитивный внешний скипт, чтобы попрактиковаться. На этом урок окончен. Спасибо за внимание! :)|1621|1|0||vneshnie\_skripty\_v\_main\_scm|1499523457


# 00050. Статус-тексты

Статус-тексты|В этом уроке мы рассмотрим статус-тексты.|wmysterio|wmysterio||||Здравствуйте, уважаемые пользователи сайта ru-script.3dn.ru. В оригинальных миссиях можно увидеть полоску жизни дружественной цели и при получении ею урона полоска начинает показывать уровень здоровья. Если полоска станет пустой, то миссия будет считаться проваленной. Сегодня мы напишем миссию с использованием статус-текстов. Но прежде всего рассмотрим необходимые опкоды. Что бы создать статус-текст, используем опкод:

```
04F7: status_text $Health type 0 line 1 GXT 'BB_18'
```

Здесь:\
$Health - переменная, которая будет отвечать за движение полоски. Например: она будет хранить жизнь актёра или автомобиля\
0 - тип статус-текста. Если поставить 0 - выводит обыкновенные числа. Например: количество пойманных ящиков. Если поставить 1 - то вместо числа будет отображаться полоска ( похожая на жизнь СЖ )\
1 - указываем номер линии ( по-сути мы располагаем текст от места, где выводятся деньги СЖ). Чем больше число, тем ниже относительно денег будет полоска ( число от 0 до 4 )\
'BB\_18' - GXT-запись. Она будет выведена возле полоски. Запись должна содержать одно или несколько коротких слов, без использования \~1\~

Вот я, например создал такие записи:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/05065016.png)

Что бы удалить статус-текст, используем опкод:

```
0151: remove_status_text $Health
```

Теперь давайте создадим новый стартер:

```
:STARTER_4
thread 'STARTER_4'
wait 0
$ICON4 = marker.CreateIconAndSphere(22, 2371.0364, -1758.7781, 13.547)

:STARTER_4_1
wait 0
if AND
$ONMISSION == 0
0102: actor $PLAYER_ACTOR in_sphere 2371.0364 -1758.7781 13.547 radius 2.0 2.0 2.0 sphere 0 stopped_on_foot 
jf @STARTER_4_1
if AND
8741: not actor $PLAYER_ACTOR busted
not actor.Dead($PLAYER_ACTOR)
jf @STARTER_4_1
if
not actor.Driving($PLAYER_ACTOR)
jf @STARTER_4_1
marker.Disable($ICON4)
player.CanMove($PLAYER_CHAR) = false
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
00BA: show_text_styled GXT 'MIS_04' time 1000 style 2
fade 0 2000
wait 2000
start_mission 3
end_thread
```

После этого добавим новую миссию. Прежде всего создадим случайного актёра опкодом:

```
0376: 1@ = create_random_actor_at 2370.4766 -1767.1378 13.5469
```

И зададим ему жизнь в 1000 единиц. После этого создадим статус-текст:

```
actor.Health(1@) = 1000
$HEALTH = actor.Health(1@)
0084: $TEMP = $HEALTH // (int)
04F7: status_text $TEMP type 1 line 1 GXT 'HEALACT'
```

Вот что в нас получилось:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/61518594.png)

Цель миссии - дойти до точки вместе с рандомным другом. Но чтобы заставить актёра следовать за СЖ, переместим его в группу игрока а так же сделаем, чтобы созданный нами актёр уважал СЖ:

```
077A: set_actor 1@ acquaintance 0 to_actors_pedtype 0
0631: put_actor 1@ in_group $PLAYER_GROUP
```

Всё необходимое уже сделано. Теперь нам нужно заставить статус-текст правильно работать, чтобы полоска нормально и без ошибок показывала здоровье друга. Здесь есть некоторая закономерность. Если мы задали актёру 1000 жизни - нужно делить их на 10, если 2000 - нужно делить их на 20, если 3000 - делить на 30 и так дальше. Таким образом делаем цикл:

```
0@ == 0

while 0@ == 0
 $HEALTH = actor.Health(1@) // считываем текущее значение жизни друга
 $HEALTH /= 10 // делим их на 10, так как мы задали 1000 жизней перед объявлением статус-текста
 0084: $TEMP = $HEALTH // (int) присваиваем статус-тексту значение переменной жизни актёра, что бы отобразить состояние жизни на экране
wait 0
end
```

Теперь жизни у нас считаются, актёр слушается, остаётся написать только условия, при котором миссия будет проиграна или пройдена. Так же добавим маркер над другом. В результате мы получили неплохой скрипт и этот шаблон уже можно использовать для похожих миссий:

```
:MISSION_3
thread 'MISSION_3'
gosub @MISSION_3_29_57 
if 
wasted_or_busted 
jf @MISSION_3_29_46 
gosub @MISSION_3_29_144 

:MISSION_3_29_46
$ONMISSION = 0 
mission_cleanup 
end_thread 

:MISSION_3_29_57
increment_mission_attempts 
$ONMISSION = 1 
0395: clear_area 1 at 2370.4766 -1767.1378 13.5469 radius 300.0
0376: 1@ = create_random_actor_at 2370.4766 -1767.1378 13.5469
wait 1500
actor.Health(1@) = 1000
077A: set_actor 1@ acquaintance 0 to_actors_pedtype 0
0631: put_actor 1@ in_group $PLAYER_GROUP
$HEALTH = actor.Health(1@)
0084: $TEMP = $HEALTH // (int)
04F7: status_text $TEMP type 1 line 1 GXT 'HEALACT'
fade 1 1000
wait 1000
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
player.CanMove($PLAYER_CHAR) = true
03BC: 2@ = create_sphere_at 2225.8528 -1724.875 13.5585 radius 2.0
018A: 3@ = create_checkpoint_at 2225.8528 -1724.875 13.5585
4@ = marker.CreateAboveActor(1@)
07E0: set_marker 4@ type_to 1
00BC: show_text_highpriority GXT 'M_RU_ST' time 4000 flag 1 // Отведи друга к спортзалу
0@ = 0

while 0@ == 0
 if OR
 actor.Dead($PLAYER_ACTOR)
 0741: actor $PLAYER_ACTOR busted
 then
 0@ = 1
 end
 
 if
 actor.Dead(1@)
 then
 0@ = 2
 end
 
 if AND
 0102: actor $PLAYER_ACTOR in_sphere 2225.8528 -1724.875 13.5585 radius 3.0 3.0 3.0 sphere 0 stopped_on_foot 
 0102: actor 1@ in_sphere 2225.8528 -1724.875 13.5585 radius 3.0 3.0 3.0 sphere 0 stopped_on_foot 
 then
 0@ = 3
 end
 
 $HEALTH = actor.Health(1@)
 $HEALTH /= 10 
 0084: $TEMP = $HEALTH // (int)
wait 0
end

if
0@ == 1
then
jump @MISSION_3_29_144
end

if
0@ == 2
then
jump @MISSION_3_29_DRUG
end

fade 0 500
wait 500
actor.DestroyInstantly(1@)
wait 100
fade 1 500
wait 500
0318: set_latest_mission_passed 'HEALACT' 
01E3: show_text_1number_styled GXT 'M_PASS' number 10000 time 4000 style 1 
Player.Money($PLAYER_CHAR) += 10000
play_music 1
gosub @MISSION_3_END
create_thread @STARTER_4
return 

:MISSION_3_29_144
wait 0 
gosub @MISSION_3_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 
create_thread @STARTER_4 
return

:MISSION_3_29_DRUG
wait 0 
gosub @MISSION_3_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1
00BC: show_text_highpriority GXT 'M_PA_ST' time 4000 flag 1 // Друг мёртв!
create_thread @STARTER_4 
return

:MISSION_3_END
wait 0 
if
056D: actor 1@ defined
then
actor.DestroyInstantly(1@)
end
0151: remove_status_text $TEMP
03BD: destroy_sphere 2@
marker.Disable(3@)
marker.Disable(4@)
return
```

Результат кажет сам за себя:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/0/52828888.jpg)

Вы можете усовершенствовать этот скрипт. Добавьте несколько противников, которые будут атаковать СЖ и его друга. Вот и сам исходник: [смотреть/скачать](https://github.com/wmysterio/scm-scripting-lessons/blob/main/data_base/sa/STATUS_TEXT.txt).|1344|1|0|52828888`jpg`600`360`400`240``\|05065016`png`430`316`400`293``\|61518594`png`640`400`400`250``||status\_teksty|1499072355




---

[Next Page](/llms-full.txt/1)

