пятница, 6 апреля 2012 г.

О биндах и алиасах

Играм L4D и L4D2 уже много лет, а уж движку source и подавно. Посему тема консоли, команд, биндов и алиасов должны быть обсосана вдоль и поперёк. Так какого хрена я пишу об этом ещё раз? Что я могу нового сказать? Нового - ничего. Зачем - если кто будет задавать вопросы о работе того или иного бинда, то я буду отправлять их читать эту статью. С вводной закончили, переходим к делу.



Существует четыре способа использования команд. Можно прямо в консоле, можно отредактировать файл config.cfg, можно создать файл autoexec.cfg, ну а можно создать свой файл с конфигом my_super_config.cfg и вызывать его любым предыдущим способом командой exec " my_super_config ". И да, все конечно же понимают, что файлы конфигов должны находится в папке cfg. Для простоты условимся, что мы создали файл autoexec.cfg и все правки будем делать в нём.

Начнём знакомство с биндами. Английское слово Bind переводится как глагол "связывать" или как существительное "соединяющая деталь". Т.е. бинд связывает что-то с чем-то. в нашем случаем бинд связывает кнопку с действием. Для простоты (а может просто разработчики поленились) бинд связывает даже не с самой кнопкой, а с символом на ней изображённом. Ну а т.к. разрабы в большинстве своём англоговорящие, то и символы принимаются только те, что присутствуют на их клавиатурах. Таким образом кнопка с буквой "ы" в бинде должна быть буквой "s", а кнопка с буквой "х" будет сиволом "[". Если не уловили закономерность, то смотрите на клавиатуру до просветления. Проще обстоит со служебными клавишами. Так кнопка "delete" превратится в "del", кнопки "F1"..."F12" в "f1"..."f12", пробел в "space". Впрочем вот вам ссылка с перечнем специальных кнопок. В общем формат бинда таков:


bind символ "команда 1; команда 2; ...; команда N"


Да, писать можно несколько команда сразу. В этом случае команды должны разделяться точкой с запятой. После последней команды точка с запятой не ставится. В качестве затравки два простых примера:


bind del "quit"
bind ins "Disconnect"


Итак, если мы нажмём кнопочку delete, то сразу же выйдем из игры. Полезная вещь. Например представим, что в комнату заходит мама, а мы вместо того, что бы делать уроки мочим зомбей. Оценили полезность? То-то же. Второй бинд просто разрывает связь с текущим сервером. Вот представьте себе - вы играете с какими-то лохами, которые мало того, что играть не умеют, советы наши не слушают, не защищают нас и не лечат, так ещё и голосование устроили, что бы нас кикнуть. Нет, с такими игроками нам западло играть и что бы это показать, надо уйти самим. Жмакаем кнопку "insert" и эти мудаки поймут всю тяжесть совершённого поступка.

Теперь об алиасах. В переводе с английского "alias" - это псевдоним. В нашем случае псевдоним можно задать для команды или последовательности команд. Но сам по себе алиас не имеет смысла, если его не вызывать. Формат алиаса:


alias имя_алиаса "команда 1; команда 2; ...; команда N"
имя_алиаса
bind символ "имя_алиаса"


В первой строке мы определяем алиас для списка команд. Во второй строке мы выполняем все команды вызвав алиас по имени. В третьей строке мы связали некий символ с нашим алиасом. Т.е. произойдёт вот что - наши команды выполнятся один раз при загрузке файла конфига, а потом они будут выполнятся по требованию игрока при нажатии на кнопку. Тут стоило бы дать пример настоящего алиаса, но я не могу придумать одновременно простой и полезный алиас. Если простой, то бессмысленный, если полезный, то не простой. Посему двигаемся дальше.

Так же алиасы могут иметь два состояния. Их имена должны начинаться со знаков "+" и "-". Что же значит два состояния? Ну например мы задумали сделать нечто, что должно быть не продолжительно по времени. Например стрелять, сидеть или целиться. Таким образом два таких алиаса дополняют друг друга - один алиас начинает действие, второй заканчивает. В качестве примера можно привести стандартные команды +attack и -attack, +duck и -duck, +zoom и -zoom. Ну и т.д. Этому способствует ещё одна особенность - достаточно забиндить один из алиасов. При этом забинденый алиас будет срабатывать при нажатии кнопки, а второй при отпускании. Вот например приседание забиндено так:


bind ctrl +duck


Теперь при нажатии контрола сработает +duck, при отпускании -duck. Но что делать, если мы хотим долго выполнять краткосрочное действие? Придётся алиасы с состояниями оборачивать в обычные алиасы.


alias ZoomIn "+zoom"
alias ZoomOut "-zoom"
bind kp_plus "ZoomIn"
bind kp_minus "ZoomOut"


Теперь при нажатии плюса на цифровой клавиатуре мы будем задействовать прицел кемперки, а при нажатии на минус перестанем целится. Но использовать две кнопки неудобно, ведь правда?

Ещё одна прелесть биндов и алиасов в том, что их можно переопределять на лету. Причём даже внутри самих алиасов и биндов. При этом всё выглядит точно так же, как и в примерах выше. Для биндов даже не надо делать unbind. И вот вам пример по сложнее и по полезнее. Иногда бывает необходимость долго сидеть. Например при выполнении какого-нибудь бага. Или просто место нашли удачное и сидеть надо для уменьшения разброса пуль. Не привередливый игрок не увидит тут проблемы и просто будет держать нажатой кнопку ctrl (или как у вас там настроено). Но это же не кошерно. Вот вам бинд:


alias IWantSitDown "+duck; alias ToggleDuck IWantStandUp"
alias IWantStandUp "-duck; alias ToggleDuck IWantSitDown"
alias ToggleDuck IWantSitDown
bind c ToggleDuck


В этом случае мы избавлены от необходимости использования второй кнопки. Что же происходит? Алиас ToggleDuck циклически переопределяется при каждом нажатии на кнопку "с" (только не перепутайте, в данном случае это не русская эс, это английская це). Сели? Значит в следующий раз мы встанем. Встали? Значит в следующий раз сядем.

А знаете где это нам ещё может пригодиться? К сожалению движок не позволяет нам напрямую забиндить какие-либо команды на сочетания клавиш. Но это можно обойти с помощью переопределения. Модифицируем наш предыдущий скрипт:


alias IWantSitDown "+duck; alias ToggleDuck IWantStandUp"
alias IWantStandUp "-duck; alias ToggleDuck IWantSitDown"
alias ToggleDuck IWantSitDown
alias "+ToggleDuckType" "bind c ToggleDuck"
alias "-ToggleDuckType" "bind c +duck"
bind shift "+ToggleDuckType"


Добавилось всего-то две строчки, а полезность скрипта выросла на порядок. Итак, если мы просто нажмём кнопку "c", то наше поведение будет стандартным: пока жмём - сидим, отпустили кнопку - встаём. Но если нажмём сочетание shift+c, то наше поведение будет таким же, как в предыдущем примере. Причём давайте уж задротствовать до конца. Если присмотреться, то оказывается, что вторая и третья строчки скрипта нам не нужны. И написана она лишь для полноты картины. Действительно, не будем же мы нажимать shift+c ещё раз для того, что бы встать. Мы просто нажмём "c" и всё. При этом происходит вот что - т.к. мы и так находимся в состоянии +duck, то во время нажатия кнопки ничего не произойдёт. Зато при отпускании сработает -duck, что и заставит нас встать. Т.е. наш скрипт можно сократить до такого:


alias IWantSitDown "+duck"
alias "+ToggleDuckType" "bind c IWantSitDown"
alias "-ToggleDuckType" "bind c +duck"
bind shift "+ToggleDuckType"


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


alias InfinityToggleFlashlight "inpulse 100; InfinityToggleFlashlight"
bind f "InfinityToggleFlashlight"


Теперь, если мы нажмём кнопку "f", то наш фонарик сойдёт с ума и будет всё время включаться и выключаться. Но тут кроется одна опасность. Командный интерпретатор движка работает параллельно с игрой. И если его постоянно спамить нашими командами, то это скажется и на игре. В лучшем случае фонарик будет "заикаться" а игра начнёт тормозить. В худшем игра может вылететь. Поэтому надо давать интерпретатору отдыхать. Сделать это можно с помощью команды "wait x", где x - это количество кадров (про fps все слышали?). Например "wait 10" ждёт десять кадров. Модифицируем скрипт:


alias InfinityToggleFlashlight "inpulse 100; wait 10; InfinityToggleFlashlight"
bind f "InfinityToggleFlashlight"


Отлично, теперь и игра не тормозит, и командный интерпритатор не забит. И не стоит забывать, что "wait 10" на вашем старом компьютере будет длиться столько же, сколько и на новом компьютере соседа. Нет, величина задержки в более привычных нам секундах будет зависеть от вашего fps.

Согласитесь - пример явно дебильный. Давайте придумаем чего-нибудь по сложнее и по полезнее. Вот возьмём например пистолеты. Всё оружие как оружие - при нажатой левой кнопки мыши стреляет само, а пистолеты только один выстрел делают. Давайте превратим наши пистолеты в автоматические? А давайте:


alias quick_shot_body "+attack; wait 3; -attack; wait 5; quick_shot"
alias quick_shot "quick_shot_body"
alias "+q_shot" "alias quick_shot quick_shot_body; slot2; quick_shot"
alias "-q_shot" "alias quick_shot wait"
bind Mouse5 "+q_shot"


В качестве домашнего задания предлагаю самостоятельно разобрать этот пример и ответить на вопросы:

- Зачем принудительно переключаться на пистолеты?
- Почему подобный скрипт не стоит применять для другого оружия?
- Есть ли у меня пятая кнопка мышки?

И напоследок ещё вот что. Командный интерпретатор поддерживает комментарии в файлах конфигурации. Комментарии - это текст, предназначенный для человека и игнорируемый интерпретатором. Выглядят комментарии так:


//это комментарий
alias InfinityToggleFlashlight "inpulse 100; wait 10; InfinityToggleFlashlight"
bind f "InfinityToggleFlashlight" //это тоже комментарий после дебильного бинда
//---------------------------------
//предыдущая строчка тоже комментарий


Итак, мы успели заметить, что комментарии начинаются с двух слешей. Игнорируется всё, что написано после них и до конца строки. Если следующая строка не начинается с двух слешей, то это уже не комментарий. Что они нам дают? Удобство при редактировании конфигов. Так например было бы удобно разделять блоки скриптов по группам используя комментарий вида как в предпоследней строчке примера. Так же было бы полезным писать пояснения к скриптам - что делает скрипт, какими кнопками, какие при этом бывают глюки и т.д. Скажем вот вы поиграли-поиграли и бросили это дело. А через год или больше захотели вспомнить былые времена. Устанавливаете игру, достаёте конфиг из закромов, открываете его и понимаете, что всё забыли. Вот тут и помогут комментарии. Или вот например вы решили поделиться своим конфигом с другом, который не такой прошаренный. Ему опять таки помогут комментарии.

На этом пока всё, спасибо за внимание.

Комментариев нет:

Отправить комментарий