Перейти к основному содержимому

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_idstringИмя модели-чертежа (например, "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)

Воспроизводит именованную анимацию на модели пропса.

ПараметрТипПо умолчаниюПримечания
namestringобязательныйИмя анимации, определённое в файле модели
blendbooleantrueПлавный переход от текущей анимации
loopbooleantrueЗацикливание анимации

Возвращает 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 на сервере.

ПараметрТипПримечания
filenamestringИмя файла кастомного босса (например, "my_boss.yml")
xnumberКоордината X
ynumberКоордината Y
znumberКоордината 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обязательныйИгрок, которому показать инвентарь
titlestringобязательныйЗаголовок инвентаря (поддерживает цветовые коды &)
rowsint3Количество рядов (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 стойки для брони пропса. Эти данные переживают перезапуски сервера и выгрузки чанков.

ПараметрТипПримечания
keystringУникальное имя ключа (внутренне хранится как fmm_lua_<key>)
valuestringЗначение для сохранения. Для чисел и булевых значений используйте tostring().

Возвращает true при успехе, false если у пропса нет базовой стойки для брони.


prop:get_persistent_data(key)

Извлекает строковое значение, ранее сохранённое через set_persistent_data. Возвращает nil, если ключ не был установлен.

ПараметрТипПримечания
keystringИмя ключа, использованное в 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.idstringID типа предмета (fmm_item_id из YML-конфига)

item:material()

Возвращает имя материала предмета в виде строки (например, "DIAMOND_SWORD", "STICK").


item:get_amount() / item:set_amount(n)

Получает или устанавливает размер стака предмета.

ПараметрТипПримечания
nintНовый размер стака

item:consume(n)

Уменьшает размер стака предмета на n (по умолчанию 1). Если результирующее количество равно 0 или меньше, предмет удаляется из инвентаря игрока.

ПараметрТипПо умолчаниюПримечания
nint1Количество для потребления

item:get_uses() / item:set_uses(n)

Получает или устанавливает счётчик пользовательских использований, хранящийся в PersistentDataContainer предмета. Это не зависит от ванильной прочности и может использоваться для реализации пользовательской прочности или систем зарядки.

ПараметрТипПримечания
nintНовое количество использований

item:get_name() / item:set_name(s)

Получает или устанавливает отображаемое имя предмета. Поддерживает цветовые коды с &.

ПараметрТипПримечания
sstringНовое отображаемое имя (например, "&b&lFrost Sword")

item:get_lore() / item:set_lore(table)

Получает или устанавливает описание предмета. get_lore() возвращает таблицу строк (по одной на строку). set_lore() принимает таблицу строк.

ПараметрТипПримечания
tabletableМассив строк, по одной на строку описания
Пример: скрипт предмета с отслеживанием использований
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)

Уменьшает ванильную прочность предмета на фиксированное количество.

ПараметрТипПо умолчаниюПримечания
amountintобязательныйСколько единиц прочности потребить
can_breakbooleanfalseЕсли true, предмет уничтожается при исчерпании прочности. Если false, прочность останавливается на 1.

item:use_durability_percentage(fraction, can_break)

Уменьшает ванильную прочность предмета на процент от максимума.

ПараметрТипПо умолчаниюПримечания
fractionnumberобязательныйДоля максимальной прочности для потребления (например, 0.1 = 10%)
can_breakbooleanfalseЕсли 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_cancelledbooleanОтменено ли событие в данный момент
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() и обратных вызовов зон.

Общий API

Таблицы сущностей, методы живых сущностей, методы, специфичные для игроков, и методы 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, принадлежат создавшему их рантайму. При удалении пропса:

  1. Рантайм завершается.
  2. Все принадлежащие задачи — как одноразовые, так и повторяющиеся — автоматически отменяются.
  3. Все наблюдения за зонами очищаются.

Бюджет выполнения

Каждый вызов хука и каждый вызов обратного вызова хронометрируется. Если один вызов занимает более 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

Следующие шаги