Делаем кодовый замок
Вы когда-нибудь хотели сделать на своей карте кодовый замок или дверь забитую деревянными брусьями, при разбивании которых дверь можно бы было открыть? И не могли взять в толк как это сделать? Вот тут то вам и придёт на помощь энтитя под названием math_counter, не используя которую, вы не можете называться хорошим маппером.

Поводом для написания статьи бывают разные вещи, на этот раз я решил написать стаью, потому как из своего многолетнего стажа маппера я вспомнил, что в основном все стараются избегать сложных скриптов и сам counter в частности.
Вообще не правельно писать целую статью только об одной энтити. Но math_counter это исключение из правил. С помощью math_counter можно создавать не мыслемые по сложности скрипты, с несколькими циклическими разветвлениями. В общем только одна примитивная энтитя в качестве перехода между событиями даёт огромные возможности в сфере скриптинга.

Так что давайте учиться, учиться и ещё раз учиться.

Начнём того, что узнаем, что же такое math_counter.
math_counter — энтитя производящая математические значения типа прибавить\отнять или делить\умножать, при достижении особого значения происходит событие.

А теперь описание её функций:
Name — обязательный параметр для обращения к этой энтити с помощью другой.
Initial value — стартовое значение этой энтити. Т.е. число, которое будет с самого начала заложено в эту энтитю.
Minimum legal value — минимальное действительное число, относительно которого можно выполнять событие.
Maximum legal value — максимальное действительное число.
Minimum legal value и Maximum legal value не должны быть равны нулю одновременно, к тому же они должны быть разными.

Теперь Inputs
Kill — удалить эту энтитю с карты.
Add — прибавить число к Initial value.
Divide — разделить Initial value на число.
Multiply — умножить Initial value на число.
Set Value — установить новое значение в поле Initial value.
Subtract — вычесть число из Initial value.

Теперь Outputs.
Outvalue — событие происхоит при изменении значений.
OnHitMin — событие происхоит когда число достигает Minimum legal value (глагол достигает означает равенство). Чтобы событие снова произошло, число должно снова достичь минимума.
OnHitMax — событие происхоит когда число достигает Maximum legal value. Чтобы событие снова произошло, число должно снова достичь минимума.

А теперь я расскажу о нескольких приёмах с помощью math_counter.

Начнём с забитых дверей.
Создайте на карте дверь, я буду использовать prop_door_rotating, о создании которой я уже писал в одном из туториалов. Настроте дверь по своему усмотрению. И во флагах поставьте галочку возле Starts Locked (при загрузке крты дверь закрыта на замок).
Назовите дверь в поле Name - door_interror01a.

Теперь создаём math_counter. Настраиваем:
Name — math_counter01a
Initial value — 0
Minimum legal value — 0
Maximum legal value — здесь укажите число досок, которые нужно будет разбить, чтобы дверь открылась. У меня будет 4.

Теперь заходим во вкладку Outputs.
Создаём 1 output и настраиваем:
My output named — OnHitMax
Targets entities maned - door_interror01a
Via this input — Unlock

Теперь нам понадобятся доски которыми будет забита наша дверь. Я использовал prop_physics с моделью models/props_debris/wood_board04a.mdl, и не забыл зайти во флажки наших досок и установить флажок напротив Motion Disabled, на землю не падали раньше времни.

Теперь выделяем все доски и заходим во вкладку Outputs.
Создаём 1 output и настраиваем:
My output named — OnBreak
Targets entities maned - math_counter01a
Via this input — Add

With a parameter override of - 1

Теперь компилируйте это всё. Будет работать. Если кому непонятно как всё пашет вот схема:

Доска разбивается и прибавляет 1 к значению math_counter, когда значение достигает 4 — дверь разблокируется.

Всё просто. И совет, не используйте гранаты и прочие взрывчатые вещества, чтобы сломать доски, иначе HL2 может вылететь, кроче лом 4eva!!!

Теперь создадим болтающуюся вывсеку, выстрелим по ней 2 раза — она оторвётся и будет болтаться на одном креплении, выстрелим ещё 1 раз — отвалится вовсе.

Создайте вывеску в виде func_physbox, произвольных размеров и текстурой (я использовал браш размером 64×64x4 с текстурой props/sign_cafe01a).

Натройте на своё усмотрение, но не трогайте флажки.
Имя дайте — sign_kill_me_please_01a
Теперь создайте два phys_ballsocket. Первому дайте имя ballsocket_to_sign_01a, второму ballsocket_to_sign_01b. В поле Atachment 1 введите sign_kill_me_please_01a.
Можете ещё и в поле Play Sound on break (я использовал для одного impact/metal/vent_drop2.wav, а для другого impact/metal/vent_open2.wav, но вроде как эти звуки не работают). Разместите эти два phys_ballsocket, так чтобы они представляли из себя крепления для вывески.

Теперь создайте два math_counter, первый назовите math_counter02a, второй — math_counter02b.
У первого Maximum legal value должен быть 2, у второго 3.

Теперь зайдите во вкладку OutPuts у первого, создайте новый OutPut и настройте так:
My output named — OnHitMax
Targets entities maned - ballsocket_to_sign_01a
Via this input — Break
After a delay in seconds of — 0.50


Поставьте галочку возле Fire only once.

Теперь зайдите во вкладку OutPuts у второго math_counter, создайте новый OutPut и настройте так:
My output named — OnHitMax
Targets entities maned - ballsocket_to_sign_01b
Via this input — Break
After a delay in seconds of — 0.50


Поставьте галочку возле Fire only once, если уже стоит, уберите и снова поставьте.

Теперь откройте свойства func_physbox. Зайдите во вкладку OutPuts у второго math_counter, создайте новый OutPut и настройте так:
My output named — OnDamaged
Targets entities maned - math_counter02a
Via this input — Add
With a parameter override of - 1


Снова создайте новый OutPut и настройте так:
My output named — OnDamaged
Targets entities maned - math_counter02b
Via this input — Add
With a parameter override of - 1

Это всё. Компилируйте и наслаждайтесь.


А теперь самое сложное, что я когда-либо изобретал. Я потратил целый день, только на то чтобы разработаь верную теоретическую схему, во время создания я выкурил около 9 сигарет и придумал около 20 неверных циклических схем используя всеь запас логических энтить ХЛ2 кода. И как вы думаете что это? Неповерите, это кодовый замок! Если вы думаете, что это очень просто, попробуйте для интереса, без прочтения туториала, изобрести его самостоятельно.
Выражаю особую благодарность Asgaard'у (Леониду Семенцову) за его помощь.
Итак, давайте приступать.

Создайте некое подобие этого:

Я использовал браши размером 4х4х4 и текстуры класса Sign + текстура lights/white004 для белой кнопки ввода и tools/nodraw для других сторон кнопок.
Теперь назначте всем кнопкам функцию func_button. Настройте так:
Name — каждой кнопке имя соответствующее её номеру. К примеру, кнопке с нулём имя — 0. Белой кнопке не давайте имя.
Move Direction — поверните белую полоску в ту сторону, в которую бы вы хотели чтобы кнопка двигалась относительно вида сверху.
Speed — 200
Lip — 1
Delay before reset — 0.1

Всё — кнопки настроены.

Теперь создайте на карте math_counter. Настройте так:
Name — counter
Initial value — 0
Maximum legal value
 — в зависимости от того какой длины код (у меня 4).

Теперь новая для вас энтитя — logic_branch. Это бинарная энтитя, рабатающая по принцыпу переключателя, она может принимать значение 0 или 1 в зависимости от них происходит проверка и соответственно событие.
Создайте на карте эту энтитю и настройте:
Name — logic_branch
Initial value (начальное значение) — 0.
Пока всё.

Дублируйте эту энтитю и дайте ей имя logic_branch1.

Теперь создайте новую энтитю game_text, настройте по усмотрению, кто умеет, кто нет — не трожьте настройки. Теперь добавьте в настройки следующее:
Name — fucking_text
Message Text — Code is not right!!! :E


Дальше, открывайте свойства каждой из func_button и заходите во вкладку Outputs, создавайте новый OutPut и настраивайте (рекомендую использовать Copy и Past):
My output named — OnPressed
Targets entities maned - counter
Via this input — Add
With a parameter override of - 1


Снова создайте новый OutPut и настройте так:
My output named — OnIn
Targets entities maned — укажите имя той кнопки свойства которой вы настраиваете.
Via this input — Lock


Дальше, открывайте свойства тех кнопок, которые будут самой комбинацией, и заходите во вкладку Outputs, создавайте новый OutPut и добавьте к существующим OutPut`ам:
My output named — OnPressed
Targets entities maned - counter
Via this input — Add
With a parameter override of - 1


Дальше, открывайте свойства тех кнопок, которые будут неправильной комбинацией, и заходите во вкладку Outputs, создавайте новый OutPut и добавьте к существующим OutPut`ам:
My output named — OnPressed
Targets entities maned - logic_branch1
Via this input — SetValue
With a parameter override of - 1


Дальше, откройте свойства math_corner и заходите во вкладку Outputs, создавайте новый OutPut и настраивайте:
My output named — OnHitMax
Targets entities maned - logic_branch
Via this input — SetValue
With a parameter override of - 1


Теперь, откройте свойства logic_branch и заходите во вкладку Outputs, создавайте новый OutPut и настраивайте:
My output named — OnTrue
Targets entities maned
 — имя объекта открывающегося кодовым замком.
Via this input — открыть или ещё чего.

Снова создайте новый OutPut и настройте так:
My output named — OnFalse
Targets entities maned - fucking_text
Via this input — Display


Снова создайте новый OutPut и настройте так:
My output named — OnFalse
Targets entities maned - counter
Via this input — SetValue
With a parameter override of - 0


Снова создайте новый OutPut и настройте так:
My output named — OnTrue
Targets entities maned - counter
Via this input — SetValue
With a parameter override of - 0


Теперь, откройте свойства logic_branch1 и заходите во вкладку Outputs, создавайте новый OutPut и настраивайте:
My output named — OnTrue
Targets entities maned - logic_branch1
Via this input — SetValue
With a parameter override of - 0


Дальше, откройте свойства вашей белой кнопки и заходите во вкладку Outputs, создавайте новый OutPut и настраивайте:
My output named — OnPressed
Targets entities maned  — создайте несколько OutPuts с параметром этого поля от 0 до 9.
Via this input — UnLock

Снова создайте новый OutPut и настройте так:
My output named — OnPressed
Targets entities maned - logic_branch
Via this input — Test
After a delay in seconds of — 0.1


Снова создайте новый OutPut и настройте так:
My output named — OnPressed
Targets entities maned - logic_branch1
Via this input — Test


Снова создайте новый OutPut и настройте так:
My output named — OnPressed
Targets entities maned - logic_branch
Via this input — SetValue
With a parameter override of - 0
After a delay in seconds of — 0.11


Снова создайте новый OutPut и настройте так:
My output named — OnPressed
Targets entities maned - logic_branch1
Via this input — SetValue
With a parameter override of - 0
After a delay in seconds of — 0.1


Теперь, откройте свойства logic_branch1 и заходите во вкладку Outputs, создавайте новый OutPut и настраивайте:
My output named — OnPressed
Targets entities maned - logic_branch
Via this input — SetValue
With a parameter override of - 0


Теперь компилируйте. Должно всё работать и незабывайте что Maximum legal value соответствует колличеству ваших кнопок. Ну что сложно? ОФИГЕННО! И самое смешное — это не самое сложное я видел и посложнее, в некоторых даже элементарно разобраться непросто.

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

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

А для тех, кто не смог всё это проделать, ниже пример. Там 4 комнаты, в первыйх 2, то о чём я говорил, в остальных двух я просто баловался. И ещё одно, чтобы открыть дверь введите код — 1230 и используйте её.
Скачать исходник
Автор: FishMan.
20 марта 2005, 18:06