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

В этом уроке мы ознакомимся с базовыми понятиями скриптов: потоками, командами, метками, прыжками и задержкой. Будет введено понятие опкода.

Для начала сделаем резервную копию игровых файлов. А именно 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. Запустите игру ( F8 ), обязательно нажимаем "НОВАЯ ИГРА"! Посмотрите что изменилось. Думаю большинство заметило, что нету вступительного ролика и прочего. Такой мейн называется "Чистым".

Начнем с потоков думаю. Я не буду выражаться какими то сложными выражениями. Скажу только несколько слов о них. Я назову это отдельным блоком, в котором делаются некоторые действия. Каждый поток имеет свое имя, как и каждый человек. Нельзя создать два потоки с одинаковыми именами и длиной больше 15 символов. Рекомендую брать пример с оригинального "main.scm", где длина потока составляет не больше 7 символов. Лучше делать так, как это делали разработчики игры.

Как же создать поток? Для начала изучим правила написания потока. Каждый поток начинается командой:

thread 'POTOK' // POTOK - это имя нашего потока

и заканчивается командой ( команда завершения или деактивации ):

end_thread // команда завершения потока

Это очень легкие команды, думаю за небольшой промежуток времени вы запомните их.

Что такое метка? На этот вопрос я очень легко могу ответить, и этот ответ станет основой скриптинга, поэтому запоминайте.

  1. Как узнать метку и её создать? Создание метки очень просто. Нужно написать сначала символ : а затем ввести имя метки. Вот пример:

    :METKA

    Узнать метку можно за правилами написания, о котором я написал выше. Принято писать метки с теми именами, что и поток, далее уже после имени потока добавляют несколько чисел или букв.

    С техничекой точки зрения метка - это смещение в файле "main.scm" и представляет собой обычное число. В прочем, для нас это не важно, так как Sanny Builder все эти смещения высчитывает самостоятельно, основываясь на наших метках.

  2. Пример написания потока и и его меткок:

    :POTOK
    thread 'POTOK'
    
    :POTOK_1
    
    :POTOK_2
    
    :POTOK_3
    
    end_thread

Весь скриптинг основан на построчном считывании информации. То есть одна команда - одна строка. В примере показано, что сначала будет выполняться команды от метки ":POTOK_1", затем ":POTOK_2" и вконце ":POTOK_3". Естественно можно изменить порядок выполнения меток, не изменяя их положения. Для этого служит команда jump. Если перевести дословно, то это значит прыжок. Далее мы будем использовать именно это выражение. Что же, давайте напишем пример, где используются прыжки:

: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

Сложновато, правда? Далее будет ещё сложнее. Особенно если вы решили увидеть чужой скрипт. :) Но не будем о грустном! Разобраться не так уже и сложно. Давайте представим маленький шарик. Представили? Назовём его "Указатель". Нет, пусть будет просто "Шарик" :) Этому шарику предстоит пройти определенный путь. Начинает путь наш шарик с имени потока, то есть с команды "thread", и начинает идти вниз. Используя прыжки ( jump ) можно нарисовать путь прохождения шарика. Я уже нарисовал путь. Вот по примеру должно примерно так получится:

Итак, вы увидели шарика. Оранжевым указано куда именно я направлял шарика. Я специально загрузил этот рисунок, что бы вам легче было представить себе принцип работы скриптов. Если шарик достиг места финиша, то он автоматично отправляется на заслуженную пенсию и больше использоваться в потоке не будет, пока его не вызовут опять на службу. :)

Как запустить поток и что нужно для его правильной работы? Хороший вопрос. Особенно интересно слово "правильной"! Что же, думаю самое время познакомиться с опкодами! Это наши верные помощники! Так и будем называть их, потому что они помогают выполнить кое-какие действия. Для правильной работы нам нужно запомнить помощника по имени 0001:, то есть опкод:

0001: wait 0 ms // 0 - это задержка

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

С новой версией СБ и Клео, в целях удобства, ему присвоили статус команды ( так званный кейворд ), и мы можем писать просто

wait 0 // 0 - это задержка

Технически разницы между опкодами и командами нету - команда имеет упрощённый синтаксис, но в процессе преобразования заменяется на опкод. Опкод - это операционная код ( команда ).

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

create_thread @POTOK // POTOK - имя потока, который нужно запустить

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

// 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

Конечно, толку от нашего примера никакого, но, думаю, вы приобрели необходимый опыт в написании потоков.

В нашем случае, поток вызывается с активного потока ( "MAIN" ), а когда поток запущен командой "thread", то вызванный поток сам стает активным, так сказать вызывается тогда, когда шарик при деле :) Первый поток называется ГЛАВНЫМ, или MAIN.


Теги: Jump, Прижок, Wait, SCM, thread, поток, задержка

Yurko_UA   (17.07.12 22:15)
А буває команда
Code
gosub_if_false
???

wmysterio   (17.07.12 22:29)
Є.
Code
0AA0: gosub_if_false @CREATE_NEW_ACTOR

BalashovM   (27.12.15 13:23)
Я так понимаю, чтобы поток завершился, нужно прыгнуть (или просто пройти без прыжков) до последней метки, если же последняя метка в потоке будет отсылать на первую, а первая - на последнюю, то у нас получится вечный цикл - рекурсия?

0
wmysterio   (28.12.15 06:07)
Метки не ссылаются на другие метки, есть просто команды, которые указывают переход по меткам. По-сути, метка - это смещение от начала файла и является просто числом.

Если в последней метке идёт прыжок на первую, то это - цикл. Рекурсия - это совсем другое.
Вход на сайт

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

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

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