Универсальный солдат (GTA SA) — различия между версиями
Материал из GTAModding.ru
Seemann (обсуждение | вклад) |
Sergeanur (обсуждение | вклад) |
||
Строка 215: | Строка 215: | ||
</source> | </source> | ||
Автор: '''Axel218''' | Автор: '''Axel218''' | ||
− | [[Категория:Скрипты]] | + | [[Категория:Скрипты]][[Категория:GTA_SA]] |
Версия 15:59, 3 августа 2011
Данный скрипт добавляет в игру "универсальных солдат" - это секретный военный проект правительства США :) Они появляются недалеко от игрока и ведут по нему огонь, если у того 6 звёзд розыска. Но это в игре. А на деле - это небольшой пример развития искуственного интеллекта актёров скриптом. Конечно, это не идеально, но может послужить хорошим примером управления поведением актёров для скриптеров.
Особенности скрипта:
- Солдат может применять в разных ситуациях различные виды оружия
- Может уворачиваться от выстрелов (стрейфиться)
- Периодически забрасывает игрока гранатами :)
Код:
... create_thread @Universal_Soldier_Thread ... :Universal_Soldier_Thread // Объявляем переменные для компилятора var 7@ : Integer // Переменная для вычисления кувырка 30@ : Integer // Переменная для контроля таймера end :Universal_Soldier wait 0 ms // Проверяем уровень розыска игрока - равен ли он 6-ти звёздам? 01C0: 6@ = player $PLAYER_CHAR wanted_level 6@ == 6 jf @Universal_Soldier // Если уровень не равен 6-ти - проверяем ещё // Получаем Handle случайного пешехода на улице 02DD: 1@ = get_random_ped_in_zone 'SAN_AND' with_pedtype_civilian 1 gang 0 criminal/prostitute 1 // Если Handle равен -1, значит он не получен - возможно, поблизости нет пешеходов 1@ <> -1 jf @Universal_Soldier // Пробуем ещё раз сначала // Handle получен. Сохраняем координаты пешехода в переменные 00A0: store_actor 1@ position_to 2@ 3@ 4@ // Удаляем пешехода. Он был нужен нам только для получения точных координат 009B: destroy_actor 1@ 01C2: remove_references_to_actor 1@ // Загружаем необходимые модели 0247: load_model #SWAT // Модель SWAT'овца - "забугорный спецназ" 0247: load_model #M4 // Модель M4 0247: load_model #SHOTGSPA // Модель боевого дробовика 0247: load_model #KNIFECUR // Модель ножа 0247: load_model #HEATSEEK // Модель ракетницы 0247: load_model #GRENADE // Модель гранаты 038B: load_requested_models :Universal_Soldier_Check1 wait 0 ms // Проверяем - загрузились ли модели? if and 0248: model #SWAT available 0248: model #M4 available 0248: model #SHOTGSPA available 0248: model #KNIFECUR available 0248: model #HEATSEEK available 0248: model #GRENADE available jf @Universal_Soldier_Check1 // Если не загрузились - проверяем ещё // Создаём универсального солдата на координатах, полученых ранее 009A: 1@ = create_actor_pedtype 23 model #SWAT at 2@ 3@ 4@ // Устанавливаем ему много очков здоровья 0223: set_actor 1@ health_to 1500 // Столько же много брони 035F: actor 1@ armour += 1500 // Создаёи над ним маркер, чтобы его было видно на радаре. Так же это создаёт над ним // стрелку. По умолчанию и маркер, и стрелка имеют красный цвет 0187: 5@ = create_marker_above_actor 1@ // Устанавливаем солдату иммунитет к выстрелам в голову (чтобы её не снесло при попадании) 0446: set_actor 1@ immune_to_headshots 0 // Даём ему оружие с бесконечным боезапасом 01B2: give_actor 1@ weapon 31 ammo -1 // M4 01B2: give_actor 1@ weapon 27 ammo -1 // Боевой дробовик 01B2: give_actor 1@ weapon 36 ammo -1 // Ракетница 01B2: give_actor 1@ weapon 4 ammo -1 // Нож // После смерти солдата всё его оружие нельзя будет поднять (оно не появится) 087E: set_actor 1@ weapon_droppable 0 // Устанавливаем точность стрельбы 02E2: set_actor 1@ weapon_accuracy_to 95 // Уровень владения оружием - Hitman. От уровня зависит скорость стрельбы и передвижение // во время стрельбы 081A: set_actor 1@ weapon_skill_to 2 // Модель поведения актёра. Например, при прицеливании актёр поднимает руки вверх, // отскакивает от проезжающей рядом машины и так далее. // Мы установим нулевой параметр, так как мы сами будем контролировать поведение. 060A: create_decision_maker_type 0 store_to 8@ // decision\allowed\m_.ped files 060B: set_actor 1@ decision_maker_to 8@ // Этот опкод устанавливает отношение актёра к определённому типу пешеходов. // В нашем случае это ненависть (4) к игроку (0) 077A: set_actor 1@ acquaintance 4 to_actors_pedtype 0 // see ped.dat // Заставляем солдата атаковать игрока 07A5: AS_actor 1@ attack_actor $PLAYER_ACTOR -1 ms // Выгружаем ненужные модели из памяти. Модель гранаты остаётся в памяти! 0249: release_model #SWAT 0249: release_model #M4 0249: release_model #SHOTGSPA 0249: release_model #KNIFECUR 0249: release_model #HEATSEEK :Universal_Soldier_AI // Цикл, управляющий поведением солдата wait 0 ms // Проверяем, если игрока не существует (его убили или т.п.) или если солдата убили if or 8256: not player $PLAYER_CHAR defined 0118: actor 1@ dead then // то // Удаляем маркер над солдатом 0164: disable_marker 5@ // Удаляем информацию солдата из памяти игры 01C2: remove_references_to_actor 1@ // Удаляем модель поведения солдата 065C: release_decision_maker 8@ // Выгружаем модель гранаты 0249: release_model #GRENADE // Ждём 10 секунд wait 10000 ms // Идём в самое начало скрипта jump @Universal_Soldier end // Если игрок водит наземный или воздушный транспорт if or 00DF: actor $PLAYER_ACTOR driving 04AB: actor $PLAYER_ACTOR driving_plane then // то // Меняем активное оружие солдата на ракетницу и заставляем его поджарить игрока :) 01B9: set_actor 1@ armed_weapon_to 36 07A5: AS_actor 1@ attack_actor $PLAYER_ACTOR -1 ms else // иначе // Записываем координаты солдата в переменные 00A0: store_actor 1@ position_to 2@ 3@ 4@ // Записываем координаты игрока в переменные 00A0: store_actor $PLAYER_ACTOR position_to 6@ 7@ 8@ // Получаем расстояние между солдатом и игроком 050A: 9@ = distance_between_XYZ 2@ 3@ 4@ and_XYZ 6@ 7@ 8@ // Если игрок находится более чем в 50-ти метрах от солдата if 9@ >= 20.0 then // то // Меняем активное оружие солдата на M4 01B9: set_actor 1@ armed_weapon_to 31 else // иначе // Если игрок на средней дистанции от солдата if and 9@ < 18.0 9@ > 12.0 then // Проверим, может гранатку бросим? ;) gosub @Universal_Soldier_Grenade_Check end // Если игрок находится близко к солдату if 9@ < 2.5 then // то // Меняем активное оружие солдата на нож 01B9: set_actor 1@ armed_weapon_to 4 else // иначе // На средних дистанциях // Меняем активное оружие солдата на боевой дробовик 01B9: set_actor 1@ armed_weapon_to 27 end end end if and // если 0457: player $PLAYER_CHAR aiming_at_actor 1@ // Игрок целится в солдата 874F: not actor $PLAYER_ACTOR ped_event == 12 // Игрок не перезаряжается 82D8: not actor 1@ current_weapon == 4 // У солдата нет в руках ножа 02A0: actor 1@ stopped // Солдат стоит на месте then // то // Смысл следующей операции в том, что если игрок целится в солдата - тот делает // кувырок в случайную сторону, а затем бычтрый выстрел. Получается весьма эффектно. // Генерируем случайное число (0/1) 7@ = Random(-1, 1) // Делаем на мнгновение солдата миролюбивым существом, чтобы он не натворил глупостей 077C: clear_actor 1@ default_action 4 to_all_actor_types // Получаем угол игрока и отнимаем от него 180, затем устанавливаем полученный угол // солдату, чтобы тот был повёрнут лицом к игроку 0172: 9@ = actor $PLAYER_ACTOR Z_angle 000F: 9@ -= 180.0 0173: set_actor 1@ Z_angle_to 9@ // Заставляем солдата сделать кувырок в случайную сторону (7@). 0 - влево, 1 - вправо 06E3: AS_actor 1@ roll_sideways 7@ // Ждём, пока солдат кувыркнётся wait 1200 ms // Делаем солдата вновь агрессивно настроеным к игроку :) 077A: set_actor 1@ default_action 4 to_actors_pedtype 0 // Заставляем солдата атаковать игрока 07A5: AS_actor 1@ attack_actor $PLAYER_ACTOR -1 ms // Ждём пол-секунды, чтобы солдат не кувыркался со стороны в сторону как угорелый wait 500 end // Идём в начало цикла jump @Universal_Soldier_AI :Universal_Soldier_Grenade_Check // Eсли таймер достиг нужного нам значения if 002D: 32@ >= 30@ then // то // Даём солдату одну гранату 01B2: give_actor 1@ weapon 16 ammo 1 // Поднимаем его. Сидя он не сможет кинуть гранату 04EB: AS_actor 1@ crouch 0 // Заставляем кинуть гранату 07A5: AS_actor 1@ attack_actor $PLAYER_ACTOR -1 ms // Ждём, пока солдат не бросит гранату while 02D8: actor 1@ current_weapon == 16 wait 0 ms end // Задаём случайное значение между 20-ю и 40-а секундами, чтобы сверять таймер 30@ = Random(20000, 40000) // Обнуляем таймер 32@ = 0 end return
Автор: Axel218