Рейтинг - 3.8 (4)

Вроде нигде не видел подобного урока, поэтому решил написать о использовании scm-функции в качестве проверок.

Впрочем, тут и писать особо нечего. Например, вам нужно сделать 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_pointer
0AA6: call_method 0x4859D0 struct 30@ num_params 1 pop 0 return 0x0
0AB2: ret 1 0

Теги: scm-функции

BoPoH   (17.07.14 00:34)
Забавно. Обнаружил сейчас, что опкоды 0485 и 059A, предназначенные для gosub тоже подходят. Т.е. использовать опкод 0AB2 по прежнему нужно, но перед ним нужно использовать один из этих опкодов.

Vital   (03.08.14 16:23)
Увидев статью, сразу вспомнил эти два опкода. Хорошее открытие, так ведь гораздо легче будет. Интересно, если использовать эти два опкода, то ограничения и особые правила для множественных условий (if and, if or) останутся в силе, или код будет работать лучше...

BoPoH   (07.08.14 12:00)
Цитата
то ограничения и особые правила для множественных условий (if and, if or) останутся в силе, или код будет работать лучше...

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

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

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

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