Lua-скрипты: API реквизита
На этой странице описаны context.prop, context.event, context.player, context.projectile, context.world, context.zones, context.scheduler, context.state, context.cooldowns и context.log для скриптов реквизита FreeMinecraftModels. Если вы только начинаете, прочтите Начало работы.
context.prop
Предоставляет сведения о реквизите и методы управления анимацией. FMM кеширует таблицу для каждого реквизита. Поля вроде current_location запрашиваются при чтении и отражают текущее состояние.
Поля
| Поле | Тип | Описание |
|---|---|---|
prop.model_id | string | Имя модели в шаблоне, например "torch_01" |
prop.current_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 | true ставит переключение в очередь после тика текущего состояния; false прерывает сразу. Плавного смешивания нет |
loop | boolean | true | Повтор пользовательской анимации; встроенные состояния следуют собственным правилам |
Возвращает true, если запрос принят, включая отложенные и подавленные запросы. false означает, что принять запрос нельзя. Конечное состояние death отклоняет дальнейшие запросы. Запрос атаки во время пользовательской анимации принимается без её прерывания. В очереди только одно место: новый отложенный запрос заменяет предыдущий. Принятие не доказывает видимое воспроизведение. См. Анимации.
Пример
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()
Очищает очередь и возвращается к idle, если оно есть; иначе останавливает текущее состояние общего движка. Конечное состояние death сохраняется, хотя реализация Bedrock получает запрос остановки. Параметров нет.
Пример
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)
-- Flash red when punched, but don't actually take damage
if context.event then
context.event.cancel()
end
context.prop:hurt_visual()
end
}
prop:pickup()
Удаляет реквизит из мира и выбрасывает на его месте бумажный предмет размещения. Щёлкните этим предметом по блоку правой кнопкой, чтобы снова разместить реквизит.
Параметров и возвращаемого значения нет. Удаление и выпадение ставятся в очередь главного потока Bukkit. Метод не проверяет разрешения и не переносит сохранённый инвентарь или книгу на бумагу. Перед вызовом проверьте доступ и обработайте сохранённое содержимое. Не повторяйте pickup(), пока изъятие уже стоит в очереди.
Пример
return {
api_version = 1,
on_right_click = function(context)
-- Let players pick up the prop by right-clicking it
context.prop:pickup()
end
}
prop:mount(player)
Сажает игрока на первое свободное место. Модели нужны кости точек посадки.
| Параметр | Тип | Описание |
|---|---|---|
player | таблица сущности | Игрок, например из context.player или context.event.player |
Возвращает true, если игрок найден, у реквизита есть точки посадки и действие поставлено в очередь. При неверных базовых ссылках возвращает false. true не гарантирует свободное место в момент выполнения.
Если скрипт правого клика управляет посадкой, отмените context.event, чтобы стандартная обработка FMM не пыталась посадить игрока повторно.
Пример
return {
api_version = 1,
on_right_click = function(context)
if context.event then context.event.cancel() end
local player = context.event and context.event.player
if player then
context.prop:mount(player)
end
end
}
prop:dismount(player)
Снимает игрока с места на реквизите.
| Параметр | Тип | Описание |
|---|---|---|
player | таблица сущности | Игрок |
Возвращает true, если игрок найден, есть менеджер посадки и проверка высадки поставлена в очередь. При неверных базовых ссылках возвращает false.
Пример
return {
api_version = 1,
on_right_click = function(context)
if context.event then context.event.cancel() end
local player = context.event and context.event.player
if player then
-- Toggle mount/dismount
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)
if context.event then context.event.cancel() end
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. Само значение nil не указывает причину.
Пример
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)
Ставит в очередь открытие интерфейса инвентаря сундука для игрока. У каждого реквизита один общий инвентарь: первое открытие создаёт его из сохранённого содержимого PersistentDataContainer реквизита, а последующие открытия показывают всем зрителям этот же живой инвентарь. FMM сохраняет его обратно в реквизит, когда его закрывает последний зритель, когда выгружается чанк реквизита и перед тем, как его прочитает drop_inventory().
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
player | таблица сущности | Обязателен | Игрок, которому показать инвентарь |
title | string | Обязателен | Заголовок с поддержкой цветов & |
rows | int | 3 | От 1 до 6 рядов; 6 рядов дают 54 слота двойного сундука |
Возвращает true, если ссылки действительны и открытие поставлено в очередь, иначе false. Перед созданием число рядов ограничивается диапазоном от 1 до 6.
Размер и заголовок берутся из вызова, который создаёт инвентарь; пока он открыт, последующие вызовы используют его как есть. Если в сохранённом содержимом больше слотов, чем в запрошенных рядах, инвентарь увеличивается, чтобы вместить их, поэтому меньшее значение rows никогда не уничтожает хранящиеся предметы. Если сохранённые данные не удаётся прочитать, инвентарь не открывается. Действие пропускается, если реквизит был удалён до его выполнения. Возвращаемое значение не гарантирует, что инвентарь открылся.
prop:is_viewing_inventory(player)
Проверяет, числится ли игрок зрителем этого реквизита в обработчике инвентарей. Это не гарантирует, что интерфейс действительно ещё открыт.
| Параметр | Тип | Описание |
|---|---|---|
player | таблица сущности | Проверяемый игрок |
Возвращает 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 | таблица сущности | Игрок с книгой |
Возвращает true, если ссылки действительны и действие поставлено в очередь. Последующая операция главного потока кладёт книгу только при наличии подходящей книги в руке и отсутствии книги на реквизите.
prop:read_book(player)
Открывает сохранённую книгу для чтения.
| Параметр | Тип | Описание |
|---|---|---|
player | таблица сущности | Читатель |
Возвращает true, если ссылки действительны и чтение поставлено в очередь. Для выполнения нужна сохранённая и десериализуемая WRITTEN_BOOK. Сохранённая WRITABLE_BOOK не откроется.
prop:take_book(player)
Возвращает сохранённую книгу в инвентарь игрока и удаляет её с реквизита.
| Параметр | Тип | Описание |
|---|---|---|
player | таблица сущности | Получатель книги |
Возвращает true, если ссылки действительны и изъятие поставлено в очередь. Наличие книги не гарантируется.
Сначала освободите место в инвентаре. Сохранённая запись удаляется до добавления книги; не поместившиеся предметы не выбрасываются. place_book сериализует весь стек в руке, а затем уменьшает его на один предмет. Используйте обычные одиночные книги.
prop:has_book()
Проверяет только наличие ключа книги в PDC базовой стойки для брони. Содержимое сериализованных данных не проверяется. Параметров нет.
prop:drop_inventory()
Ставит в очередь сохранение открытого инвентаря, если он есть, и его закрытие для всех зрителей, затем читает сохранённое содержимое, удаляет запись PDC и выбрасывает предметы у реквизита. Изменения, сделанные в открытом инвентаре до этого момента, учитываются. Ошибка декодирования после удаления записи может привести к тому, что выпадать будет нечему.
Параметров нет. Возвращает true, если базовая стойка действительна и действие поставлено в очередь. Наличие сохранённых предметов не гарантируется.
prop:drop_book()
Ставит в очередь выпадение сохранённой книги у реквизита. Запись удаляется до декодирования, поэтому ошибка декодирования может привести к потере книги.
Параметров нет. Возвращает true, если базовая стойка действительна и действие поставлено в очередь. Наличие книги не гарантируется.
prop:set_persistent_data(key, value)
Сохраняет строку в PersistentDataContainer стойки реквизита. Данные остаются вместе с этой стойкой при обычном сохранении мира и выгрузке чанков. Полное удаление реквизита или замена бумажным предметом размещения не переносит эти данные.
| Параметр | Тип | Описание |
|---|---|---|
key | string | Допустимый суффикс ключа Bukkit: строчные буквы, цифры и ._-/. Хранится как fmm_lua_<key>; недопустимые символы вызывают ошибку |
value | string | Значение; для чисел и логических значений используйте tostring() |
Возвращает true при успехе и false, если базовой стойки нет.
prop:get_persistent_data(key)
Читает строку, сохранённую через set_persistent_data. Если ключ не задан, возвращает nil.
| Параметр | Тип | Описание |
|---|---|---|
key | string | Ключ, использованный при сохранении |
Пример: сохранение состояния переключателя
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
}
Эффекты предметов
API экипированных предметов context.item удалён. Определяйте эффекты через собственные чары и подключайте их списком enchantments: предмета с идентификаторами, включающими пространство имён.
context.event
Данные текущего события доступны в хуках кликов реквизита, попадания снаряда и общих хуках зон. В on_spawn, on_game_tick, on_destroy и других хуках без события или игрока значение равно nil.
Клики FMM используют собственный флаг отмены стандартного поведения реквизита. Lua-обёртка предоставляет только перечисленные ниже поля и методы.
Поля и методы
| Поле или метод | Тип | Описание |
|---|---|---|
event.player | таблица игрока | Игрок, щёлкнувший по реквизиту или пересёкший границу зоны. Доступен в on_left_click, on_right_click, on_zone_enter, on_zone_leave. В on_projectile_hit это живая сущность, выпустившая снаряд (может быть мобом); если стрелок не является живой сущностью, поле отсутствует. См. Методы игрока |
event.is_cancelled | boolean | Снимок состояния отмены при создании контекста. После cancel() или uncancel() не обновляется |
event.cancel() | function | Отменяет событие, например стандартный урон или взаимодействие |
event.uncancel() | function | Снимает отмену |
cancel и uncancel игнорируют все аргументы, поэтому context.event.cancel() и context.event:cancel() работают одинаково. На этой странице используется точка; допустимы обе формы.
Общие хуки зон передают игрока без флага отмены. Поэтому event.cancel() и event.uncancel() отсутствуют, а event.is_cancelled равен false. Отмена клика реквизита предотвращает соответствующее стандартное действие FMM.
Считайте event.is_cancelled снимком начального состояния. Чтобы помнить изменение отмены далее в том же хуке, храните локальный флаг.
Таблица события не предоставляет поля Bukkit target, block, projectile или item. Для дополнительных сведений используйте context.player, context.event.player, context.projectile (в on_projectile_hit), player:get_target_entity(range), context.world:raycast(...) или поиск ближайших сущностей.
on_projectile_hit
Срабатывает, когда снаряд попадает в хитбокс реквизита, один раз на снаряд.
| Значение контекста | Описание |
|---|---|
context.projectile | Таблица сущности снаряда (стрела, трезубец, снежок и т. д.). Задаётся только в этом хуке |
context.event.player | Живая сущность, выпустившая снаряд, если она есть |
context.player | Стрелок, если это игрок, иначе nil |
Хук выполняется после того, как FMM обработал попадание, а стандартная обработка снарядов FMM для реквизита ничего не делает. Вызов context.event.cancel() здесь не мешает тому, что непробивающий снаряд расходуется при попадании. Хук не срабатывает, если попадание уже отменил другой плагин.
return {
api_version = 1,
on_projectile_hit = function(context)
local shooter = context.player
if shooter then
shooter:send_message("&eYou hit the target!")
end
context.prop:play_animation("hit", false, false)
end
}
Пример: отмена урона от левого клика
Пример
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 мира FMM/MagmaCore. Полная справка находится в context.world.
Методы общей страницы 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, place_temporary_block, drop_item и spawn_firework доступны в FMM. API мира MagmaCore описывает обнаружение сущностей и блоков лучом через world:raycast(), временную замену блоков через world:place_temporary_block() и настраиваемые фейерверки через world:spawn_firework(). Силы боссов EliteMobs расширяют ту же основу методами с таблицами позиции для боссов, подкреплений, падающих и временных блоков. См. Мир и окружение EliteMobs.
Дополнения FMM к API мира
FMM добавляет три необязательных метода добычи EliteMobs. Они доступны всегда, но без EliteMobs ничего не делают и возвращают false.
| Метод | Описание |
|---|---|
world:drop_elitemobs_procedural_loot(player, level, location?) | Создаёт процедурную добычу. Учитывает настройку прямой выдачи в инвентарь EliteMobs, выбрасывая избыток у игрока; иначе использует выбранную позицию. Возвращает false, если процедурная добыча отключена |
world:drop_elitemobs_random_loot(player, level, location?) | Выбирает добычу из таблиц EliteMobs для игрока указанного уровня |
world:drop_elitemobs_custom_loot(player, file, level, location?) | Выбрасывает указанный пользовательский предмет EliteMobs. Возвращает false, если файл не удаётся разрешить |
Полные сигнатуры см. в Справочнике Lua API. Для создания босса через реквизит используйте описанный выше prop:spawn_elitemobs_boss(...).
Методы сущности игрока
Таблицы игроков возвращают context.player, context.event.player и context.world:get_nearby_players(). Общие хуки MagmaCore on_zone_enter и on_zone_leave записывают вошедшего или вышедшего игрока в первые два поля.
FMM использует описанные на общей странице таблицы сущностей, живых сущностей, игроков и методы интерфейса. Силы боссов EliteMobs предоставляют похожие специализированные таблицы в разделе Боссы и сущности. Поля и методы FMM см. в Движке Lua MagmaCore и Методах интерфейса игрока. Выбор цели лучом через player:get_target_entity(), player:get_eye_location(), player:get_look_direction(), показ ложных блоков одному игроку через player:send_block_change() и player:reset_block() описаны в Методах игрока.
Дополнительные поля сущностей FMM
LuaEntityEnricher добавляет следующие поля в таблицы FMM. Флаги и ссылка на модель являются снимками на момент создания таблицы. После изменения привязки модели получите новую таблицу. has_permission проверяет текущие разрешения игрока, а is_op остаётся снимком.
| Поле | Тип | Описание |
|---|---|---|
entity.is_modeled | boolean | true, если Bukkit-сущность лежит в основе ModeledEntity |
entity.is_prop | boolean | true, если это стойка для брони, лежащая в основе PropEntity |
entity.model | таблица или nil | Есть только при is_modeled = true |
Таблица модели предоставляет следующие поля и методы.
| Поле или метод | Описание |
|---|---|
model.model_id | Имя модели в шаблоне, например "dragon" |
model.is_dynamic | true для DynamicEntity, привязанной к живой сущности |
model:play_animation(name, blend, loop) | Запрашивает анимацию. В этой интеграции blend и loop по умолчанию равны false. true подтверждает принятие запроса, а не видимое воспроизведение |
model:stop_animations() | Очищает очередь и возвращает к idle, если оно есть; конечное состояние смерти не прерывает |
model:remove() | Немедленно удаляет сущность с моделью и все её кости |
on_right_click = function(context)
local player = context.event and context.event.player
if not player then return end
local target = player:get_target_entity(8)
if target and target.is_modeled then
target.model:play_animation("hurt", true, false)
end
end
Поля сущностей EliteMobs
При установленном EliteMobs FMM обращается к его enricher и добавляет следующие поля.
| Поле | Тип | Описание |
|---|---|---|
entity.is_elite | boolean | true, если сущность отслеживается EliteMobs |
entity.is_custom_boss | boolean | true для конфигурации пользовательского босса |
entity.is_significant_boss | boolean | true для пользовательского босса с healthMultiplier > 1, исключает обычных именованных мобов |
entity.elite | таблица или nil | Есть при is_elite = true; содержит level, name, health, max_health, health_multiplier, damage_multiplier, is_custom_boss и elite:remove() |
Флаги и большинство полей elite являются снимками; health и max_health запрашиваются при чтении. При включённом EliteMobs метод entity:can_receive_hostile_effect(player_uuid) после общей проверки враждебной цели применяет разрешения EliteMobs для магических целей. Если адаптер недоступен, проверка отклоняется, а союзники не рассматриваются как независимые цели.
context.zones
API зон FMM/MagmaCore описан в context.zones. Силы боссов используют отдельную таблицу с собственными определениями зон EliteMobs; см. Зоны и выбор целей EliteMobs.
context.scheduler
FMM и скрипты NPC EliteMobs используют планировщик MagmaCore. run_after, run_every и cancel_task также являются его псевдонимами, поэтому работают обе системы имён. Силы боссов предоставляют те же псевдонимы через свой контекст. См. context.scheduler.
context.state
Общий API состояния для FMM, сил боссов и NPC EliteMobs описан в context.state.
context.log
Журнал FMM/MagmaCore предоставляет info, warn, error. NPC EliteMobs используют его же, а силы боссов предоставляют info, warn, debug. См. context.log.
context.cooldowns
FMM и NPC EliteMobs используют общий порядок аргументов check_local(key?, duration). У сил боссов порядок такой же, но отдельные хранилища. См. context.cooldowns.
| Метод | Описание |
|---|---|
local_ready(key?) | Проверяет завершение локальной перезарядки |
local_remaining(key?) | Возвращает оставшиеся тики или 0 |
check_local(key?, duration) | Атомарно проверяет и запускает локальную перезарядку |
set_local(duration, key?) | Задаёт локальную перезарядку без проверки |
global_ready() | Проверяет общую глобальную перезарядку владельца скрипта |
set_global(duration) | Задаёт глобальную перезарядку |
Для обычных действий реквизита используйте context.cooldowns:check_local("my_key", 40).
Модель выполнения
Одна среда на экземпляр скрипта
Каждая запись списка scripts: реквизита получает независимую среду Lua. При регистрации провайдера FMM обнаруживает и проверяет исходники, затем выполняет кешированный код в новой песочнице для каждой привязки. После изменения или добавления файла Lua нужна успешная перезагрузка, чтобы новые привязки использовали изменения. Колбэки выполняются в порядке списка; прочитанное priority не меняет порядок. Удаление реквизита завершает все его экземпляры скриптов.
Чары предметов имеют отдельный жизненный цикл и не создают экземпляр скрипта реквизита для экипированного предмета.
- Локальные переменные уровня файла принадлежат только этому экземпляру.
context.stateполностью изолирован между экземплярами, даже использующими один файл.
Владение запланированными задачами
Задачи context.scheduler принадлежат создавшей их среде. При удалении реквизита:
- Среда завершается.
- Все её одноразовые и повторяющиеся задачи отменяются автоматически.
- Все наблюдения за зонами удаляются.
on_destroy выполняется перед этими шагами только при окончательном удалении реквизита: его подобрали, сломали, удалили через /fmm deleteall или удалил плагин. Когда выгружается чанк или мир реквизита либо FMM перезагружается или выключается, среда останавливается без вызова on_destroy. При следующей загрузке чанка реквизит возвращается с новой средой и новым вызовом on_spawn.
Область перезарядок
Общий движок предоставляет локальные методы local_ready, local_remaining, check_local, set_local и глобальные global_ready, set_global.
| Скрипт | Локальное хранилище | Глобальное хранилище |
|---|---|---|
| Реквизит | На ScriptInstance, то есть реквизит и файл скрипта | На PropEntity, общее для всех его привязанных скриптов |
Глобальные перезарядки очищаются при снятии реквизита с регистрации или завершении менеджера во время успешной перезагрузки либо отключения. Отклонённая подготовка перезагрузки сохраняет текущую среду. Длительность перезарядок использует монотонное прошедшее время, по 50 мс на указанный тик. Задержки планировщика следуют серверным тикам, поэтому при задержках сервера результаты могут различаться.
Бюджет выполнения
Хуки, запланированные колбэки и начальное выполнение файла ограничены жёстким бюджетом. Он применяется внутри Lua VM во время выполнения.
| Ограничение | Значение |
|---|---|
| Процессорное время текущего потока | 50 миллисекунд |
| Инструкции Lua | 250 000 |
Первое достигнутое ограничение прерывает вызов с ошибкой Lua и отключает экземпляр. Сообщения:
Lua instruction budget exceeded (250000 instruction limit)
Lua CPU-time budget exceeded (50ms current-thread CPU limit)
Счётчик инструкций ограничивает чистые циклы Lua вроде while true do end. Время проверяется через каждые 1 024 инструкции и при возврате из вызова. Механизм не прерывает блокирующий метод Java/Bukkit, пока тот выполняется.
Процессорное время не включает периоды, когда серверному потоку не выделялось исполнение. Если JVM не предоставляет такое измерение, применяется предел 250 мс прошедшего времени с ошибкой Lua elapsed-time fallback budget exceeded (250ms fallback; current-thread CPU time unavailable). Ограничение в 250 000 инструкций сохраняется.
Вложенные вызовы делят один бюджет. Хук и вся цепочка вызванных им колбэков вместе получают 50 мс процессорного времени и 250 000 инструкций.
Выполнение при обнаружении провайдера отклоняет неверное определение до регистрации. Кешированный исходник снова выполняется для каждого нового экземпляра с тем же бюджетом.
- Избегайте неограниченных циклов.
- Сохраняйте
on_game_tickлёгким: он выполняется каждый тик. - Распределяйте работу по тикам через
context.scheduler:run_repeating(...).
Полная справка по хукам
Ниже перечислены активные хуки реквизита. context.event обозначает флаг отмены FMM или игрока зоны. Обёртка предоставляет event.player, event.is_cancelled, event.cancel() и event.uncancel() там, где они применимы.
Восемь активных хуков реквизита
| Хук | Когда вызывается | context.event |
|---|---|---|
on_spawn | Реквизит появляется в мире или снова загружается вместе со своим чанком | nil |
on_game_tick | Каждый серверный тик, 50 мс при 20 TPS | nil |
on_destroy | Реквизит удаляется окончательно (не при выгрузке чанка и не при перезагрузке) | nil |
on_left_click | Игрок нажимает левой кнопкой | Флаг отмены стандартного урона |
on_right_click | Игрок нажимает правой кнопкой | Флаг отмены стандартного взаимодействия |
on_zone_enter | Игрок входит в наблюдаемую зону | context.player / context.event.player, без отмены |
on_zone_leave | Игрок выходит из наблюдаемой зоны | context.player / context.event.player, без отмены |
on_projectile_hit | Снаряд попадает в реквизит | Событие попадания снаряда; event.player — стрелок. См. on_projectile_hit |
Эффекты предметов
Для эффектов предметов в руках используйте собственные чары. Старая таблица из 22 хуков предметов больше не описывает действующий интерфейс.
Дальнейшие шаги
- Примеры и шаблоны: скрипты реквизита с объяснениями и указаниями по настройке.
- Решение проблем: частые ошибки, отладка и проверка качества.
- Начало работы: структура файлов, хуки и первый скрипт.
Транспорт EliteMobs
context.world:start_elitemobs_transport(player, route_id) запускает для игрока сохранённый маршрут EliteMobs в мире контекста. Возвращает результат принятия запроса. Нужны EliteMobs и загруженный маршрут; ID указывается без .yml. См. Транспортные маршруты.