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

Например, вам нужно сделать 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

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-функцию из госаба. Поэтому, конечно, правильней использовать вариант, описанный в уроке.
Вход на сайт

Поиск
Категории раздела
Мини-чат
Наш опрос
Что скажете о новом дизайне?
Всего ответов: 0
Активность на сайте
Друзья сайта
Статистика

Онлайн всего: 2
Гостей: 1
Пользователей: 1
wmysterio
Сегодня нас посетили:
wmysterio