Искусство войны. Осваиваем скрипты

Материал из Бронетанковой Энциклопедии — armor.kiev.ua/wiki
Версия от 11:07, 20 января 2010; LostArtilleryMan (обсуждение | вклад) (Новая страница: «Одним из главных недостатков любой военной игры из серии «Искусство войны» вполне справе…»)

(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Одним из главных недостатков любой военной игры из серии «Искусство войны» вполне справедливо называется малое число игровых миссий. Однако сама игра снабжена редакторами карт и миссий, которые позволяют создавать антураж и сценарии, не уступающие включённым в базовый комплект программного продукта. Как справедливо отмечено критикой, их использование требует определённого умения, но при этом абсолютно не нужно быть асом программирования как Дейкстра или создатели RT-11. Немножко логики и понимания основ заложенной в программный продукт сценарной машины — и работающие скрипты, позволяющие получить от игры удовольствие, обеспечены. Чтобы показать, что «не боги горшки обжигают», давайте вместе с автором пройдёмся по этапам создания скриптов несложной, но вполне интересной по прохождению миссии «Forza, Carristi!» для дополнения «Итальянский вариант» первой инкарнации «Искусство войны. Африка 1943».

Постановка задачи

Именно с этого всегда надо начинать. После некоторых раздумий сценарий на одной из стандартных карт для мультиплеера выкристаллизовался в следующее: танковому и берсальерскому взводам итальянской дивизии «Чентауро» надо захватить занятую британцами деревню, которые они используют как снабженческий и коммуникационный пункт. К деревне от стартовых позиций ведут два непересекающихся пути, на каждом из которых итальянцев ждут нелёгкие испытания. Один проход защищается мощной группировкой из двухфунтовых противотанковых орудий и станковых пулемётов, а другой проходит мимо малюсенького населённого пункта, где расположилось британское пехотное отделение с наличием противотанкового ружья системы Бойса и два «Крузейдера». Один вражеский танк вооружён двухфунтовой пушкой, второй — трёхдюймовой гаубицей. Сама деревня-цель атаки защищена тремя отделениями британской пехоты с наличием противотанковых ружей системы Бойса. Для некоторого усложнения задачи игроку его непосредственный начальник, майор Луиджи Ферретти, не разрешил ввести в бой все имеющиеся силы (5 танков М14/41 и 4 берсальерских отделения сразу) и оставил в резерве два танка и два отделения. Таким образом, в составе контролируемых игроком сил 3 М14/41 и 2 отделения. Распылять их, пытаясь атаковать по обоим путям сразу — верный путь к поражению, поэтому игроку предстоит либо осторожно, шаг за шагом, в тесном взаимодействии танков и пехоты продавливать оборону вражеской группировки с орудиями и пулемётами, либо решиться на танковый бой с «Крузейдерами». В этом случае эффективным против М14/41 является один 40-мм ствол, гаубица второго «Крузейдера» «близкой поддержки» и ПТР системы Бойса могут при удаче лишь обездвижить наши танки, что весьма неприятно (они нужны для штурма деревни), но в целом ещё не фатально. Но радио у британцев есть и в случае невозможности огня из этой 40-мм пушки (уничтожения «Крузейдера», повреждения его орудия или полной гибели экипажа), а следовательно и защитить проход от наших танков они вызывают подкрепление — два бронеавтомобиля «Даймлер», которые появляются с тыла и постараются пройти угрожаемым проходом к деревне, чтобы усилить её защиту, по пути истребляя всех попадающихся им на глаза итальянцев. Вне зависимости от выбранного игроком пути в случае больших потерь майор Ферретти передаёт нам под командование резерв для выполнения задачи. Пусть также на основании данных разведки наш командир предупредит нас при подходе к тому или иному проходу, с чем нам предстоит иметь дело.

Таков общий план миссии. Осталось только уточнить частности — деревню считаем захваченной и задачу выполненной, если в её области находится минимум десять наших солдат, причём это число включает членов экипажей танков, как в своих машинах, так и вне их; а из вражеских сил осталось в живых не более двух Томми. Если эти условия выполнены, посчитаем выживших британских солдат крайне деморализованными, бросившими оружие, сдавшимися в плен. Очевидно, что если у нас осталось менее десяти берсальеров и танкистов (вне зависимости от числа и состояния танков), то поставленная задача не может быть выполнена и это будет условием поражения. Определим также взгляды майора Ферретти на то, когда стоит вводить в бой резерв. Пусть он сочтёт это нужным, если у нас из первоначальных сил не осталось больше ни одного исправного танка (танк считается исправным, если у него не повреждены ходовая часть, основное вооружение и в нём присутствует хотя бы один член экипажа) или общее число берсальеров и танкистов стало меньше 15 человек.

Программируем скрипты

Когда задача стала ясной, не стоит пугаться её кажущегося объёма — и слона можно съесть по кусочкам. Сначала приступаем к «разрезке» этого «слона» на эти самые кусочки, но перед этим следует немного сказать пару слов о принципе работы скриптовой машины «Искусства войны». Поведение и своих, и вражеских войск управляется последовательностями управляющих инструкций, которые сгруппированы в блоки — так называемые триггера. Проводя аналогию с заводским цехом, можно сказать, что триггера - это рабочие. Сколько их работает в данный момент, определяется текущей обстановкой, если нужно, то один рабочий может позвать другого на помощь или отпустить помощника отдыхать в курилку, завершить работу, передать её результаты другому рабочему и пойти в курилку сам. Точно также и триггера — в зависимости от ситуации могут запускать и останавливать другие триггера, завершать свою выполненную работу, чтобы не занимать более ресурсы процессора компьютера. Работающий в данный момент триггер называется активным, их может быть несколько и они выполняются одновременно (в рамках процессорной «многозадачности» — когда процессор быстро-быстро переключается с одного дела на другое, в итоге за большое время в успевая сделать всю порученную ему работу). Также и в цеху могут одновременно работать сразу несколько рабочих над одним или разными делами. Те триггера, которым ещё предстоит вступить в дело или уже выполнившие свою работу, называются неактивными — как отдыхающие рабочие в курилке.

Как в производстве есть промежуточные результаты — полуфабрикаты и готовые детали, так и в скриптовой машине есть их полный аналог — это ячейки для хранения чисел и текстов, называемые переменными. Там, к примеру, может храниться количество танков противника или название группы боевых единиц, нужные для определения выигрышного положения дел. Причём следует иметь в виду, что часть таких ячеек доступна абсолютно всем триггерам (их названия начинаются с двух символов @@), а часть — только одному триггеру, где в них есть необходимость (их названия начинаются с одиночного символа @). Это схоже с ящиком с запчастями, доступным для всего цеха и с бардачком с необходимым инвентарём и деталями у конкретного рабочего, нужным только ему.

В соответствии с этим производим разбиение (по-научному декомпозицию) задуманного сценария на составные части. В нашем случае они достаточно просты — необходимо контролировать следующие ситуации:

  1. Наличие более 9 наших и менее 3 вражеских комбатантов в области деревни. Если это случилось — мы победили;
  2. Наличие в нашем распоряжении менее 10 комбатантов. Если это случилось — мы проиграли;
  3. Наличие в нашем распоряжении менее 15 комбатантов и ни одного исправного танка с экипажем. Если это случилось — мы получаем подкрепления;
  4. Невозможность стрельбы из основного оружия вражеского танка «Крузейдер» с 40-мм пушкой. Если это случилось — противник получает подкрепление.
  5. Наличие хотя бы одного нашего комбатанта к началу прохода с обороняющими его противотанковыми пушками и пулемётами. Если это случилось — мы получаем соответствующее сообщение;
  6. Наличие хотя бы одного нашего комбатанта к началу прохода с обороняющими его «Крузейдерами». Если это случилось — мы получаем соответствующее сообщение;

Каждый пункт — это триггер, в миссии «Forza, Carristi!» они имеют следующие названия:

  1. WinCheck — проверка выигрыша (от английских слов Win - выигрыш и Check — проверка);
  2. FailCheck — проверка поражения (Fail - провал и Check — проверка);
  3. Reinforcement — подкрепление нашим силам (Reinforcement - подкрепление);
  4. Brit_Daimler — подкрепление в виде «Даймлеров» вражеским силам (British Daimlers - британские «Даймлеры»);
  5. Warning_1 — 1-е предупреждение от майора Ферретти (Warning — предупреждение);
  6. Warning_2 — 2-е предупреждение от майора Ферретти.

И в единое целое их связывает триггер init, который автоматически выполняется скриптовой машиной игры сразу после загрузки сценария. Рассмотрим их теперь по отдельности. Однако за подробным описанием синтаксиса и возможностей того или иного оператора всё равно следует обратиться к соответствующему руководству, прилагаемому в электронном виде к игре.

init

// 1. Армия ИГРОКА
Set @@army = 1
// 2. Армия КОМПЬЮТЕРА
Set @@enemy_army = 2
// 3. НЕЙТРАЛЬНАЯ армия
Set @@neutral_army = 3
// 4. Армия СОЮЗНИКА
Set @@allied_army = 4

Set @disposition = "Initial_Area"
ActivateDispositionMode ( @disposition )

ChangeFogOfWar ( ENABLE ) 
SetWorkArmy ( ARMY , @@army )
// Сообщаем игроку о задании
QuestActivate ( "MainTask" , "Luigi" , 15000 )
PingShow ( "Ping_01" , 1 , POINT , "Ultimate_target" )
RunTrigger ( "FailCheck" )
Delay ( 5000 )
RunTrigger ( "WinCheck" )
RunTrigger ( "Reinforcement" )
RunTrigger ( "Warning_1" )
RunTrigger ( "Warning_2" )
RunTrigger ( "Brit_Daimler" )
Halt

Поскольку в сценарии есть управляемые игроком силы, а также управляемые искусственным интеллектом союзные, вражеские и нейтральные (взятые в плен британские солдаты), то в редакторе миссий организованы четыре армии с соответствующими характеристиками враждебности друг к другу, каждой из них при создании автоматически присваивается свой номер. Конечно, его можно указывать каждый раз в нужном месте, но гораздо лучше создать для каждой армии свою переменную, в которой он хранится и используется при надобности. Да, вместо числа 1 при наборе кода надо будет печатать @@army, но, представим, что из-за каких-нибудь правок в редакторе номер армии сменится, а задействован он в доброй полсотне мест в самых разных триггерах. И придётся их выискивать, править, с высокой вероятностью при этом можно забыть что-то исправить или изменить число 1, которое к номеру армии вообще отношения не имеет. Чтобы избежать этого, везде, где требуется номер армии, используем соответствующие имена переменных, при необходимости его изменения достаточно исправить его только в определении оператором Set и всё снова заработает. Отметим, что эти переменные должны быть доступны абсолютно всем триггерам и потому их имена начинаются с @@. Первые четыре оператора Set здесь задают соответствующие переменные и устанавливают для них числовые значения номеров армий, выданные редактором миссий.