Lua-скриптинг: Prop & Item API
Эта страница описывает все API, доступные в скриптах пропсов и предметов FreeMinecraftModels: context.prop, context.item, context.event, context.player, context.world, context.zones, context.scheduler, context.state и context.log. Если вы новичок в скриптинге, начните с Начало работы.
context.prop
Таблица prop предоставляет информацию о сущности пропса и методы для управления его анимациями. Создаётся заново для каждого вызова хука.
Поля
| Поле | Тип | Примечания |
|---|---|---|
prop.model_id | string | Имя модели-чертежа (например, "torch_01") |
prop.current_location | таблица location | Позиция пропса на момент создания context |
Таблица location имеет стандартные поля: x, y, z, world, yaw, pitch.
Пример: чтение информации о пропсе
return {
api_version = 1,
on_spawn = function(context)
context.log:info("Prop spawned: " .. (context.prop.model_id or "unknown"))
local loc = context.prop.current_location
if loc then
context.log:info("Location: " .. loc.x .. ", " .. loc.y .. ", " .. loc.z)
end
end
}
prop:play_animation(name, blend, loop)
Воспроизводит именованную анимацию на модели пропса.
| Параметр | Тип | По умолчанию | Примечания |
|---|---|---|---|
name | string | обязательный | Имя анимации, определённое в файле модели |
blend | boolean | true | Плавный переход от текущей анимации |
loop | boolean | true | Зацикливание анимации |
Возвращает true, если анимация найдена и запущена, false в противном случае.
Пример
return {
api_version = 1,
on_right_click = function(context)
local success = context.prop:play_animation("open", true, false)
if not success then
context.log:warn("Animation 'open' not found on this model!")
end
end
}
prop:stop_animation()
Останавливает все текущие анимации на пропсе.
Не принимает параметров.
Пример
return {
api_version = 1,
on_right_click = function(context)
context.prop:stop_animation()
end
}
prop:hurt_visual()
Воспроизводит визуальную анимацию повреждения (красная вспышка) на пропсе без нанесения фактического урона.
Не принимает параметров.
Пример
return {
api_version = 1,
on_left_click = function(context)
-- Красная вспышка при ударе, но без фактического урона
if context.event then
context.event.cancel()
end
context.prop:hurt_visual()
end
}
prop:pickup()
Удаляет пропс из мира и выбрасывает бумажный предмет размещения на его месте. Выброшенный предмет можно использовать правым кликом по блоку для повторного размещения пропса.
Не принимает параметров.
Пример
return {
api_version = 1,
on_right_click = function(context)
-- Позволяет игрокам подбирать пропс правым кликом
context.prop:pickup()
end
}
prop:mount(player)
Сажает игрока на первое доступное место посадки на пропсе. Модель должна иметь определённые кости точек посадки.
| Параметр | Тип | Примечания |
|---|---|---|
player | таблица entity | Таблица сущности игрока (например, из context.event.player) |
Пример
return {
api_version = 1,
on_right_click = function(context)
local player = context.event and context.event.player
if player then
context.prop:mount(player)
end
end
}
prop:dismount(player)
Снимает игрока с места посадки на пропсе.
| Параметр | Тип | Примечания |
|---|---|---|
player | таблица entity | Таблица сущности игрока |
Пример
return {
api_version = 1,
on_right_click = function(context)
local player = context.event and context.event.player
if player then
-- Переключение посадки/высадки
local passengers = context.prop:get_passengers()
for i = 1, #passengers do
if passengers[i].uuid == player.uuid then
context.prop:dismount(player)
return
end
end
context.prop:mount(player)
end
end
}
prop:get_passengers()
Возвращает Lua-массив таблиц сущностей для всех текущих пассажиров пропса.
Не принимает параметров.
Пример
return {
api_version = 1,
on_game_tick = function(context)
local passengers = context.prop:get_passengers()
if #passengers > 0 then
context.log:info("Prop has " .. #passengers .. " passenger(s)")
end
end
}
prop:has_mount_points()
Возвращает, определены ли в модели пропса кости точек посадки.
Не принимает параметров. Возвращает true или false.
Пример
return {
api_version = 1,
on_right_click = function(context)
local player = context.event and context.event.player
if player and context.prop:has_mount_points() then
context.prop:mount(player)
end
end
}
prop:spawn_elitemobs_boss(filename, x, y, z)
Спавнит кастомного босса EliteMobs в заданном местоположении. Требует установленного EliteMobs на сервере.
| Параметр | Тип | Примечания |
|---|---|---|
filename | string | Имя файла кастомного босса (например, "my_boss.yml") |
x | number | Координата X |
y | number | Координата Y |
z | number | Координата Z |
Возвращает таблицу живой сущности для заспавненного босса или nil, если EliteMobs не установлен или файл босса не существует.
Пример
return {
api_version = 1,
on_right_click = function(context)
local loc = context.prop.current_location
if loc then
local boss = context.prop:spawn_elitemobs_boss("dungeon_guardian.yml", loc.x, loc.y + 1, loc.z)
if boss then
context.log:info("Spawned boss: " .. (boss.name or "unknown"))
else
context.log:warn("Could not spawn boss -- is EliteMobs installed?")
end
end
end
}
prop:open_inventory(player, title, rows)
Открывает для игрока постоянный GUI инвентаря сундука. Содержимое сохраняется в PersistentDataContainer пропса при закрытии инвентаря и восстанавливается при повторном открытии.
| Параметр | Тип | По умолчанию | Примечания |
|---|---|---|---|
player | таблица entity | обязательный | Игрок, которому показать инвентарь |
title | string | обязательный | Заголовок инвентаря (поддерживает цветовые коды &) |
rows | int | 3 | Количество рядов (1-6, где 6 = 54 слота = двойной сундук) |
Возвращает true, если инвентарь был открыт, false в противном случае.
prop:is_viewing_inventory(player)
Возвращает, открыт ли у данного игрока в данный момент инвентарь этого пропса.
| Параметр | Тип | Примечания |
|---|---|---|
player | таблица entity | Игрок для проверки |
Возвращает true или false.
Пример: анимация закрытия при закрытии инвентаря
context.state["task_" .. player.uuid] = context.scheduler:run_repeating(5, 5, function(tick_context)
if not tick_context.prop:is_viewing_inventory(player) then
tick_context.prop:play_animation("close", true, false)
tick_context.scheduler:cancel(tick_context.state["task_" .. player.uuid])
end
end)
prop:place_book(player)
Берёт написанную или записываемую книгу из главной руки игрока и сохраняет её на пропсе.
| Параметр | Тип | Примечания |
|---|---|---|
player | таблица entity | Игрок, держащий книгу |
Возвращает true при успехе.
prop:read_book(player)
Открывает сохранённую книгу для чтения игроком.
| Параметр | Тип | Примечания |
|---|---|---|
player | таблица entity | Игрок, которому показать книгу |
Возвращает true, если книга была открыта.
prop:take_book(player)
Возвращает сохранённую книгу в инвентарь игрока и удаляет её с пропса.
| Параметр | Тип | Примечания |
|---|---|---|
player | таблица entity | Игрок, которому отдать книгу |
Возвращает true при успехе.
prop:has_book()
Возвращает, хранится ли книга на этом пропсе. Не принимает параметров.
prop:drop_inventory()
Выбрасывает всё содержимое сохранённого инвентаря в виде предметных сущностей на месте пропса, затем очищает сохранённые данные. Автоматически закрывает инвентарь для всех игроков, которые в данный момент его просматривают.
Не принимает параметров. Возвращает true при успехе.
prop:drop_book()
Выбрасывает сохранённую книгу в виде предметной сущности на месте пропса и очищает сохранённые данные книги.
Не принимает параметров. Возвращает true при успехе.
prop:set_persistent_data(key, value)
Сохраняет строковое значение в PersistentDataContainer стойки для брони пропса. Эти данные переживают перезапуски сервера и выгрузки чанков.
| Параметр | Тип | Примечания |
|---|---|---|
key | string | Уникальное имя ключа (внутренне хранится как fmm_lua_<key>) |
value | string | Значение для сохранения. Для чисел и булевых значений используйте tostring(). |
Возвращает true при успехе, false если у пропса нет базовой стойки для брони.
prop:get_persistent_data(key)
Извлекает строковое значение, ранее сохранённое через set_persistent_data. Возвращает nil, если ключ не был установлен.
| Параметр | Тип | Примечания |
|---|---|---|
key | string | Имя ключа, использованное в set_persistent_data |
Пример: постоянное состояние переключения
return {
api_version = 1,
on_spawn = function(context)
local saved = context.prop:get_persistent_data("active")
context.state.active = saved == "true"
end,
on_right_click = function(context)
context.state.active = not context.state.active
context.prop:set_persistent_data("active", tostring(context.state.active))
end
}
context.item
Таблица item доступна только в скриптах предметов (не в скриптах пропсов). Она предоставляет информацию о пользовательском предмете и методы для его манипуляции. Эта таблица создаётся заново для каждого вызова хука.
Поля
| Поле | Тип | Примечания |
|---|---|---|
item.id | string | ID типа предмета (fmm_item_id из YML-конфига) |
item:material()
Возвращает имя материала предмета в виде строки (например, "DIAMOND_SWORD", "STICK").
item:get_amount() / item:set_amount(n)
Получает или устанавливает размер стака предмета.
| Параметр | Тип | Примечания |
|---|---|---|
n | int | Новый размер стака |
item:consume(n)
Уменьшает размер стака предмета на n (по умолчанию 1). Если результирующее количество равно 0 или меньше, предмет удаляется из инвентаря игрока.
| Параметр | Тип | По умолчанию | Примечания |
|---|---|---|---|
n | int | 1 | Количество для потребления |
item:get_uses() / item:set_uses(n)
Получает или устанавливает счётчик пользовательских использований, хранящийся в PersistentDataContainer предмета. Это не зависит от ванильной прочности и может использоваться для реализации пользовательской прочности или систем зарядки.
| Параметр | Тип | Примечания |
|---|---|---|
n | int | Новое количество использований |
item:get_name() / item:set_name(s)
Получает или устанавливает отображаемое имя предмета. Поддерживает цветовые коды с &.
| Параметр | Тип | Примечания |
|---|---|---|
s | string | Новое отображаемое имя (например, "&b&lFrost Sword") |
item:get_lore() / item:set_lore(table)
Получает или устанавливает описание предмета. get_lore() возвращает таблицу строк (по одной на строку). set_lore() принимает таблицу строк.
| Параметр | Тип | Примечания |
|---|---|---|
table | table | Массив строк, по одной на строку описания |
Пример: скрипт предмета с отслеживанием использований
return {
api_version = 1,
on_right_click = function(context)
local uses = context.item:get_uses()
if uses <= 0 then
context.player:send_message("&cThis item is out of charges!")
return
end
context.item:set_uses(uses - 1)
context.player:send_message("&aUsed! Charges remaining: " .. (uses - 1))
end
}
item:get_durability()
Возвращает таблицу с полями current и max, представляющими ванильную прочность предмета, или nil, если у предмета нет шкалы прочности.
Пример
local dur = context.item:get_durability()
if dur then
context.player:send_message("Durability: " .. dur.current .. "/" .. dur.max)
end
item:get_durability_percentage()
Возвращает оставшуюся прочность как дробь от 0.0 до 1.0, или nil, если у предмета нет шкалы прочности.
item:use_durability(amount, can_break)
Уменьшает ванильную прочность предмета на фиксированное количество.
| Параметр | Тип | По умолчанию | Примечания |
|---|---|---|---|
amount | int | обязательный | Сколько единиц прочности потребить |
can_break | boolean | false | Если true, предмет уничтожается при исчерпании прочности. Если false, прочность останавливается на 1. |
item:use_durability_percentage(fraction, can_break)
Уменьшает ванильную прочность предмета на процент от максимума.
| Параметр | Тип | По умолчанию | Примечания |
|---|---|---|---|
fraction | number | обязательный | Доля максимальной прочности для потребления (например, 0.1 = 10%) |
can_break | boolean | false | Если true, предмет уничтожается при исчерпании прочности. Если false, прочность останавливается на 1. |
context.event
Данные события для текущего хука. Доступны в хуках кликов, боя и взаимодействия как для скриптов пропсов, так и для скриптов предметов. Возвращает nil в хуках без связанного события (on_spawn, on_game_tick, on_destroy, on_zone_enter, on_zone_leave, on_equip).
Поля и методы
| Поле или метод | Тип | Примечания |
|---|---|---|
event.player | таблица сущности игрока | Игрок, вызвавший событие. Доступен в on_left_click, on_right_click и on_projectile_hit (стрелок, если это был игрок). См. Методы сущности игрока для всех полей и методов. |
event.is_cancelled | boolean | Отменено ли событие в данный момент |
event.cancel() | function | Отменяет событие (например, предотвращает урон или взаимодействие) |
event.uncancel() | function | Снимает отмену ранее отменённого события |
Не все события можно отменить. Если базовое событие Bukkit не реализует Cancellable, event.cancel() и event.uncancel() не будут присутствовать, а event.is_cancelled всегда будет false.
Пример: Создание неуязвимого пропса
Пример
return {
api_version = 1,
on_left_click = function(context)
if context.event then
context.event.cancel()
end
end
}
Пример: Проверка состояния отмены
Пример
return {
api_version = 1,
on_left_click = function(context)
if context.event and not context.event.is_cancelled then
context.event.cancel()
context.log:info("Damage cancelled!")
end
end
}
Внутри запланированных обратных вызовов (scheduler:run_later, scheduler:run_repeating) context.event всегда nil. Модификация события возможна только во время самого хука события.
context.world
API world является общим для всех плагинов Nightbreak. Полный справочник см. в context.world.
Пропсы FMM используют ту же таблицу world из MagmaCore, что и боссы EliteMobs. Все методы, документированные на глобальной странице (get_block_at, set_block_at, spawn_particle, play_sound, strike_lightning, get_time, set_time, get_nearby_entities, get_nearby_players, spawn_entity, get_highest_block_y, raycast, spawn_firework), доступны в FMM. Подробности о world:raycast() (бросить луч и обнаружить попавшие сущности/блоки) и world:spawn_firework() (создать фейерверк с пользовательскими цветами и формами) см. в MagmaCore world API. EliteMobs расширяет таблицу world дополнительными методами для спавна боссов, подкреплений и т.д. — см. EliteMobs World & Environment.
Методы сущности игрока
Таблицы сущностей игроков возвращаются из context.event.player, context.world:get_nearby_players() и обратных вызовов зон.
Таблицы сущностей, методы живых сущностей, методы, специфичные для игроков, и методы UI игрока являются общими для всех плагинов Nightbreak. Полный справочник, охватывающий базовые поля сущностей, поля и методы живых сущностей, поля и методы, специфичные для игроков, и методы UI игрока, см. в MagmaCore Lua Scripting Engine. Новые методы игрока включают player:get_target_entity() (прицеливание лучом), player:get_eye_location(), player:get_look_direction(), player:send_block_change() (фейковые блоки для каждого игрока) и player:reset_block() — подробности см. в Методы, специфичные для игроков.
context.zones
API zones является общим для всех плагинов Nightbreak. Полный справочник см. в context.zones.
context.scheduler
API scheduler является общим для всех плагинов Nightbreak. Полный справочник см. в context.scheduler.
context.state
API state является общим для всех плагинов Nightbreak. Полный справочник см. в context.state.
context.log
API логирования является общим для всех плагинов Nightbreak. Полный справочник см. в context.log.
Модель выполнения
Один рантайм на экземпляр скрипта
Каждая сущность пропса со скриптами получает свой независимый экземпляр Lua-рантайма. При спавне пропса FMM загружает Lua-источник, выполняет его в новом изолированном окружении и сохраняет возвращённую таблицу. При удалении пропса рантайм завершается.
Для скриптов предметов один рантайм создаётся на пару (игрок, itemId). Когда игрок экипирует пользовательский предмет, FMM создаёт экземпляр скрипта для этого игрока и типа предмета. Когда предмет снимается, рантайм завершается.
Это означает:
- Локальные переменные, объявленные на уровне файла, являются приватными для данного экземпляра скрипта.
context.stateполностью изолирован между экземплярами, даже если они используют один и тот же файл скрипта.
Владение запланированными задачами
Все задачи, созданные через context.scheduler, принадлежат создавшему их рантайму. При удалении пропса:
- Рантайм завершается.
- Все принадлежащие задачи — как одноразовые, так и повторяющиеся — автоматически отменяются.
- Все наблюдения за зонами очищаются.
Бюджет выполнения
Каждый вызов хука и каждый вызов обратного вызова хронометрируется. Если один вызов занимает более 50 миллисекунд, скрипт отключается с предупреждением в консоли:
[Lua] my_script.lua took 73ms in 'on_game_tick' (limit: 50ms) -- script disabled to prevent lag.
Для соблюдения бюджета:
- Избегайте неограниченных циклов внутри хуков.
- Держите обработчики
on_game_tickлегковесными — они выполняются каждый тик. - Используйте
context.scheduler:run_repeating(...)для распределения работы между тиками.
Полный справочник хуков
Эта таблица перечисляет все хуки, доступные в скриптах пропсов и предметов.
Хуки пропсов (8)
| Хук | Срабатывает когда | context.event |
|---|---|---|
on_spawn | Пропс появляется в мире | nil |
on_game_tick | Каждый серверный тик (50мс) | nil |
on_destroy | Пропс удаляется | nil |
on_left_click | Игрок кликает ЛКМ по пропсу | событие урона |
on_right_click | Игрок кликает ПКМ по пропсу | событие взаимодействия |
on_projectile_hit | Снаряд попадает в пропс | событие попадания снаряда |
on_zone_enter | Игрок входит в наблюдаемую зону | nil |
on_zone_leave | Игрок покидает наблюдаемую зону | nil |
Хуки предметов (22)
| Хук | Категория | Срабатывает когда | context.event |
|---|---|---|---|
on_attack_entity | Бой | Игрок атакует сущность | событие урона |
on_kill_entity | Бой | Игрок убивает сущность | событие смерти |
on_take_damage | Бой | Игрок получает урон | событие урона |
on_shield_block | Бой | Игрок блокирует щитом | событие урона |
on_shoot_bow | Бой | Игрок стреляет из лука | событие выстрела |
on_projectile_hit | Бой | Снаряд игрока попадает | событие попадания снаряда |
on_projectile_launch | Бой | Игрок запускает снаряд | событие запуска |
on_right_click | Взаимодействие | Игрок кликает ПКМ | событие взаимодействия |
on_left_click | Взаимодействие | Игрок кликает ЛКМ | событие взаимодействия |
on_shift_right_click | Взаимодействие | Игрок кликает Shift+ПКМ | событие взаимодействия |
on_shift_left_click | Взаимодействие | Игрок кликает Shift+ЛКМ | событие взаимодействия |
on_interact_entity | Взаимодействие | Игрок кликает ПКМ по сущности | событие взаимодействия с сущностью |
on_equip | Экипировка | Предмет попадает в активный слот | nil |
on_unequip | Экипировка | Предмет покидает активный слот | nil |
on_swap_hands | Экипировка | Смена основной/вторичной руки | событие смены |
on_drop | Экипировка | Игрок выбрасывает предмет | событие выброса |
on_break_block | Утилиты | Игрок ломает блок | событие разрушения блока |
on_consume | Утилиты | Игрок потребляет предмет | событие потребления |
on_item_damage | Утилиты | Предмет получает урон прочности | событие повреждения предмета |
on_fish | Утилиты | Игрок использует удочку | событие рыбалки |
on_death | Утилиты | Игрок умирает при экипированном предмете | событие смерти |
on_game_tick | Жизненный цикл | Каждый тик, пока экипирован | nil |
Следующие шаги
- Примеры и паттерны — полные рабочие скрипты для пропсов и предметов с пояснениями
- Устранение неполадок — распространённые проблемы, советы по отладке и контрольный список QC
- Начало работы — структура файлов, хуки, пошаговое создание первого скрипта