Рейтинг - 5.0 (2)

Сегодня мы рассмотрим одну из интереснейших тем - создание SCM-функций.

Здравствуйте, дорогие друзья. Начинаем очередной урок по скриптингу. Использование функций очень удобно, когда нужно выполнять один и тот же код несколько раз. Действуют функции по аналогии с 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@

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



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

Один интересный факт насчет опкода 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

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

Задания!

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

Посмотрите на картинку выше. На ней есть незначительная ошибка. Тот, кто первый найдёт её - получит + к репутации :D


Теги: Подключение текстовых файлов, scm-функции

Slivkin-Sergey   (24.06.12 12:46)
А где картинка? happy

wmysterio   (24.06.12 14:14)
Под спойлером выше посмотри smile
Забыл указать ))

KiLLeR96   (25.06.12 19:55)
ага! Загружается модель #WMYDRUG, а уничтожается #WMYCLOT! Вот она ошибочка

wmysterio   (25.06.12 20:17)
Совершенно верно! =)
Плюсик твой =)

KiLLeR96   (25.06.12 20:58)
happy

GeniusZ   (03.08.15 18:46)
Мне кажется или не нужно возвращать параметр $ACTOR?

0
wmysterio   (04.08.15 04:18)
кажется
Вход на сайт

Поиск
Категории раздела
Мини-чат
Пожалуйста, все вопросы по скриптингу задавать на форуме!
Наш опрос
Кто из главных героев GTA 5 круче?
Всего ответов: 10
Активность на сайте
Пожертвования
Кошельки WebMoney:
U859420971000
R407741810602
Z331072372430
E314272616890
Друзья сайта
Полезные ресурсы
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Сегодня нас посетили:
Рекомендую
Реклама