Пропуск роликов
Материал из GTAModding.ru
В стандартных миссиях Rockstar North большинство роликов можно пропустить, нажав клавишу Shift. В скриптах со времён San Andreas это реализуется не проверкой на нажатие Shift, а встроенными в игру опкодами/функциями.
Пропуск роликов в San Andreas
В SA пропуск роликов реализуется всего лишь парой опкодов:
0707: start_scene_skip_to @End_Scene 0701: end_scene_skip
Первый включает режим пропуска ролика и назначает метку, на которую прыгает игра при нажатии клавиши. Второй его выключает. Пример:
0707: start_scene_skip_to @End_Scene
{Ролик...}
:End_Scene
0701: end_scene_skip
При этом нужно учитывать, что игра при нажатии клавиши прыгнет на эту метку, пропуская все опкоды (как jump) и после ролика (после опкода end_scene_skip) нужно поставить (PutAt и Angle) актёров и машины так, как если бы они стояли после ролика, также если внутри ролика машины взрываются, то после ролика их нужно взорвать опкодом 08CB, и т. д. . Более того, нельзя создавать внутри ролика чего бы то нибыло, что будет использоваться вне ролика. То есть если вы создали актёра внутри ролика, а после ролика дали ему команду зайти в машину, а игрок пропустил ролик, то актёр не создатся и скрипт даст команду несуществующему актёру зайти в машину. Итог: игра зависла. Решение: создать актёра до начала ролика (вне пространства между опкодами start_scene_skip_to и end_scene_skip). И ещё: обычно ролики начинаются и заканчиваются фейдами (опкод fade).
Возможные ошибки
Пример ошибки и её решения
Неправильно:
0707: start_scene_skip_to @End_Scene
{актёр создаётся нутри ролика}
1@ = Actor.Create(Special, #SPECIAL02, -2044.6775, 159.0651, 28.8359)
{Ролик...}
:End_Scene
0701: end_scene_skip
0631: put_actor 1@ in_group $PLAYER_GROUP {<< Ира заиснет тут}
Правильно:
{актёр создаётся не ролика}
1@ = Actor.Create(Special, #SPECIAL02, -2044.6775, 159.0651, 28.8359)
0707: start_scene_skip_to @End_Scene
{Ролик...}
:End_Scene
0701: end_scene_skip
0631: put_actor 1@ in_group $PLAYER_GROUP
Пример мини-ролика
thread 'rolik'
{$CLEO}
var
$Player_Char: Player
$Player_Actor: Actor
end
while true
if and
$Player_Char.Defined
$ONMISSION == false
00FE: actor $PLAYER_ACTOR sphere 1 in_sphere 2476.9993 -1679.3445 13.3376 radius 2.0 2.0 3.0
then
fade 0 500
while fading
wait 0
end
$Player_Char.CanMove = false
#MAVERICK.Load
#MRWHOOP.Load
#WMOICE.Load
:load
wait 0
if and
#MAVERICK.Available
#MRWHOOP.Available
#WMOICE.Available
jf @load
042B: clear_peds_from_cube_cornerA 2500.511 -1663.5464 11.0 cornerB 2420.6042 -1653.6869 15.0
03BA: clear_cars_from_cube_cornerA 2500.511 -1663.5464 11.0 cornerB 2420.6042 -1653.6869 15.0
1@ = Car.Create(#MRWHOOP, 2412.1978, -1655.386, 12.6141)
Car.Angle(1@) = 270.0
Car.SetSpeedInstantly(1@, 20.0)
Car.SetMaxSpeed(1@, 30.0)
0423: set_car 1@ improved_handling_to 2.0 // (float)
0397: enable_car 1@ siren 1
0129: 2@ = create_actor_pedtype 23 model #WMOICE in_car 1@ driverseat
01C8: 3@ = create_actor_pedtype 23 model #WMOICE in_car 1@ passenger_seat 0
4@ = Actor.Create(23, #WMOICE, 0.0, 0.0, 0.0)
0464: put_actor 4@ into_turret_on_car 1@ at_car_offset 0.7 -0.4 0.23 position 3 shooting_angle_limit 0.0 with_weapon 0
#MAVERICK.Destroy
#MRWHOOP.Destroy
#WMOICE.Destroy
0707: start_scene_skip_to @end_scene1
0704: car 1@ drive_to 2490.0583 -1656.3477 13.5915
Camera.SetPosition(2473.269, -1672.4255, 17.2742, 0.0,0.0,0.0)
Camera.OnVehicle(1@, 15, 2)
0A48: enable_menu_access_in_widescreen_mode 1
02A3: enable_widescreen 1
fade 1 1000
while 81AF: not car 1@ sphere 1 in_sphere 2490.0583 -1656.3477 13.5915 radius 4.0 4.0 1.5
wait 0
end
wait 1000
:end_scene1
0701: end_scene_skip
fade 0 500 ms
while fading
wait 0
end
0397: enable_car 1@ siren 0
02A3: enable_widescreen 0
Car.PutAt(1@, 2490.0583, -1656.3477, 13.5915)// Что-бы при пропуске
Car.Angle(1@) = 270.0 // машина стояла где надо
Camera.Restore_WithJumpCut
// Можно заменить на RemoveReferences
0AB1: call_scm_func @CarChangeRef 2 params handle 1@ ref 1 {random}
0AB1: call_scm_func @ActorChangeRef 2 params handle 2@ ref 1 {random}
0AB1: call_scm_func @ActorChangeRef 2 params handle 3@ ref 1 {random}
0AB1: call_scm_func @ActorChangeRef 2 params handle 4@ ref 1 {random}
$Player_Char.CanMove = true
fade 1 500
while 00FE: actor $PLAYER_ACTOR sphere 0 in_sphere 2476.9993 -1679.3445 13.3376 radius 2.0 2.0 3.0
wait 0
end
end
wait 0
end
// Это понимать необязательно, к ролику не относится.
// Это аналогично RemoveReferences и AddReferences.
:ActorChangeRef
0A96: 2@ = actor 0@ struct
2@+=0x484
0A8C: write_memory 2@ size 1 value 1@ virtual_protect 0
0AB2: ret 0
:CarChangeRef
0A97: 2@ = car 0@ struct
2@+=0x4A4
0A8C: write_memory 2@ size 1 value 1@ virtual_protect 0
0AB2: ret 0