Руководство для начинающих от Derveeen
Бьендгайд от Дервена Часть 1
В языке DM(dream maker) все объекты, что мы создаем делятся на две важные части: 1. datum — их нельзя поставить на карту 2. atom — их можно поставить на карту atom —аббревиатура, расшифровывается как area turf object mob, это значит что ты пидар что все перечисленные в ней типы являются подтипами atom, и их можно ставить на карту. У каждого объекта могут быть свои методы(proc), свойства(var) независимо от того, является ли он атомом или датумом. Но пока рано переходить к этому, важно запомнить, что бьенд учитывает отступы и они играют определенное значение! Например, если мы напишем:
obj
vasya
То мы создадим объект vasya, который является подтипом obj. Таким образом благодаря табуляции мы помогли дрим мейкеру правильно понять иерархию объектов, что и к чему относится. Теперь поговорим о методах и свойствах. Если говорить простыми словами, то методы — это те действия, которые может выполнить объект. Свойства — это переменные, которые говорят нам о каких-то показателях (здоровье, инвентарь), важно понять, что свойством может быть и другой объект, например, перчатка на нашем персонаже. Также у всех объектов есть встроенные методы и свойства. Чтобы проиллюстрировать все это я приведу пример:
obj
cverkun luminosity = 0 var message = ‘я не свечусь’ //с помощью var мы объявили нашу переменную, и // определили(задали) её значение. И да, двойной слэш означает комментарии proc/switch_me() luminosity = 1 message = ‘я свечусь’
У цверкуни, как и у всех объектов есть встроенное свойства luminosity, оно освещает столько тайлов, сколько мы укажем. При значении равном 0, ничего не будет светится. Также мы объявили переменную и определили её значение, так как мы поставили количество табуляций ровно на 1 больше, чем у cverkun данные свойства принадлежат именно к этому объекту и его подтипам. Также мы создали для cverkun метод(proc), который заставляет наш объект светиться на 1 тайл и записывает ему в message ‘я свечусь’
Как же нам задействовать то, что мы написали? Вариантов много, например мы можем использовать конструктор New() в качестве команды, с которой начнет свое выполнение наш метод cverkun.
obj
cverkun luminosity = 0 var message = ‘я не свечусь’ //с помощью var мы объявили нашу переменную, и
// определили(задали) её значение. И да, двойной слэш означает комментарии
proc/switch_me() luminosity = 1 message = ‘я свечусь’ New() switch_me() world << message //<< и >> означает вывод и ввод, с помощью этой //команды мы выводим на всеообщее обозрение значение message
То есть теперь, если мы поместим наш объект на карту, то при его создании дрим мейкер должен будет выполнить все то, что мы прописали под New().
Но как вы могли догадаться кроме того, что мы можем с помощью языка ДМ менять luminosity обжекта при его создании, возможностей в дрим мейкере много. И множество тонкостей.
Взаимодействие с объектами. Есть много вариантов взаимодействия, начнем с кнопок. Кнопка, или verb позволяет пользователю взаимодействовать с миром бьенда через специальный интерфейс, который на космической станции, к примеру, расположен справа, вверху. verb’ы могут разделяться на вкладки, таким образом их можно расположить удобным для пользователя образом. Покажем пример работы verb’a на примере:
/mob
dog verb/gav_gav() set category = "gav" set name = "sobaka" world << "gav-gav!"
Итак, данная кнопка будет иметь имя “sobaka” где имя задается с помощью set name = "sobaka" и будет расположено во вкладке панели “gav” где вкладка задается с помощью set category = "gav". “gav-gav!” будет выводиться всем при нажатии на кнопку. Используя set можно задать многие интересные параметры, не только имя кнопки и имя вкладки: set desc = text — где text - это описание кнопки, будет высвечиваться в левом нижнем углу; set hidden = 1 или 0 — где 1 и 0 означают видимость и невидимость соответственно; set popup_menu = 1 или 0 — где 1 и 0 означают, выводить при правом клике на объект действие в списке действий или нет; set instant = 0 или 1 где 0, значит что мы можем вызывать наш верб сколько угодно раз в секунду, а 1 значит, что максимум раз в секунду мы можем использовать наш верб. Таким образом иногда делают защиту от спама; set invisibility = от 0 до 100. Это довольно интересный параметр, дело в том, что у каждого объекта есть некоторое значения invisibility, назовем это условно слоями видимости, и на каждом слое видимости расположены разные объекты. Например мы можем не видеть призрака так как его invisibilty выше, чем наше значение встроенного свойства see_invisible. Так вот в данном, случае от see_invisible зависит не видимость объекта, а видимость кнопки; set src = view() или oview() или world или world.contents или usr или usr.contents или usr.loc — пожалуй нам нужно разобраться, что такое списки, чтобы полностью понять смысл, но пока нам не нужно понимать полностью и этот верб выполняется для того, что за знаком «=», к примеру если там view(), то мы можем выполнить верб для всех объектов определенно подтипа в зоне видимости нашего моба.
Помимо кнопок в текущей части мы разберем еще кое-что. Разберем Bump() и немного общих понятий.
/mob
Bump(var/atom/O) if(istype(O, /turf/wall))
world << "Bump!"
Итак, вот у нас есть метод Bump, где в качестве аргумента используется какой-то атом, далее мы используем proc istype(type_a, type_x) внутри нашего условия. Если тип type_a эквивалентен type_x, то вернется true, иначе false. Если в условии возвращается false, то тело условия не выполняется, если возвращается true, то выполняется. Все довольно просто. Итак, что же это за метод? Он вызывается, когда что-то врезается во что-то, в данном случае mob врезается в O, где O это некий атом, если этот атом является стеной и условие возвращает true, то выполнится тело условия и мы выведем “Bump!”. Иными словами, если мы врежемся в стену, то бьенд напишет "Bump!" всем пользователям в игре.
Важно помнить, что если мы пропишем
/turf/wall
Bump(var/atom/O) if(istype(O, /mob)) world << "Bump!"
То ничего не будет работать, так как стена недвижимый объект и она не может врезаться в моба. Да, «стена врезается в моба» и «моб врезается в стену» это разный код, и он не равнозначен.
Взаимодействие с объектами Enter(). Этот способ взаимодействия используется, когда мы пытаемся войти куда-то. Именно войти, если мы просто будем стоять на одном тайле с чем-то, данный способ не будет работать. Для справки, когда мы перемещаемся куда-то, мы записываем себя в список под названием contents, который есть у всех atom, о которых говорилось в первой части. Даже когда мы просто жмем на стрелочки и ходим по тайлам мы переносим себя из contents одного тайла в contents другого. Когда мы закрываемся в шкафу, мы тоже переносим себя из contents тайла в contents шкафа.
Так как с этим работать? Легко. Допустим у нас есть тайл с лавой, мы хотим чтобы при попадании на него нас отправляло в вальгаллу. Достаточно сделать вот такой код:
/turf/lava/Enter(var/mob/nash_mob) //фиксируем попадание на тайл с лавой
nash_mob.Move(valhalla) //перемещаем моба в вальхаллу return 1 //разрешаем мобу наступить на тайл
Хм. return. Помните, когда мы говорили о условиях и о том, что true или false должно быть возвращено каким-то proc’ом? Так вот, в данном случае мы сами возвращаем то, что нужно. А нужно нам именно 1, так как если вернуть 0 при работе с методом Enter() мы не сможем наступить на тайл. Это особенность этого конкретно прока, если что. Ах да, Move(). Данный метод вызывается для того, чтобы переместить объекты, где в качество аргумента используется точка перемещения. Это может быть другой объект либо же координаты заданные через locate(x, y, z).
Exit(). Зеркальное отражение Enter(), работает точно также, но срабатывает когда мы пытаемся выйти откуда-то, то есть удалить себя из contents какого-то atoma’a.
Взаимодействие с объектами
Click() — метод, переопределяя который мы можем привязать действие, к, собственно, клику. Вот так оно работает:
obj/bomb //бомба
Click() //клик
world << “boom!” //получили взрыв. Просто до безумия
Среди похожих можно отметить DblClick(), единственное отличие лишь в том, что нужно сделать не клик, а двойной клик. MouseEntered() — мы навели курсор на что-то, MouseExited() — мы убрали курсор с чего-то, MouseMove() — мы водим по какому-то атому курсором.
Задержки
Задержки — важный инструмент при разработке в бьенде. Они могут быть использованы, чтобы симулировать процессы, протекающие в течении времени (рост растений в гидропонике, кровотечение, старение, голод, болезнь, что угодно). Могут быть использованы, чтобы просто сделать какую-то паузу, как когда мы разбираем/собираем стену, например. Но все не так просто, паузу можно сделать двумя разными путями и сейчас мы их разберем.
sleep(num) — пока не пройдет время num другие proc’и конкретного атома не смогут выполняться. Надо использовать с осторожностью и умом. spawn(num) — задержка, при которой другие proc’и смогут выполняться несмотря на эту паузу. Не стоит ставить слишком маленькое время num для каких-то сложных и объемных proc’ов. Чтобы пауза работала, действия выполняемые через эти промежутки времени должны быть сдвинуты от spawn(num) на одну табуляцию вперед.
С задержками связано очень много, подробнее о применении с примерами и вероятными проблемами, я расскажу в следующей части. Спасибо за внимание.
/turf/valhalla /Exit (var/mob/nash_mob) //фиксируем попадание на тайл
nash_mob << “Нельзя выйти отсюда” //выводим мобу сообщение
return 0 //не разрешаем мобу выйти с тайла
Cross(). Работает почти абсолютно таким же образом как Enter, но отличие в том, что в данном случае фиксируется как раз наступание на объект, а не перемещение в него. То есть, мы должны просто попасть на один тайл с объектом. И да, наступание тоже можно блокировать с помощью return 0.
/mob/snek/Cross(var/mob/nash_mob) //фиксируем наступание на змею
nash_mob << “no step on snek ” //выводим мобу сообщение return 0 //не разрешаем мобу наступить на snek