Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

Туториал Denizen

Продолжать?

snr93

Активный участник
Пользователь
Баллы
88
Данный пост будет посвящен плагину Denizen.
Я создаю RPG сервер, и, среди кучи плагинов мне все же приглянулся Denizen своей гибкостью, так же он поддерживает формулы!
Итак, сервер у меня 1.8.8., поэтому и данный материал будет для 1.8.
Так же надеюсь, что информация, которую я тут буду писать, поможет другим людям делать более качественные и интересные сервера.
P.S. на момент написания версия Denizen for 1.8.1Jul 18, 2015
http://dev.bukkit.org/bukkit-plugins/citizens/ - это основа, без него denizen не будет работать
http://dev.bukkit.org/bukkit-plugins/denizen/ - сам плагин, по которому будет информация
Citizens + Denizen это весьма мощная связка для того, чтобы делать задачи, квесты и многое другое! Я думаю, если ты это читаешь, то что такое citizens рассказывать не нужно, а Denizen, это дополнение возможностей к NPC! Все буду стараться рассматривать с примерами.
P.S. я сам только учусь. Буду рад дополнениями подсказкам!

Итак, все скрипты пишутся руками в текстовых файлах с расширением yml. Этот файл нужно открывать любым текстовым редактором. Советую Notepad++, т.к. там есть подсветка кода. Так же все конфиги должны быть в UTF-8 без BOM! Иначе весь русский текст у вас кракозябрами. Чтобы это сделать в notepad++, выбираем кодировки -> преобразовать в utf-8 без bom

npc assignment --set <имя скрипта> - задать скрипт выбранному npc
denizen reload config - перезагрузить конфиг
denizen reload scripts - перезагрузить только ваши скрипты
denizen reload -a - перезагрузить весь плагин

zap 'имя шага'- прыгнуть на какой-либо шаг
disengage - завершает скрипт
execute as_server 'команда' - выполнить от имени консоли
determine cancelled - отменяет последнее действие
determine <переменная или название предмета> - заменяет что-либо на указанную переменную или предмет
<параметры> to_console - вывести итог в консоль
random <число> - выполнить рандомное действие из списка
look <куда> - npc смотрит куда ему указано
chat 'текст' - выводит текст в чат
narrate 'текст' - выводит неоформленный текст в чат
playeffect <имя эффекта> <где> qty:количество - выводит эффект в нужном месте с определенным количеством
debug: false | true - выводить ли в консоль все исполнение скрипта. Указывается после type

<npc.name> - выводит название npc
<npc.location> - считывает координаты npc
<player> - вернет ваш UUID номер
<player.name> - вернет ваш ник
<player.location> - считывает координаты игрока, который обращается к скрипту\npc
<player.health> - считывает кол-во здоровья у игрока
<player.health.max> - считывает максимальное кол-во здоровья у игрока
<context.material> - показывает блок, с которым произошло взаимодействие

&& - означает и
|| - означает или

<&co> - заменяет знак :

Все цвета указываются в скобках <>
<green> - зеленый
<red> - красный

on player breaks <имя блока> - если игрок разрушил этот блок, то что-то делаем
on player breaks block - если игрок разрушил любой блок, то что-то делаем

click trigger - срабатывает, когда на NPC щелкают правой кнопкой мыши(ПКМ)
chat trigger - срабатывает, когда в чате появляется определенная фраза или слово

Этого нам хватит, чтобы написать первый скрипт. Давайте напишем телепортиста.
Итак, создаем файл, я его назову teleport.yml, вы можете по другому
И начинаем писать
Код:
Teleport: #имя скрипта
  type: assignment #говорим что это задание
  debug: false #выключаем вывод в консоль
  interact scripts: #скрипт, с которого начинаем
  - 100 telep #указываем перезагрузку 100 секунд и название, с которого начинаем

telep: #название
  type: interact #говорим что это задание
  steps: #начинаем создавать шаги
    "question*": #первый шаг, * на конце нужна, если в скрипте есть несколько вариантов
      click trigger: #срабатываем только когда кликнули по NPC
        script: #пишем тело скрипта
        - random 2 #говорим, что будем использовать любой из 2 вариантов сообщений чата ниже
        - chat 'Ты хочешь чтобы я тебя перенес со спавна?' #первый вариант
        - chat 'Хочешь телепортироваться со спавна?' #второй вариант
      chat trigger: #назначаем триггер чата, он отслеживает сообщения или слова
        'Yes': #Имя триггера
          trigger: '/Да/!' #Если в чат написали да(без разницы как: да, Да, дА, ДА)
          script: #что делаем, если увидели да
          - chat 'Хорошо! Сейчас только прочитаю заклинание.' #выводим сообщение  от nps в чат
          - narrate '<npc.name> что-то бормочет себе под нос...' #выводим простое сообщение в чат с именем npc
          - playeffect cloud <player.location> qty:20 #задаем эффект на месте игрока с кол-вом 20
          - playeffect cloud <player.location> qty:30 #задаем эффект на месте игрока с кол-вом 30
          - playeffect cloud <player.location> qty:40 #задаем эффект на месте игрока с кол-вом 40
          - playeffect flame <player.location> qty:50 #задаем эффект на месте игрока с кол-вом 50
          - execute as_server 'tp @p 155 80 -87' #выполняем от имени консоль команду
          - playeffect flame <player.location> qty:50 #задаем эффект на месте игрока с кол-вом 50
          - chat 'Вы были телепортированы.' #выводим сообщение в чат от имени npc
          - zap 'step:succes' #переходим на шаг с именем succes
    'succes': #шаг с именем succes
        click trigger: #ждем щелчка по npc
            script: #начинаем скрипт
            - zap 'step:question' #переходим на шаг question, то есть в начало. Это будет цикл, чтобы телепортом можно было пользоваться всегда.
Так же denizen позволяет создавать свои предметы для крафта!
Давайте рассмотрим пример:

Код:
sharp_arrow: #название. т.к. это не задание, можно начинать сразу так
    type: item #тип : предмет
    debug: false #выключили режим отладки
    material: arrow #материал : стрела
    display name: Шрапнель #отображаемое имя
    lore: #текст у предмета
    - <&c>Шрапнель #1-я  строка
    - <&c>страшная вещь! #2-я  строка
    recipe: #крафт в верстаке
    - i@arrow|i@arrow|i@arrow #верх: стрела \ стрела \ стрела
    - i@air|i@air|i@air #середина пусто \ пусто  \ пусто
    - i@air|i@air|i@air #низ пусто \ пусто  \ пусто
Все! Теперь при укладывании 3 стрел вверх мы получаем шрапнель.
 
Последнее редактирование:
Дополнил данные, и теперь, с помощью них мы можем написать скрипт, запрещающий ломать нужный нам блок и заменять его на другой
Код:
#имя скрипта
nocrashblock:
#тип: если происходит в мире
    type: world
#событие
    events:
#если игрок разрушил песок то
        on player breaks sand:
#выводим в чат что это делать нельзя
        - narrate Запрещено рушить <context.material>'
#заменяем этот блок на блок земли
        - determine grass
 
Последнее редактирование:
Извиняюсь, но не нашел нужный. Надеюсь модераторы перенесут .
http://rubukkit.org/threads/kak-naznachit-komandu-na-npc.114776/#post-1289584
Забавно... Я тоже хотел туториал по Denizen'у написать)
Да, кстати, быть может вы не знаете, с помощью скриптов Denizen можно создавать не только взаимодействия с НПС.
Вот небольшой пример простого скрипта (скрипт не мой).
Когда у игрока в руках факел - появляется свет. Если двигатся вместе с факелом то и свет будет двигатся за вами.
Код:
# @автор - mcmonkey

torch_light_world:
    type: world
    debug: false
    events:
        on player steps on block:
        - if <player.has_flag[torch_light_prev]> {
          - light <context.previous_location> reset
          - flag player torch_light_prev:!
          }
        - if <player.item_in_hand.material.name> == torch {
          - light <context.location.add[0,1,0]> 14
          - flag player torch_light_prev
          }
        on player quits:
        - if <player.has_flag[torch_light_prev]> {
          - light <context.previous_location> reset
          - flag player torch_light_prev:!
          }
 
[QUOTE="CoolBoy, Я тоже хотел туториал по Denizen'у написать)
Да, кстати, быть может вы не знаете, с помощью скриптов Denizen можно создавать не только взаимодействия с НПС.
Вот небольшой пример простого скрипта (скрипт не мой).
Когда у игрока в руках факел - появляется свет. Если двигатся вместе с факелом то и свет будет двигатся за вами.
Код:
# @автор - mcmonkey

torch_light_world:
    type: world
    debug: false
    events:
        on player steps on block:
        - if <player.has_flag[torch_light_prev]> {
          - light <context.previous_location> reset
          - flag player torch_light_prev:!
          }
        - if <player.item_in_hand.material.name> == torch {
          - light <context.location.add[0,1,0]> 14
          - flag player torch_light_prev
          }
        on player quits:
        - if <player.has_flag[torch_light_prev]> {
          - light <context.previous_location> reset
          - flag player torch_light_prev:!
          }
[/QUOTE]
Вообще о возможностях знаю, но реализация хромает т.к. Только учусь. Буду рад увидеть ваши знания)
 
Молодец, полезная тема.
Прикрепи ид предметов и добавь в тутор(или сделай новый)добавление эффектов к предмету(ид ихние тоже добавь)
 
Все! Теперь при укладывании 3 стрел вверх мы получаем шрапнель.
Возник вопрос по поводу обращения к игроку. Скопировал скрипт, подкорректировал тексты. Но команда не исполняется, игрок не телепортируется. Ввел вместо @p свой ник, получилось. Что делать?
 
Все! Теперь при укладывании 3 стрел вверх мы получаем шрапнель.
Возник вопрос по поводу обращения к игроку. Скопировал скрипт, подкорректировал тексты. Но команда не исполняется, игрок не телепортируется. Ввел вместо @p свой ник, получилось. Что делать?
- execute as_npc "tp <player.name> Х Y Z (координаты телепортации) указывай сам."
 
тема хорошая. Если нужно - могу помочь в создании скриптов/туториала
http://rubukkit.org/threads/kak-naznachit-komandu-na-npc.114776/#post-1289584
Забавно... Я тоже хотел туториал по Denizen'у написать)
Да, кстати, быть может вы не знаете, с помощью скриптов Denizen можно создавать не только взаимодействия с НПС.
Вот небольшой пример простого скрипта (скрипт не мой).
Когда у игрока в руках факел - появляется свет. Если двигатся вместе с факелом то и свет будет двигатся за вами.
Код:
# @автор - mcmonkey

torch_light_world:
    type: world
    debug: false
    events:
        on player steps on block:
        - if <player.has_flag[torch_light_prev]> {
          - light <context.previous_location> reset
          - flag player torch_light_prev:!
          }
        - if <player.item_in_hand.material.name> == torch {
          - light <context.location.add[0,1,0]> 14
          - flag player torch_light_prev
          }
        on player quits:
        - if <player.has_flag[torch_light_prev]> {
          - light <context.previous_location> reset
          - flag player torch_light_prev:!
          }
P.S.: скорее всего после этого консоль будет невозможно читать
 
тема хорошая. Если нужно - могу помочь в создании скриптов/туториала

P.S.: скорее всего после этого консоль будет невозможно читать
Скорее всего кто-то не умеет отключать логирование в консоль)
 
Скорее всего кто-то не умеет отключать логирование в консоль)
не обращал на эту функцию никогда внимания)
ну помимо этого...
только этот скрипт будет чекать каждого игрока при перемещении из одного блока в другой.
Даже если и отключить логирование. Нагрузку это не уменьшит.
Как возможность плагина - действительно занятная. Но ведь если не ошибаюсь, там игрока проверяет при перемещении в каждый новый блок? А если он быстро будет перемещаться? А если их много?
P.S.: в IRC плагина пытался задать вопрос одному из команды разработчиков, как сделать автоматические выплаты каждые 10-15 минут игрокам n-ную сумму денег (это как мне казалось должно быть ближе к реалиям повседневной жизни (к привычным зарплатам обычных людей). Так у него волосы на голове встали, когда я ему показал, как я при входе игрока на сервер запускаю в цикле
- выдать денег
- подождать некоторое время
он меня пытался отговорить так делать из-за того, что это создает нагрузку.
А тут вообще страшно представить, что будет происходить в игре, если сервер вообще не крашнется.
 
Последнее редактирование:
не обращал на эту функцию никогда внимания)
ну помимо этого...
только этот скрипт будет чекать каждого игрока при перемещении из одного блока в другой.
Даже если и отключить логирование. Нагрузку это не уменьшит.
Как возможность плагина - действительно занятная. Но ведь если не ошибаюсь, там игрока проверяет при перемещении в каждый новый блок? А если он быстро будет перемещаться? А если их много?
P.S.: в IRC плагина пытался задать вопрос одному из команды разработчиков, как сделать автоматические выплаты каждые 10-15 минут игрокам n-ную сумму денег (это как мне казалось должно быть ближе к реалиям повседневной жизни (к привычным зарплатам обычных людей). Так у него волосы на голове встали, когда я ему показал, как я при входе игрока на сервер запускаю в цикле
- выдать денег
- подождать некоторое время
он меня пытался отговорить так делать из-за того, что это создает нагрузку.
А тут вообще страшно представить, что будет происходить в игре, если сервер вообще не крашнется.
Хм, я лишь показал возможности плагина, а не саму функцию.
Я включал её у себя как-то, при онлайне в 2 человека и 2 гб оперативы с набором из 30 плагинов тпс падал до 10. Да и играть становилось невозможно.
Тем неменее, с помощью плагина можно делать "практически" всё.
У меня например топ PvP'шеров одним скриптом выводится на таблички, так плюс еще и записывает топ в отдельный файлик. Да и сам топ можно командой проверить. И нагрузки от скрипта я пока не чувствую)
 
Хм, я лишь показал возможности плагина, а не саму функцию.
Я включал её у себя как-то, при онлайне в 2 человека и 2 гб оперативы с набором из 30 плагинов тпс падал до 10. Да и играть становилось невозможно.
Тем неменее, с помощью плагина можно делать "практически" всё.
У меня например топ PvP'шеров одним скриптом выводится на таблички, так плюс еще и записывает топ в отдельный файлик. Да и сам топ можно командой проверить. И нагрузки от скрипта я пока не чувствую)
тут согласен. Функциональность практически только фантазией ограничивается.
ничего не имею против скрипта на топ, если только проверка не будет проходить чаще чем раз в несколько секунд:good:
Перекапывал туториалы плагина. В "Замену символов" можно добавить
| = <&pipe>
< = <&lt>
> = <&gt>
newline = <&nl>
& = <&amp>
; = <&sc>
[ = <&lb>
] = <&rb>
@ = <&at>
. = <&dot>
\ = <&bs>
' = <&sq>
" = <&quo>
! = <&exc>
/ = <&fs>
§ = <&ss>
 
Хелп, при создании более 1 тригера предыдущие не работают
Код:
Guider:
  type: assignment
  debug: false
  interact scripts:
  - 100 telep

telep:
  type: interact
  steps:
    "step0*":
      click trigger:
        script:
        - narrate '§9§l[§e§lКрестьянин§9§l] §6§l-> §9§l[§e§l<player.name>§9§l]§6§l:§f§l Здравствуй,путник.'
        - chat '§9§l[§e§lКрестьянин§9§l] §6§l-> §9§l[§e§l<player.name>§9§l]§6§l:§f§l Ты видимо впервые тут?'
        - narrate '§6§lВозможные ответы: §9§l[§e§lда§9§l] [§e§l2нет§9§l]'
      chat trigger:
        'Yes':
          trigger: '/1/'
          script:
          - narrate '§9§l[§e§l<player.name>§9§l] §6§l-> §9§l[§e§lКрестьянин§9§l]§6§l:§f§l Да, вот только зашел на rpg'
          - narrate '§9§l[§e§lКрестьянин§9§l] §6§l-> §9§l[§e§l<player.name>§9§l]§6§l:§f§l Понятно.Может тебе обьяснить что-то?'
          - zap 'step:step1'
    'step1':
        click trigger:
            script:
            - narrate '§9§l[§e§lКрестьянин§9§l] §6§l-> §9§l[§e§l<player.name>§9§l]§6§l:§f§l О чем именно ты хочешь узнать?'
            - narrate '§6§lВозможные ответы: §9§l[§e§l1 - Мне надо идти§9§l] [§e§l2 - о Безопасных зонах§9§l]'
        chat trigger:
          'mnepora':
            trigger: '/1/'
            script:
            - narrate '§9§l[§e§l<player.name>§9§l] §6§l-> §9§l[§e§lКрестьянин§9§l]§6§l:§f§l Извините но мне надо идти.'
            - narrate '§9§l[§e§lКрестьянин§9§l] §6§l-> §9§l[§e§l<player.name>§9§l]§6§l:§f§l Понимаю...Но если нужна будет помощь - подходи!'
        chat trigger:
          'zones2':
            trigger: '/3/'
            script:
            - narrate '§9§l[§e§l<player.name>§9§l] §6§l-> §9§l[§e§lКрестьянин§9§l]§6§l:§f§l Я хочу подробно узнать о безопасных зонах.'
            - narrate '§9§l[§e§lКрестьянин§9§l] §6§l-> §9§l[§e§l<player.name>§9§l]§6§l:§f§l Хорошо.Мы сейчас в безопасной зоне.Безопасные зоны зоны это зоны где отключенно пвп,спавн враждебных монстров и вообще разлиичный урон.'
            - narrate '§f§l Также,тут можно писать команды, §a§lв том числе и /sethome§f§l,как только ты покидаешь безопасную зону ты попадаешь в опасную зону.'
            - narrate '§f§l В опасных зонах нельзя писать команды,там спавнятся монстры и боссы.Но пвп там выключенно.'
            - narrate '§f§l К слову есть также особо-опасные зоны в которых включенно пвп, но о них заранее предупреждают,да и встречаются они крайне редко.'
            - narrate '§f§l Хочешь ещё о чем небудь спросить?'
            - narrate '§6§lВозможные ответы: §9§l[§e§l1 - Мне надо идти§9§l]'
 
подскажите, как можно что то дать игроку или положить в созданный сундук ? Если это вообще возможно
Пробую делать так:

# Получаю координаты блока
- define base <player.location>

# К переменной base прибавляется смещение по X на +1 (т.е. вправо от выбранного блока),
# чтобы разместить сундук рядом. Результат сохраняется как chest_loc
- define chest_loc <def[base].add[1,0,0]>

# Ставит сундук по координате chest_loc.
- modifyblock <def[chest_loc]> chest

# Кладёт 16 алмазов в первый слот сундука, расположенного на chest_loc.
# d: — объект инвентаря (сундук)
# o:slot[1] — слот №1
# "i@diamond[quantity=16]" — 16 алмазов
# - inventory set d:<def[chest_loc].inventory> o:slot[1] "i@diamond[quantity=16]"
- inventory set d:<def[chest_loc].inventory> o:<player.inventory> slot:1 i@diamond[quantity=16]

и тут получается ошибка:

[09:50:31 INFO]: +> Executing 'INVENTORY': actions='[SET]' origin='o:in@player[holder=p@4d653728-eff9-3a94-a36b-bc9105d0ba19]' destination='d:in@location[holder=l@410,78,-175,world]' slot='1' data_action='i@diamond[quantity=16]'
[09:50:31 INFO]: ERROR in script 'spawn_portal_command' in queue 'SPAWN_PORTAL_COMMAND_27_TtKo' while executing command 'INVENTORY' in file '\scripts\portal1.dsc' on line '31' with player 'DenisNpp'!

Error Message: Woah! An exception has been called with this command!
[09:50:31 INFO]: Additional Error Info: Internal exception was thrown!
[Error Continued] java.lang.ArrayIndexOutOfBoundsException: Index 27 out of bounds for length 27
[Error Continued] java.base/java.util.Arrays$ArrayList.set(Arrays.java:4232)
[Error Continued] net.minecraft.core.NonNullList.set(NonNullList.java:50)

Есть ли у плагина вообще живое сообщество ?
 

Поделиться этой страницей

Назад
Верх