Уроки моддинга
Основной раздел
Search
K
Links

00052. Пример полноценной миссии "Взрывчатка"

Пример полноценной миссии "Взрывчатка"|Всем привет! Давно не было уроков по скриптингу Санни Билдер, так как все известные моменты мы рассмотрели, я решил писать уже не уроки, а примеры полноценных миссий. Сегодня мы будем "хардкорить" в написании миссии, которую я назвал "Взрывчатка".|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
Результат нашей миссии:
Вам задание: Дописать миссию до логического завершения - нужно приехать к дому Свита. На этом урок окончен. С Вами был wmysterio, всего доброго!
P.S Исходники вы можете скачать здесь. Улучшайте миссию на свой вкус.|1238|1|0|12857216png800480400240``\|79472534png800480400240``||primer_polnocennoj_missii_vzryvchatka|1504598907