00064. Работа со стартерами ( Cleo - Часть 1 )

Работа со стартерами ( Cleo - Часть 1 )|Мы продолжаем изучать стартеры и сегодня мы будем делать их для Cleo-миссий.|wmysterio|wmysterio||||Стартера отличаются от тех, что мы писали в мейне, так как мы не будем использовать глобальные переменные в качестве счетчика. Есть один опкод, который позволяет хранить потоки:

0A95: enable_thread_saving

Но я их не использую, так как он у меня не работает так как нужно. Где же выход? Как заставить миссии запускаться в каком-то порядке? Думаю вы видели мой старый мод "NFS GTA RACE". Там всегда миссии не повторялись после прохождения. Что бы и мы сделали подобное, нам необходимо хранить данные в файле. Давайте создадим ini-файл "MISSION.ini" в папке CLEO с таким содержимым:

ini
[MISSION_CJ]
markerID = 15 ; Здесь будет хранится номер иконки
MARKER_X_CJ = 2498.2966 ; Координата X сферы
MARKER_Y_CJ = -1684.5094 ; Координата Y сферы
MARKER_Z_CJ = 12.41 ; Координата Z сферы
MISSION_CJ_TOTAL = 0 ; Здесь будет хранится текущее количество пройденных миссий

Это необходимые данные для стартовой миссии. Как нам сделать, что бы при завершении одной миссии, начиналась вторая, третья и т.п? Ответ прост. Давайте сначала напишем простой код Cleo-миссии:

{$CLEO .CM}
//------------- mission ---------------
:mission
thread 'mission'
gosub @mission_29_57
if
wasted_or_busted
jf @mission_29_46
gosub @mission_29_144

:mission_29_46
$ONMISSION = 0
mission_cleanup
end_thread

:mission_29_57
increment_mission_attempts
$ONMISSION = 1
fade 1 1000
wait 1000
gosub @mission_END
00BA: show_text_styled GXT 'M_PASS' time 5000 style 1 // MISSION PASSED
0318: set_latest_mission_passed 'MISS_00' // GXT MISSION name
return

:mission_29_144
wait 0
gosub @mission_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 // MISSION FAILED
return

:mission_END
wait 0
return

Преимущество cleo-миссий ещё в том, что нам необязательно называть потоки разными именами, как это было в мейне. Можно всегда называть одним именем. Всёравно запуск идёт по названию файла :)

Как вы помните, в мейне мы использовали "$MISSION_CJ_TOTAL += 1", что бы указывать стартеру какую миссию запускать. В cleo-миссии нам предстоит запись в созданный ini-файл. Давайте сделаем запись в блоке, где миссия будет считаться пройденной:

//...
:mission_29_57
increment_mission_attempts
$ONMISSION = 1
fade 1 1000
wait 1000
gosub @mission_END
00BA: show_text_styled GXT 'M_PASS' time 5000 style 1 // MISSION PASSED
0318: set_latest_mission_passed 'MISS_00' // GXT MISSION name

0AF0: 0@ = get_int_from_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"
0@ += 1
0AF1: write_int 0@ to_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"

return

:mission_29_144
//...

Сначала мы считываем текущее количество пройденных миссий. Потом прибавляем ей 1 и в конце запишем новое значение в ту же секцию. Естественно мы могли бы напрямую записать значение, но тогда бы нам пришлось бы постоянно менять число ( количество пройденных миссий ), а это лишний геморрой. Так что оставляем именно такой вариант. Кроме этого в блоке провала миссии мы ничего не пишем, так как при провале данные ini-файла не изменятся.

Если вы хотите, что бы при выполнении миссии, позиция маркера переместилась, то используем запись в файл:

//...
:mission_29_57
increment_mission_attempts
$ONMISSION = 1
fade 1 1000
wait 1000
gosub @mission_END
00BA: show_text_styled GXT 'M_PASS' time 5000 style 1 // MISSION PASSED
0318: set_latest_mission_passed 'MISS_00' // GXT MISSION name
0AF0: 0@ = get_int_from_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"
0@ += 1
0AF1: write_int 0@ to_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"

0AF3: write_float -1446.6484 to_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MARKER_X_CJ"
0AF3: write_float 1502.4534 to_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MARKER_Y_CJ"
0AF3: write_float 1.7366 to_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MARKER_Z_CJ"

return

:mission_29_144
//...

"-1446.6484 1502.4534 1.7366" - наша новая точка и теперь маркер будет создаваться именно в этих координатах. Думаю вы заметили запись в ini-файле:

ini
markerID = 15 ; Здесь будет хранится номер иконки

Как вы думаете, зачем я добавил эту строчку в ини-файл? Правильно! Что бы мы могли менять иконки радара, то есть если мы прошли 3 миссии и хотим, что бы дальше появилась иконка незнакомца, то мы можем в коде выполнения третьей миссии записать новое значение номера меркера:

//...
:mission_3_29_57
increment_mission_attempts
$ONMISSION = 1
fade 1 1000
wait 1000
gosub @mission_3_END
00BA: show_text_styled GXT 'M_PASS' time 5000 style 1 // MISSION PASSED
0318: set_latest_mission_passed 'MISS_00' // GXT MISSION name
0AF0: 0@ = get_int_from_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"
0@ += 1
0AF1: write_int 0@ to_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"

0AF1: write_int 37 to_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "markerID"

return

:mission_3_29_144
//...

37 - наша новая иконка радара ( см. номера в Иконки радара). Теперь осталось компилировать миссию и дать ей какое то имя. Допустим, её название будет "MIS_001". Вы можете переместить её в папку "Cleo\Missions" или оставить так. В примерах я оставляю её в папке Cleo а вы уже можете перемещать их куда Вам нужно. Это дело вашей личной индивидуальности :)

Используя шаблон, давайте создадим ещё 4 Cleo-миссий ( их имена ,будут "MIS_002", "MIS_003", "MIS_004" и "MIS_005" ). Мы будем по очереди запускать миссии.

С миссиями разобрались. Нам осталось написать стартер. Он немного отличается от стартера в мейне, так как мы используем файл для хранения данных. Начнём! :)

Прежде всего нам нужно проверить - есть ли файл "MISSION.ini". Если его нет, то завершаем поток, так как без него будут сплошные проблемы и вылеты! Дальше проверим "Находится ли игрок на миссии?". Если да, то прыгаем на начало потока. Иначе создаём маркер, используя опкоды для ini-файлов. Так же здесь нужно проверить "Существует ли маркер?". Это нужно для того, что бы после прохождении миссии маркер удалялся. Вот текущий код:

{$CLEO}
0000:

:NAME
thread 'NAME'
wait 0
if
0AAB: file_exists "CLEO\MISSION.ini"
jf @NAME_END
if
$ONMISSION == 0
jf @NAME
if
075C: marker 0@ enabled // проверка: "Маркер включен?"
then
marker.Disable(0@)
end

:NAME_1
wait 0
0AF0: 1@ = get_int_from_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "markerID"
0AF2: 2@ = get_float_from_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MARKER_X_CJ"
0AF2: 3@ = get_float_from_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MARKER_Y_CJ"
0AF2: 4@ = get_float_from_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MARKER_Z_CJ"
0@ = marker.CreateIconAndSphere(1@, 2@, 3@, 4@)

:NAME_END
wait 0
0A93: end_custom_thread

Дальше нам необходимо написать простенький цикл, в котором будут условия запуска миссий. Так же мы должны считать количество пройденных миссий CJ:

//...
:NAME_2
wait 0
// Считываем текущее количество пройденных миссий миссий:
0AF0: 5@ = get_int_from_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"
if AND
not actor.Dead($PLAYER_ACTOR)
not actor.Driving($PLAYER_ACTOR)
8A0C: not player $PLAYER_CHAR on_jetpack
8741: not actor $PLAYER_ACTOR busted // Это, наверное, самые используемые проверки в стартере :)
then
 if AND
 $ONMISSION == 0
 0102: actor $PLAYER_ACTOR in_sphere 2@ 3@ 4@ radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 00BE: text_clear_all
 03E6: remove_text_box
 fade 0 1000
 if
 5@ == 0 // проверяем: "количество пройденных миссий равно 0?"
 then
 00BA: show_text_styled GXT 'MISS_01' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_001"
 jump @NAME
 end
 if
 5@ == 1
 then
 00BA: show_text_styled GXT 'MISS_02' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_002"
 jump @NAME
 end 
 if
 5@ == 2
 then
 00BA: show_text_styled GXT 'MISS_03' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_003"
 jump @NAME
 end
 if
 5@ == 3
 then
 00BA: show_text_styled GXT 'MISS_04' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_004"
 jump @NAME
 end
 if
 5@ == 4
 then
 00BA: show_text_styled GXT 'MISS_05' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_005"
 jump @NAME
 end
 end 
end
jump @NAME_2
//...

Давайте взгяним на полную картину:

{$CLEO}
0000:

:NAME
thread 'NAME'
wait 0
if
0AAB: file_exists "CLEO\MISSION.ini"
jf @NAME_END
if
$ONMISSION == 0
jf @NAME
if
075C: marker 0@ enabled
then
marker.Disable(0@)
end

:NAME_1
wait 0
0AF0: 1@ = get_int_from_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "markerID"
0AF2: 2@ = get_float_from_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MARKER_X_CJ"
0AF2: 3@ = get_float_from_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MARKER_Y_CJ"
0AF2: 4@ = get_float_from_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MARKER_Z_CJ"
0@ = marker.CreateIconAndSphere(1@, 2@, 3@, 4@)

:NAME_2
wait 0
0AF0: 5@ = get_int_from_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"
if AND
not actor.Dead($PLAYER_ACTOR)
not actor.Driving($PLAYER_ACTOR)
8A0C: not player $PLAYER_CHAR on_jetpack
8741: not actor $PLAYER_ACTOR busted
then
 if AND
 $ONMISSION == 0
 0102: actor $PLAYER_ACTOR in_sphere 2@ 3@ 4@ radius 2.0 2.0 2.0 sphere 0 stopped_on_foot
 then
 00BE: text_clear_all
 03E6: remove_text_box
 fade 0 1000
 if
 5@ == 0
 then
 00BA: show_text_styled GXT 'MISS_01' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_001"
 jump @NAME
 end
 if
 5@ == 1
 then
 00BA: show_text_styled GXT 'MISS_02' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_002"
 jump @NAME
 end 
 if
 5@ == 2
 then
 00BA: show_text_styled GXT 'MISS_03' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_003"
 jump @NAME
 end
 if
 5@ == 3
 then
 00BA: show_text_styled GXT 'MISS_04' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_004"
 jump @NAME
 end
 if
 5@ == 4
 then
 00BA: show_text_styled GXT 'MISS_05' time 1000 style 2
 wait 1000
 0A94: start_custom_mission "MIS_005"
 jump @NAME
 end
 end 
end
jump @NAME_2

:NAME_END
wait 0
0A93: end_custom_thread

Наш стартер готов! Теперь будут идти последовательно пять Cleo-миссий. :) Но есть один глюк. Когда игрок пройдет последнюю миссию, то появится иконка, став на которую ничего не произойдет. Что бы избежать появления такой "настойчивой" иконки нам жужно проверить количество пройденных миссий. Если пройдены все, то завершаем поток:

:NAME
thread 'NAME'
wait 0
if
0AAB: file_exists "CLEO\MISSION.ini"
jf @NAME_END
if
$ONMISSION == 0
jf @NAME
if
075C: marker 0@ enabled
then
marker.Disable(0@)
end

0AF0: 5@ = get_int_from_ini_file "CLEO\MISSION.ini" section "MISSION_CJ" key "MISSION_CJ_TOTAL"
if
5@ > 4 // Это число должно быть равно количеству пройденных миссий. В нашем случаи 1+1+1+1=4
then
jump @NAME_END
end

:NAME_1
wait 0
//...

Теперь при прохождении последней миссии маркер появляться не будет. :) Если Вы написали ещё одну миссию, то добавить её в стартер не составляет проблем! Используйте этот шаблон:

if
5@ == 6 // 7, 8, 9 и так, пока не будет номер последней миссии
then
00BA: show_text_styled GXT 'MISS_06' time 1000 style 2 // 'MISS_07', 'MISS_08', 'MISS_09' указывайте названия для новых миссий
wait 1000
0A94: start_custom_mission "MIS_006" // MISS_07, MISS_08, MISS_09 указывайте имена миссий для запуска
jump @NAME
end

Этот кусок вставляйте сразу после завершения блока с подобными записями ( после "fade 0 1000" ). В следующем уроке мы рассмотрим запуск нескольких стартеров в Cleo.|1311|1|0||rabota_so_starterami_cleo_chast_1|1499620646

Last updated