Плагин событий для Paper: аирдропы, алтари, метеориты, вулканы и другие сценарии. Событие описывается в YAML как набор компонентов, связанных командами.
Workflow — сценарий события. Спавнер запускает его, генератор выбирает точку, а компоненты строят схематику, показывают отсчёт, выдают лут и выполняют остальные действия.
Основные файлы в plugins/BAirdropFlow/:
| Путь | Назначение |
|---|---|
workflow/*.yml |
Сценарии событий |
spawner/*.yml |
Расписание, призывные предметы и голосования |
loot.yml |
Таблицы лута |
schematics/ |
Схематики построек |
particles/ |
Анимации частиц |
menu/ |
Меню, включая редактор лута и голосование |
messages.yml, lang.yml |
Сообщения и форматирование |
config.yml |
Общие настройки и подключение веб-редактора |
Готовые сценарии можно посмотреть в src/main/resources/workflow. Для нового события скопируйте подходящий файл, задайте уникальный id и измените компоненты.
Для разработчиков: API и создание аддонов.
| Команда | Действие | Право |
|---|---|---|
/baf start <id> |
Запустить workflow или голосование по ID | baf.admin |
/baf give <игрок> <предмет> |
Выдать призывной предмет; ID подсказывает команда | baf.admin |
/baf reload |
Перезагрузить плагин; активные события очищаются | baf.admin |
/baf web |
Получить ссылку на редактор сценариев | baf.web.admin |
/baf particle_web |
Получить ссылку на редактор частиц | baf.web.admin |
/baf loot list |
Список таблиц лута | baf.loot.admin |
/baf loot create <id> |
Создать таблицу | baf.loot.admin |
/baf loot edit <id> |
Открыть редактор таблицы | baf.loot.admin |
/baf loot delete <id> |
Удалить таблицу | baf.loot.admin |
/vote |
Открыть текущее голосование | — |
/gps [id] |
Показать события или выбрать точку GPS | — |
Файл workflow/example.yml создаёт событие в фиксированной точке, показывает голограмму на 30 секунд и затем удаляет событие:
id: custom:example
world: world
nearby_radius: 40
generator:
type: generator:fixed
at: 0;100;0
spawner:
type: spawner:timer
time: 5s
when: {}
on_timer_end:
- make: {}
nodes:
__init__:
type: default:__init__
on_init:
- create: lifetime
__destroy__:
type: default:__destroy__
on_destroy: []
lifetime:
type: tick:timer
timer: 30
on_create:
- create: title
on_timer_end:
- destroy: ''
title:
type: default:hologram
offsets: 0.5;2;0.5
lines:
- '<gold>Событие'После загрузки: /baf start custom:example. Имя файла служит для хранения, запуск использует поле id.
nodes содержит определения компонентов. Само наличие ноды в файле её не запускает: при появлении события автоматически создаётся __init__, а остальные ноды создаются командами из её обработчика и следующих обработчиков.
on_create:
- create: countdown
on_remove:
- remove: countdown| Команда в обработчике | Действие |
|---|---|
create: <нода> |
Создать компонент из nodes |
remove: <нода> |
Удалить активный компонент; отсутствие ноды допустимо |
call: update <нода> |
Вызвать вход компонента, например обновление голограммы |
call?: update <нода> |
То же, но пропустить отсутствующую ноду |
set_arg: loot_count 30 |
Изменить аргумент текущего события |
destroy: '' |
Завершить всё событие |
Одновременно может существовать только один компонент с конкретным именем. После удаления его можно создать снова. Компоненты не удаляют связанные ноды автоматически: задавайте нужные remove в обработчиках. Завершение всего события вызывает __destroy__.on_destroy, удаляет активные компоненты и очищает принадлежащие событию ресурсы.
Обработчики также поддерживают команды библиотеки событий: условия if / do, выбор weights, сообщения, звуки и другие действия. Примеры их сочетания есть в готовых workflow.
- Векторы записываются как
x;y;z, например0.5;2;0.5.offsetsобычно отсчитывается от точки события. - Поля с суффиксом
_ticksзадаются в тиках: при 20 TPS 20 тиков ≈ 1 секунда.tick:timer.timerзадаётся в секундах,spawner:timer.time— длительностью вида30sили5m. {x},{y},{z},{world}— точка события;{args:ключ}— его аргумент;{ctx:имя_ноды.ключ}— значение активного компонента.- Например,
timer: '{args:duration}'берёт длительность из аргумента, аtitle: 'Осталось {ctx:countdown.timer} сек.'показывает таймер. argsзадаёт начальные изменяемые аргументы события.defaultsвыполняет подстановку{ключ}при чтении workflow и подходит для общих текстов.- Динамические значения поддерживаются полями компонентов на базе
Parameter(IntValue,StringValueи т. п.). Обычные поля расписания и некоторые настройки FT читаются при загрузке. Числовое поле после подстановки должно содержать корректное число. - Текстовые поля с оформлением поддерживают MiniMessage, например
<gold>Аирдроп.
Глобальные спавнеры лежат в spawner/. Они определяют, когда и каким способом запустить событие. Встроенный спавнер workflow задаётся в его секции spawner и отвечает за отсчёт до появления.
При запуске workflow генератор сначала выбирает точку, затем начинается отсчёт. По завершении выполняется on_timer_end. Чтобы событие действительно появилось, в обработчике нужна команда make:
spawner:
type: spawner:timer
time: 5m
gps:
publish: true
publish_location: true
gps_line: '<gold>Аирдроп через {formated_time_left}: {x} {y} {z}'
on_create: []
when:
'1m': []
'10s-1s': []
on_timer_end:
- make: {}when проверяется по оставшемуся времени раз в 20 тиков. Ключ 1m сработает на минуте, диапазон 10s-1s — каждую секунду от 10 до 1 включительно. Диапазон записывается от большего времени к меньшему.
Доступны {time} в секундах, {millis_left}, {formated_time_left}, {world}, {x}, {y}, {z}. Команда set_value: ключ значение сохраняет значение спавнера для {value:ключ}. В make можно передать карту аргументов, которая переопределит args создаваемого события.
Этот таймер одноразовый: для следующего события нужен новый запуск workflow. Без gps.publish отсчёт не публикуется в GPS.
type: default:by_time
time_zone: Europe/Moscow
publish_gps: true
events:
'13:00': ft:vote
'20:00':
ft:volcano: 3
ft:geyser: 1
'SATURDAY 18:00': ft:meteoriteHH:mm повторяется ежедневно, DAY HH:mm — раз в неделю; день записывается английским именем, например MONDAY. Значение — ID события либо карта ID: вес для случайного выбора. Веса должны быть положительными; в примере вулкан выбирается с вероятностью 3/4.
events и workflows — альтернативные имена одной секции, вместе их указывать нельзя. Можно запускать как workflow, так и голосование. Для отображения ожидания следующего события в GPS публикация должна быть включена у расписания и выбранного события.
type: default:by_item
items:
signal:
item:
material: REDSTONE_TORCH
name: '<gold>Сигнал аирдропа'
workflow: ft:airdrop
args:
loot_count: '30'
consume: true
requirements:
min_y: -64
max_y: 319
flat_surface: true
radius: 2
clear_height: 4
outside_regions: trueИгрок нажимает ПКМ призывным предметом по блоку опоры. Событие создаётся сразу над опорой: генератор и встроенный таймер workflow здесь не используются. workflow должен ссылаться именно на сценарий, а не на голосование. Выдавайте предмет через /baf give, чтобы он содержал идентификатор плагина.
consume расходует предмет после успешного призыва. min_y / max_y ограничивают высоту точки появления. При flat_surface: true проверяется площадка (2 × radius + 1)²; над ней нужно clear_height свободных блоков без жидкости. Без flat_surface проверяется только центральная колонна. outside_regions запрещает призыв в проверяемой области регионов WorldGuard.
type: default:vote
id: custom:vote
duration: 60s
menu: baf:vote
publish_gps: true
options:
ft:volcano: Вулкан
ft:geyser: Гейзер
tie: random
no_votes: randomФайл регистрирует голосование, но не запускает его при загрузке. Запуск — через расписание или /baf start custom:vote. Игроки выбирают вариант в /vote, победитель запускается по своему ID.
tie определяет исход ничьей, no_votes — исход без голосов. Значения: random — случайный вариант, first — первый подходящий, cancel — отмена запуска. Сообщения задаются в messages.started, ended, voted, cancelled; используются {time_left}, {winner}, {selected}. Меню должно иметь provider: baf:vote.
generator:fixed берёт координаты из at: x;y;z. Мир задаётся полем world workflow.
generator:random выбирает случайные X/Z в квадрате вокруг center и ищет подходящую высоту сверху вниз:
generator:
type: generator:random
center: 0;0;0
radius: 2500
min_y: 50
max_y: 150
clear_zone: 4
clear_y: 3
air_tester: '!solid & !water & !lava'
solid_tester: 'solid & !ice'
offsets: 0;0;0center.y не используется. clear_zone задаёт радиус проверяемой области по X/Z, clear_y — число свободных слоёв над опорой. Условия свободных блоков и опоры задаются через air_tester и solid_tester; указывайте их явно, поскольку без них фильтры разрешают любой материал. offsets сдвигает найденную точку.
Ниже перечислены все 26 типов из реестра плагина, включая необязательный dh:hologram. default: можно опустить: type: hologram равнозначен type: default:hologram. Остальные пространства имён указываются явно.
Обработчики событий — списки команд; если не нужны, их можно не указывать. Для обычных долгоживущих компонентов on_create срабатывает при создании, on_remove — при удалении. Дополнительные события указаны отдельно.
Специальная нода с именем __init__. Выполняет on_init и удаляет себя. Обычно здесь создают регион, начальную схематику и таймер первой фазы.
Специальная нода с именем __destroy__. Выполняет on_destroy при завершении всего события, перед удалением остальных активных компонентов. Подходит для финальных сообщений и действий.
Выполняет on_run при создании и сразу удаляется. Запускается обычной командой create: имя_ноды. Удобен для общих наборов команд и ветвления сценария.
timer — положительное число секунд, по умолчанию 20. Каждые 20 тиков уменьшает счётчик: на промежуточных значениях вызывает on_tick, на нуле — on_timer_end, затем удаляется с on_remove. Также поддерживает on_create.
Плейсхолдер: {ctx:имя.timer} — оставшиеся секунды. Досрочное удаление не вызывает on_timer_end.
ticks — положительное число тиков, по умолчанию 1200. События: on_create, on_timer_end, on_remove. После ожидания вызывает on_timer_end и удаляется; команда remove отменяет ожидание без завершения таймера.
Показывает боссбар игрокам в nearby_radius workflow. Текст и состояние обновляются каждый тик.
title— заголовок;color— цвет, по умолчаниюgreen;overlay— деления, по умолчаниюprogress.flags— список флагов:darken_screen,play_boss_music,create_world_fog.progress— заполнение от0до1, по умолчанию1.time— источник времени в секундах, например'{ctx:active.timer}'.progress_from_time: true— считать заполнение относительно начального времени; требуетtime.
События: on_create, on_remove. Плейсхолдер {ctx:имя.time} выдаёт время в формате lang.yml. Радиус задаётся через nearby_radius всего workflow; отдельного параметра radius у компонента нет.
gps_line — текст записи, publish_location — публиковать координаты, по умолчанию true. При удалении компонента запись убирается. События: on_create, on_remove. Плейсхолдер {ctx:имя.gps_id} — ID записи для /gps <id>.
lines — строки, offsets — смещение, по умолчанию 0;0;0. Использует ArmorStand, отображается в радиусе workflow; шаг строк — 0.3 блока. События: on_create, on_update, on_remove.
Для обновления динамического текста вызывайте call: update имя_ноды, например из on_tick таймера.
Доступен при установленном DecentHolograms. Поля lines, offsets, события on_create, on_update, on_remove и вызов call: update имя_ноды аналогичны встроенной голограмме.
animation — обязательный ID анимации из particles/, offsets — смещение, ticks — время проигрывания, по умолчанию 100; -1 означает работу до удаления. События: on_create, on_timer_end, on_remove. Частицы видны игрокам в радиусе workflow.
Отслеживает попытки сломать блок по offsets от точки события. count — обязательное положительное число попыток. Промежуточные попытки вызывают on_break, последняя — on_broken, после чего компонент удаляется. Также есть on_create и on_remove.
Плейсхолдер {ctx:имя.count} — оставшееся число попыток. Это счётчик взаимодействий; изменение блока задавайте действиями сценария.
Считает ЛКМ и ПКМ основной рукой по блоку с заданным offsets. count — обязательное положительное число кликов. События: on_create, промежуточное on_click, финальное on_clicked, on_remove. После последнего клика удаляется. Плейсхолдер {ctx:имя.count} — сколько кликов осталось.
path— обязательный путь к файлу схематики; пример:../BAirdropFlow/schematics/altar.schem.offsets— смещение относительно точки события.no_replace— материалы мира, которые нельзя заменять;no_place— материалы схематики, которые не нужно вставлять. Если исключений нет, укажите пустые списки[].replace— карта замены материалов, напримерbarrier: air.animation.interval_ticks— интервал постепенной вставки,0означает вставку сразу.animation.blocks_per_step— блоков за шаг, по умолчанию1;shuffle_layer— перемешивание внутри слоя, по умолчаниюtrue.animation.sound,volume,pitch— звук установки, его громкость и тон.
Слои вставляются снизу вверх. События: on_create, on_complete, on_remove. Для действий после завершения постройки используйте on_complete. Удаление компонента восстанавливает изменённые блоки.
Создаёт временный регион вокруг точки события. size: 5;5;5 — полуразмер по каждой оси. flags — список строк вида block-break deny, block-place deny. События: on_create, on_remove; при удалении компонента регион удаляется.
Открывает общий инвентарь при взаимодействии с блоком по offsets.
| Поле | Назначение и значение по умолчанию |
|---|---|
loot_table |
Обязательный ID таблицы из loot.yml |
rolls |
Число выборок с повторениями, 1 |
title |
Заголовок инвентаря |
inventory_type |
Тип инвентаря, chest |
size |
Размер CHEST, 54; у других типов размер фиксированный |
fill_interval_ticks |
Минимальный интервал добавления предметов, 0 — выключен |
fill_interval_max_ticks |
Максимальный интервал, 0 — равен минимальному |
fill_duration_ticks |
Длительность постепенного заполнения, 0 — выключена |
reveal_delay_ticks |
Минимальное время остывания маски, 0 — раскрытие при взятии |
reveal_delay_max_ticks |
Максимальное время остывания, 0 — равно минимальному |
take_cooldown_ticks |
Кулдаун взятия, -1 — выключен |
obfuscation_materials |
Материалы масок; пустой список отключает маскировку |
obfuscation_name |
Общее имя замаскированных предметов |
События: on_create, on_open, on_remove. Для dispenser, например, используется фиксированный инвентарь на 9 слотов.
Выбрасывает предметы из обязательной loot_table в мир. rolls — число выборок, по умолчанию 10; offsets — точка выброса, по умолчанию 0.5;1;0.5.
interval_ticks: 2— интервал выброса.spread_duration_ticks: 0— использовать интервал; положительное значение распределяет весь лут по заданной длительности.horizontal_speed: 0.4,vertical_speed: 0.6— скорости разлёта.pickup_delay_ticks: 20,item_lifetime_ticks: 1200— задержка подбора и время жизни каждого предмета.obfuscation_materials,obfuscation_name— маскировка до подбора.trail_animation— ID анимации следа; пустая строка отключает след.trail_interval_ticks: 1— его интервал.
События: on_create, on_spread_end, on_remove. on_spread_end означает, что очередь выброса закончилась; предметы ещё могут лежать в мире. После исчезновения всех предметов компонент удаляется сам. Досрочное удаление убирает оставшиеся предметы.
Все следующие компоненты поддерживают общие поля:
| Поле | Значение по умолчанию | Назначение |
|---|---|---|
offsets |
0;0;0 |
Смещение точки работы |
ticks |
-1 |
Длительность компонента; -1 — до удаления или собственного завершения |
entity_lifetime_ticks |
1200 |
Максимальное время жизни создаваемых сущностей |
max_entities |
256 |
Лимит принадлежащих компоненту сущностей |
trail_animation |
'' |
ID анимации следа |
trail_ticks |
80 |
Время проигрывания следа на каждой сущности |
Общие события: on_create, on_remove, on_finish, а для соответствующих сущностей — on_land, on_death, on_impact. Очистка через remove не считается смертью или естественным завершением. При завершении вызывается on_finish, затем компонент удаляется.
Общие плейсхолдеры: {ctx:имя.alive}, {ctx:имя.killed}, {ctx:имя.x}, {ctx:имя.y}, {ctx:имя.z}. Координаты относятся к последнему событию компонента. FT-компоненты, созданные из обработчика приземления, смерти или удара, могут использовать точку этого события как начало своих offsets.
Создаёт физические блоки без установки в мир и выпадения предметов. materials — материалы, count — количество, spread — разброс по X/Z, velocity_min / velocity_max — диапазон скорости. ground_material: true берёт материал опоры.
Вместо обычного выброса можно задать steps: список шагов с полями tick, offsets, material, velocity. Так настраивается точная последовательность появления блоков. Удаление компонента очищает группу.
fuse_ticks: 100 — время до взрыва, damage: false — урон выключен по умолчанию. Блоки не разрушает. Взрыв вызывает on_impact; защита WorldGuard не обходится.
Создаёт настоящий фейерверк без урона. Поля: count: 1, power: 1, flicker: true, trail: true, списки цветов colors и затухания fade. Цвета записываются строками '#ff0000'.
types— список типов, по умолчанию[zombie];total: 12— общее количество,-1— неограниченное пополнение.interval_ticks: 160,wave_size: 1,max_alive: 12— интервал, размер волны и лимит живых мобов.health_multiplier: 5— множитель HP. Положительныйhealth_minвместе сhealth_maxзадаёт диапазон HP вместо множителя.launch: true,lift_ticks: 20,horizontal_speed: 0.5,vertical_speed: 1.2— подъём и бросок мобов.mob_name— имя с локальными подстановками{health}и{max_health}.equipment_table— таблица предмета в руке;loot_tableиrolls: 1— награда за реальную смерть.
Дополнительный плейсхолдер {ctx:имя.spawned} — число созданных мобов; alive здесь считает живых мобов. Очистка и выгрузка не выдают награду за убийство.
Периодически запускает падающие метеориты с ударом и временной воронкой, которая восстанавливается.
interval_ticks: 100,flight_ticks: 55— интервал волн и время полёта.wave_min: 1,wave_max: 2— количество в волне;radius: 15,height: 70— разброс и высота появления.impact_radius: 10,max_damage: 20— радиус и максимальный урон от удара.loot_table: ''— таблица лута после остывания;drop_chance: 70— шанс в процентах.
Находит NETHERRACK в уже загруженных чанках и запускает источники с лутом. Поля поиска: scan_radius: 15, scan_y: 10. Работа источников: interval_ticks: 4, max_concurrent: 3, effect_ticks: 60, item_delay_ticks: 2.
loot_table, obfuscation_materials, obfuscation_name задают лут и его маскировку. Финальный выброс: falling_blocks: 50, falling_materials — список {material: stone, weight: 1}, damage_radius: 8, max_damage: 10.
Команда call: erupt имя_ноды запускает финал; обычный remove только очищает компонент.
Строит процедурные лучи из стоек, повторяющие рельеф.
rays:radius: 9,count: 8,step: 0.6,speed: 0.225,jitter: 0.15,rotation: 0— радиус, число лучей, шаг, скорость, разброс и поворот.ground:search_up: 8,search_down: 8,offset: -0.3,vertical_step: 0.3— поиск поверхности и переходы высоты.stages— список стадий сmaterialи длительностьюticksдля смены предмета на стойках.build_start_tick: 81— момент вызова дополнительного событияon_build_start. В нём можно запустить постройку схематики.
Выбрасывает лут волнами, например из вулкана. loot_table обязателен, rolls: 20 — число выборок.
wave_size: 5,interval_ticks: 5,wave_interval_ticks: 60— размер волны, интервалы между предметами и волнами.spread_duration_ticks: 0— обычные интервалы; положительное значение задаёт длительность выброса всего лута.velocity_min: 0.4;0.3;-0.25,velocity_max: 0.9;0.6;0.25— диапазон скорости;alternate_x: trueчередует направление волн.fire_ticks: 100,pickup_delay_ticks: 60,item_name_visible: true— горение, задержка подбора и видимость имени.obfuscation_materials,obfuscation_name— маскировка предметов.
Дополнительные события: on_each_spread и on_wave.
Каждые interval_ticks: 50 находит игроков в radius: 20 и вызывает on_reward отдельно для каждого получателя. Сам компонент вычисляет сумму; команду фактической выплаты нужно задать в on_reward.
min_reward: 10000 — сумма на границе радиуса, max_reward: 90000 — в центре. Значение линейно уменьшается с расстоянием и делится на число получателей.
Плейсхолдеры: {ctx:имя.amount} — доля текущего игрока с двумя знаками после точки, {ctx:имя.distance} — расстояние, {ctx:имя.players} — число получателей. Поиск получателей использует собственный radius.
Каждые interval_ticks: 600 применяет Glowing и Hunger и проигрывает звук игрокам в радиусе X/Z radius: 15. Максимальная длительность эффектов — effect_ticks: 80, она уменьшается с расстоянием от точки пульса.