CLEO_&_DYOM
August 30, 2020

CLEO & DYOM: Делаем нервометр

Если вы проходили оригинальные миссии GTA SA, вы наверняка знаете, что такое нервометр. Но если кто не в курсе, нервометр - это такой датчик приближения в игре.


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

Сегодня попробуем сделать упрощенную версию нервометра для своей миссии. Мы не будем создавать шкалу приближения, а просто будем выводить предупреждение в виде текста, что игрок подошел слишком близко к цели, и если игрок не уйдет из зоны поражения - миссия провалится. А если игрок окажется слишком далеко от цели, то миссия сразу же будет провалена без предупреждения.

Если вы не читали предыдущий урок, обязательно прочитайте его, чтобы понимать принцип взаимодействия DYOM и CLEO.

И так, приступим. Создаем скрипт, и добавляем 3 условия при которых будет работать наш нервометр

{$CLEO}
0000:

:NERVOMETR
wait 0
if and
$ONMISSION == 1 //миссия запущена
$10914 == 1 //слот миссии равен 1
$9903 == 0 //текущая цель равна 0
jf @NERVOMETR

Далее добавляем такое условие:

if
0AE1: 0@ = random_actor_near_point 2469.8926 -1657.8087 13.3443 in_radius 1.0 find_next 0 pass_deads 1
jf @NERVOMETR
wait 500

Данный опкод записывает рандомного актера в точке 2469.8926 -1657.8087 13.3443 с радиусом 1 в переменную 0@. Так же этот опкод работает и как проверка существует ли актер. Если актер существует, то ждем 500 мс и идем дальше по скрипту, если нет - возвращаемся в начало.

Вместо координат 2469.8926 -1657.8087 13.3443 вам нужно вставить координаты актера для которого будет действовать нервометр. Для этого зайдите в игру, встаньте на то место, где стоит нужный актер, сверните игру и зайдите в Sanny Builder. Теперь поставьте курсор туда, куда нужно вставить координаты и нажмите CTRL+SHIFT+C.

Дальше создаем цикл while, который будет повторяться пока текущей целью является цель №1.
Добавляем условие, если актер 0@ не находится около игрока в радиусе 50 единиц, то завершаем миссию, выводим текст "Цель ушла" большими буквами, как при провале миссии, и выходим из цикла с помощью break.
Текст для CLEO скриптов нужно переводить через rus2gxtcoder, либо писать на языке мефисто, иначе у вас в игре вместо нормального текста будет не пойми что.

while $9903 == 0
wait 0
    if
    80F2:   not actor 0@ near_actor $PLAYER_ACTOR radius 50.0 50.0 sphere 0
    then
    045C: abort_mission
    0ACF: show_formatted_styled_text "~r~‰eћ© yҐћa" time 2000 style 1 //"~r~‰eћ© yҐћa" - текст, time - время появления текста, style - стиль текста
    break
    end

Отлично, пол дела сделано. Теперь если цель отдалится от игрока более чем на 50 единиц, то миссия будет завершена с надписью "Цель ушла"

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

Для этого добавляем следующее условие (все так же в цикле): если актер около игрока в радиусе 10 единиц, то выводим текст "Вы слишком близко" на 2 секунды.

    if
    00F2:   actor 0@ near_actor $PLAYER_ACTOR radius 10.0 10.0 sphere 0
    then
    0ACD: show_text_highpriority "‹¨ cžœ¥ko¯ —žœŸko" time 2000 

Ждем 4 секунды и еще раз проверяем находится ли актер 0@ около игрока в радиусе 10 единиц. Это нужно для того, чтобы после появления предупреждения у игрока было немного времени и он мог бы отойти от цели на определенное расстояние, чтобы избежать провала миссии. Если игрок все еще остался в этом радиусе, то завершаем миссию, выводим текст "Вас заметили" и прерываем цикл с помощью break. Не забываем закрыть все открытые условия с помощью end

    wait 4000
        if
        00F2:   actor 0@ near_actor $PLAYER_ACTOR radius 10.0 10.0 sphere 0
        then
        045C: abort_mission
        0ACF: show_formatted_styled_text "~r~‹Ё џaЇe¤e®Ё" time 2000 style 1
        break
        end
    end  

Пишем последние две строчки кода. Закрываем открытый ранее цикл while и переходим в начало скрипта.

end 
jump @NERVOMETR

Вот, что у нас получилось в итоге:

{$CLEO}
0000:

:NERVOMETR
wait 0
if and
$ONMISSION == 1
$10914 == 1
$9903 == 0
jf @NERVOMETR
wait 500
if
0AE1: 0@ = random_actor_near_point 2469.8926 -1657.8087 13.3443 in_radius 1.0 find_next 0 pass_deads 1
jf @NERVOMETR
wait 500
while $9903 == 0
wait 0
    if
    80F2:   not actor 0@ near_actor $PLAYER_ACTOR radius 50.0 50.0 sphere 0
    then
    045C: abort_mission
    0ACF: show_formatted_styled_text "~r~‰eћ© yҐћa" time 2000 style 1
    break
    end
    if
    00F2:   actor 0@ near_actor $PLAYER_ACTOR radius 10.0 10.0 sphere 0
    then
    0ACD: show_text_highpriority "‹Ё cћњҐkoЇ —ћњџko" time 2000
    wait 4000
        if
        00F2:   actor 0@ near_actor $PLAYER_ACTOR radius 10.0 10.0 sphere 0
        then
        045C: abort_mission
        0ACF: show_formatted_styled_text "~r~‹Ё џaЇe¤e®Ё" time 2000 style 1
        break
        end
    end
end 
jump @NERVOMETR


Заходим в игру и смотрим результат. Наш скрипт прекрасно работает.