Особая память: notable-объекты
Некоторые объекты заслуживают внимания
Некоторые из ваших объектов на сервере действительно заслуживают внимания! Точка спавна очень важна! Центральная зона города — место бурной активности игроков!
Скорее всего, вам приходится ссылаться на некоторые из этих объектов очень часто. Более того, часто нужно ссылаться на них в ключевых местах — например, в строках событий. Может быть, вы хотите событие, которое срабатывает, когда игрок входит в регион вашего города или выходит из него, и показывает приветственное/прощальное сообщение. Сценариев использования — масса.
Лучший инструмент для подобных случаев — система Notable Objects в Denizen.
Некоторые типы объектов — notable
Система notable поддерживает лишь несколько ключевых типов объектов в Denizen. Это локации, области и инвентари.
Когда тип объекта является «notable», это значит, что вы можете создать «note» для любого объекта такого типа. «Note» — это, по сути, глобально уникальное имя-ссылка на этот объект. Представьте себе разновидность серверного флага, где имя note — это имя флага, а сам объект — значение флага.
Тогда почему бы просто не использовать серверные флаги?
У noted-объектов есть несколько важных преимуществ по сравнению с обычными серверными флагами:
Когда объект «занотирован», запоминается именно этот объект, а не его копия. То есть если вы измените объект, вы на самом деле меняете объект в note, и вам не нужно снова вызывать команду
note(в случае с флагом после любых изменений пришлось бы снова вызывать команду flag, чтобы положить результат обратно во флаг).Объекты «знают» своё имя note. Например, обычный
LocationTagидентифицируется какl@0,64,0,world, но если вы занотируете эту локацию с именемspawn, она дальше будет идентифицироваться какl@spawn. Узнать имя note любой локации можно тегом<[some_location].note_name>.На note можно ссылаться просто по имени. Если у вас есть
LocationTag, занотированный под именемspawn, в скрипте достаточно написать- teleport <player> spawn, чтобы отправить игрока на спавн — одного только имениspawnдостаточно, чтобы Denizen понял, что вы имеете в виду. (В случае с флагом пришлось бы писать- teleport <player> <server.flag[spawn]>— целый тег, чтобы уточнить, на что вы ссылаетесь.)На note можно ссылаться в строках событий. Если у вас есть
CuboidTag, занотированный какmain_town, вы можете писать события вродеon player breaks block in:main_town:, и событиеbreaks blockбудет срабатывать только когда блок находится внутри города, заданного вашей noted-областью. Это самый важный сценарий использования note, и ниже на этой странице мы рассмотрим его подробнее.У note стабильное персистентное уникальное состояние. Звучит замысловато, но суть простая: если вы занотируете
InventoryTag, этот инвентарь смогут открыть несколько игроков, они смогут перекладывать в нём предметы, и каждый увидит изменения остальных, а после перезапуска сервера содержимое останется ровно в том виде, в каком его оставили игроки, — и всё это автоматически.
Так как же создать note?
Здесь, как и в большинстве подобных «не-для-начинающих» вопросов в Denizen, ответ таков: возьмите ключевое слово из своего вопроса и загляните в поиск по документации. В нашем случае вы наверняка найдёте команду note, которая делает ровно то, что написано.
Базовый синтаксис команды note выглядит так: - note [<object>/remove] [as:<name>]
Вход object, разумеется, принимает любой объект одного из notable-типов. Вход as:<name>, разумеется, принимает имя, которое вы хотите дать note.
Давайте попробуем на примере.
Note для локации
Note локации — не самый полезный тип note, но они создаются быстро и просто, и могут сделать многие скрипты аккуратнее и проще.
Встаньте в какой-нибудь важной точке вашего мира (или просто бросьте золотой блок посреди пустыря и для пробы команды объявите его важным) и наберите /ex note <player.location> as:importantspot

Команда /ex обычно используется для тестирования, но в данном случае вам больше ничего и не нужно. После выполнения /ex note эта note существует на сервере постоянно (пока вы её не удалите) и уже содержит все нужные данные.
Теперь снова воспользуемся /ex, на этот раз — чтобы протестировать note. Отойдите от локации и наберите /ex teleport <player> importantspot. Если всё прошло как надо, вы телепортируетесь обратно ровно в ту же точку.
С этих пор вы можете использовать тот же /ex note для любой важной локации и с любым именем, а затем применять простой синтаксис — просто указать имя в команде teleport (или в команде modifyblock, или в любой другой команде, принимающей локацию) как в скрипте, так и в /ex. Учтите, что при желании создавать note динамически вы, конечно, можете вызывать - note прямо из скрипта.
Частые вопросы про noted-локации
Когда вас в примере выше телепортировало ровно в ту же точку, вы, возможно, заметили: это та самая точка. Если вы стояли у края блока — вас телепортирует к этому краю; если смотрели вниз — будете смотреть вниз. Если хотите изменить результат, первое очевидное решение — встать в другое место и пересоздать note. Если хочется большей точности, можно, конечно, просто изменить тег, который вы использовали при создании note. Например, чтобы отцентрировать локацию, используйте /ex note <player.location.center> as:importantspot. Чтобы выровнять углы поворота — например, /ex note <player.location.with_pitch[0].with_yaw[90]> as:importantspot.
Возможно, вам захочется занотировать локацию рычага, кнопки, двери и т. п. для использования в команде switch, чтобы скрипт автоматически что-то активировал, и окажется, что просто стоя в нужной точке точно отметить локацию непросто. Что делать? Просто! Наведите курсор на блок и введите /ex note <player.cursor_on> as:lever. Тег cursor_on вернёт локацию блока, на который вы смотрите, а не того места, где вы стоите.
Note для области
Пожалуй, самый важный — или, по крайней мере, самый распространённый — тип объектов, для которых создают note, — это объект-область. Это категория, в которую входят CuboidTag, EllipsoidTag и PolygonTag — разные способы ограничить участок мира: внутри прямоугольной коробки, внутри круглой области или внутри многоугольника.
Команда и синтаксис для создания note у областей те же, что и у локаций; отличается только то, как именно создаётся сам объект.
Note для кубоидов
Кубоиды — крайне распространённый способ задавать области. Если вы когда-нибудь пользовались WorldGuard, общая идея кубоида вам знакома. У кубоида есть два угла, и он включает в себя все блоки в пределах коробки между ними. Заметьте, что границы кубоида задаются в блоках и не могут иметь дробных значений.
Для очень быстрого и простого примера: встаньте в одном углу комнаты, посмотрите на противоположный угол и наберите /ex note <player.location.to_cuboid[<player.cursor_on>]> as:myroom.

Чтобы проверить, что всё сработало, походите по комнате и набирайте /ex narrate <player.location.is_within[myroom]> — пока вы в комнате, в выводе будет true, а как только выйдете — станет false.
Удобный скрипт
Скорее всего, вы сейчас думаете: «это же такой неудобный способ, я бы хотел волшебную палочку, чтобы ткнул — и готово» — и вам повезло! Это же Denizen, а значит, работа с note для областей завязана на теги и команды, а такая задача легко решается скриптом. Более того, поскольку запрос очень частый, уже существует качественный готовый скрипт, который делает ровно это — выдаёт вам волшебную палочку для выделения областей и создания note. Скачать его можно здесь, в разделе ресурсов на форуме Denizen.

Чтобы им воспользоваться, просто скачайте файл .dsc и положите его в папку со скриптами. Если хотите, пройдитесь по нему в редакторе скриптов, чтобы посмотреть, что и как он делает. Когда будете готовы, зайдите на сервер и наберите /ex reload, чтобы загрузить скрипт, а затем /seltool, чтобы получить волшебную палочку. Левый клик по любому блоку начинает выделение, правый — расширяет его. Скрипт автоматически подсвечивает частицами уже выделенную область. Когда область выделена, наберите /selnote myareaname. Готово: у вас есть noted-кубоид с именем myareaname.
Использование area-note
Итак, как же воспользоваться этой area-note? Во-первых, конечно, её можно использовать в тегах вроде is_within из примера выше. Её можно использовать и в командах — частый пример для кубоидов: команда schematic принимает кубоид в качестве входа. Но чаще всего area-note применяют в событиях.
Один из распространённых вариантов использования area-note в событиях — событие входа/выхода в область. Оно используется с синтаксисом [on/after] player [enters/exits] <note-name>:. Попробуем на таком примере:
cuboid_note_sample:
type: world
events:
after player enters myroom:
- narrate "hi <player.name> welcome to my room!!!"
after player exits myroom:
- ratelimit <player> 10s
- narrate "oh bye <player.name>"
С загруженным скриптом вы можете зайти в область, занотированную как myroom, и каждый раз получать приветствие. Когда выйдете — получите сообщение bye, но не чаще одного раза в 10 секунд: команду ratelimit мы используем, чтобы не было спама.
Ещё один очень распространённый способ использования area-note — переключатель in:<area>. Когда вы будете просматривать документацию по событиям, во многих из них встретите строку вида Has Location: True - This adds the switches 'in:<area>', 'location_flagged:<flag>', .... Для любого такого события можно написать, например, следующее:
in_area_sample:
type: world
events:
after player places block in:myroom:
- narrate "hey <player.name>! get that block outta here!"
С этим скриптом каждый раз, когда вы ставите блок в my room, таинственный голос будет требовать, чтобы вы убрали его. Если поставите блок где-то ещё — ничего не произойдёт.
Ограничивать события подобным образом полезно в бесчисленных сценариях. Можно реализовать защищённые регионы — в некоторых зонах нельзя ставить/ломать блоки, для чего используется determine cancelled; можно запретить PvP или что-то ещё. Можно сделать так, что в отдельных зонах всё работает чуть иначе — например, в особом озере рыбалка приносит вдвое больше добычи, через событие player fishes in:special_lake. Игроки, погибшие в вашей арене, могут возрождаться прямо у входа на арену, а не на глобальном спавне. Предел — только ваше воображение!
Note для эллипсоидов
Note для эллипсоидов работает в целом так же, как для кубоидов, просто они более круглые. И, в отличие от кубоидов, значения у эллипсоидов могут быть дробными.
Не буду тянуть: вы можете делать всё то же самое, просто вместо слова cuboid используйте ellipsoid. Если вы пользуетесь готовым скриптом по ссылке выше, просто введите /seltool ellipsoid или /etool, чтобы получить волшебную палочку, левый клик — начало, правый — расширение, а /selnote — создание note.

Эллипсоиды в событиях и командах используются ровно так же, как и кубоиды.
Note для полигонов
С полигонами всё немного сложнее. Полигон задаётся минимальным и максимальным Y (высотой) и набором угловых точек. Углы должны обозначать внешние границы полигона. Если рёбра полигона пересекаются, внутри полигона появятся «дыры». Координаты углов полигона могут быть дробными.
Если не считать более хитрого способа создания, в остальном они используются так же, как кубоиды и эллипсоиды, — есть команды и теги, работающие с полигонами, и любой вход события, принимающий «область», принимает полигон точно так же, как эллипсоид или кубоид.
Если вы пользуетесь готовым скриптом-селектором, введите /seltool polygon или /ptool, чтобы получить волшебную палочку, затем левым кликом выберите первую угловую точку области, а правым — каждую следующую точку. Будьте внимательны с выбором блоков: двигайтесь в одном направлении (по часовой стрелке или против), не разворачивайтесь назад, не загибайте контур внутрь себя и не проскакивайте стартовую точку. После того как вы поставите минимум 3 угла, появятся частицы. Если хотите расширить полигон вверх или вниз, подлетите на нужную высоту и введите /selheight. Если всё это звучит запутанно… просто попробуйте и поэкспериментируйте немного — скорее всего, вы во всём разберётесь, когда увидите, как частицы очерчивают вашу область. Если потеряетесь, не стесняйтесь зайти в Discord и спросить совета.

Note для инвентаря
Чтобы создать note для инвентаря, нужен конструктор инвентаря. Это может быть inventory-скрипт или общий конструктор.
Вот пример inventory-скрипта:
my_inventory_script:
type: inventory
inventory: chest
size: 27
title: Backpack
Чтобы воспользоваться общим конструктором, нужно написать что-то вроде <inventory[generic[size=27;title=MyInv]]>. Это выглядит довольно громоздко, поэтому inventory-скрипты удобнее, но общий конструктор может пригодиться для быстрых тестовых инвентарей.
Чтобы создать note из инвентаря, команда выглядит так: /ex note <inventory[my_inventory_script]> as:my_inv_note. Здесь тег-конструктор inventory нужен, чтобы команда note поняла, объект какого типа мы хотим занотировать.
Inventory-скрипт — это способ сконструировать инвентарь: каждый раз, когда вы открываете my_inventory_script, он генерирует новый инвентарь. А note для инвентаря — это один конкретный инвентарь.
На практике это означает вот что: если несколько игроков выполнят - inventory open d:my_inventory_script, каждый увидит свой отдельный инвентарь. А если несколько игроков выполнят - inventory open d:my_inv_note, у всех будет открыт один и тот же инвентарь. То есть если один игрок переложит предмет, все остальные тоже увидят это перемещение.
Содержимое noted-инвентаря сохраняется между сессиями. Это значит, что если вы руками переложите предметы в note-инвентаре, закроете и снова откроете его — содержимое останется тем же. Даже после перезапуска сервера содержимое будет ровно в том виде, в каком его оставили. Распространённый пример использования — скрипт рюкзака: пара из простого inventory-скрипта, как в примере выше, и command-скрипта /backpack, который открывает note-инвентарь, уникальный для игрока, — обычно создаваемый командой вроде - note <inventory[my_backpack_script]> as:backpack_<player.uuid> и открываемый командой - inventory open d:backpack_<player.uuid>. Так у каждого игрока появляется свой персистентный рюкзак — что-то вроде второго эндерчеста.
Имена note-инвентарей можно использовать и в событиях, во всех тех же местах, где допустимы имена inventory-скриптов. Например, after player opens my_inventory_script: и after player opens my_inv_note: обе сработают при открытии note, потому что note был создан из скрипта — обе строки события применимы.

Редактирование note
Редактировать note можно двумя способами:
Первый — просто перезаписать note новой командой note. Не нравится положение вашего LocationTag с именем spawn? Просто встаньте в более удачное место и снова выполните /ex note <player.location> as:spawn.
Второй способ удобен для ряда продвинутых сценариев, особенно с note-инвентарями: команда adjust. Любой механизм, применённый к noted-объекту, будет применён напрямую к исходному объекту в note. С командой adjust вам нужно явно указать тип объекта во входе через тег-конструктор. Например, чтобы поменять заголовок noted-инвентаря, выполните /ex adjust <inventory[my_inv_note]> title:NewTitle. Можно свободно использовать и другие команды над этим объектом. Например, /ex give stick to:my_inv_note добавит палку в этот noted-инвентарь.
Удаление note
Если note больше не нужна, удалить её просто: /ex note remove as:<name>. Вместо объекта введите литеральное слово remove. Вот и всё — note с указанным именем больше не существует.
Имейте в виду: сам по себе лежащий в основе объект при этом не уничтожается. Например, если вы удалите note-инвентарь, а какой-то игрок в этот момент держит его открытым, инвентарь останется открытым и рабочим, пока игрок не закроет его, — просто имя note на него больше не ссылается.
Частые вопросы
Что-то плохое случится, если выполнить команду
noteс уже существующим именем? Существующая note будет удалена и заменена новой. Ничего не сломается, если только вам не нужна была та самая старая note.Как лучше именовать свои note? В целом — как хотите. Главное помнить, что список note общий для всех скриптов на сервере, поэтому лучше давать имена так, чтобы избежать риска, что два разных скрипта попытаются использовать одно и то же имя. Так что примеры имён вроде
importantspotиleverдля реального использования, наверное, не очень подходят. Лучше подойдут имена вродеquest_savethecows_lever(в этом примере на сервере есть квест под названием «спаси коров», а рычаг относится именно к нему). Тем не менее, для note часто нормально работают и простые имена — например, занотировать локацию с именемspawnвполне разумно: сколько точек спавна может быть на одном сервере? И конечно, как всегда, соблюдайте общие правила чистых имён — простые слова, без пробелов, без странной капитализации, без символов кроме нижнего подчёркивания_. Это не обязательно, просто рекомендация, чтобы всё было аккуратно.