Универсальный солдат (GTA SA) — различия между версиями

Материал из GTAModding.ru
Перейти к: навигация, поиск
(Новая: Автор: '''Axel218''' Данный скрипт добавляет в игру "универсальных солдат" - это секретный военный проект пр...)
 
Строка 1: Строка 1:
 
Автор: '''Axel218'''
 
Автор: '''Axel218'''
  
Данный скрипт добавляет в игру "универсальных солдат" - это секретный военный проект правительства США :) Они появляются недалеко от игрока и  
+
Данный скрипт добавляет в игру "универсальных солдат" - это секретный военный проект правительства США :) Они появляются недалеко от игрока и ведут по нему огонь, если у того 6 звёзд розыска.
 
+
Но это в игре. А на деле - это небольшой пример развития исскуственного интелекта [[Актёр|актёров]] скриптом. Конечно, это не идеально, но может послужить хорошим примером управления поведением актёров для скриптеров.
ведут по нему огонь, если у того 6 звёзд розыска.
+
Но это в игре. А на деле - это небольшой пример развития исскуственного интелекта [[Актёр|актёров]] скриптом. Конечно, это не идеально, но  
+
 
+
может послужить хорошим примером управления поведением актёров для скриптеров.
+
  
 
Особенности скрипта:
 
Особенности скрипта:
Строка 12: Строка 8:
 
* Может уворачиваться от выстрелов (стрейфиться)
 
* Может уворачиваться от выстрелов (стрейфиться)
 
* Периодически забрасывает игрока гранатами :)  
 
* Периодически забрасывает игрока гранатами :)  
 +
 +
Код:
  
 
<source lang="scm" line>
 
<source lang="scm" line>

Версия 06:35, 21 января 2009

Автор: Axel218

Данный скрипт добавляет в игру "универсальных солдат" - это секретный военный проект правительства США :) Они появляются недалеко от игрока и ведут по нему огонь, если у того 6 звёзд розыска. Но это в игре. А на деле - это небольшой пример развития исскуственного интелекта актёров скриптом. Конечно, это не идеально, но может послужить хорошим примером управления поведением актёров для скриптеров.

Особенности скрипта:

  • Солдат может применять в разных ситуациях различные виды оружия
  • Может уворачиваться от выстрелов (стрейфиться)
  • Периодически забрасывает игрока гранатами :)

Код:

  1. ...
  2.  
  3. create_thread @Universal_Soldier_Thread
  4.  
  5. ...
  6.  
  7. :Universal_Soldier_Thread
  8.  
  9.  // Объявляем переменные для компилятора
  10. var 
  11.     7@  : Integer   // Переменная для вычисления кувырка
  12.     30@ : Integer   // Переменная для контроля таймера
  13. end
  14.  
  15. :Universal_Soldier
  16. wait 0 ms
  17.  // Проверяем уровень розыска игрока - равен ли он 6-ти звёздам?
  18. 01C0: 6@ = player $PLAYER_CHAR wanted_level 
  19.     6@ == 6
  20. jf @Universal_Soldier // Если уровень не равен 6-ти - проверяем ещё
  21.  // Получаем Handle случайного пешехода на улице
  22. 02DD: 1@ = get_random_ped_in_zone 'SAN_AND' with_pedtype_civilian 1 gang 0 criminal/prostitute 1
  23.  // Если Handle равен -1, значит он не получен - возможно, поблизости нет пешеходов 
  24.     1@ <> -1            
  25. jf @Universal_Soldier // Пробуем ещё раз сначала
  26.  // Handle получен. Сохраняем координаты пешехода в переменные
  27. 00A0: store_actor 1@ position_to 2@ 3@ 4@
  28.  // Удаляем пешехода. Он был нужен нам только для получения точных координат
  29. 009B: destroy_actor 1@ 
  30. 01C2: remove_references_to_actor 1@
  31.  // Загружаем необходимые модели      
  32. 0247: load_model #SWAT      // Модель SWAT'овца - "забугорный спецназ"
  33. 0247: load_model #M4        // Модель M4
  34. 0247: load_model #SHOTGSPA  // Модель боевого дробовика
  35. 0247: load_model #KNIFECUR  // Модель ножа
  36. 0247: load_model #HEATSEEK  // Модель ракетницы
  37. 0247: load_model #GRENADE   // Модель гранаты
  38. 038B: load_requested_models 
  39.  
  40. :Universal_Soldier_Check1
  41. wait 0 ms
  42.  // Проверяем - загрузились ли модели? 
  43. if and  
  44.     0248: model #SWAT available
  45.     0248: model #M4 available
  46.     0248: model #SHOTGSPA available
  47.     0248: model #KNIFECUR available
  48.     0248: model #HEATSEEK available
  49.     0248: model #GRENADE available    
  50. jf @Universal_Soldier_Check1 // Если не загрузились - проверяем ещё
  51.  // Создаём универсального солдата на координатах, полученых ранее
  52. 009A: 1@ = create_actor_pedtype 23 model #SWAT at 2@ 3@ 4@
  53.  // Устанавливаем ему много очков здоровья
  54. 0223: set_actor 1@ health_to 1500 
  55.  // Столько же много брони
  56. 035F: actor 1@ armour += 1500 
  57.  // Создаёи над ним маркер, чтобы его было видно на радаре. Так же это создаёт над ним 
  58.  // стрелку. По умолчанию и маркер, и стрелка имеют красный цвет
  59. 0187: 5@ = create_marker_above_actor 1@ 
  60.  // Устанавливаем солдату иммунитет к выстрелам в голову (чтобы её не снесло при попадании) 
  61. 0446: set_actor 1@ immune_to_headshots 0 
  62.  // Даём ему оружие с бесконечным боезапасом
  63. 01B2: give_actor 1@ weapon 31 ammo -1 // M4
  64. 01B2: give_actor 1@ weapon 27 ammo -1 // Боевой дробовик
  65. 01B2: give_actor 1@ weapon 36 ammo -1 // Ракетница
  66. 01B2: give_actor 1@ weapon  4 ammo -1 // Нож
  67.  // После смерти солдата всё его оружие нельзя будет поднять (оно не появится)
  68. 087E: set_actor 1@ weapon_droppable 0 
  69.  // Устанавливаем точность стрельбы
  70. 02E2: set_actor 1@ weapon_accuracy_to 95
  71.  // Уровень владения оружием - Hitman. От уровня зависит скорость стрельбы и передвижение
  72.  // во время стрельбы
  73. 081A: set_actor 1@ weapon_skill_to 2
  74.  // Модель поведения актёра. Например, при прицеливании актёр поднимает руки вверх,
  75.  // отскакивает от проезжающей рядом машины и так далее. 
  76.  // Мы установим нулевой параметр, так как мы сами будем контролировать поведение.
  77. 060A: create_decision_maker_type 0 store_to 8@ // decision\allowed\m_.ped files
  78. 060B: set_actor 1@ decision_maker_to 8@
  79.  // Этот опкод устанавливает отношение актёра к определённому типу пешеходов.
  80.  // В нашем случае это ненависть (4) к игроку (0) 
  81. 077A: set_actor 1@ acquaintance 4 to_actors_pedtype 0 // see ped.dat
  82.  // Заставляем солдата атаковать игрока 
  83. 07A5: AS_actor 1@ attack_actor $PLAYER_ACTOR -1 ms
  84.  // Выгружаем ненужные модели из памяти. Модель гранаты остаётся в памяти!
  85. 0249: release_model #SWAT
  86. 0249: release_model #M4
  87. 0249: release_model #SHOTGSPA
  88. 0249: release_model #KNIFECUR
  89. 0249: release_model #HEATSEEK
  90.  
  91. :Universal_Soldier_AI // Цикл, управляющий поведением солдата
  92. wait 0 ms
  93.  // Проверяем, если игрока не существует (его убили или т.п.) или если солдата убили
  94. if or 
  95.     8256: not player $PLAYER_CHAR defined 
  96.     0118: actor 1@ dead 
  97. then // то
  98.      // Удаляем маркер над солдатом
  99.     0164: disable_marker 5@    
  100.      // Удаляем информацию солдата из памяти игры 
  101.     01C2: remove_references_to_actor 1@
  102.      // Удаляем модель поведения солдата
  103.     065C: release_decision_maker 8@
  104.      // Выгружаем модель гранаты 
  105.     0249: release_model #GRENADE 
  106.      // Ждём 10 секунд
  107.     wait 10000 ms    
  108.      // Идём в самое начало скрипта
  109.     jump @Universal_Soldier
  110. end
  111.  // Если игрок водит наземный или воздушный транспорт
  112. if or
  113.     00DF: actor $PLAYER_ACTOR driving 
  114.     04AB: actor $PLAYER_ACTOR driving_plane 
  115. then // то
  116.      // Меняем активное оружие солдата на ракетницу и заставляем его поджарить игрока :)
  117.     01B9: set_actor 1@ armed_weapon_to 36
  118.     07A5: AS_actor 1@ attack_actor $PLAYER_ACTOR -1 ms
  119. else // иначе
  120.      // Записываем координаты солдата в переменные
  121.     00A0: store_actor 1@ position_to 2@ 3@ 4@
  122.      // Записываем координаты игрока в переменные
  123.     00A0: store_actor $PLAYER_ACTOR position_to 6@ 7@ 8@
  124.      // Получаем расстояние между солдатом и игроком    
  125.     050A: 9@ = distance_between_XYZ 2@ 3@ 4@ and_XYZ 6@ 7@ 8@ 
  126.      // Если игрок находится более чем в 50-ти метрах от солдата
  127.     if 9@ >= 20.0 
  128.     then // то        
  129.          // Меняем активное оружие солдата на M4    
  130.         01B9: set_actor 1@ armed_weapon_to 31
  131.     else // иначе   
  132.         // Если игрок на средней дистанции от солдата
  133.         if and
  134.             9@ < 18.0
  135.             9@ > 12.0
  136.         then
  137.              // Проверим, может гранатку бросим? ;)
  138.             gosub @Universal_Soldier_Grenade_Check
  139.         end 
  140.          // Если игрок находится близко к солдату
  141.         if 9@ < 2.5        
  142.         then // то  
  143.              // Меняем активное оружие солдата на нож 
  144.             01B9: set_actor 1@ armed_weapon_to 4            
  145.         else // иначе   
  146.              // На средних дистанциях
  147.              // Меняем активное оружие солдата на боевой дробовик  
  148.             01B9: set_actor 1@ armed_weapon_to 27
  149.         end
  150.     end
  151. end
  152. if and // если
  153.     0457: player $PLAYER_CHAR aiming_at_actor 1@    // Игрок целится в солдата
  154.     874F: not actor $PLAYER_ACTOR ped_event == 12   // Игрок не перезаряжается
  155.     82D8: not actor 1@ current_weapon == 4          // У солдата нет в руках ножа    
  156.     02A0: actor 1@ stopped                          // Солдат стоит на месте
  157. then // то
  158.  
  159.     // Смысл следующей операции в том, что если игрок целится в солдата - тот делает
  160.     // кувырок в случайную сторону, а затем бычтрый выстрел. Получается весьма эффектно.
  161.  
  162.      // Генерируем случайное число (0/1)
  163.     7@ = Random(-1, 1)   
  164.      // Делаем на мнгновение солдата миролюбивым существом, чтобы он не натворил глупостей
  165.     077C: clear_actor 1@ default_action 4 to_all_actor_types
  166.      // Получаем угол игрока и отнимаем от него 180, затем устанавливаем полученный угол
  167.      // солдату, чтобы тот был повёрнут лицом к игроку
  168.     0172: 9@ = actor $PLAYER_ACTOR Z_angle 
  169.     000F: 9@ -= 180.0
  170.     0173: set_actor 1@ Z_angle_to 9@
  171.      // Заставляем солдата сделать кувырок в случайную сторону (7@). 0 - влево, 1 - вправо
  172.     06E3: AS_actor 1@ roll_sideways 7@   
  173.      // Ждём, пока солдат кувыркнётся 
  174.     wait 1200 ms    
  175.      // Делаем солдата вновь агрессивно настроеным к игроку :)
  176.     077A: set_actor 1@ default_action 4 to_actors_pedtype 0   
  177.      // Заставляем солдата атаковать игрока
  178.     07A5: AS_actor 1@ attack_actor $PLAYER_ACTOR -1 ms   
  179.      // Ждём пол-секунды, чтобы солдат не кувыркался со стороны в сторону как угорелый
  180.     wait 500      
  181. end
  182.  // Идём в начало цикла
  183. jump @Universal_Soldier_AI 
  184.  
  185. :Universal_Soldier_Grenade_Check
  186.  // Eсли таймер достиг нужного нам значения 
  187. if 002D: 32@ >= 30@
  188. then // то
  189.      // Даём солдату одну гранату
  190.     01B2: give_actor 1@ weapon 16 ammo 1
  191.      // Поднимаем его. Сидя он не сможет кинуть гранату
  192.     04EB: AS_actor 1@ crouch 0 
  193.      // Заставляем кинуть гранату
  194.     07A5: AS_actor 1@ attack_actor $PLAYER_ACTOR -1 ms 
  195.      // Ждём, пока солдат не бросит гранату
  196.     while 02D8: actor 1@ current_weapon == 16 
  197.         wait 0 ms
  198.     end
  199.      // Задаём случайное значение между 20-ю и 40-а секундами, чтобы сверять таймер
  200.     30@ = Random(20000, 40000) 
  201.      // Обнуляем таймер
  202.     32@ = 0   
  203. end
  204. return