Этот сайт предназначен, прежде всего, людям, ностальгирующим по ушедшим РУССКОМУ СЛОВУ, Windows 3.1, ФОТОНУ, процессорам 486SX и иже с ними.
Конечно, времена должны идти вперед, но почему они обязательно должны уходить?
StuhlbergR 2007-2008 ©
|
"Why are there monsters?" (DOOM - Infernal Sky)
"Кровищи, кровищи побольше..." или еще раз о детализации в мапинге DOOM 3 (продолжение)
Небольшое лирическое отступление от темы. (Хотя, может, и не отступление вовсе)
Заинтересовавшись сравнительно недавно строительством карт для Counter-Strike 1.6, я поневоле начал сравнивать не только моторы DOOM 3 и Контры, не только редакторы карт D3 Radiant и Valve Hammer Editor (он же, как известно, WorldCraft), но и способы реализации того или иного эффекта в них. Признаться, доселе мыслил, будто Hammer во многом удобнее Radiant'a. Все-таки последний не был предназначен для широкой публики, а писался разработчиками ID для "внутреннего пользования". Но, столкнувшись с Хаммером "нос к носу", убедился в наивности своих представлений. Да, и тот и другой периодически выкидывают коленца, от которых порой хочется разломать клавиатуру об колено (естественно, никто этого не делает ;) ), но Radiant все же существенно устойчив к выбросам и - главное - способен довести компиляцию до победного конца даже с кучей непростительных ошибок. В то время, как редактор от Valve из-за одного-единственного разнесчастного битого браша способен встать на дыбы и категорически отказать в каких-либо дружелюбных действиях по отношению к вам.
Хотя... толковому человеку он все же протягивает руку помощи в виде компиляционного лога. Вот и у меня недавно неприятность случилась: отказывается редактор создавать BSP-файл в папке карт для Контры - и все тут. Не помогли ни коврик для медитации (по доброму совету c4tnt), ни шаманский бубен, ни всякие русские народные слова, ни замена встроенных компиляторов на ZHLT. Пришлось таки лезть в лог. Там обнаружились следующие дела:
Error: Entity 0, Brush 150, Side 3: plane with no normal
Error: plane with no normal
Description: The map has a problem which must be fixed
Howto Fix: Check the file ZHLTProblems.html for a detailed explanation of this problem
Естественно, один вредный браш (под номером 150) нагло портил всю картину. Не стал я с ним долго колдовать - удалил, чтоб "никаких перитонитов" - и дело с концом. Благо, и без него все распрекрасно смотрелось.
Но о чем это бишь я?.. Ах да, о брашах в Контре и ДУМе Третьем немного написать хотел. Так вот. Как известно, на движке от Valve можно реализовать разбивающиеся браши. Скажем, доски, которыми заколочена дверь, или табуретка, блокирующая проход... И как же заманчиво сотворить подобное для DOOM 3! А взрывающиеся стены помните? Вот-вот. К сожалению, в Radiant'e не обнаружился заветный func_breakable, при помощи которого в Half-Life или Counter-Strike реализуются подобные штуковины; но кто ж нам мешает использовать func_fracture, который мы привыкли ставить в качестве разбивающегося стекла?.. Правильно, никто. И вот что у меня получилось после пары минут работы (при желании можно подрисовать и гвозди):
Но вот незадача: текстур дерева-то в DOOM 3 как раз и нету! В самом деле, откуда взяться на Марсе дереву? (Туда и пилы-то по ошибке попали.) Правда, для любителей "выдирать" текстуры из других игр или рисовать свои это вовсе не проблема, но расписывание сей процедуры выходит за рамки данной заметки. К тому же, выясняется еще одна неприятность: наши "металлические" доски здесь ведут себя как... стекло. Посмотрите сами:
Хотя задачу-минимум мы и реализовали, то есть разбиваемую преграду все-таки создали (кстати, это могут быть не только доски, естественно, но и знакомые всем вентиляционные решетки, ящики и т.д.), но ведет себя такая преграда вовсе не естественно. Даже звук - и тот стеклянный. Последнее можно попытаться изменить через параметр snd_shatter, назначив звук разрушаемого материала, только дерево в стандартных звуковых шейдерах вы все равно вряд ли найдете. Остается, опять же, внедрить свои. Подозреваю также, что материал можно назначить в одном из файле DOOM 3, только вот не знаю, как это сделать... Возможно, стоит покопаться в папке \particles из pak000.pk4. Дерево вряд ли там отыщется, но пошаманить с эффектами, наверное, все же можно попробовать.
Также наверняка многим было бы заманчиво сделать разрушаемые взрываемые стены. В принципе, это реализовать несложно. Более того, возможно применение нескольких способов. Мы рассмотрим один из них.
Если в HL2 данный эффект функционирует путем добавления, скажем, какой-нибудь exploding_wall_explosion_1 с натягиванием текстуры стены, то в DOOM3, конечно же, придется поступать иначе. Хотя бы потому, что базовым для движка D3 является не func_wall, а func_static. Вот с ним и станем работать. Для начала соорудим непосредственно проем.
Создаем func_static из контекстного меню в окне проекции (лучше вид сверху) и растягиваем его по размерам проема. Текстурируем по вкусу. Например, камнем. (Камень, как известно, прекрасно взрывается.) Можно, конечно, не выделять текстурой "взрывоопасную" стену, преподнеся таким образом игроку сюрприз в виде тайного прохода, но можно и намекнуть... (Вспомните, в перводумах "секретки" едва заметно, но все же выделялись из общего монолита стен.)
Пропишите имя (name) для func_static. Все равно, какое. Хоть stena. Кстати, если хотите, можно назначить модель - тогда это будет не просто стена, а... например, плита (немного моделей плит в наборе редактора имеется). Поставим несколько бочек (moveable_explodingbarrel), которые, по сценарию, и будут взрывать нашу стену. Только не переусердствуйте с этим делом, иначе бочки могут взорвать игрока еще до того, как он успеет оценить вашу изобретательность.
Возможен вариант, когда вместо вашего браша с параметром func_static в игре вы ничего не увидите. Это опять же тот самый баг, что был описан в части касательно вставки моделей. Нужно просто "пробелом" выполнить прямое копирование, а неудачный браш удалить. И не забываем в таком случае вновь назначить имя скопированному брашу! Если же сквозь свежесозданную стену можно вдруг пройти, аки Коперфильду, натяните рядом со стеной новый func_static, но с текстурой clip. Тогда через вашу стену никто не пройдет. Можно также назначить имя, скажем, stenka.
Вставляем небольшой по размерам триггер trig_once и размещаем его повыше, чтобы игрок случайно не мог его пересечь и активировать раньше положенного. Также вставляем func_remove и цепляем его за триггер. Сам же func_remove нацеливаем на два созданных ранее func_static'a (stena и stenka соответственно). Теперь при активации func_remove через триггер обе стены исчезнут, осободив проход изумленному игроку. Только вот как задействовать этот самый триггер? По правилам сценария, сам игрок не должен его пересечь, а сработать он должен только после взрыва бочек. Все просто! Ищем у одной из бочек параметр triggerTargets и выставляем ему 1. Теперь после уничтожения данной бочки сработает назначенный триггер. Ну а нам как раз нужен наш. Нацеливаем бочку на trig_once (так же, как и за триггер всегда цепляли объекты: выделяем сначала бочку, затем, не снимая выделения, - сам триггер; жмем комбинацию <Ctrl>+<K>; если стрелочка протянулась - то все в порядке). Диспозиция, в общем, такая:
Где:
1 - триггер, который нацелен на 2, т.е. активирует его;
2 - func_remove - функция, убирающая выбранные объекты. В нашем случае это 3 и 4;
3 и 4 - два func_static'a, которые нужно убрать (stena и stenka);
5 - бочка, нацеленная на триггер (при уничтожении оной триггер активируется, активируя, в свою очередь, func_remove... ну вы поняли, конечно).
А вот как все это веселое безобразие выглядит в игре. На скринах я добавил несколько мелких деталей: не забываем про детализацию! ;) Можете поставить некоторое количество перемещаемых объектов, чтоб их при взрыве разметало в разные стороны для пущего эффекта.
Дым и огонь взрыва заслонят собой мгновенно исчезающую стену, так что игрок подвоха не заметит. Даже не нужно вставлять env_explosion для взрыва и env_physexplosion - толчок. Бочки все сделают сами. Не бочки, а прелесть, в общем.
Само собой, напрашивается проход в секретную комнату, где будут для игрока в изобилии заготовлены аптечки, патроны, броня и прочие приятности. Впрочем, не исключены также и новые монстры (а вдруг он таким образом открыл новый портал для вторжения?!). Представляете: вместо ожидаемого бонуса вылезает из дыры бонус неожидаемый в виде грохочущего своими железяками пинки или разъяренного колобка... то есть КАКОДЕМОНА, конечно!..
Можно и просто ноут со своей фотографией поставить или "секретный" PDA, в котором поведается о нелегком труде разработчика данной карты.
Кстати, возвращаясь все к той же Контре, замечу, что на небезызвестной (и моей любимой) карте cs_office имеется подобный секрет. Недалеко от респауна террористов заходите в комнатку и стреляете в стену (как правило, это место можно заметить по легкому выступу). Там в открывшемся проломе обнаруживаете тайничок с картинкой, на которой написано, что карту сделал некий Хоббит. Впрочем, это вы и без меня, должно быть, знаете.
- Ну, хорошо, прекрасно, - скажут мне бывалые игроки, - а где обломки? Обломки-то - где?! Ежели был взрыв, то уж пущай будут и обломки. Да и пролом какой-то не естественно ровный вышел. А подавай-ка ты нам еще и неровности проломанной стены впридачу. И чтоб к завтрему.
- Ладно, - отвечу, - пускай будет к завтрему.
И спокойно отправлюсь спать. А утром сделаю вот что.
Поставлю обыкновенный "каменный" браш на весь проем, а затем, вырезав из него кусок инструментом CSG Subtract, как для обычной двери, назначу тому брашу, которым вырезал, быть func_static'ом, прописав соответствующее значение в Key во вкладке Entity. А далее - по вышеописанному. Можно также поэкспериментировать с несколькими брашами, осторожно деформировав их вертексами. Оставшимся после вырезания брашам назначу, опять же, func_static. Таким образом, после взрыва заплатка func_static исчезнет, ну а исходные брашевые углы останутся, изображая неровности открывшегося после взрыва пролома.
Как быть с осколками. А проще простого! Положите их с обратной стороны стены. Игрок будет думать, что они образовались потом. Такая вот иллюзия.
Есть и еще способ, который, кстати, хорош тем, что прибавляет реализма. Все делается так же, только заплатки в виде брашей (им мы назначим уже не func_static, а func_mover) будем не стирать, а разбрасывать (двигать) при помощи несложного скрипта в различные стороны.
...Вот и прозвучало страшное слово "скрипт" :) Для некоторых мапперов это как приговор их карте. На самом же деле, в написании скриптов для DOOM 3 ничего сверхъестественного нет. Даже если вы не знаете язык Си (DOOM 3 использует в скриптах Си-подобный язык), рано или поздно скрипты писать научитесь. Поверьте, они значительно расширят ваши возможности. Я не Бог весть, какой скриптолог (и даже, если честно, никакой скриптолог), но я не волшебник, а только учусь. Вращать, передвигать предметы, а также заставлять их исчезать и материализовываться все же умею.
Так вот. Заметим, какие имена дал Radiant нашим осколкам (можем назначить и свои; например, oskolok). Поставим еще один func_static - это будет цель, в которую и полетит этот осколок. Закрасьте текстурой nodraw, чтоб придать невидимость. Можно ставить его в любом месте - долетит. Разбросайте несколько таких целей - для каждого из обломков свою - по всей комнате. Дам-ка я название первой цели point_oskolok. И еще: следите за координатами точки приземления осколка. Красная точка origin вам точно их укажет. Просто не очень красиво, когда большущий тяжелый обломок вдруг исчезнет под полом или, наоборот, зависнет в нескольких юнитах от него.
В обычном Блокноте пишем следующее:
void my_script() \\имя вызываемого от триггера скрипта
{
$oskolok.time(0.5); \\время полета обломка. Чтоб домчал в мгновение ока - я поставил половину секунды. В противном случае игрок увидит, как во все стороны плавно и неторопливо перемещаются громадные каменные плиты... Интересный прием для парения каменюк в адском небе.
$oskolok.accelTime(0); \\время разгона обломка (можете поиграть параметрами)
$oskolok.decelTime(0); \\время его торможения (можете поиграть параметрами)
$oskolok.moveTo($point_oskolok); \\точка, к которую прибудет наш осколок в конце своего полета
$plitka.rotateOnce('0 0 90'); \\а это параметры трехмерного вращения после приземления. Измерения - в геометрических углах. Можете вовсе не задействовать эту строку, если не хотите, чтоб обломок переворачивался
}
Вот и все. Сохраняйте документ с расширением my_map.SCRIPT (my_map - имя вашей карты и никакое другое имя!). Сохраните в одной папке с картой. Весьма просто оказалось, не правда ли? Но именно таким образом можно двигать любые предметы (назначив им func_mover или прибиндив к нему), рушить плиты и скалы, швыряться дверями и катать игрока на поездах.
Здесь описан пример для одного обломка. Думается, вам не составит труда повторить то же самое с другими. А сам скрипт вызывается триггером (используйте уже созданный - чего мудрить-то), прописав в его параметрах Key: call, Val: my_script \\имя вызываемого скрипта.
Для пущего реализма пропишите в свойствах осколков Key: damage, Val: 1. Тогда долетевшие до игрока обломки будут больно ранить его. Если соприкосновение окажется продолжительным - то и вовсе убьет, поэтому рассчитайте место приземления таким образом, чтобы осколок не врезался в игрока, а, скажем, немного не долетал до него. Тогда игрок, пробежав по инерции небольшой отрезок пути, непременно столкнется с вашим "подарочком". Кстати, обломок смертоносен не только для игрока, но и для монстра. На карте Refueling Station кусок плиты, упавший с потолка, насмерть придавливает свежетелепортировавшегося по нашу душу импа.
В общем, при известной фантазии можно реализовать много чего оригинального. Чего я вам, собственно, и желаю.
Немаловажное примечание от C4tnt:
в примере про каменную стену скрипты можно объехать на кривой козе :) Для этого нужно, как и в HL нарезать браш кусочками, тем кусочкам, которые полетят, поставить func_moveable(_domino) и выставить поле nodrop в 1 и поля init_velocity и init_avelocity;
первое - вектор скорости в формате X Y Z, второе - угловая скорость. В результате такой moveable прикидывается стеной, пока его не затриггерят, а потом стартует с указанной скоростью. И вместо trigger_once можно использовать trigger_relay, он не реагирует на игрока вообще, только на другие триггеры.
|
[1] [2] [3] [4] [5] [6] [7] [8] [9]
Ветка DOOM-ностальгияСтатьи о DOOM
|
Большинство предоставленного здесь материала является цитированием со старых номеров компьютерных журналов, таких, как
"Мир ПК" или "Весь Компьютерный Мир". К сожалению, все мои попытки связаться с этими изданиями по поводу вопроса о цитировании были безуспешны.
Издания упорно хранили молчание. Что я разрешил себе расценивать как знак согласия, указывая, тем не менее, повсюду как выходные данные
издания (с работающей ссылкой на Интернет-представительство), так и автора публикации. Тем более, что, в силу срока давности этих публикаций, вряд ли материал можно рассматривать как коммерческий или рекламный,
пусть даже названия фирм здесь и присутствуют (уж без этого никуда).
Ежели появятся какие претензии по оному поводу, прошу
издания связаться со мной
Райво Штулберг |