Это в меру занудное вступление, которое смело можно пропустить. Про сам замок начинается с первого раздела :)
Поводом для этой статьи послужили следующие строчки некоего Fishman'а:
Цитата: А теперь самое сложное, что я когда-либо изобретал. Я потратил целый день, только на то чтобы разработаь верную теоретическую схему, во время создания я выкурил около 9 сигарет и придумал около 20 неверных циклических схем используя всеь запас логических энтить ХЛ2 кода. И как вы думаете что это? Неповерите, это кодовый замок! Если вы думаете, что это очень просто, попробуйте для интереса, без прочтения туториала, изобрести его самостоятельно.
Так что толчек к изобретению настоящего замка (а не той, на мой взгляд - ужасной поделки), и затем написанию тутора как это сделать любому желающему, а не только мазохистам, это в основном его заслуга :). Мне кодовый замок еще не был нужен, я его просто решил сделать. И сделал. И если Вам нужен кодовый замок, и Вы не знаете как его делать, то можете смело приниматься, сложного здесь ничего нет. А для мазохистов на www.source-inside.ru видимо вечно будет лежать оригинальная статья.
Итак, существенно более простой, понятный, и в то же время более функциональный и удобный кодовый замок. На его осмысление ушло минут 15-20, т.к. я не курю, то ничего не выкурил, но исписал примерно 5 квадратных сантиметров белой бумаги простым карандашом :) Реализация долго не рождалась, но это скорей от того, что я первый раз юзал math_counter.
1. Что же мы сделаем?
О, это будет то, что надо. Мы сделаем такой замок, в который можно относительно удобно задавать любой код, числами в десятичном виде, т.е. как мы и привыкли, и пока этот код не будет натыкан кнопками, или еще каким-нибудь известным лишь Вам способом, замочек не пошлет свой заветный аутпут дверке, и та не откроется. Или не дверке а супер-мега-механизму. Все зависит от Вашей фантазии... При желании можно будет снабдить замочек автоматическим случайным кодом, и тогда злобные игроки проходя вашу карту 2 раз, не смогут почитать солюшен, или вспомнить что код был 123. Код изменится. Но для этого варианта придется сделать и нечто, что этот код отобразит(об этом позже). При желании Вы можете заменить цифры таинственными знаками, лишь бы сами не запутались в них :). Тогда рекомендую расположить знаки так, чтобы Вы четко ориентировались какой знак - какая цифра. Тогда в уме можно будет прикинуть какой нужно поставить код, чтобы сработала комбинация из мега-таинственных знаков. Если это то, что Вам нужно, то потрудитесь освоить следующий раздел. Он проще чем кажется. Если я достаточно понятно изъясняюсь, уйдет минут 15-20.
2. Сам замок, и как он работает.
В этом разделе мы создадим полностью рабочий кодовый замок с фиксированным кодом(который Вы придумаете) и с одним ограничением - код не должен начинаться с нуля. Он уже будет работать, и если окажется что это было тяжело, и Вам дальше не захочется читать, можно будет его полноценно использовать на своих картах.
Для начала создадим математику и логику. Это еньтитьки math_counter и logic_compare. math_counter обзовем (name) math_counter1 logic_compare обзовем logic_compare1. Да, вот так бесхитростно, и понятно :) .
Счетчик - math_counter будет выступать в роли элемента который поймет что мы натыкали. Т.е. если мы набираем 3845095, то это число и будет текущим значением данного счетчика. Элемент сравнения чисел - logic_compare будет сравнивать заданное ему число, с тем что мы натыкали счетчику с помощью кнопок.
Кнопки создаются очень просто. Делаете брашик по размерам кнопки(1-4 юнита примерно) конвертируете его в еньтитьку func_button.
Кнопка первая, образ для остальных:
Name button1 (разумеется нужно будет для всех кнопок переделать цифру)
Аутпут1: My output named - OnPressed (когда нажимается) Target entities named - math_counter1 (цель аутпута - счетчик) Via this input - Multiply (что мы ему делаем - умножаем With a parameter override of - 10 (на сколько - на десять :) )
Аутпут2: Скопируйте первый аутпут, и измените два последних значения для простоты. My output named - OnPressed Target entities named - math_counter1 Via this input - Add (а здесь - прибавляем) With a parameter override of - 1 (прибавляем значение нажатой кнопки) After a delay in seconds of 0.01 (чтобы прибавлялось после умножения). В принципе у меня работало и без этого параметра, просто если есть 2 аутпута в одно и то же время, они могут выполниться в разной последовательности. А в нашей ситуации это до неузнаваемости изменит код, так что лучше перестраховаться.
Предпоследний параметр - единица, зависит от кнопки(там написано "а здесь - прибавляем"). Он здесь единица лишь потому, что кнопка первая. На второй кнопке имя и этот параметр будут уже соответственно button2 и 2. И так далее до нуля.
Если хотите хоть какую-нибудь текстуру, а своей пока нет(нормальных текстур цифр в оригинальной халфе нет), можно использовать sprites/numbers. Для тренировки более чем подойдет.
На данном этапе, нужно настроить свою первую кнопку чтобы она правильно "нажималась" в нужном направлении, и возвращалась с необходимой скоростью. Чтобы потом все 12 кнопок не переделывать. Как вариант: -- Move Direction - поверните белую полоску в ту сторону, в которую бы вы хотели чтобы кнопка двигалась относительно вида сверху. Speed - 200 Lip - 1 Delay before reset - 0.1 -- Это нужно лишь для того, чтобы они быстро нажимались, и быстро "отпускались" . Вот че у меня вышло:
Теперь создадим еще одну кнопку, для сброса набора. Можно ее при желании переделать заодно для ввода натыканного кнопками числа, но это уже по желанию. Name - reset Аутпут: My output named - OnPressed Target entities named - math_counter Via this input - SetValue With a parameter override of - 0
Она просто обнуляет наш счетчик. Без этой кнопки один раз ошибившись, мы больше никогда не сможем открыть замок.
Настроим драгоценную логику.
math_counter Name - math_counter1 Initial value - 0 Minimum Legal Value - 0 Maximum Legal Value - Число которое больше Вашего кода. Оно нужно чтобы дать возможность счетчику так много уметь считать, но при этом не особенно напрягаться когда какой-нибудь талант решит набрать такое число, чтобы игра сглючила и открыла ему замок. Ох и долго ему предстоит этим заниматься, учитывая что при достижении максимума наш счетчик больше не прибавит ни единицы...
Аутпут: My output named - OutValue Target entities named - logic_compare Via this input - SetValueCompare With a parameter override of - <none>
logic_compare Name - logic_compare Initial value - 0 Compare value - Ваш код(тот самый код ради которого все и делалось!).
My output named - OnEqualTo Target entities named -Имя Вашей двери или чего там у Вас. Via this input - Unlock если это закрытая дверь.
Если хотите чтобы дверь еще и открылась сама, то через некоторое время после Unlock'а хотя бы одну сотую секунды, сделайте еще один аутпут который ее будет Open.
Теперь если надо(мне надо) добавте еще одну кнопку - ввод. В данный момент замок откроется как только наберешь код правильно, т.е. если ваш код 234, а игрок станет набирать 234567, у него получится как только он 234 наберет, а с добавлением этой кнопки придется ее нажимать только после ввода кода, и эта фишка уже не прокатит.
Для этого: В аутпуте math_counter1 Via this input - SetValueCompare Меняем на Via this input - SetValue
И конечно делаем саму кнопку. Name - enter Аутпуты: 1 My output named - OnPressed Target entities named - logic_compare1 Via this input - Compare 2 My output named - OnPressed Target entities named - math_counter1 Via this input - SetValue With a parameter override of - 1
Звуки
Еще очень неплохо привязать звуки на все кнопки, и какой-нибудь нехороший звук на событие когда неправильно введен код.
Для этого нужно сначала сделать ambient_generic с именем button_sound и параметром поля Sound Name - Buttons.snd3(ну или на ваш вкус), выделить кнопки(думаю можно все), и добавить им аутпут: OnPressed - button_sound - PlaySound
Чтобы не мостить ambient_generic точно возле кнопок(чтобы звук от них шел) можно ему указать в параметре SourceEntityName имя какой-нибудь центральной кнопки. Звук будет идти оттуда.
Звук закрытого замка делается примерно так же. Создается еще один ambient_generic, называется locked_sound, подбираете звук в поле Sound Name типа Buttons.snd40, и можно сразу указать в поле SourceEntityName источник звука. Аутпут создается у энтити logic_compare1 и имеет примерно такой вид: OnNotEqualTo - locked_sound - PlaySound
Вроде все. Когда я по данному мануалу, предварительно все напрочь забыв, пытался сделать все как надо, у меня ушло меньше 15 минут, при том, что я еще немного статью корректировал.
3. Коды начинающиеся с нуля
Всем хорош наш замочек, да только не умеет он всасывать комбинации начинающиеся с нуля. Вот захотите вы 007 кодом сделать, а работать будет 7 и 00000000000000007. В общем последующий раздел призван этот косяк исправить, и соответственно если у Вас в планах нет такой потребности, можно его не читать. Не нашел я идеальное решение этой проблемы, но предлагаю наиболее простое и изящное.
У math_counter1 меняем Initial value на 1 Кнопке сброса в аутпуте меняем параметр With a parameter override of тоже на 1. И конечно logic_compare в поле Compare value куда заносится код, нужно перед кодом ставить единичку. Т.е. если код 007, пишем 1007. Набирать надо будет 007. Так можно и 0000 кодом сделать, вписав 10000 в это поле. По моему идеально просто.
Отличный кодовый замок, в Max legal value надо писать 999999999 (9 девяток), так как unsigned int на 32-разрядных системах может быть от -214748 3648..2147483647, итого - максимальная длинна кода - 9 цифр, исключая ведущие нули. Это позволит и код по-максимуму использовать, и глюка игры не будет.
Ошибка, на кнопке энтер, последний аутпут должен быть с параметром 0.
Можно было и почитать. У меня такое ощущение что за многолетний период прошедший с момента написания никто ее так и не прочитал нормально :). А ведь эта статья есть только на русском, и реализации описанного я не видел ни в одной игре.
Да, это единственный в мире кодовый замок который мало того что делается не через жопу, а еще и работает как часики. Коды набираются как коды а не как жопа. Если код 12345, то 54321 не прокатит и близко.
Если кто-нибудь сделает это когда-нибудь, возможно допишу ее :). В планах изготовление удобной текстуры для кнопок, механизм построения случайного кода, и как вытекающее - механизм отображения этого случайного кода на основе твоих переключающихся текстур ;).
Очень полезная статья! Молодец, Джон! Правда я прочитал поверхностно, но я уверен, что она пригодится в дальнейшем мне, да и не только мне... Очень рад иметь такую статью на нашем сайте.
Добавлять комментарии могут только зарегистрированные пользователи. [ Регистрация | Вход ]