# 00052. Пример полноценной миссии \&quot;Взрывчатка\&quot;

Пример полноценной миссии "Взрывчатка"|Всем привет! Давно не было уроков по скриптингу Санни Билдер, так как все известные моменты мы рассмотрели, я решил писать уже не уроки, а примеры полноценных миссий. Сегодня мы будем "хардкорить" в написании миссии, которую я назвал "Взрывчатка".|wmysterio|wmysterio||||Суть миссии в том, что к CJ обращается Свит и сообщает что его машину заминировали. Допустим, что Свит насколько привязан к этой тачки, что решает разминировать её. Нам необходимо привести сапёра, чтобы тот взялся за это нелёгкое дело. Как оказалось, что для этого дела понадобится неординарное решение - чтобы успешно разминировать её, нужно держать скорость автомобиля примерно на скорости 100 км/час. В противном случаи машину не разминировать. Думаю идея понятна.

Хочу добавить, что данная статья не для новичков, а для тех, что более-менее уже понимает чужой код и может дополнить его.

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

```
{$CLEO .cm}
thread 'BOMB'

gosub @BOMB_RUN
if
wasted_or_busted
jf @BOMB_FINISH
gosub @BOMB_FAILED

:BOMB_FINISH
$ONMISSION = 0
mission_cleanup
end_thread

:BOMB_RUN
increment_mission_attempts
$ONMISSION = 1
wait 1000
fade 1 1000

// Код миссии

gosub @BOMB_END
0394: play_music 1
01E3: show_text_1number_styled GXT 'M_PASS' number 5000 time 5000 style 1
Player.Money(0) += 5000
return

:BOMB_FAILED
gosub @BOMB_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 
return

:BOMB_END
return
```

А необходимую конструкцию миссии я привёл к такому виду:

```
{$CLEO .cm}
thread 'BOMB'

gosub @BOMB_RUN
if
wasted_or_busted
jf @BOMB_FINISH
gosub @BOMB_FAILED

:BOMB_FINISH
$ONMISSION = 0
mission_cleanup
end_thread

:BOMB_RUN
increment_mission_attempts
$ONMISSION = 1
wait 1000
fade 1 1000

// Код миссии

gosub @BOMB_END
0394: play_music 1
01E3: show_text_1number_styled GXT 'M_PASS' number 5000 time 5000 style 1
Player.Money(0) += 5000
return

:BOMB_FAILED
gosub @BOMB_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 
return

:BOMB_END
return
```

Приступаем к написанию последовательности скрипта. Прежде всего очищаем местность от всего хлама и рендерим местность для камеры, убрав трафик пешеходов и автомобилей. Создаём неподалёку тачку Свита и садовим его в транспорт. Перемещаем СЖ к нему:

```
03DE: set_pedestrians_density_multiplier_to 0.0
01EB: set_traffic_density_multiplier_to 0.0
00C0: set_current_time 4 0
0395: clear_area 0 at 2514.7581 -1670.5378 12.5749 radius 3.0
04E4: refresh_game_renderer_at 2514.7581 -1670.5378
023C: load_special_actor 'SWEET' as 1
model.Load(#GREENWOO)
038B: load_requested_models

repeat
wait 0
until 023D: special_actor 1 loaded

0@ = Car.Create(#GREENWOO, 2517.1985, -1665.6057, 12.7179)
Car.Angle(0@) = 96.3102
0229: set_car 0@ primary_color_to 0 secondary_color_to 1
01C8: 1@ = create_actor_pedtype 23 model #SPECIAL01 in_car 0@ passenger_seat 0
077A: set_actor 1@ acquaintance 0 to_actors_pedtype 0
0296: unload_special_actor 1
Model.Destroy(#GREENWOO)
Actor.PutAt($PLAYER_ACTOR, 2516.5964, -1663.8156, 12.8959)
Actor.Angle($PLAYER_ACTOR) = 203.1531
```

Ставим нашим героям иммунитеты и устанавливаем камеру для видеоролика. Дальше пишем код пропуска этого видеоролика:

```
Car.SetImmunities(0@, 1, 1, 1, 1, 1)
Actor.SetImmunities(1@, 1, 1, 1, 1, 1)
015F: set_camera_position 2513.7539 -1666.6892 14.5696 rotation 0.0 0.0 0.0
0160: set_camera_point_at 2516.5203 -1664.2532 13.8745 switchstyle 2
wait 1000
00BE: text_clear_all
03E6: remove_text_box
0826: enable_hud 0
0581: enable_radar 0
02A3: enable_widescreen 1
05BF: AS_actor 1@ look_at_actor $PLAYER_ACTOR 20000 ms
05BF: AS_actor $PLAYER_ACTOR look_at_actor 1@ 20000 ms
fade 1 1000
0707: start_scene_skip_to @BOMB_END_SCENE_1
wait 1000
// Диалог

:BOMB_END_SCENE_1
fade 0 1000
0701: end_scene_skip
wait 1000
```

Используется анимация PED, актёры смотрят друг на друга и шевелят губами. По окончанию диалога, как и при нажатии клавиши Пробел\` идёт затемнение экрана, СЖ перемещается в транспорт, за руль. Камера сбрасывается в обычный режим.

Далее, по-сюжету, мы должны приехать к сапёру, и подобрать его. Организуем простой цикл, в котором нельзя ехать больше 100 км/час. В нём же не допустим смерти тачки и Свита:

```
Player.CanMove(0, 1)
Actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
Car.SetImmunities(0@, 0, 0, 0, 0, 0)
Actor.SetImmunities(1@, 0, 0, 0, 0, 0)
2@ = 99
5@ = 0

while 5@ == 0
wait 0
 if or
 0741: actor $PLAYER_ACTOR busted
 Actor.Dead($PLAYER_ACTOR)
 then
 5@ = -3
 continue
 end 
 if or
 02BF: car 0@ sunk
 car.Wrecked(0@)
 then
 5@ = -1
 continue
 end 
 if
 Actor.Dead(1@)
 then
 5@ = -2
 continue
 end 
 02E3: 10@ = car 0@ speed
 10@ *= 4.2
 if
 10@ > 99.0
 then
 then
 5@ = -4
 continue
 end
 if and
 not 2@ == 1
 Actor.InCar($PLAYER_ACTOR, 0@)
 Actor.InCar(1@, 0@)
 then
 Marker.Disable(6@)
 Marker.Disable(7@)
 018A: 3@ = create_checkpoint_at 2336.2732 -1679.54 12.2143
 03BC: 4@ = create_sphere_at 2336.2732 -1679.54 12.2143 radius 2.0
 0AD1: show_formatted_text_highpriority "O¦£pa¢ž¬¦ec© k ~y~ca£epy~w~!" time 3000
 2@ = 1
 continue
 end 
 if or
 not Actor.InCar($PLAYER_ACTOR, 0@)
 not Actor.InCar(1@, 0@)
 then
 if
 2@ == 1
 then
 Marker.Disable(3@)
 03BD: destroy_sphere 4@
 6@ = Marker.CreateAboveActor(1@)
 7@ = Marker.CreateAboveCar(0@)
 0AD1: show_formatted_text_highpriority "Cašœ¦ec© ¢ ~b~¯a¥œ®y~w~!" time 3000
 2@ = 2
 continue
 end
 end 
 if AND
 2@ == 1
 00EC: actor $PLAYER_ACTOR sphere 0 near_point 2336.2732 -1679.54 radius 2.0 2.0
 then
 5@ = 1
 end
end

Marker.Disable(3@)
03BD: destroy_sphere 4@
Marker.Disable(6@)
Marker.Disable(7@)
if
5@ == -1
then
jump @BOMB_FINISH_SWEET_DEAD
end
if
5@ == -2
then
jump @BOMB_FINISH_CAR_DEAD
end
if
5@ == -3
then
jump @BOMB_FAILED
end
if
5@ == -4
then
jump @BOMB_SPEED
end

Player.CanMove(0, 0)
Actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
Car.SetImmunities(0@, 1, 1, 1, 1, 1)
Actor.SetImmunities(1@, 1, 1, 1, 1, 1)
fade 0 1000
wait 1000
// Следующая мини-сцена

{ блоки провала }
:BOMB_FINISH_SWEET_DEAD
gosub @BOMB_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1
0AD1: show_formatted_text_highpriority "Cўњ¦ yЇep!" time 3000
return

:BOMB_FINISH_CAR_DEAD
gosub @BOMB_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1
0AD1: show_formatted_text_highpriority "–aҐњ®a y®њ¤¦o›e®a!" time 3000
return

:BOMB_SPEED
gosub @BOMB_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1
0AD1: show_formatted_text_highpriority "‹Ё ЈpeўЁcњћњ ckopoc¦©!" time 3000
return
```

Дальше нужно организовать цикл, в котором будут условия обезвреживания бомбы. Как сказал в диалогах сапёр, нужно проверить на открытия двери, чтобы взорвать транспорт. Это можно осуществить путём проверки к-ва занятых мест. Если такое число превышает 0, то это значит, что кто-то покинул траспорт, тем самым открыв дверь. Цикл будел разделён на три этапа:

* Когда игрок не набрал 100 км/час
* Когда уже набрал такую скорость, включается таймер
* Ожидание времени. Для полного хардкора включим трафик, чтобы игрок попотел :)

```
5@ = 0
3@ = 1 // etap
02E3: $CAR_SPEED = car 0@ speed
008C: $CAR_SPEED = float $CAR_SPEED to_integer
04F7: status_text $CAR_SPEED type 0 line 1 GXT 'DEF0' // global_variable // Score
$TIMER = 60000

while 5@ == 0
wait 0
 if or
 02BF: car 0@ sunk
 car.Wrecked(0@)
 then
 5@ = -1
 continue
 end
 if
 Actor.Dead(1@)
 then
 5@ = -2
 continue
 end 
 if
 Actor.Dead(11@)
 then
 5@ = -3
 continue
 end 
 
 01E9: 10@ = car 0@ num_passengers
 046C: 12@ = car 0@ driver

 if OR
 87D6: not 12@ == $PLAYER_ACTOR // @ == $ (int)
 not 10@ == 2
 then
 020B: explode_car 0@
 continue
 end
 
 02E3: $CAR_SPEED = car 0@ speed
 $CAR_SPEED *= 3.2 
 008C: $CAR_SPEED = float $CAR_SPEED to_integer
 
 if AND
 3@ == 1
 $CAR_SPEED > 100
 then
 3@ = 2
 continue
 end
 
 if
 3@ == 2
 then 
 03C3: set_timer_to $TIMER type 1 GXT 'DEF1' // global_variable // Time
 3@ = 3
 end
 
 if AND
 3@ == 3
 Actor.InCar($PLAYER_ACTOR, 0@)
 100 > $CAR_SPEED
 then
 020B: explode_car 0@
 continue
 end
 
 if AND
 3@ == 3
 Actor.InCar($PLAYER_ACTOR, 0@)
 $TIMER == 0
 then
 5@ = 1
 end 
end

014F: stop_timer $TIMER
0151: remove_status_text $CAR_SPEED
if
5@ == -1
then
jump @BOMB_FINISH_CAR_DEAD
end
if
5@ == -2
then
jump @BOMB_FINISH_SWEET_DEAD
end
if
5@ == -3
then
jump @BOMB_FINISH_SAP_DEAD
end
```

Нам осталось только написать код, который выгружает из памяти все ненужные объекты:

```
:BOMB_END
if
056D: actor 1@ defined
then
Actor.RemoveReferences(1@)
Actor.DestroyInstantly(1@)
end
if
056D: actor 11@ defined
then
Actor.RemoveReferences(11@)
Actor.DestroyInstantly(11@)
end
if
056E: car 0@ defined
then
Car.RemoveReferences(0@)
 if
 not Actor.InCar($PLAYER_ACTOR, 0@)
 then
 Car.Destroy(0@)
 end
end
return
```

Результат нашей миссии:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/79472534.png)\
![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/12857216.png)<br>

Вам задание: Дописать миссию до логического завершения - нужно приехать к дому Свита. На этом урок окончен. С Вами был wmysterio, всего доброго!

P.S Исходники вы можете скачать [здесь](https://github.com/wmysterio/scm-scripting-lessons/blob/main/data_base/sa/BOMB.rar). Улучшайте миссию на свой вкус.|1238|1|0|12857216`png`800`480`400`240``\|79472534`png`800`480`400`240\`\`||primer\_polnocennoj\_missii\_vzryvchatka|1504598907


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lessons.sannybuilder.com/00100/00600/00052.-primer-polnocennoi-missii-and-quot-vzryvchatka-and-quot.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
