Запуск миссии
Вы уже знаете как создавать миссии теперь пришло время научиться запускать эти миссии. В GTA по сути есть всего два способа запуска миссий:
Запуск миссии при старте новой игры
Запуск миссий по очереди.
В GTA SA миссии разделены на три категории:
Технические миссии – это миссии не нуждаются в прохождении и чаще всего запускаются при старте новой игры. Простой пользователь даже не знает о их существовании. Например, миссии INITIAL и INITIL2 содержат в себе все или почти все сведения о пикапах, координатах маркеров, сфер, парковках авто и т.д.
Сюжетные миссии – миссии имеющие отношение к определенному персонажу игры (SWEET, SMOKE, RYDER, и т.д.).
Одиночные миссии – это чаще всего второстепенные (необязательные миссии), например, миссия игры на бильярде или так называемые подмиссии ( пожарного, медика и т.д.). Эти миссии могут запускаться бесконечное количество раз, в отличие от сюжетных миссий. Есть одиночные миссии, так сказать, одноразового использования, например, миссии «INTRO», «INTRO1», «INTRO2». Эти миссии являются обязательными для прохождения. Чаще всего прохождение этих миссий открывает возможность запуска следующего блока сюжетных миссий.
Запуск миссии при старте новой игры.
Обычно производится запуск «технических» миссий «INITIAL» и «INITIL2», а также миссии «INTRO», чаще всего, не требующих вмешательства в игровой процесс пользователя. То есть миссия «INTRO» - это своего рода видео ролик.
Запуск таких миссий производится из главного потока ('MAIN').
0417: start_mission INTRO // Intro
Предположим у Вас есть миссия и желательно, чтобы она начиналась при старте новой игры, но Вас смущает наличие в этой миссии кода провала. Как быть в этом случае? Делаем, стартер миссии и запускаем его только в том случае, если миссия провалена.
:START_1
wait 250
if and
Player.Defined($PLAYER_CHAR)
0102: actor $PLAYER_ACTOR in_sphere 2490.7 -1669.8 13.4 radius 2.0 2.0 1.0 sphere 1 stopped_on_foot
//проверяем находится ли игрок в данной точке
jf @START_1
Marker.Disable(1@) // удаляем маркер
start_mission FIRST //Старт миссии
end_thread // закрываем поток
В код провала вставим create_thread @START
{
use macro (Ctrl+J) "headsa"
to insert a file header
}
DEFINE MISSIONS 1 // общее количество миссий
DEFINE MISSION {ID} 0 AT {LABEL} @FIRST // Ваша миссия
DEFINE EXTERNAL_SCRIPTS 0 // Use -1 in order not to compile AAA script
//DEFINE SCRIPT {NAME} AT {LABEL} @
DEFINE UNKNOWN_EMPTY_SEGMENT 0
DEFINE UNKNOWN_THREADS_MEMORY 0
{$VERSION 3.0.0000}
thread 'MAIN'
var
$PLAYER_CHAR: Player
end // var
01F0: set_max_wanted_level_to 6
set_wb_check_to 0
00C0: set_current_time 8 0
04E4: unknown_refresh_game_renderer_at 2488.5601 -1666.84
Camera.SetAtPos(2488.5601, -1666.84, 13.38)
$PLAYER_CHAR = Player.Create(#NULL, 2488.5601, -1666.84, 13.38)
$PLAYER_ACTOR = Actor.EmulateFromPlayer($PLAYER_CHAR)
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
Camera.SetBehindPlayer
set_weather 0
wait 0 ms
$PLAYER_CHAR.SetClothes("PLAYER_FACE", "HEAD", Head)
$PLAYER_CHAR.SetClothes("JEANSDENIM", "JEANS", Legs)
$PLAYER_CHAR.SetClothes("SNEAKERBINCBLK", "SNEAKER", Shoes)
$PLAYER_CHAR.SetClothes("VEST", "VEST", Torso)
$PLAYER_CHAR.Build
$PLAYER_CHAR.CanMove = True
select_interior 0
0629: change_stat 181 (islands unlocked) to 4
016C: restart_if_wasted at 2027.77 -1420.52 15.99 angle 137.0 for_town_number 0
016D: restart_if_busted at 1550.68 -1675.49 14.51 angle 90.0 for_town_number 0
0180: set_on_mission_flag_to $ONMISSION
// Note: your missions have to use the variable defined here ($ONMISSION)
03E6: remove_text_box
fade 0 500 ms
:MAIN_49
if
fading
jf @MAIN_50
wait 0 ms
00BE: text_clear_all
03E6: remove_text_box
jump @MAIN_49
:MAIN_50
wait 0 ms
start_mission FIRST //Старт миссии
end_thread
// put your mods (threads) here
:STARTwait 0 1@ = Marker.CreateIconAndSphere(36, 2490.768, -1669.816, 13.3359):START_1wait 250 if andPlayer.Defined($PLAYER_CHAR)0102: actor $PLAYER_ACTOR in_sphere 2490.7 -1669.8 13.4 radius 2.0 2.0 1.0 sphere 1 stopped_on_footjf @START_1 Marker.Disable(1@)start_mission FIRST //Старт миссииend_thread
//-------------Mission 0---------------
:FIRST
thread 'FIRST'
gosub @FIRST_49 // переход к коду миссии с возвратом на следующую строку
if
wasted_or_busted // убит или арестован
jf @FIRST_38
// если условие не выполнено, то переходим на метку FIRST_38,
// т.е. gosub @FIRST_145 игнорируется.
gosub @FIRST_145 // переход к коду провала с возвратом на следующую строку
:FIRST_49
increment_mission_attempts
$ONMISSION = 1
…
//----- Код миссии-----
…
:FIRST_100
0318: set_latest_mission_passed 'FIRST' // 1st
01E3: show_text_1number_styled GXT 'M_PASSS' number 200 time 5000 style 1
// MISSION PASSED!~n~~w~$~1~~n~~w~RESPECT +
0998: add_respect 3
Player.Money($PLAYER_CHAR) += 200
Player.ClearWantedLevel($PLAYER_CHAR)
0394: play_music 1
return // возвращаемся на следующую после gosub @FIRST_49 строку
:FIRST_145
00BA: text_styled 'M_FAIL' 5000 ms 1 // ~r~MISSION FAILED!
create_thread @START
return // возвращаемся на следующую после gosub @FIRST_145 строку
Запуск миссий по очереди.
Такой вариант запуска применяется к сюжетным миссиям. Для этого варианта нам понадобится глобальная переменная в качестве «счетчика» миссий. Назовем ее например: $NEW_TOTAL_PASSED_MISSIONS и присвоим ей значение 0 ($NEW_TOTAL_PASSED_MISSIONS = 0). Запись этой переменной может быть произведена либо в главном потоке, а также в любом другом потоке или миссии, в котором будет вызываться стартер наших миссий.
В коде миссии в блоке удачного прохождения увеличиваем значение переменной на единицу ($NEW_TOTAL_PASSED_MISSIONS += 1), тем самым предотвращаем повторный запуск первой миссии.
:FIRST_100
0318: set_latest_mission_passed 'FIRST' // 1st
01E3: show_text_1number_styled GXT 'M_PASSS' number 200 time 5000 style 1
// MISSION PASSED!~n~~w~$~1~~n~~w~RESPECT +
0998: add_respect 3 Player.Money($PLAYER_CHAR) += 200
Player.ClearWantedLevel($PLAYER_CHAR)
$NEW_TOTAL_PASSED_MISSIONS += 1
$Marker_Sweet_House = Marker.CreateIconAndSphere(52, 2468.632, -1650.888, 13.4716)
// создаем маркер для второй миссии
0394: play_music 1
return
А теперь напишем стартер для поочередного запуска нескольких миссий.
:STARTER
thread 'STARTER'
$Marker_Sweet_House = Marker.CreateIconAndSphere(16, 2498.228, -1647.457, 13.5479)
// создаем маркер первой миссии
:STARTER_11
wait 250
if
$NEW_TOTAL_PASSED_MISSIONS == 2 // 2 – количество миссий
jf @STARTER_36 // если условие не выполнено то переходим на метку STARTER_36
end_thread // закрываем поток
:STARTER_36 // блок запуска первой миссии
if
Player.Defined($PLAYER_CHAR)
jf @STARTER_352
if
$ONMISSION == 0 // не на миссии
jf @STARTER_352
if
Player.Controllable($PLAYER_CHAR) //игроком можно управлять
jf @STARTER_352
if
$NEW_TOTAL_PASSED_MISSIONS == 0
jf @STARTER_219 // если условие не выполнено
if
00FF: actor $PLAYER_ACTOR sphere 0 in_sphere 2498.228 -1647.457 13.5479 radius 1.2 1.2 2.0 on_foot //проверяем находится ли игрок в данной точке
jf @STARTER_352
Marker.Disable($Marker_Sweet_House) // удаляем маркер
$ONMISSION = 1 // игрок находится на миссии
00BA: show_text_styled GXT 'SWEET_1' time 1000 style 2 // выводим название миссии
fade 0 500
:STARTER_187
if
fading
jf @STARTER_215
wait 0
00BE: text_clear_all // убираем весь текст
03E6: remove_text_box
jump @STARTER_187
:STARTER_215
start_mission FIRST // запускаем первую миссию
:STARTER_219 // блок запуска второй миссии
if
$NEW_TOTAL_PASSED_MISSIONS == 1
jf @STARTER_352
if
00FF: actor $PLAYER_ACTOR sphere 0 in_sphere 2468.632 -1650.888 13.4716 radius 1.2 1.2 2.0 on_foot
jf @STARTER_352
Marker.Disable($Marker_Sweet_House) // удаляем маркер
$ONMISSION = 1
00BA: show_text_styled GXT 'SWEET1B' time 1000 style 2 // Cleaning the Hood
fade 0 500
:STARTER_348
start_mission SECOND // запускаем вторую миссию
:STARTER_352
jump @STARTER_11 //возвращаемся на метку STARTER_11
И на последок, вызывать этот поток (create_thread @STARTER) можно как из главного потока, так и из любой предыдущей миссии.