Военный конструктор. Редактор Operation Flashpoint: 1985 Cold War Crisis. Часть пятая: Скрипты
Где взять: Встроен в игру Возможности: 40% игровых; после данной статьи: 85% игровых Сложность освоения: В зависимости от вашего желания. От очень легкого до экстремально сложного Уважаемые читатели, вышла локализованная версия Operation Flashpoint, изданная на территории России компанией "Бука". Поэтому мы — как и обещали — продолжаем публикацию цикла статей "Военный конструктор: Редактор Operation Flashpoint: 1985 Cold War Crisis". На нашем компакте в разделе "ИнфоБлок" находятся все четыре статьи цикла, опубликованные в 9, 10, 11 и 12-ом номерах "Мании" за 2001 год. В ваших руках — уникальное руководство по созданию собственных миссий и кампаний, аналогов которому на русском языке не существует.Алексей Кравчун, редактор "Игромании" Приветствую всех, кто не сошел с дистанции из-за кажущейся сложности редактирования и продолжает создавать свои собственные миссии. Да, казалось бы, столько всего уже сказано-пересказано о Flashpoint, а говорить еще есть о чем. И даже много. Начинаем рассказ о продвинутом редактировании в Operation Flashpoint, и тема у нас сегодня — скрипты. Вернее, первая часть разговора о них, ибо для начала неплохо бы добиться "въезжания" в тему, а затем уже говорить о крутых наворотах. Введение Итак, зачем нужны скрипты? Скрипты созданы, во-первых, для более гибкого управления ходом миссии, а во-вторых, для создания режиссуры (как роликов, так и непосредственно игры). Это своеобразные команды движку игры, которые выполняются друг за другом. Отчасти вы создаете скрипты, используя строку инициализации юнита в редакторе, а также с помощью триггеров и вейпойнтов, но все это маленькие скрипты. Внешние .sqs-скрипты предоставляют гораздо больше возможностей, и использовать их гораздо удобнее, несмотря на кажущуюся сложность. Все скрипты пишутся, как вы уже догадались, вне редактора. Вас, наверное, уже достали постоянные употребления этого "вне", но что поделать, если у редактора возможностей только на 40% игровых. Файл скрипта имеет расширение .sqs, должен располагаться в директории исходников миссии (X:\OperationFlashpoint\Users\имяпользователя\имякарты) и активизируется командой: имя объекта/условие/значения (можно несколько, но тогда перечислять их нужно [в квадратных скобках]) exec "имяскрипта.sqs". Например, [ig1,ig2,ig3] exec "go.sqs". Основы Для начала попробуем создать простейший скрипт, который выведет на экран сообщение "Igromania — rulezzz forever!". Зачем, если можно сделать это в редакторе? А просто так, чтобы вы получили хотя бы начальное представление. Да и потом, в сложных скриптах пригодится. Итак, открываем Notepad, создаем файл rulez.sqs и в нем пишем: ;Скрипт вывода на
экран сообщения для игрока. TitleText ["Igromania — rulezzz forever!", "plain down"] ; Теперь строка выхода. Каждый скрипт должен оканчиваться строкой exit. exit Вот и все! Сложно было? Вот и я говорю, что нет. "Plain Down" — тип вывода текста. Подробнее смотрите в командах (предыдущие номера "Мании"), а также в эффектах в редакторе. Команду titletext не обязательно писать как "TitleText" — движку игры все равно, с каким регистром вы напишете команду. Но учтите, что тайтлтекст выводит только буквы, но не цифровые значения. Надеюсь, все понимают, что 1 или 2 тоже могут быть буквенным значением — нужно просто писать в кавычках? Теперь идите в редактор (не забудьте положить .sqs в директорию миссии) и в своей миссии создайте игрока; в строке инициализации напишите this exec "rulez.sqs" или, как вариант, [] exec "rulez.sqs". Теперь давайте сделаем немного по-другому. Напишем скрипт, который позволит нам выводить текст, но набранный уже в редакторе в качестве аргумента (в [] скобках): ; Скрипт вывода на экран набранного в редакторе сообщения для игрока. ; Строка ожидания ввода. _this select 0 означает ожидание ввода первого значения ; в [квадратных скобках]. Можно также сделать _this select 1 — такая команда будет ; принимать показания второго аргумента в скобках. То есть, например, [arg1,arg2] — ; arg1 это _this select 0, а arg2 — _this select 1. _soobshenie = _this select 0 ; Распечатка введенного в редакторе сообщения. TitleText [_soobshenie,"plain down"] exit Теперь вредакторе (например, встроке инициализации игрока) пишем ["Igromania — rulezzz forever!"] exec "soobshenie.sqs". Все. Теперь вы можете просто писать где угодно сообщение и командой exec "soobshenie.sqs" выводить его на экран. Преимущества такого подхода в том, что вы можете, однажды написав все параметры текста, просто менять сам текст, что сэкономит ваше время. Ведь с триггерами и вейпойнтами все нужно вводить каждый раз. Скрипты и объекты Разобравшись с
простейшими скриптами, постепенно перейдем к более сложным. Сейчас мы коснемся обращения с объектами в скриптах. Тут как при работе с вводимым сообщением: ; Пример обращения объекта к скрипту. ; Ожидание ввода объекта (как и с текстом). _obyekt = _this select 0 ; Результат действия скрипта — применение анимации от генерала Лебедя: "упал- ; отжался". _obyekt SwitchMove "FXStandDip" exit Имя объекта вводится в [квадратных скобках]. Например, [igroman] exec "obyekt.sqs". Вообще, будьте осторожны при написании скриптов — неправильно поставленная кавычка придет к невыполнению скрипта. Теперь усложним задачу. Напишем скрипт взрыва машины в тот момент, когда в нее садится солдат. Здесь мы применим прием зацикливания (loop). ; Скрипт "завел-взорвался". ; Юнит, который пойдет заводить машину. _psih = _this select 0 ; Машина, которая заведется и взорвется. _bibibka = _this select 1 ; Начинаем цикл. #Update ; Идет проверка — юнит в машине или нет. ? (_psih in _bibibka) : goto "Big-bada-bum" ; Ждем две секунды (особо кровожадные могут сразу). ~2 goto "Update" ; Юнит в машине, и тогда... #Big-bada-bum ; ...машина взрывается. _bibibka setdammage 1 exit Теперь в редакторе в строке инициализации нужной машины пишем [this, this] exec "boom.sqs". Как только в нее кто-нибудь залезет — состоится взрыв. Естественно, вместо this можно указать специфического юнита. Продвинутые скрипты Плавно подходим к более сложным скриптам. Теперь коснемся темы переклички нескольких скриптов. Попробуем составить цепь из нескольких скриптов. Для начала создадим скрип счетчика, который, отсчитав определенное время до нуля, активизирует следующий скрипт: ; Скрипт таймера.
; Вводим ожидаемые значения: _timeleft = _this select 0 _text = _this select 1 _location = _this select 2 _script = _this select 3 ; Цикл #Update ; Wait 1 second ~1 ; Делаем отсчет в обратную сторону. _timeleft = _timeleft — 1 ; Проверяем — время на нуле или нет. Обратите
внимание, что пишется "-1", а не "0" — ; иначе таймер остановится на единице. Если да, то переходим к "Done". ? (_timeleft == -1) : goto "Done" ; Все это время будем показывать таймер. Команда format задает формат текста. TitleText [format [_text + " %1", _timeleft], _location] goto "Update" #Done ; Как только будет 0, выполнится _скрипт. [] exec _script exit Теперь в редакторе пишем все в соответствии с порядком скрипта: [11, "Time Left:", "plain", "blow.sqs"] exec "countdown.sqs". Первый параметр (аргумент) обозначает время на счетчике. Обратите внимание на значение 11, а не 10. Если поставить 10, то отсчет начнется с 9. Второй параметр — текст. Третий — его размещение. И, наконец, четвертый — скрипт, который начнет выполняться после наступления на таймере нуля. Как видите, все довольно просто. Теперь напишем скрипт, который пройдет по всей цепи и соберет параметры, чтобы передать их другому скрипту: ; Ожидаемые значения скрипта и собирателя. _script = _this select 0 _vektor = _this select 1 ~2 TitleText ["Look!", "Plain Down"] ~2 ; Сосчитаем число элементов в цепи. _elements = count _vektor ; Теперь распечатаем число аргументов, которое мы собрали. TitleText [Format["You passed: %1 arguments.", _elements],"Plain Down"] ~3 ; Собрав аргументы, даем добро на
выполнение скрипта вместе с ними. _vektor exec _script exit Например, сделаем вышеуказанное с нашей цепью: ["countdown.sqs",[10,"Time Left:", "plain", "blow.sqs"]] exec "chain.sqs". Скрипт сосчитает 4 аргумента. Честно говоря, довольно сложно понять, что мы с вами сейчас сделали, но попробуйте, и все разложится по полочкам. Теперь соберем оба примера цепей на основе вышеописанного счетчика: _timeleft = _this select 0 _caption = _this select 1 _location = _this select 2 _script = _this select 3 _vektor = _this select 4 #Update ; Пауза в одну секунду ~1 _timeleft = _timeleft — 1 ? _timeleft == -1 : goto "Done" titletext [format [_caption + " %1",_timeleft], _location] goto "Update" #Done ; Выполняем скрипт с аргументами. _vektor exec _script exit В редакторе пишем [10,"Time Left To Blow:", "plain", "blow.sqs",[]] exec "countdown2.sqs". Уверен, что сейчас вам ничегошеньки не понятно, так что садитесь за редактор. Новости Flashpoint Официальный справочник команд BIS выложила на своем сайте официальный справочник по командам. В общем, как я и говорил — читайте "Манию". У нас все как-то быстрее печатается. С другой стороны, иметь официал все же рекомендую, ибо там на 100% полная и проверенная информация. Взять эту ценную вещицу можно на официальном сайте (www.flashpoint1985.com) и, естественно, у нас на компакте.
Многострадальная, неофициальная, но уже продающаяся
за деньги кампания Between The Lines благополучно вышла. И это несмотря на наглое нарушение авторских прав как самих BIS/Codemasters, так и известного в OFP-сообществе человека под ником Gunslinger, который выпустил неофициальное дополнение к редактору. Самому мне в это чудесное творенье поиграть не удалось, но то, что написал об этом аддоне Gunslinger на http://flaspoint.xaos.ru, достойно "уважения". Весит все это чудо 50 мегабайт (это на диск-то!), причем 40 из них занимает музыка и озвучка. Создатели из XMP умудрились сваять аж три разных кампании: за медика, за НАТО и... за НАТО. Русских забыли. Но это еще цветочки. Сюжет BTL скорее подходит под очередной "Квейк", нежели Flashpoint: бедный доктор отправился из дома на работу. В этот момент неподалеку сражались НАТО с русскими (целью которых, по сюжету, является истребление мирного населения). Вдруг в воздухе появился "Ми-24" и сровнял с землей дом незадачливого доктора. Тот поклялся отомстить... Хм... Замысловато, ничего не скажешь... Не говоря о том, что пойдет дальше. Как вам, например, сюжетный ход: герой мчится на машине, наезжает на мину и... выживает после этого! Зимовка на Кулгуеве подошла к концу Известный энтузиаст закончил работу над зимней версией острова Кулгуев во Flashpoint. Выглядит все просто потрясающе: очень хорошие и четкие текстуры как юнитов, так и территорий. Здешние елки — ну прям как за окном! Если, конечно, у вас есть елка за окном... Текстуры территорий брать тут: www.operationflashpoint.d2.cz/Downloady/Kegetys/WinterKolgujev10.zip, а техники — тут: ftp://145.249.10.11:22/flashpoint/Unofaddond/WinterVehicles20.zip. Вес нескромный — 8,86Мб остров и еще 7,73Мб техника, но оно и понятно. Да, и нужна, как минимум, версия 1.26. Вот.
Еще один известный в OFP-сообществе субъект под ником Devil быстро нашел применение новому разведывательному вертолету Kiowa Warrior, который в оригинале был летающим гробом. Больше ничего говорить не буду — смотрите картинку. Смешно.
Брать на Devil's Workshop (www.thegreenjeep.com/devil/). Кстати, там же вы сможете найти "Чинук", описанный в предыдущем номере. Работа с камерой Вот мы и подобрались к самому интересному — созданию скриптовых роликов. Грамотное составление скриптовых роликов может многократно повысить интерес к вашей миссии, тогда как их отсутствие вообще грозит потерей заинтересованности масс. Для начала создадим простейший скрипт с камерой, нацеленной на солдата: ; Прием вводных значений. Первый — объект, на который будет нацелена камера. ; Последующие значения — расположение камеры в координатной сетке относительно объекта. _Object = _this select 0 _camx = getpos _Object select 0 _camy = getpos _Object select 1 _camz = getpos _Object select 2 ; Создадим камеру и поместим ее в 5 метрах от объекта и в одном метре над землей. _cam = "camera" CamCreate [_camx,_camy+5,_camz+1] ; Направим камеру на объект. _cam CamSetTarget _Object ; Выберем эффект для камеры. _cam CameraEffect ["Internal","Back"] ; Закрепим изменения. _cam CamCommit 0 ; Сделаем затухание камеры через 10 секунд. ~10 _cam CameraEffect ["Terminate","Back"] ; В конце работы с камерой нужно ее уничтожить. Непонятно зачем — после этого ; камера все равно остается "живой". CamDestroy _cam exit Подробнее о командах камерам смотрите в предыдущих номерах, а я, в свою очередь, напомню, что вместо _cam = "camera" можно написать _cam = "Seagull" — камера предстанет в виде чайки. Также напомню команду GetPos, которая представляет собой направляющий вектор камеры. CamCommit назначает время, за которое камера сделает изменения. Например, вы сделали камеру, а затем ее
передвинули. CamCommit 5 сделает "переезд" камеры за 5 секунд. Если вы хотите, чтобы изменения прошли сразу — пишите 0. Стоит отдельно упомянуть об эффектах камеры — никакие из них, кроме значений Internal и Terminate, не работают. Почему-то. Ладно, пора запустить камеру. Для этого в редакторе, например, пишем [this] exec "firstcam.sqs". Запускайте! Каково, а? И это только начало. Усложним скрипт, добавив вид наблюдения из бинокля и зуминг. ; Здесь у нас будет два солдата. Один — оператор, а второй — актер. _CameraMan = _this select 0 _Actor = _this select 1 ; Снимем координаты оператора и автоматически передадим их камере. _CameraPos = getpos _CameraMan _cmx = _CameraPos select 0 _cmy = _CameraPos select 1 _cmz = _CameraPos select 2 ; Создадим камеру на месте полученных от оператора координат. _cam = "camera" CamCreate [_cmx,_cmy,_cmz+2] ; Направим камеру на юнит. _cam CamSetTarget _Actor _cam CameraEffect ["Internal","Back"] ; Закрепляем настройки. _cam CamCommit 0 @CamCommitted _cam ; Для пущего эффекта добавим вид бинокля и сделаем зум. CutRSC ["Binocular","Plain Down",100] _Zoom = 0.7 ; Блок "приближения". #ZoomIn ; Zoom in _zoom = _zoom — 0.01 ; Зададим зону обзора. _cam CamSetFov _zoom ; Закрепим изменения и через мгновение начнем процесс удаления от точки. _cam CamCommit 0 ~0.01 ? _zoom < 0.1 : goto "ZoomOutWait" goto "ZoomIn" #ZoomOutWait ; Упал-отжался. _Actor PlayMove "FXStandDip" ~8
#ZoomOut ; Zoom out _zoom = _zoom + 0.01 _cam CamSetFov _zoom _cam CamCommit 0 ~0.01 ? _zoom > 0.7 : goto "Done" goto "ZoomOut" #Done ~2 ; Теперь отдадим управление игроку обратно и уберем вид из бинокля. CutRSC ["Default","Plain Down",100] _cam CameraEffect ["Terminate","Back"] CamDestroy _cam exit В редакторе, соответственно, пишите [имя оператора, актера] exec "secondcam.sqs". Понравилось? Другого сложно было ожидать. CutRSC— отрезает ресурсы. Не совсем понятно, зачем эта команда, но она должна быть. Команды _zoom +/— 0.01 написаны для смягчения эффекта зума. Еще больше усложним задачу — добавим мимику, описанную в предыдущем номере: ; Опять делаем актера и оператора, получаем и вносим координаты. _CameraObj = _this select 0 _Actor = _this select 1 _CamPos = GetPos _CameraObj _cx = _CamPos select 0 _cy = _CamPos select 1 _cz = _CamPos select 2 ; Делаем телевизионный (линиями) вид. CutObj ["TvSet","Plain Down",100] ; Создаем камеру. _Camera = "Camera" CamCreate [_cx,_cy,_cz+1.25] _Camera CamSetTarget _Actor _Camera CameraEffect ["Internal","Back"] _Camera CamCommit 0 @CamCommitted_Camera ; Теперь сделаем так, чтобы актер заговорил и изменял свою мимику. Все считывается ; движком игры построчно. Для правдоподобности делаем задержки во времени. _Actor PlayMove "StandStraight" _Actor SetMimic "Happy" _Actor Say "RUS2" ~2 _Actor Say "RUS7" _Actor SetMimic "Angry" ~3 _Actor Say "RUS12" ~2
_Actor Say "RUS9" ~2 _Actor SetMimic "Ironic" _Actor Say "RUS14" ~5 _Actor SetMimic "Angry" _Actor Say "RUS20" ~3 ; Убираем камеру. CutRSC ["Default","Plain Down",100] _Camera CameraEffect ["Terminate","Back"] CamDestroy _Camera exit В редакторе, как и раньше, пишем [оператора, актера] exec "cam3.sqs". Только учтите, что в качестве оператора солдат уже не пойдет (будет заслонять обзор) — используйте какой-нибудь пустой объект, можно Game Logic. Кстати, обязательно посмотрите пример на компакте — несмотря на то, что я ставил say "от балды", получилось довольно прикольно. *** Вот и все на сегодня. Я постарался подготовить большую основу для вашей фантазии в нелегком деле написания скриптов. В следующем номере ждите продолжения разговора о них. Забегая вперед, скажу, что там речь пойдет о часто употребляемых, но очень сложных для самостоятельного изобретения скриптов. Например, выброска группы десанта, удар артиллерии и т.д. Все описанные сегодня в качестве примеров скрипты лежат на компакте, вместе с учебной миссией, наглядно демонстрирующей некоторые из них. Удачи, и до следующего номера! Operation Flashpoint FAQ №3
Сегодня FAQ в привычном виде не будет. А все из-за вас. Дело в том, что ответ на вопрос о распаковке миссий вызвал массовый поток писем типа "не въехал" с попутными вопросами "Ну скажите, пожалуйста, где и какие проги нужно взять!". В связи с этим даю наиподробнейшее руководство по распаковке и запаковке миссий с перечислением названий программ. Для избежания нестыковок пользоваться будем только внешними программами, не прибегая к самому Flashpoint. Итак, вы увидели интересный прием в чужой миссии и захотели его если не позаимствовать, то уж точно "посмотреть, как это он так здорово сделан". Для начала вам нужно распаковать архив .pbo. С этим делом вам поможет программка DePBO (~150Kb). В использовании она проста, как ваша мышь. Первый клик — выбираете файл, второй — директорию, куда распаковать содержимое. Кстати, распаковать можно любые .pbo, в том числе и содержащие модели техники с их техническими характеристиками. Продолжаем. Теперь перед вами файлы миссии. Все они закодированы. Алгоритм кодирования различается для официальных и пользовательских миссий. Для декодинга пользовательских миссий используется программа UnPack (~300Кб). Поместите ее в директорию с миссией и запустите — она автоматически декодирует содержимое mission.sqm в файл mission.txt. Но только его. Для успешного же использования чужой карты вам нужно будет декодировать все файлы миссии. Делается это просто: нужный файл переименовывается в mission.sqm, а потом образовавшийся mission.txt переименовывается обратно. Для декодинга официальных миссий используется программа UnComp (~600Кб). Положите ее в папку с распакованной миссией и в командной строке пропишите cmiss-uncomp.exe>mission.txt. После образования mission.txt откройте его и удалите текстовые строки, начинающиеся с "This exe file was...". Переименовываем в .sqm, и файл готов к употреблению. Чтобы запаковать миссию обратно без использования Flashpoint, найдите программу StuffPBO (~140Кб). В использовании она так же проста, как и DePBO, — выбирается директория миссии и файл, в который будет запаковано ее содержимое. Все. Неужели сложно разобраться? Вышеописанных программ вы на диске не найдете, — как уже говорилось в прошлом номере, не выкладываем из принципа (да и не хочется лишних проблем с разработчиками). Поискать их можно на центральных Flashpoint-сайтах, в том числе и на отечественном http://flashpoint.xaos.ru.
1665 Прочтений • [Военный конструктор. Редактор Operation Flashpoint: 1985 Cold War Crisis. Часть пятая: Скрипты] [19.05.2012] [Комментариев: 0]