Lua-скриптовый движок MagmaCore
MagmaCore предоставляет общий Lua-скриптовый движок, используемый несколькими плагинами Nightbreak. Движок обеспечивает песочницу, планировщик, управление зонами, взаимодействие с миром, таблицы сущностей и пользовательский интерфейс игрока — всё с единым API для всех плагинов.
В настоящее время следующие плагины используют этот движок:
- EliteMobs — Lua-способности для пользовательских боссов (хуки вроде
on_boss_damaged_by_player,on_enter_combatи т.д.) - FreeMinecraftModels — Lua-скрипты для пропов и пользовательских предметов (хуки вроде
on_right_click,on_left_click,on_equipи т.д.)
Эта страница документирует общие возможности движка. Для хуков, API и рабочих процессов, специфичных для конкретных плагинов, см. страницы плагинов по ссылкам выше.
Краткий учебник по Lua
Если вы совершенно незнакомы с Lua, вот минимальный синтаксис, необходимый для написания скриптов для любого плагина Nightbreak.
Переменные
Используйте local для сохранения значения:
local cooldown_key = "fire_burst"
local damage_multiplier = 1.5
local означает, что переменная принадлежит только этому файлу или блоку.
Функции
Функции — это многоразовые блоки логики:
local function warn_player(player)
player:send_message("&cMove!")
end
Позже вы можете вызвать её:
warn_player(some_player)
Проверки if
Используйте if, когда что-то должно происходить только иногда:
if context.player == nil then
return
end
Это означает «если для этого хука нет игрока, остановиться здесь».
nil
nil означает «нет значения». Это Lua-аналог «здесь ничего нет».
Часто проверяется наличие nil:
if context.event ~= nil then
-- do something with the event
end
~= означает «не равно».
Таблицы
Lua использует таблицы для нескольких целей:
- Списки
- Объекты с именованными ключами
- Финальное определение скрипта, возвращаемое в конце файла
Пример таблицы с именованными ключами:
local particle = {
particle = "FLAME",
amount = 1,
speed = 0.05
}
Возврат определения скрипта
В конце каждого файла скрипта вы возвращаете одну таблицу:
return {
api_version = 1,
on_spawn = function(context)
end
}
Эта возвращаемая таблица и является файлом скрипта.
Комментарии
Используйте -- для написания заметок для людей:
-- This cooldown stops the attack from firing every hit
context.cooldowns:set_local(60, "fire_burst")
Песочница Lua
Все Lua-скрипты выполняются внутри изолированной среды LuaJ. Несколько глобальных переменных, которые могут обеспечить доступ к файловой системе или Java-среде выполнения, удалены. Правила песочницы идентичны для всех плагинов, использующих MagmaCore.
Удалённые глобальные переменные
Следующие стандартные глобальные переменные Lua установлены в nil и не могут использоваться:
| Удалено | Причина |
|---|---|
debug | Раскрывает внутреннее состояние ВМ |
dofile | Доступ к файловой системе |
io | Доступ к файловой системе |
load | Произвольная загрузка кода |
loadfile | Доступ к файловой системе |
luajava | Прямой доступ к Java-классам |
module | Система модулей (не нужна) |
os | Доступ к операционной системе |
package | Система модулей (не нужна) |
require | Система модулей / доступ к файловой системе |
Доступная стандартная библиотека
Всё остальное из стандартной библиотеки Lua работает нормально:
| Категория | Функции |
|---|---|
| Math | math.abs, math.ceil, math.floor, math.max, math.min, math.random, math.sin, math.cos, math.sqrt, math.pi и все остальные функции math.* |
| String | string.byte, string.char, string.find, string.format, string.gsub, string.len, string.lower, string.match, string.rep, string.sub, string.upper и все остальные функции string.* |
| Table | table.insert, table.remove, table.sort, table.concat и все остальные функции table.* |
| Итераторы | pairs, ipairs, next |
| Типы | type, tostring, tonumber, select, unpack |
| Обработка ошибок | pcall, xpcall, error, assert |
| Прочее | print, rawget, rawset, rawequal, rawlen, setmetatable, getmetatable |
os недоступнаБиблиотека os полностью удалена из песочницы. Если вам нужна информация о времени, используйте context.world:get_time() для игрового времени или сохраняйте метки времени в context.state с помощью счётчиков тиков в on_tick / on_game_tick.
print выводит в консоль сервера, но предпочтительнее использовать context.log:info(msg) для вывода. Сообщения лога имеют префикс с именем файла скрипта, что упрощает отслеживание источника сообщения.
Контракт файла
Каждый Lua-скрипт должен возвращать (return) таблицу. Эта таблица намеренно строгая.
Обязательные и необязательные поля верхнего уровня
| Поле | Обязательно | Тип | Примечания |
|---|---|---|---|
api_version | Да | Number | В настоящее время должно быть 1 |
priority | Нет | Number | Приоритет выполнения. Меньшие значения выполняются первыми. По умолчанию 0 |
| поддерживаемые ключи хуков | Нет | Function | Должны использовать одно из точных имён хуков, поддерживаемых плагином |
Правила валидации
- Файл должен возвращать таблицу.
api_versionобязателен и в настоящее время должен быть1.priorityдолжен быть числом, если присутствует.- Каждый дополнительный ключ верхнего уровня должен быть поддерживаемым именем хука.
- Каждый ключ хука должен указывать на функцию.
- Неизвестные ключи верхнего уровня отклоняются.
Вспомогательные функции и локальные константы должны располагаться выше финального return, а не внутри возвращаемой таблицы, если только они не являются фактическими хуками.
local ANIMATION_NAME = "idle"
local function do_something(context)
context.log:info("Doing something!")
end
return {
api_version = 1,
priority = 0,
on_spawn = function(context)
do_something(context)
end
}
Синтаксис методов: : vs .
В Lua object:method(arg) — это сокращение для object.method(object, arg). API MagmaCore принимает обе формы, поэтому оба варианта работают:
context.log:info("hello")
context.log.info("hello") -- same thing
Вся документация последовательно использует :.
Бюджет выполнения
Каждый вызов хука и каждый вызов обратного вызова замеряется по времени. Если один вызов занимает более 50 миллисекунд, скрипт отключается с предупреждением в консоли:
[Lua] my_script.lua took 73ms in 'on_game_tick' (limit: 50ms) -- script disabled to prevent lag.
Чтобы оставаться в рамках бюджета:
- Избегайте неограниченных циклов внутри хуков.
- Делайте обработчики
on_game_tick/on_tickлегковесными — они выполняются каждый тик. - Используйте
context.scheduler:run_repeating(...)для распределения работы по тикам. - Переносите дорогостоящую работу за кулдаун на основе состояния или разумный интервал.
context.state
Обычная Lua-таблица, которая сохраняется на протяжении всего времени жизни экземпляра скрипта. Используйте её для хранения флагов, счётчиков, ID задач, состояний переключения и любых данных, которыми нужно делиться между хуками.
on_spawn = function(context)
context.state.is_open = false
context.state.click_count = 0
context.state.task_id = nil
end,
on_right_click = function(context)
context.state.click_count = (context.state.click_count or 0) + 1
end
Только context.state сохраняется между вызовами хуков. Все остальные таблицы контекста (context.prop, context.world, context.event и т.д.) пересоздаются каждый раз заново. context.state не пересоздаётся — он существует с момента создания экземпляра скрипта до его уничтожения.
context.log
Методы логирования в консоль. Сообщения в консоли сервера имеют префикс с именем файла скрипта.
| Метод | Примечания |
|---|---|
log:info(message) | Информационное сообщение |
log:warn(message) | Предупреждение |
log:error(message) | Сообщение уровня предупреждения (логируется на уровне WARN, аналогично log:warn) |
log:debug(message) | Отладочное сообщение (отображается как info-уровень с префиксом debug) |
context.log:info("Script loaded!")
context.log:warn("Something unexpected happened")
context.log:error("Critical failure in zone setup")
context.log:debug("State value: " .. tostring(context.state.counter))
context.cooldowns
Таблица cooldowns управляет временными перезарядками для ваших скриптов. Есть два уровня:
- Локальные перезарядки привязаны к экземпляру скрипта и идентифицируются строковым ключом. Если ключ не указан, используется имя файла скрипта в качестве ключа по умолчанию.
- Глобальные перезарядки общие для всех скриптов одного владельца сущности (например, все скрипты одного пропа или все Lua-способности одного босса).
cooldowns:check_local(key?, duration)
Наиболее часто используемый метод. Проверяет, готова ли перезарядка, и если да, запускает её и возвращает true. Если не готова, возвращает false. Это атомарная операция проверки-и-установки — без условий гонки.
| Параметр | Тип | Примечания |
|---|---|---|
key | string (необязательно) | Идентификатор перезарядки. По умолчанию — имя файла скрипта. |
duration | int | Длительность перезарядки в тиках (20 = 1 секунда) |
on_right_click = function(context)
-- Only allow this action once every 3 seconds
if not context.cooldowns:check_local("interact", 60) then
return
end
-- ... do the action
end
cooldowns:local_ready(key?)
Возвращает true, если локальная перезарядка истекла (или никогда не была установлена), false, если ещё активна.
cooldowns:local_remaining(key?)
Возвращает количество оставшихся тиков локальной перезарядки, или 0, если готова.
cooldowns:set_local(duration, key?)
Устанавливает локальную перезарядку без проверки, активна ли уже одна. Используйте для безусловного сброса перезарядки.
| Параметр | Тип | Примечания |
|---|---|---|
duration | int | Длительность в тиках. Передайте 0 или отрицательное значение для очистки. |
key | string (необязательно) | Идентификатор перезарядки. По умолчанию — имя файла скрипта. |
cooldowns:global_ready()
Возвращает true, если глобальная перезарядка (общая для всех скриптов одной сущности) истекла.
cooldowns:set_global(duration)
Устанавливает глобальную перезарядку.
| Параметр | Тип | Примечания |
|---|---|---|
duration | int | Длительность в тиках |
В скриптах способностей EliteMobs global_ready() и set_global() используют встроенную систему перезарядки способностей босса, которая является общей для всех Lua-способностей одного босса. Локальные перезарядки в EliteMobs также общие для всех способностей одной сущности босса (идентифицируются выбранным вами строковым ключом).
context.scheduler
Планировщик позволяет запускать отложенные и повторяющиеся задачи. Все задачи принадлежат экземпляру скрипта и автоматически отменяются при уничтожении экземпляра скрипта (например, при удалении пропа или смерти босса).
scheduler:run_later(ticks, callback)
Запускает обратный вызов один раз после задержки. Возвращает числовой ID задачи.
| Параметр | Тип | Примечания |
|---|---|---|
ticks | int | Задержка в серверных тиках (20 тиков = 1 секунда) |
callback | function | Вызывается со свежим context по истечении задержки |
context.scheduler:run_later(40, function(delayed_context)
delayed_context.log:info("2 seconds have passed!")
end)
scheduler:run_repeating(delay, interval, callback)
Запускает обратный вызов повторно с фиксированным интервалом. Возвращает числовой ID задачи.
| Параметр | Тип | Примечания |
|---|---|---|
delay | int | Начальная задержка в тиках перед первым запуском |
interval | int | Тики между каждым последующим запуском |
callback | function | Вызывается со свежим context каждый интервал |
context.state.particle_task = context.scheduler:run_repeating(0, 20, function(tick_context)
tick_context.log:info("Another second passed!")
end)
scheduler:cancel(taskId)
Отменяет запланированную задачу по её ID.
| Параметр | Тип | Примечания |
|---|---|---|
taskId | int | ID задачи, возвращённый run_later или run_repeating |
Если вы запускаете повторяющуюся задачу, всегда отменяйте её в хуке очистки (on_destroy для пропов, on_exit_combat / on_death для боссов, on_unequip для предметов). Забывание отменить оставляет фоновую задачу работающей до уничтожения экземпляра скрипта, что тратит производительность и может вызвать ошибки.
Запланированные обратные вызовы получают свежий контекст в качестве параметра. Всегда используйте аргумент контекста самого обратного вызова, а не внешний context из хука, который создал обратный вызов. Внешний контекст может содержать устаревшие ссылки.
context.world
Таблица мира предоставляет методы для запросов и взаимодействия с миром Minecraft. Она строится из текущего мира сущности.
EliteMobs расширяет context.world дополнительными методами для спавна боссов, подкреплений, падающих блоков, фейерверков, зелий-брызг и временных блоков. Полный расширенный API см. в Мир и окружение EliteMobs. Описанные здесь методы доступны во всех плагинах.
world.name
Строковое поле, содержащее имя мира.
world:get_block_at(x, y, z)
Возвращает имя материала блока по заданным координатам в виде строки нижнего регистра (например, "stone", "air").
| Параметр | Тип | Примечания |
|---|---|---|
x | int | X-координата блока |
y | int | Y-координата блока |
z | int | Z-координата блока |
world:set_block_at(x, y, z, material)
Устанавливает блок по заданным координатам. Выполняется в главном потоке.
| Параметр | Тип | Примечания |
|---|---|---|
x | int | X-координата блока |
y | int | Y-координата блока |
z | int | Z-координата блока |
material | string | Имя Bukkit Material, нижний регистр (например, "stone", "air", "oak_planks") |
Возвращает true, если блок был установлен успешно, false в противном случае.
world:spawn_particle(particle, x, y, z, count, dx, dy, dz, speed)
Создаёт частицы в указанном местоположении.
| Параметр | Тип | По умолчанию | Примечания |
|---|---|---|---|
particle | string | обязательно | Имя перечисления Bukkit Particle, ВЕРХНИЙ_РЕГИСТР (например, "FLAME", "DUST") |
x | number | обязательно | X-координата |
y | number | обязательно | Y-координата |
z | number | обязательно | Z-координата |
count | int | 1 | Количество частиц |
dx | number | 0 | Разброс/смещение по X |
dy | number | 0 | Разброс/смещение по Y |
dz | number | 0 | Разброс/смещение по Z |
speed | number | 0 | Скорость частиц |
Некоторые типы частиц требуют данных о блоке или предмете, которые не поддерживаются этим простым API. BLOCK_CRACK, FALLING_DUST, BLOCK_DUST и ITEM_CRACK не будут работать или не будут давать видимого эффекта. Используйте альтернативы, не требующие данных: CLOUD, SMOKE, CAMPFIRE_COSY_SMOKE, SNOWFLAKE, FLAME, DUST и т.д.
world:play_sound(sound, x, y, z, volume, pitch)
Воспроизводит звук в указанном местоположении.
| Параметр | Тип | По умолчанию | Примечания |
|---|---|---|---|
sound | string | обязательно | Имя перечисления Bukkit Sound, ВЕРХНИЙ_РЕГИСТР (например, "ENTITY_EXPERIENCE_ORB_PICKUP") |
x | number | обязательно | X-координата |
y | number | обязательно | Y-координата |
z | number | обязательно | Z-координата |
volume | number | 1.0 | Громкость |
pitch | number | 1.0 | Тональность |
world:strike_lightning(x, y, z)
Ударяет молнией в указанном местоположении (визуально и с нанесением урона).
| Параметр | Тип | Примечания |
|---|---|---|
x | number | X-координата |
y | number | Y-координата |
z | number | Z-координата |
world:get_time()
Возвращает текущее время мира в тиках.
world:set_time(ticks)
Устанавливает время мира.
| Параметр | Тип | Примечания |
|---|---|---|
ticks | int | Время мира (0 = рассвет, 6000 = полдень, 13000 = ночь, 18000 = полночь) |
world:get_nearby_entities(x, y, z, radius)
Возвращает массив таблиц-обёрток сущностей для всех сущностей в пределах ограничивающего параллелепипеда с центром в указанных координатах.
| Параметр | Тип | Примечания |
|---|---|---|
x | number | Центр X |
y | number | Центр Y |
z | number | Центр Z |
radius | number | Радиус поиска (используется как полуразмер по всем трём осям) |
Возвращает ВСЕ сущности в радиусе, включая неживые сущности (стойки для брони, выброшенные предметы и т.д.). Всегда проверяйте if entity.damage then перед вызовом методов живых сущностей.
world:get_nearby_players(x, y, z, radius)
Возвращает массив таблиц-обёрток игроков для всех игроков в пределах ограничивающего параллелепипеда с центром в указанных координатах.
| Параметр | Тип | Примечания |
|---|---|---|
x | number | Центр X |
y | number | Центр Y |
z | number | Центр Z |
radius | number | Радиус поиска |
world:spawn_entity(entity_type, x, y, z)
Создаёт ванильную сущность Minecraft в указанном местоположении.
| Параметр | Тип | Примечания |
|---|---|---|
entity_type | string | Имя типа сущности Bukkit, нижний регистр (например, "zombie", "skeleton", "pig") |
x | number | X-координата |
y | number | Y-координата |
z | number | Z-координата |
Возвращает таблицу сущности для созданной сущности (с методами живой сущности, если применимо) или nil, если тип сущности недействителен.
world:get_highest_block_y(x, z)
Возвращает Y-координату самого высокого не воздушного блока на заданной позиции X/Z.
| Параметр | Тип | Примечания |
|---|---|---|
x | int | X-координата блока |
z | int | Z-координата блока |
world:raycast(from_x, from_y, from_z, dir_x, dir_y, dir_z, [max_distance])
Бросает луч из точки в направлении и возвращает информацию о том, во что он попал.
| Параметр | Тип | По умолчанию | Примечания |
|---|---|---|---|
from_x | number | обязательно | X начала |
from_y | number | обязательно | Y начала |
from_z | number | обязательно | Z начала |
dir_x | number | обязательно | X-компонент направления |
dir_y | number | обязательно | Y-компонент направления |
dir_z | number | обязательно | Z-компонент направления |
max_distance | number | 50 | Максимальное расстояние луча |
Возвращает таблицу со следующими полями:
| Поле | Тип | Примечания |
|---|---|---|
hit_entity | таблица сущности или nil | Первая сущность, в которую попал луч, или nil, если ни одна |
hit_location | таблица местоположения или nil | Точная точка, где луч во что-то попал |
hit_block | таблица или nil | {x, y, z, material} блока, в который попал луч, или nil, если блок не был задет |
world:spawn_firework(x, y, z, colors, [type], [power])
Создаёт фейерверк в указанном местоположении.
| Параметр | Тип | По умолчанию | Примечания |
|---|---|---|---|
x | number | обязательно | X-координата |
y | number | обязательно | Y-координата |
z | number | обязательно | Z-координата |
colors | table | обязательно | Массив строк цветов, например {"RED", "BLUE", "WHITE"} |
type | string | "BALL" | Форма фейерверка: "BALL", "BALL_LARGE", "STAR", "BURST", "CREEPER" |
power | int | 1 | Мощность полёта, 0-127 |
-- Example: red and gold firework burst
context.world:spawn_firework(loc.x, loc.y, loc.z, {"RED", "GOLD"}, "BURST", 2)
world:place_temporary_block(x, y, z, material, [ticks], [require_air])
Размещает блок, который автоматически возвращается в исходное состояние после задержки.
| Параметр | Тип | По умолчанию | Примечания |
|---|---|---|---|
x | int | обязательно | X-координата блока |
y | int | обязательно | Y-координата блока |
z | int | обязательно | Z-координата блока |
material | string | обязательно | Имя Bukkit Material (например, "stone", "ice") |
ticks | int | 0 | Длительность в тиках до возврата блока. 0 означает постоянный. |
require_air | boolean | false | Если true, размещает блок только если целевая позиция — воздух |
Возвращает true, если блок был размещён, false, если материал недействителен или требование воздуха не выполнено.
world:drop_item(x, y, z, material, [amount])
Создаёт выброшенный предмет в указанном местоположении с естественным разбросом.
| Параметр | Тип | По умолчанию | Примечания |
|---|---|---|---|
x | number | обязательно | X-координата |
y | number | обязательно | Y-координата |
z | number | обязательно | Z-координата |
material | string | обязательно | Имя Bukkit Material |
amount | int | 1 | Размер стопки |
Возвращает таблицу сущности для выброшенного предмета, или nil, если материал недействителен.
context.zones
Таблица зон позволяет создавать пространственные зоны и отслеживать вход/выход игроков. Зоны привязаны к экземпляру скрипта и автоматически очищаются при уничтожении экземпляра скрипта.
zones:create_sphere(x, y, z, radius)
Создаёт сферическую зону с центром в указанных координатах. Возвращает числовой дескриптор зоны.
| Параметр | Тип | Примечания |
|---|---|---|
x | number | Центр X |
y | number | Центр Y |
z | number | Центр Z |
radius | number | Радиус сферы |
zones:create_cylinder(x, y, z, radius, height)
Создаёт цилиндрическую зону. Возвращает числовой дескриптор зоны.
| Параметр | Тип | Примечания |
|---|---|---|
x | number | Центр X |
y | number | Центр Y (основание) |
z | number | Центр Z |
radius | number | Радиус цилиндра |
height | number | Высота цилиндра |
zones:create_cuboid(x, y, z, xSize, ySize, zSize)
Создаёт кубоидную зону. Возвращает числовой дескриптор зоны.
| Параметр | Тип | Примечания |
|---|---|---|
x | number | Центр X |
y | number | Центр Y |
z | number | Центр Z |
xSize | number | Полуразмер по X |
ySize | number | Полуразмер по Y |
zSize | number | Полуразмер по Z |
zones:watch(handle, onEnterCallback, onLeaveCallback)
Начинает отслеживание зоны на предмет входа/выхода игроков. Когда игрок входит или выходит из зоны, срабатывает соответствующий обратный вызов (и, если определены, хуки on_zone_enter / on_zone_leave).
| Параметр | Тип | Примечания |
|---|---|---|
handle | int | Дескриптор зоны из вызова create_* |
onEnterCallback | function или nil | Вызывается, когда игрок входит в зону |
onLeaveCallback | function или nil | Вызывается, когда игрок покидает зону |
Возвращает true, если наблюдение было настроено успешно, nil, если дескриптор зоны был недействительным.
Наблюдения за зонами проверяются каждый серверный тик для всех игроков в том же мире. Держите количество зон разумным, чтобы избежать влияния на производительность.
zones:unwatch(handle)
Останавливает наблюдение за зоной и очищает её ресурсы.
| Параметр | Тип | Примечания |
|---|---|---|
handle | int | Дескриптор зоны для остановки наблюдения |
Пример: зона срабатывания по приближению
return {
api_version = 1,
on_spawn = function(context)
local loc = context.prop.current_location -- or context.boss:get_location()
if loc == nil then return end
local handle = context.zones:create_sphere(loc.x, loc.y, loc.z, 5)
context.zones:watch(
handle,
function(player)
context.log:info("Player entered zone!")
end,
function(player)
context.log:info("Player left zone!")
end
)
context.state.zone_handle = handle
end,
on_destroy = function(context)
if context.state.zone_handle then
context.zones:unwatch(context.state.zone_handle)
end
end
}
context.event
Таблица event присутствует, когда текущий хук был вызван игровым событием (например, on_right_click, on_zone_enter). Она не присутствует во время on_tick или запланированных обратных вызовов.
| Поле / Метод | Тип | Примечания |
|---|---|---|
is_cancelled | boolean | Отменено ли событие |
cancel() | method | Отменяет событие (предотвращает поведение по умолчанию) |
uncancel() | method | Снимает отмену ранее отменённого события |
player | entity table | Игрок, участвующий в событии, если есть |
on_right_click = function(context)
if context.event then
context.event:cancel() -- prevent the default right-click interaction
end
end
Скрипты способностей EliteMobs имеют более подробную таблицу событий с объёмами урона, причинами урона, ссылками на атакующего и методами модификации урона. См. Справочник Lua API для полных полей событий EliteMobs.
Пространство имён em
Таблица em доступна во время загрузки файла (до запуска любого хука). Она предоставляет вспомогательные конструкторы для создания таблиц местоположений, таблиц векторов и определений зон, используемых во всём API.
| Функция | Назначение |
|---|---|
em.create_location(x, y, z [, world, yaw, pitch]) | Создать таблицу местоположения с необязательным именем мира, yaw и pitch. Возвращаемая таблица также имеет метод .add(dx, dy, dz), который смещает местоположение на месте и возвращает себя для цепочки вызовов. |
em.create_vector(x, y, z) | Создать таблицу вектора |
em.zone.create_sphere_zone(radius) | Создать определение сферической зоны |
em.zone.create_dome_zone(radius) | Создать определение купольной зоны |
em.zone.create_cylinder_zone(radius, height) | Создать определение цилиндрической зоны |
em.zone.create_cuboid_zone(x, y, z) | Создать определение кубоидной зоны |
em.zone.create_cone_zone(length, radius) | Создать определение конусной зоны |
em.zone.create_static_ray_zone(length, thickness) | Создать определение зоны статического луча |
em.zone.create_rotating_ray_zone(length, point_radius, animation_duration) | Создать определение зоны вращающегося луча |
em.zone.create_translating_ray_zone(length, point_radius, animation_duration) | Создать определение зоны перемещающегося луча |
Конструкторы зон возвращают цепочечные таблицы с :set_center(loc) (или :set_origin(loc) / :set_destination(loc) в зависимости от типа зоны):
-- At file scope: create a reusable zone shape
local blast_zone = em.zone.create_sphere_zone(5)
return {
api_version = 1,
on_spawn = function(context)
-- Anchor the zone at call time
blast_zone:set_center(context.boss:get_location())
local entities = context.zones:get_entities_in_zone(blast_zone)
-- ...
end
}
Пространство имён em особенно полезно в EliteMobs, где определения зон используются с context.zones:get_entities_in_zone() и context.script. В FreeMinecraftModels методы context.zones:create_sphere(...) / create_cylinder(...) / create_cuboid(...) чаще используются для простых зон на основе наблюдения.
Таблицы сущностей
Таблицы сущностей возвращаются из запросов мира, данных событий и обратных вызовов зон. Они предоставляют многоуровневый набор полей и методов в зависимости от типа сущности.
Базовые поля сущности
| Поле | Тип | Примечания |
|---|---|---|
uuid | string | UUID сущности |
entity_type | string | Тип сущности (например, "player", "zombie", "skeleton", "villager") |
is_valid | boolean | Действительна ли ссылка на сущность |
is_dead | boolean | Мертва ли сущность |
is_player | boolean | Является ли сущность игроком |
is_hostile | boolean | Является ли сущность враждебным мобом (зомби, скелет и т.д.) |
is_passive | boolean | Является ли сущность мирным мобом (корова, свинья, курица и т.д.) |
current_location | таблица местоположения | Текущая позиция сущности (x, y, z, world, yaw, pitch) |
world | string | Имя мира, в котором находится сущность |
Базовые методы сущности
| Метод | Возвращает | Примечания |
|---|---|---|
teleport(location_table) | void | Телепортирует сущность. Таблица местоположения должна содержать поля x, y, z, world; yaw и pitch необязательны. |
remove() | void | Удаляет сущность из мира. Действует только если сущность всё ещё действительна. |
set_silent(flag) | void | Подавляет или восстанавливает звуки сущности. |
set_invulnerable(flag) | void | Делает сущность неуязвимой или уязвимой к урону. |
set_gravity(flag) | void | Включает или отключает гравитацию для сущности. |
set_glowing(flag) | void | Переключает эффект светящегося контура на сущности. |
Поля живой сущности
Живые сущности (игроки, мобы и т.д.) имеют все базовые поля сущности плюс:
| Поле | Тип | Примечания |
|---|---|---|
health | number | Текущее здоровье |
maximum_health | number | Максимальное здоровье |
name | string | Отображаемое имя |
is_alive | boolean | Жива ли сущность |
Методы живой сущности
| Метод | Возвращает | Примечания |
|---|---|---|
damage(amount) | void | Наносит указанное количество урона сущности |
push(x, y, z) | void | Применяет импульс скорости |
set_facing(x, y, z) | void | Устанавливает направление взгляда сущности |
add_potion_effect(effect, duration, amplifier) | void | Добавляет эффект зелья. effect — строка (например, "speed", "slowness", "regeneration"). duration — в тиках. amplifier — уровень эффекта минус 1 (0 = уровень I). |
remove_potion_effect(effect) | void | Удаляет эффект зелья по имени |
Не все сущности, возвращаемые get_nearby_entities(), являются живыми сущностями. Вы можете использовать entity.is_player, entity.is_hostile или entity.is_passive для фильтрации по категории, или проверять if entity.damage then перед вызовом методов живых сущностей, таких как damage(), push() или add_potion_effect().
Поля интеграции с плагинами
Таблицы сущностей автоматически включают поля для обнаружения и взаимодействия с сущностями, управляемыми другими плагинами Nightbreak. Эти поля заполняются только при установленном соответствующем плагине — иначе они имеют значения false / nil без дополнительных затрат.
Поля EliteMobs
Доступны при установленном EliteMobs.
| Поле | Тип | Примечания |
|---|---|---|
is_elite | boolean | Является ли сущность элитой EliteMobs |
is_custom_boss | boolean | Является ли сущность пользовательским боссом EliteMobs (также доступно в подтаблице elite) |
is_significant_boss | boolean | Является ли сущность пользовательским боссом с множителем здоровья больше 1 (т.е. спроектированной встречей, а не рядовой элитой) |
elite | table или nil | Подтаблица информации об элите (см. ниже). nil, если сущность не является элитой. |
Подтаблица elite содержит:
| Поле | Тип | Примечания |
|---|---|---|
elite.level | int | Уровень элиты |
elite.name | string | Отображаемое имя элиты |
elite.health | number | Текущее здоровье |
elite.max_health | number | Максимальное здоровье |
elite.is_custom_boss | boolean | Является ли пользовательским боссом (в отличие от природной элиты) |
elite.health_multiplier | number | Множитель здоровья из конфигурации |
elite.damage_multiplier | number | Множитель урона из конфигурации |
elite:remove() | void | Удаляет элиту через надлежащий конвейер удаления EliteMobs (очищает отслеживание, добычу и т.д.) |
Пример: Нанесение разного урона элитам
local entities = context.world:get_nearby_entities(x, y, z, 5)
for _, entity in ipairs(entities) do
if entity.is_elite then
-- Deal double damage to elites
entity:damage(20)
context.log:info("Hit elite: " .. entity.elite.name .. " (level " .. entity.elite.level .. ")")
elseif entity.is_hostile then
entity:damage(10)
end
end
Поля FreeMinecraftModels
Доступны при установленном FreeMinecraftModels.
| Поле | Тип | Примечания |
|---|---|---|
is_modeled | boolean | Имеет ли сущность присоединённую модель FMM (DynamicEntity или PropEntity) |
is_prop | boolean | Является ли сущность пропом FMM (статическая декоративная сущность) |
model | table или nil | Подтаблица информации о модели (см. ниже). nil, если сущность не имеет модели. |
Подтаблица model содержит:
| Поле | Тип | Примечания |
|---|---|---|
model.model_id | string | ID чертежа модели (например, "torch_01") |
model:play_animation(name, [blend], [loop]) | boolean | Воспроизводит именованную анимацию. blend по умолчанию false, loop по умолчанию false. Возвращает true, если анимация найдена. |
model:stop_animations() | void | Останавливает все текущие анимации модели. |
model:remove() | void | Удаляет моделированную сущность через надлежащий конвейер удаления FMM. |
Мост модели (доступный для любой сущности) по умолчанию устанавливает blend и loop в false. Таблица пропа play_animation по умолчанию устанавливает оба в true, потому что пропы обычно используют смешанные зацикленные анимации.
Пример: Фильтрация сущностей по типу
local entities = context.world:get_nearby_entities(x, y, z, 10)
for _, entity in ipairs(entities) do
if entity.is_prop then
-- Skip props
elseif entity.is_player then
entity:damage(5)
elseif entity.entity_type == "villager" then
-- Don't hurt villagers
elseif entity.is_elite then
entity:damage(20)
elseif entity.is_hostile then
entity:damage(10)
end
end
Поля, специфичные для игрока
Сущности игроков имеют все поля сущности и живой сущности плюс:
| Поле | Тип | Примечания |
|---|---|---|
game_mode | string | Режим игры игрока ("creative", "survival", "adventure", "spectator") |
Методы, специфичные для игрока
| Метод | Возвращает | Примечания |
|---|---|---|
send_message(msg) | void | Отправляет сообщение в чат игроку. Поддерживает цветовые коды &. |
get_held_item() | table или nil | Возвращает {type, amount, display_name} для предмета в основной руке игрока, или nil, если пусто |
consume_held_item(amount?) | void | Потребляет предметы из основной руки игрока. amount по умолчанию 1 |
has_item(material, amount?) | boolean | Возвращает true, если у игрока есть хотя бы amount (по умолчанию 1) указанного материала где-либо в инвентаре |
get_target_entity([range]) | таблица сущности или nil | Возвращает сущность, на которую смотрит игрок через raycast, или nil, если нет. Дальность по умолчанию 50. |
get_eye_location() | таблица местоположения | Возвращает таблицу местоположения на уровне глаз игрока |
get_look_direction() | table | Возвращает вектор направления {x, y, z}, куда смотрит игрок |
send_block_change(x, y, z, material, [ticks]) | void | Отправляет фальшивый блок, видимый только этому игроку. Если указаны ticks, фальшивый блок автоматически сбрасывается после этой длительности. |
reset_block(x, y, z) | void | Сбрасывает фальшивый блок обратно к реальному для этого игрока |
sleep(x, y, z) | void | Заставляет игрока выполнить анимацию сна в кровати по указанным координатам. Блок автоматически восстанавливается, когда игрок перестаёт спать. |
wake_up() | void | Будит спящего игрока. |
Методы UI игрока
Эти методы доступны для любой таблицы сущности игрока и предоставляют способы отображения информации через встроенные элементы интерфейса Minecraft.
player:show_boss_bar(text, [color], progress, [ticks])
Показывает полосу босса игроку.
| Параметр | Тип | По умолчанию | Примечания |
|---|---|---|---|
text | string | обязательно | Отображаемый текст. Поддерживает цветовые коды &. |
color | string | "WHITE" | Цвет полосы. Один из: "RED", "BLUE", "GREEN", "YELLOW", "PURPLE", "PINK", "WHITE" |
progress | number | обязательно | Уровень заполнения от 0.0 (пусто) до 1.0 (полно) |
ticks | int | nil | Необязательная задержка автоскрытия в тиках. Если не указано, полоса остаётся до ручного скрытия. |
player:hide_boss_bar()
Убирает полосу босса с экрана игрока. Не принимает параметров.
player:show_action_bar(text, [ticks])
Показывает текст в области панели действий (над хотбаром).
| Параметр | Тип | По умолчанию | Примечания |
|---|---|---|---|
text | string | обязательно | Отображаемый текст. Поддерживает цветовые коды &. |
ticks | int | nil | Необязательная длительность в тиках. Если указана, сообщение повторно отправляется каждые 40 тиков, чтобы оставаться видимым в течение полной длительности. |
player:show_title(title, [subtitle], fade_in, stay, fade_out)
Показывает экран заголовка игроку.
| Параметр | Тип | По умолчанию | Примечания |
|---|---|---|---|
title | string | обязательно | Основной текст заголовка. Поддерживает цветовые коды &. |
subtitle | string | "" | Текст подзаголовка под основным заголовком. Необязательно. |
fade_in | int | обязательно | Длительность появления в тиках |
stay | int | обязательно | Как долго заголовок остаётся на экране в тиках |
fade_out | int | обязательно | Длительность исчезновения в тиках |
Следующие шаги
Для хуков, API и рабочих процессов, специфичных для плагинов:
- EliteMobs: Начало работы | Хуки и жизненный цикл | Боссы и сущности | Мир и окружение | Зоны и нацеливание
- FreeMinecraftModels: Начало работы | API пропов и предметов | Примеры