CLEO: Урок 1 - Основы
И так, в этом уроке мы разберем что такое CLEO скрипты, как они работают, и как их создавать.
Что же такое скрипт? Скрипт - это файл, содержащий набор команд, которые будут выполняться игрой. Благодаря скриптам можно добавить в игру множество дополнительных функций и нововведений.
Чтобы написать свой собственный скрипт первым делом вам нужно скачать и установить Sanny Builder. Именно в нем и пишутся CLEO скрипты.
Теперь открываем SB и нажимаем Файл/Создать.
Файл создан, далее пишем такой код:
{$CLEO} 0000:
С этих строк начинается любой CLEO скрипт, поэтому его обязательно нужно писать.
В самом конце скрипта добавляем эту строку:
0A93: end_custom_thread
Данная команда завершает скрипт. Если ваш скрипт не зациклен, и в конце не будет этой строки, произойдет вылет игры.
В последних версиях SB появился пункт в меню: Файл/Новый CLEO скрипт. Код написанный выше сам вставляется в редактор при создании скрипта таким способом.
Теперь разберемся с базовыми терминами и понятиями, которые будут вам необходимы при написании скриптов.
Опкод - действие выполняемое скриптом. Данный опкод устанавливает игроку игнорирование копами.
01F7: set_player $PLAYER_CHAR ignored_by_cops 1
Список опкодов можно посмотреть нажав Сервис/ Инструменты/ Поиск опкодов.
Чтобы скопировать опкод, выберите его и нажмите Enter (Ctrl+C тут не работает).
Переменная - контейнер в котором можно хранить какие-либо данные: целые числа (int), дробные числа (float) или текст (string).
В CLEO существуют локальные и глобальные переменные.
Локальных переменных существует всего 32 штуки + 2 таймера. Обозначаются они цифрой и знаком @ после нее. Например: 0@, 1@, 2@, 3@ и так далее до 33@.
Глобальные переменные обозначаются так: $MYGUN, $WEATHER, $SITE и так далее. Их названия можно придумывать самим в отличии от локальных переменных. Но в CLEO скриптах ими пользоваться не рекомендуется, так как их использование может приводить к случайным вылетам игры.
Такие глобальные переменные как $PLAYER_ACTOR, $PLAYER_CHAR, $ONMISSION использовать в CLEO можно, первые две переменные обозначают игрока, а третья хранит данные о том запущена какая-либо миссия или нет.
Локальные переменные можно считывать и изменять только в том скрипте, где они были созданы, глобальные же переменные действуют в пределах вообще всех скриптов в игре. Поэтому они так и называются.
С переменными можно проделывать арифметические действия, приравнивать, умножать, делить, прибавлять и отнимать. Арифметические действия выглядят так: 1+=2, 3/=4, 5*=9 и тд. То есть после знака операции всегда ставится знак = (не просто 2+1, а 2+=1).
Задание:
1@ = 10 2@ = 25 1@ += 2@ 1@ -= 1
Как думаете чему будет равна переменная 1@ после выполнения всех операций?
Подсказка: 10+25-1 = 34
Переменной можно обозначать актера, транспорт, объекты, эффекты, оружие и много много чего еще. Простыми словами переменная в данном случае - это имя актера. В жизни мы могли бы назвать его Вася, но мы в GTA SA и поэтому назовем его, например, 5@. В скриптинге это называется не имя, а хэндл. Не получив хэндл актера, машины, объекта, мы не можем производить никаких действий с ними.
Первый опкод записывает в переменную 4@ ближайший автомобиль, а в переменную 5@ ближайшего педа. Второй опкод убивает актера 5@. Третий опкод взрывает машину 4@:
0AB5: store_actor $PLAYER_ACTOR closest_vehicle_to 4@ closest_ped_to 5@ 05BE: AS_actor 5@ die 020B: explode_car 4@
Метка - обозначение определенного места в коде, к которому можно переходить командой jump. Метки нужны для передвижения по скрипту.
Обозначаются они двоеточием:
:LABEL1 :GUNS :DYOM_MENU
Названия меток могут быть любыми, но обязательно английскими буквами и без пробелов.
Стоит сказать, что выполнение скрипта всегда происходит сверху вниз, каждая строка выполняется по очереди. Не может выполняться 2 или 3 куска кода одновременно. Для того и нужны метки, чтобы, к примеру, при достижении конца скрипта мы могли вернуться в его начало и заново выполнить код.
По меткам можно передвигаться с помощью опкодов jump @NAME, jf @NAME, gosub @NAME.
Задание:
:METKA1 jump @METKA3 :METKA2 jump @METKA1 :METKA3 jump @METKA2
На какой метке мы окажемся после выполнения кода?
Подсказка: мы окажемся на :METKA1, и далее код будет повторяться по кругу бесконечное число раз.
Условия - в любых скриптах всегда есть условия при которых выполняется то или иное действие. Чтобы проверить выполнено то или иное условие, нужно использовать опкод IF и после него добавить специальные условные опкоды. Их можно узнать по большому пробелу после двоеточия.
if 00DF: actor $PLAYER_ACTOR driving
Рассмотрим использование условий на примере небольшого скрипта.
Суть скрипта: если игрок в машине, то выключается HUD.
IF jf @NAME (сокращение от "jump if false") - если условие не выполнено, то переходим к метке NAME. Если выполнено - продолжаем движение вниз по коду.
:RADAR wait 0 if 00DF: actor $PLAYER_ACTOR driving jf @RADAR 0826: enable_hud 0 jump @RADAR
IF Then End - если условие выполнено, то сработает код после Then, если нет, то скрипт пропустит эту часть и перейдет сразу к End
:RADAR wait 0 if 00DF: actor $PLAYER_ACTOR driving then 0826: enable_hud 0 end jump @RADAR
IF Then Else End - если условие выполнено, то сработает код после Then и сразу перепрыгнет к End. Если условие не выполнено, то сразу выполнится код после Else
:RADAR wait 0 if 00DF: actor $PLAYER_ACTOR driving then 0826: enable_hud 0 else 0826: enable_hud 1 end jump @RADAR
Если должно быть выполнено сразу несколько условий, то нужно использовать IF AND
if and 00E1: player 0 pressed_key 6 00DF: actor $PLAYER_ACTOR driving jf @NAME
Если нужно чтобы хотя бы одно из условий было выполнено, то используйте IF OR
if or 00E1: player 0 pressed_key 6 00DF: actor $PLAYER_ACTOR driving jf @NAME
Задание:
{$CLEO} 0000: :ONE wait 0 if 00DF: actor $PLAYER_ACTOR driving then jump @TWO else jump @TREE end :TWO wait 0 0223: set_actor $PLAYER_ACTOR health_to 500 041E: set_radio_station 0 0826: enable_hud 0 jump @ONE :TREE wait 0 0826: enable_hud 1 JUMP @ONE
Попробуйте понять что делает данный скрипт, по каким меткам он движется и какие команды выполняет.
wait 0 - вы наверняка заметили в скрипте этот опкод, так зачем же он нужен? Это задержка 0 миллисекунд. Вы спросите, зачем же она нужна, если она равна 0? Это же означает что задержки нет! На самом деле это не так. Wait 0 - это минимально возможная задержка для скрипта.
Её необходимо ставить в том участке кода, который выполняется бесконечное или неопределенное количество раз. Если не добавить эту задержку, то игра просто зависнет так как скрипт будет выполняться бесконечно без какой-либо задержки и попросту не даст игре работать и выполнять другие функции.
Поначалу я не понимал, как это работает и просто ставил wait 0 после каждой новой метки. Например так:
:1 wait 0 jump @2 :2 wait 0 jump @1
В данном коде хватило бы всего одного опкода wait 0, так как в любом случае скрипт будет переходить на одну из меток, где есть задержка.
Но если мы напишем такой код:
:1 wait 0 jump @2 :2 jump @2
Нас гарантированно ждет зависание игры, так как скрипт будет бесконечно переходить на метку 2 без какой либо задержки.
Если вы всё же не поняли, в чем смысл этого опкода, то можете так же ставить его после каждой метки. Если вам не нужна максимальная скорость работы скрипта, в этом ничего страшного нет.
Полезные ссылки:
Руководство по Sanny Builder
Уроки по скриптингу от wmysterio
Программа-учебник по скриптингу
База данных опкодов
Темы для Sunny Builder