Zdoom Mapping, иммитация многоэтажности без порталлов. Часть первая — телепортирующий лифт.

Всем привет ребята. Давайте поговорим сегодня с вами о иммитации многоэтажности без применения порталлов. Сразу сделаю оговорку, что настоящих порталлов из новых версий GZdoom в моих уроках не будет, т.к. моя направленность в конвертировании карт была на Zandronum. Таких уроков будет несколько и надеюсь они будут вам полезны. Желательно читать данные уроки по порядку, чтобы не упустить нити деталей. И так приступим.
Снова вернёмся к игре Duke 3d и к его движку — Build. Вообще первоначально прикол с лифтом был далеко не в дюке, а в TekWar, т.к. технически она является самой первой игрой на билде. Правда использовался прикол с таким лифтом там не шибко часто, да и движок там на несколько версий ниже… Но разговор не об этом. Именно в дюке данную систему очень часто применяют для иммитации многоэтажности. К счастью в думе, конкретно в АЦС есть одна интересная функция, которая позволяет воссоздать такие лифты на достаточном уровне. Давайте теперь определимся с такими вещами:
— На нашей карте есть, грубо говоря, 2 этажа друг на другом.
— На этажах нет прозрачных полов.
— Нам не обязательно видеть эти этажи снаружи, чтобы не получился «нереальный мир».
— Нам не хочется тормозов от 3д полов и хочется больше свободы на этажах в плане детейла.
— Возможно соединить 2 этажа лифтом.
С задачами определились. Давайте с вами нарисуем по размеру 2 комнаты, которые будут на разной высоте друг от друга и будут соединяться лифтом между собой. Например вот так:

Не обращайте внимания, что всё в упрощённом виде — это для простоты понимания процесса. На практике единственное связующее звено-якорь в этом всём — это лифт. Обратим внимание на скриншот — у нас есть две этажа на разной высоте. У обоих этажей есть один лифт. Лифты одинаковы в плане геометрии и текстурирования. Позже вам станет понятно почему именно так.
Следующий наш шаг — нумеруем наши сектора уникальными тэгами, ставим телепорты-якоря, которым так же задаём уникальные тэги. А так же ко всему этому давайте сделаем 2 свитча-переключателя(я их делаю одиночным линиями). Например вот так:

Первая мысль — почему телепорты в таком месте? Вообще технически телепорты могут быть вообще в любом месте, есть 2 строгих правила — связующие сектора(в данном случае сектора лифтов) должны быть строго одинаковой формы. Конкретно в данном случае должна быть и ещё одинакова везде высота. Второе правило — их телепорты-якоря должны быть строго в одинаковой позиции относительно связующих секторов.
Вроде бы всё, но нам теперь надо провести пару математических расчётов. В моём примере высота у первого этажа равна нулю, а высота второго этажа — 216. Высота сектора лифта — 72. Что эти цифры нам дают? А дают они то, что у нас есть «промежуток между этажами». Практическим методом я выяснил, что высота пола у лифта должна быть 128, в этот момент не видно ни нижний, ни верхний этажи. Запоминаем эту высоту и обращаемся теперь к ACS:
— Нам нужно, чтобы пол и потолок у лифта двигались одновременно
— Нужно проверять текущую высоту
— Нужно запоминать позицию
— Нужно как то перемещать игрока из сектора в сектор через телепорт-якорь.
Открываем в редакторе карт редактор скриптов и пишем вот такой скрипт:

int Elevator1Pos = 0; //Глобальная переменная для «запоминания» позиции лифта

script 1 (void)
{
if(Elevator1Pos == 0) //Лифт едет вверх
{
FloorAndCeiling_RaiseByValue(1, 16, 216); //Пол и потолок поднимаются вверх
FloorAndCeiling_RaiseByValue(2, 16, 216);
SetFloorTrigger(1, 128, 78, 1, 3, 4, 0, 0); //Действие при поднятии сектора лифта на 128 единиц
TagWait(1); //Свитч ждёт, пока лифт не встанет
Elevator1Pos = 1; //Глобальная переменная, которая «помнит» позицию лифта
}
else //Лифт едет вниз
{
FloorAndCeiling_LowerByValue(1, 16, 216); //Пол и потолок опускаются вниз
FloorAndCeiling_LowerByValue(2, 16, 216);
SetFloorTrigger(1, -128, 78, 2, 4, 3, 0, 0); //Действие при опускании сектора лифта на 128 единиц
TagWait(1); //Свитч ждёт, пока лифт не встанет
Elevator1Pos = 0;
}
}

И так, давайте подробнее разберём по подробнее этот скрипт. И да, да, кто то меня сейчас обвинит и скажет — «ты спёр его с DoomVacation!» И да — вы будете правы, но я его переработал, чтобы он нормально работал под UDMF(в оригинальном скрипта из того мода некорректно работала телепортация).
Вернёмся к скрипту.
Конкретно нас интересует 2 самых важных функции:
SetFloorTrigger(1, 128, 78, 1, 3, 4, 0, 0) — эта функция следит за высотой пола и выполняет какое либо действие, как только лифт поднимается на 128 единиц. Если число будет отрицательным, то функция будет следить за уменьшением высоты сектора. Там же число 78 — это номер ACS функции(TeleportInSector), 1 — это сектор ИЗ которого телепортируется игрок, 3 и 4 — это телепорты-якоря(телепорт 3 в секторе №1 и телепорт 4 в секторе №2). По сути можно повесить туда любую другую функцию, вопрос лишь в кол-ве параметров.
TagWait(1); — очень полезная функция, она заставляет свитч «ждать», пока наш лифт не встанет на месте. Это позволяет отсеить баги с преждевременным переключением позиции.

И так, со скриптом разобрались, вешаем наш скрипт на свитчи лифта:

И радуемся результату. Например от такому:


И так под конец окончание наверное… Чем же может это всё помочь? Ну например хотя бы тем, что при должном подходе можно сделать действительно подобие многоэтажности. Главный связующий «якорь», который должен быть одинаковый — это лифт, а технически этажи можно делать и разные. При должном подходе можно сделать три и более этажей, например если внедрить систему из двух свитчей. Какие идеи можно для этого брать? Ну первая мысль которая приходит мне на ум — отель с номерами. А на картах с космическим дизайном можно вытворять и «небывальщину» — делать «нереальные миры», главное чтобы лифт был всегда одинаков)
Вот впринципе и всё, пользуйтесь! Милости прошу в комменты с вопросами по тех. части)

avatar

Пожалуйста отключи блокировщик рекламы, или внеси сайт в белый список!

Please disable your adblocker or whitelist this site!