# Интересное в скриптинге

Всем привет! С Вами wmysterio, и это очередной и долгожданный урок по скриптингу GTA San Andreas. Как уже говорилось на форуме, я планирую сделать глобальную модификацию мейна, и я прошел игру заново, чтобы установить сюжет. Во время прохождения я захотел узнать как делаются некоторые вещи, и заглянул в оригинальный мейн.

Что же я нашел интересненького? Очень много любопытного. Например, узнал как сделать маркер в ввиде капельки:

![title](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/07756265.jpg)

У меня спрашивали очень много людей, и я наконец нашел ответ. Как оказалось, за это отвечает опкод:

```
075B: zoom_radar 0
```

Меня это слегка удивило, так как я, по-локиге, искал опкоды, связанные с маркерами, но как оказалось за маркеры ввиде капель отвечает радар. Чтобы достичь такого эффекта, нужно установить масштаб радара в число, отличное от нуля, например:

```
075B: zoom_radar 1
```

Удивительно, но это работает!

Cледующим шагом стало исследование исскуственно интелекта, вернее как достишь хорошего уровня интелекта за минимум строк кода. Для примера, возьмём [урок](https://github.com/wmysterio/scm-scripting-lessons/blob/main/publ/uroki_skriptinga/gta_sa/posledovatelnost_v_animacii/34-1-0-156/README.md) и [этот](https://github.com/wmysterio/scm-scripting-lessons/blob/main/publ/uroki_skriptinga/gta_sa/puti_peshekhodov/34-1-0-178/README.md) урок. В них речь шла о том, чтобы проигрывать анимацию последовательно, однако AS-паки используются не только для анимации, но и для других действий (я об этом знал, но в уроках не упомянул чего-то).

Что-бы заставить актёра патрулировать возле дома CJ, достаточно этого кода:

```
{$CLEO}

0615: define_AS_pack_begin 2@
05D3: AS_actor -1 goto_point 2500.376 -1685.9846 13.472 mode 4 time -1 ms
05D3: AS_actor -1 goto_point 2485.1157 -1686.6415 13.5085 mode 4 time -1 ms 
0643: set_AS_pack 2@ loop 1
0616: define_AS_pack_end 2@

model.Load(#WMYDRUG)
038B: load_requested_models

0@ = Actor.Create(Mission2, #WMYDRUG, 2485.1157, -1686.6415, 12.5085)9.4457
0618: assign_actor 0@ to_AS_pack 2@
061B: remove_references_to_AS_pack 2@

Model.Destroy(#WMYDRUG)

0A93: end_custom_thread
```

Обратите внимание на опкод `0643`. Он заставляет проигрывать содержимое экшн-пака с начала по окончанию действия. Здесь важно то, что этот опкод должен находится между началом и кончом AS-пака. В противном случае повторения не произойдёт. Такой подход отлично подойдёт для мейна, где можно с помощью глобальных переменных устанавливать разные маршруты движения, имея всего 4 строки кода. Это очень важно для оптимизации кода, и мы заставляем игру больше рабоать на нас, а не на оборот.

Ещё важный момент: это модели поведения ([урок](https://github.com/wmysterio/scm-scripting-lessons/blob/main/publ/uroki_skriptinga/gta_sa/modeli_povedenija_aktjorov/34-1-0-142/README.md)). От него зависит как будет реагировать актёр на внешние события. Если нужно сделать актёра дружелюбным, то отлично подойдёт такой скрипт:

```
{$CLEO}

model.Load(#WMYDRUG)
Model.Load(#TEC9)
038B: load_requested_models

07E5: copy_decision_maker 65542 to 3@

0@ = Actor.Create(Mission2, #WMYDRUG, 2485.1157, -1686.6415, 12.5085)
Actor.GiveWeaponAndAmmo(0@, 32, 5000)
060B: set_actor 0@ decision_maker_to 3@
0631: put_actor 0@ in_group $PLAYER_GROUP

Model.Destroy(#WMYDRUG)
Model.Destroy(#TEC9)

0A93: end_custom_thread
```

Эта модель поведения мне очень понравилась, так как актёр никак не реагируте на внешние факторы со стороны игрока. Одним словом Ван не нужно больше зрботиться о том, что ваш спутник вдруг начнёт у Вас стрелять или убегать куда-то от Вас.

![title](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/08492964.jpg)

Ещё одна новинка для меня и, надеюсь, для Вас - это как заставить актёра стрелять чаще и точнее. Я расскопал один опкод, который устанавливает частоту стрельбы с оружия:

```
07DD: set_actor 0@ attack_rate 50
```

Число 50 как раз таки и отвечает за частоту стрельбы. Насколько я понял, это значение указывается в процентах, но если поставить -1 или 100, то достигается максимум. Следущий скрипт сделает актёра машиной для убиства:

```
{$CLEO}

model.Load(#WMYDRUG)
Model.Load(#TEC9)
038B: load_requested_models

0@ = Actor.Create(Mission2, #WMYDRUG, 2485.1157, -1686.6415, 12.5085)
Actor.GiveWeaponAndAmmo(0@, 32, 5000)

02E2: set_actor 0@ weapon_accuracy_to -1
07DD: set_actor 0@ attack_rate -1
05E2: AS_actor 0@ kill_actor $PLAYER_ACTOR

Model.Destroy(#WMYDRUG)
Model.Destroy(#TEC9)

0A93: end_custom_thread
```

Если Вы начали играть в близи от дома CJ, то думаю вы ощутите как теперь стреляет этот дружок.

Далее рассмотрим ещё некоторые поведения актёров. Опкод:

```
0588: disable_actor 0@ validate_position 0
```

Заставляет актёра атаковать врага на месте. Полезно, когда стрелка нужно разместить где-то на крыше и не нужно чтобы он пытался с неё спрыгнуть. Актёр начинает атаку, когда игрок находится в его поле видимости.

Опкод:

```
0816: set_actor 0@ dont_chase_victim 1
```

Заставляет актёра не бегать за жетрвой а стрелять только когда она находится в радиусе действия его оружия. В отличии от предыдущего опкода, актёр может передвигаться по его усмотрению. Используя эти скрипты, можем сделать скрипт охранника, который будет атаковать CJ при обнаружении. Для этого в место опкода `07E5` используем более так сказать "зловещий" опкод `060A`, а также установим отношение актёра к игроку на ненависть. Вот что у меня получилось:

```
{$CLEO}

0615: define_AS_pack_begin 2@
05D3: AS_actor -1 goto_point 2500.376 -1685.9846 13.472 mode 4 time -1 ms
05C9: AS_actor -1 on_guard 3000 ms 
05D3: AS_actor -1 goto_point 2485.1157 -1686.6415 13.5085 mode 4 time -1 ms 
05C9: AS_actor -1 on_guard 3000 ms 
0643: set_AS_pack 2@ loop 1
0616: define_AS_pack_end 2@

060A: create_decision_maker_type 4 store_to 3@

model.Load(#WMYDRUG)
Model.Load(#TEC9)
038B: load_requested_models

0@ = Actor.Create(Mission2, #WMYDRUG, 2485.1157, -1686.6415, 12.5085)
Actor.Health(0@) = 1000
Actor.GiveWeaponAndAmmo(0@, 32, 5000)
077A: set_actor 0@ acquaintance 4 to_actors_pedtype 0 // see ped.dat
0350: set_actor 0@ maintain_position_when_attacked 1 
02E2: set_actor 0@ weapon_accuracy_to -1
07DD: set_actor 0@ attack_rate -1
0618: assign_actor 0@ to_AS_pack 2@
061B: remove_references_to_AS_pack 2@
060B: set_actor 0@ decision_maker_to 3@

Model.Destroy(#WMYDRUG)
Model.Destroy(#TEC9)

0A93: end_custom_thread
```

Результат оправдал себя: противник атакует только когда увидит CJ, при этом соблюдаюстя все нормы, например охранник не видит CJ, если тот спрятался за за забором в двух милиметрах от него.

Следующая "вкусняшка" - опкод `0677`. Он заставляет актёра идти к другому актёру, стать напротив него и общаться. Вот этот код:

```
{$CLEO}

wait 2000
model.Load(#WMYDRUG)
038B: load_requested_models

0@ = Actor.Create(Mission2, #WMYDRUG, 2480.7903, -1675.9349, 12.3378)
Model.Destroy(#WMYDRUG)
0677: AS_actor 0@ chat_with_actor $PLAYER_ACTOR lead_speaker_flag 1 unknown_flag 1 
0677: AS_actor $PLAYER_ACTOR chat_with_actor 0@ lead_speaker_flag 0 unknown_flag 1

0A93: end_custom_thread
```

Стоит расмотреть детали параметров. Значение "lead\_speaker\_flag" указывает кто первым будет жестикулировать руками. Если поставить эти флаги одновременно в 1, то оба персонажа начнут махать руками. Если оба параметра установлены в 0, то ничего не произойдёт. Другой параметр пока неизвестный мне. Мои тесты показали, что если числа будут разными, то актёры подойдут, но никаких действий больше не подадут. Если оба параметра установлены в 0 или 1, то всё работает.

Я буду продолжать исследовать main, и как только найду что-то новенькое и интересное - сразу сообщу Вам. С Вами был wmysterio, пока!


---

# 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/00400/000166.-interesnoe-v-skriptinge.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.
