Мой сайт
Архив статей

Меню сайта

Статистика


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

Cleo. Основные понятия, отличия от main'а, простые примеры

Здравствуйте, уважаемые пользователи сайта. Пришло время немного оставить скриптить main.scm и перейти на Cleo. Большинство приёмов и возможностей мы рассмотрели, и дальше нет смысла писать их в мейне, так как постоянное начало новой игры думаю достаёт. По этому уроки дальше будут на Cleo.

Действуют Cleo-скрипты как и внешние скрипты из main.scm, только загружать их не нужно. Они сами загружаются в начале игры. Особенностью этих скриптов в том, что не нужно начинать новую игру, как это было в мейне. Так же важно, что в клео нельзя создавать новые потоки. То есть create_thread здесь не пройдёт. Один скрипт - один поток. Рассмотрим написание простейшего скрипта:

{$CLEO}
0000:

:POTOK
thread 'POTOK'
wait 5000
0A93: end_custom_thread


Здесь:
{$CLEO} - указываем компилятору, что это будет cleo-скрипт(обязательно ставьте эту строку, иначе компилятор скомпилирует его как *.scm и закинет его папку data/script игры, указанной в настройке СБ)
0000: - опкод, который устраняет ошибку "Переход на нулевой оффсет". Эта ошибка возникает, когда идёт переход на первую метку.  В нашем случаи такого перехода нет, но я всегда его пишу, что бы не приходилось его добавлять в будущем.
0A93: end_custom_thread - именно этим опкодом завершаются клео-скрипты. Это очень важно, потому что end_thread вызывает ошибку при загрузке(сохранении) игры.


В Cleo-скриптах не рекомендуется использовать глобальные переменные. Это сделано для того, что бы случайно не изменить переменную в main.scm. То есть глобальные переменные действуют и на cleo. Однако некоторые переменные всё же можно(нужно :)  ) используются в cleo. Это такие, как $PLAYER_CHAR$PLAYER_ACTOR$ONMISSION.  Если всё же нужно использовать собственные глобальные переменные, то создавайте как можно длинные и запутанные имена или такие, каких нет в main.scm. Например:$KOLICHESTVO. Но всё же рекомендую использовать локальные переменные, но и здесь есть ограничения. Переменные от 0@ до 30@вы можете свободно использовать. А переменные 32@ и 33@ используются в качестве таймера, которые, кстати(как написано в справке) не запускаются опкодом 03C3, так же не не рекомендовано использовать опкоды 03C4 и 04F7(статус-тексты). Насчёт переменной 31@, то я даже не знаю можно её использовать или нет. У меня например постоянные проблемы с ней, хотя в других ничего плохого не происходит. Можете протестировать. Если у вас в всё окей, то юзайте на здоровье wink Особенности потока те же, что и в мейне. Можно использовать циклы, переходы, массивы и.т.п.

Скрипт мы написали. Когда мы компилируем его в первый раз, то компилятор предложит нам сохранить его. Указываем папку cleo(что в папке с игрой). Другой способ - создать текстовый файл в папке Cleo и переместить его на санник, затем скомпилировать. Имя файла может быть любое, но обычно его называют так же, как и поток. Потоки, кстати, можно и не называть, то есть сразу писать скрипт без thread ' '.

Раз мы будем писать на cleo, то полностью отредактируем мейн, сделаем его минимальным и работоспособным. Немного позже мы скажу зачем мы это сделали. Вот код нашего мейна:

 

// This file was decompiled using sascm.ini published by Seemann (http://sannybuilder.com/files/SASCM.rar) on 13.10.2007
// by WMYSTERIO, http://www.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 3072

{$VERSION 3.1.0027}

//-------------MAIN---------------
thread 'MAIN' 
set_wb_check_to 0 
set_weather 0 
select_interior 0 
fade 0 0 
0180: set_on_mission_flag_to $ONMISSION // Note: your missions have to use the variable defined here 
00C0: set_current_time_hours_to 8 minutes_to 0 
04E4: unknown_refresh_game_renderer_at 2491.157 -1670.343 
Camera.SetAtPos(2491.157, -1670.343, 12.3359)
$PLAYER_CHAR = Player.Create(#NULL, 2491.157, -1670.343, 12.3359)
$PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
Actor.Angle($PLAYER_ACTOR) = 66.3548
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group 
Camera.SetBehindPlayer
Player.SetClothes($PLAYER_CHAR, "WORKTRCAMOGRN", "WORKTR", Legs)
Player.SetClothes($PLAYER_CHAR, "SNEAKERBINCGANG", "SNEAKER", Shoes)
Player.SetClothes($PLAYER_CHAR, "TSHIRTERISORN", "TSHIRT", Torso)
Player.Build($PLAYER_CHAR)
Player.CanMove($PLAYER_CHAR) = True
0629: change_integer_stat 181 to 4 
016C: restart_if_wasted_at 2027.77 -1420.52 15.99 angle 137.0 town_number 0 
016C: restart_if_wasted_at 1180.85 -1325.57 12.58 angle 271.4 town_number 0 
016D: restart_if_busted_at 1550.68 -1675.49 14.51 angle 90.0 town_number 0 
016C: restart_if_wasted_at 1244.437 331.2261 18.5547 angle 7.5465 town_number 1 
016D: restart_if_busted_at 632.2344 -571.7104 15.3515 angle 267.2 town_number 1 
016C: restart_if_wasted_at -2199.719 -2308.075 29.6181 angle 322.8928 town_number 1 
016D: restart_if_busted_at -2163.829 -2387.817 29.625 angle 134.2066 town_number 1 
016C: restart_if_wasted_at -2670.285 616.4364 13.4531 angle 183.1042 town_number 1 
016D: restart_if_busted_at -1605.792 716.8598 11.0241 angle 355.2978 town_number 1 
016C: restart_if_wasted_at -316.3832 1056.045 18.7344 angle 1.6017 town_number 2 
016D: restart_if_busted_at -212.1889 979.4168 18.3219 angle 278.0478 town_number 2 
016C: restart_if_wasted_at -1514.823 2527.119 54.7443 angle 2.3546 town_number 2 
016D: restart_if_busted_at -1393.072 2633.116 54.9491 angle 86.0424 town_number 2 
016C: restart_if_wasted_at 1578.446 1770.682 9.8358 angle 99.7567 town_number 2 
016D: restart_if_busted_at 2337.083 2453.802 13.9765 angle 90.7643 town_number 2 
fade 1 0 
create_thread @SAVE
end_thread 

:SAVE
thread 'SAVE'
wait 0
if AND
not actor.Dead($PLAYER_ACTOR)
8741:   not actor $PLAYER_ACTOR busted 
then
    if AND
    $ONMISSION == 0
    8A0C:   not player $PLAYER_CHAR on_jetpack         
    then
        if AND
        8818:   not actor $PLAYER_ACTOR in_air
        8965:   not actor $PLAYER_ACTOR swimming 
        then
            if AND
            not actor.Driving($PLAYER_ACTOR)
            0AB0:   key_pressed 115 // F4
            then
            03D8: show_save_screen 
            end
        end
    end
end         
jump @SAVE


Компилируем его и запускаем новую игру. Как видим, никаких ошибок не возникало. По этому смело закрываем мейн и начинаем писать Cleo-скрипты ;)

Прежде всего напишем скрипт сохранения. Создаем в папке Cleo текстовый файл и называем его, например, CAR.txt. Дальше запускаем ярлык санника и ожидаем запуска программы. После этого перемещаем файл в окно программы:

 

Как видим появилось поле редактора :)

Дальше уже  пишем сам скрипт:

 

{$CLEO}
0000:

:car
thread 'car'
wait 0
if
0AB0:  key_pressed 50 //  Кнопка 2
then
0ADD: spawn_car_with_model #BULLET at_player_location
end
jump @car


Суть скрипта проста - нажимаем кнопку 2 и перед СЖ появится кар "Пуля". Как видите, мы не использовали опкод 0A93: в нашем скрипте, так как мы возвращаемся постоянно на метку @CAR. В таких случаях обычно не пишут опкод завершения потока, так как он никогда не выполнится :)

Компилируем. Думаю вы заметили, что в папке создался и *.cs-файл, так что клео-скрипт создан :)

Давайте удалим опкод 0000: и попробуем скомпилировать. Как видите, в нас ошибка: "Переход на нулевой оффсет". Как уже было написано выше, это случается когда идёт переход на первую метку. Именно для этого создан опкод 0000: что бы облегчить нам жизнь smile Так же можно написать вместо него задержку wait 0. Это тоже помогает ;)

Давайте протестируем скрипт. Результат виден на лицо - тачка отлично "спавнится" возле Карла



u
Категория: Скриптинг | Добавил: Bura22 (09.10.2012)
Просмотров: 1263 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Вход на сайт

Поиск