Scripting Lua: API de Props e Itens
Esta página cobre toda API disponível para scripts de prop e item do FreeMinecraftModels: context.prop, context.item, context.event, context.player, context.world, context.zones, context.scheduler, context.state e context.log. Se você é novo em scripting, comece com Primeiros Passos primeiro.
context.prop
A tabela prop fornece informações sobre a entidade prop e métodos para controlar suas animações. Ela é reconstruída do zero a cada chamada de hook.
Campos
| Campo | Tipo | Notas |
|---|---|---|
prop.model_id | string | O nome do modelo blueprint (ex.: "torch_01") |
prop.current_location | tabela de localização | A posição do prop no momento em que o contexto foi construído |
A tabela de localização tem os campos padrão: x, y, z, world, yaw, pitch.
Exemplo: lendo info do prop
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)
Toca uma animação nomeada no modelo do prop.
| Parâmetro | Tipo | Padrão | Notas |
|---|---|---|---|
name | string | obrigatório | O nome da animação como definido no arquivo do modelo |
blend | boolean | true | Se deve fazer blend com a animação atual |
loop | boolean | true | Se a animação deve fazer loop |
Retorna true se a animação foi encontrada e iniciada, false caso contrário.
Exemplo
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()
Para todas as animações atualmente em execução no prop.
Não aceita parâmetros.
Exemplo
return {
api_version = 1,
on_right_click = function(context)
context.prop:stop_animation()
end
}
prop:hurt_visual()
Toca a animação visual de dano (flash de tint vermelho) no prop sem causar dano real a ele.
Não aceita parâmetros.
Exemplo
return {
api_version = 1,
on_left_click = function(context)
-- Pisca vermelho ao ser socado, mas não toma dano de verdade
if context.event then
context.event.cancel()
end
context.prop:hurt_visual()
end
}
prop:pickup()
Remove o prop do mundo e dropa um item de papel de colocação na sua localização. O item dropado pode ser clicado com botão direito em um bloco para colocar o prop novamente.
Não aceita parâmetros.
Exemplo
return {
api_version = 1,
on_right_click = function(context)
-- Permite que jogadores peguem o prop clicando com botão direito nele
context.prop:pickup()
end
}
prop:mount(player)
Monta um jogador no primeiro ponto de assento de montaria disponível no prop. O modelo precisa ter bones de ponto de montaria definidos.
| Parâmetro | Tipo | Notas |
|---|---|---|
player | tabela de entidade | Uma tabela de entidade de jogador (ex.: de context.event.player) |
Exemplo
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)
Desmonta um jogador do seu ponto de assento de montaria no prop.
| Parâmetro | Tipo | Notas |
|---|---|---|
player | tabela de entidade | Uma tabela de entidade de jogador |
Exemplo
return {
api_version = 1,
on_right_click = function(context)
local player = context.event and context.event.player
if player then
-- Alterna montar/desmontar
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()
Retorna um array Lua de tabelas de entidade para todos os passageiros atuais no prop.
Não aceita parâmetros.
Exemplo
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()
Retorna se este prop tem bones de ponto de montaria definidos em seu modelo.
Não aceita parâmetros. Retorna true ou false.
Exemplo
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)
Spawna um chefe customizado do EliteMobs na localização dada. Requer EliteMobs instalado no servidor.
| Parâmetro | Tipo | Notas |
|---|---|---|
filename | string | O nome do arquivo do chefe customizado (ex.: "my_boss.yml") |
x | number | Coordenada X |
y | number | Coordenada Y |
z | number | Coordenada Z |
Retorna uma tabela de entidade viva para o chefe spawnado, ou nil se EliteMobs não estiver instalado ou o arquivo do chefe não existir.
Exemplo
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)
Abre uma GUI de inventário de baú persistente para o jogador. O conteúdo é salvo no PersistentDataContainer do prop quando o inventário é fechado, e restaurado quando aberto novamente.
| Parâmetro | Tipo | Padrão | Notas |
|---|---|---|---|
player | tabela de entidade | obrigatório | O jogador para mostrar o inventário |
title | string | obrigatório | O título do inventário (suporta códigos de cor &) |
rows | int | 3 | Número de linhas (1-6, onde 6 = 54 slots = baú duplo) |
Retorna true se o inventário foi aberto, false caso contrário.
prop:is_viewing_inventory(player)
Retorna se o jogador dado atualmente tem o inventário deste prop aberto.
| Parâmetro | Tipo | Notas |
|---|---|---|
player | tabela de entidade | O jogador a verificar |
Retorna true ou false.
Exemplo: Animação de fechamento quando o inventário é fechado
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)
Pega o livro escrito ou editável da mão principal do jogador e armazena no prop.
| Parâmetro | Tipo | Notas |
|---|---|---|
player | tabela de entidade | O jogador segurando o livro |
Retorna true em caso de sucesso.
prop:read_book(player)
Abre o livro armazenado para leitura pelo jogador.
| Parâmetro | Tipo | Notas |
|---|---|---|
player | tabela de entidade | O jogador para mostrar o livro |
Retorna true se um livro foi aberto.
prop:take_book(player)
Devolve o livro armazenado para o inventário do jogador e o remove do prop.
| Parâmetro | Tipo | Notas |
|---|---|---|
player | tabela de entidade | O jogador para dar o livro |
Retorna true em caso de sucesso.
prop:has_book()
Retorna se um livro está armazenado neste prop. Não aceita parâmetros.
prop:drop_inventory()
Dropa todo o conteúdo armazenado do inventário na localização do prop como entidades de item, então limpa os dados armazenados. Fecha automaticamente o inventário para quaisquer jogadores visualizando-o no momento.
Não aceita parâmetros. Retorna true em caso de sucesso.
prop:drop_book()
Dropa o livro armazenado na localização do prop como uma entidade de item e limpa os dados do livro armazenado.
Não aceita parâmetros. Retorna true em caso de sucesso.
prop:set_persistent_data(key, value)
Armazena um valor string no PersistentDataContainer do armor stand do prop. Esses dados sobrevivem a reinicializações do servidor e descarregamentos de chunk.
| Parâmetro | Tipo | Notas |
|---|---|---|
key | string | Um nome de chave único (armazenado sob fmm_lua_<key> internamente) |
value | string | O valor a armazenar. Use tostring() para números e booleanos. |
Retorna true em caso de sucesso, false se o prop não tem armor stand de suporte.
prop:get_persistent_data(key)
Recupera um valor string previamente armazenado com set_persistent_data. Retorna nil se a chave não foi definida.
| Parâmetro | Tipo | Notas |
|---|---|---|
key | string | O nome da chave usada em set_persistent_data |
Exemplo: Estado de alternância persistente
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
A tabela item está disponível apenas em scripts de item (não em scripts de prop). Fornece informações sobre o item customizado e métodos para manipulá-lo. Esta tabela é reconstruída do zero a cada chamada de hook.
Campos
| Campo | Tipo | Notas |
|---|---|---|
item.id | string | O ID de tipo do item (o fmm_item_id da config YML) |
item:material()
Retorna o nome do material do item como string (ex.: "DIAMOND_SWORD", "STICK").
item:get_amount() / item:set_amount(n)
Obtém ou define o tamanho da pilha do item.
| Parâmetro | Tipo | Notas |
|---|---|---|
n | int | A nova quantidade da pilha |
item:consume(n)
Decrementa a quantidade da pilha do item em n (padrão 1). Se a quantidade resultante for 0 ou menos, o item é removido do inventário do jogador.
| Parâmetro | Tipo | Padrão | Notas |
|---|---|---|---|
n | int | 1 | Quantidade a consumir |
item:get_uses() / item:set_uses(n)
Obtém ou define um contador de usos customizado armazenado no PersistentDataContainer do item. Isto é independente da durabilidade vanilla e pode ser usado para implementar sistemas de durabilidade ou cargas customizadas.
| Parâmetro | Tipo | Notas |
|---|---|---|
n | int | A nova contagem de usos |
item:get_name() / item:set_name(s)
Obtém ou define o nome de exibição do item. Suporta códigos de cor com &.
| Parâmetro | Tipo | Notas |
|---|---|---|
s | string | O novo nome de exibição (ex.: "&b&lFrost Sword") |
item:get_lore() / item:set_lore(table)
Obtém ou define o lore do item. get_lore() retorna uma tabela de strings (uma por linha). set_lore() aceita uma tabela de strings.
| Parâmetro | Tipo | Notas |
|---|---|---|
table | table | Array de strings, uma por linha de lore |
Exemplo: Script de item que rastreia usos
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()
Retorna uma tabela com campos current e max representando a durabilidade vanilla do item, ou nil se o item não tem barra de durabilidade.
Exemplo
local dur = context.item:get_durability()
if dur then
context.player:send_message("Durability: " .. dur.current .. "/" .. dur.max)
end
item:get_durability_percentage()
Retorna a durabilidade restante como uma fração de 0.0 a 1.0, ou nil se o item não tem barra de durabilidade.
item:use_durability(amount, can_break)
Reduz a durabilidade vanilla do item em uma quantidade fixa.
| Parâmetro | Tipo | Padrão | Notas |
|---|---|---|---|
amount | int | obrigatório | Quantos pontos de durabilidade consumir |
can_break | boolean | false | Se true, o item é destruído quando a durabilidade acaba. Se false, a durabilidade para em 1. |
item:use_durability_percentage(fraction, can_break)
Reduz a durabilidade vanilla do item por uma porcentagem do seu máximo.
| Parâmetro | Tipo | Padrão | Notas |
|---|---|---|---|
fraction | number | obrigatório | Fração da durabilidade máxima a consumir (ex.: 0.1 = 10%) |
can_break | boolean | false | Se true, o item é destruído quando a durabilidade acaba. Se false, a durabilidade para em 1. |
context.event
Dados do evento para o hook atual. Disponível em hooks de clique, combate e interação tanto para scripts de prop quanto de item. Retorna nil em hooks que não têm evento associado (on_spawn, on_game_tick, on_destroy, on_zone_enter, on_zone_leave, on_equip).
Campos e Métodos
| Campo ou Método | Tipo | Notas |
|---|---|---|
event.player | tabela de entidade de jogador | O jogador que disparou o evento. Disponível em on_left_click, on_right_click e on_projectile_hit (o atirador, se foi um jogador). Veja Métodos de Entidade de Jogador para todos os campos e métodos. |
event.is_cancelled | boolean | Se o evento está atualmente cancelado |
event.cancel() | função | Cancela o evento (ex.: previne dano ou interação) |
event.uncancel() | função | Descancela um evento previamente cancelado |
Nem todos os eventos são canceláveis. Se o evento Bukkit subjacente não implementa Cancellable, event.cancel() e event.uncancel() não estarão presentes e event.is_cancelled será sempre false.
Exemplo: Tornando um prop invulnerável
Exemplo
return {
api_version = 1,
on_left_click = function(context)
if context.event then
context.event.cancel()
end
end
}
Exemplo: Verificando estado de cancelamento
Exemplo
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
}
Dentro de callbacks agendados (scheduler:run_later, scheduler:run_repeating), context.event é sempre nil. A modificação de eventos só pode acontecer durante o próprio hook do evento.
context.world
A API world é compartilhada entre todos os plugins Nightbreak. Veja context.world para a referência completa.
Os props do FMM usam a mesma tabela world do MagmaCore que os chefes do EliteMobs. Todos os métodos documentados na página global (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) estão disponíveis no FMM. Veja a API world do MagmaCore para detalhes completos sobre world:raycast() (lança um raio e detecta entidades/blocos atingidos) e world:spawn_firework() (spawna foguetes de fogos de artifício com cores e formas customizadas). O EliteMobs estende a tabela world com métodos adicionais para spawnar chefes, reforços e mais -- veja EliteMobs World & Environment.
Métodos de Entidade de Jogador
Tabelas de entidade de jogador são retornadas de context.event.player, context.world:get_nearby_players() e callbacks de zona.
As tabelas de entidade, métodos de entidade viva, métodos específicos de jogador e métodos de UI de jogador são compartilhados entre todos os plugins Nightbreak. Veja o Motor de Scripting Lua do MagmaCore para a referência completa cobrindo campos base de entidade, campos e métodos de entidade viva, campos e métodos específicos de jogador, e Métodos de UI de Jogador. Novos métodos de jogador incluem player:get_target_entity() (mira por raycast), player:get_eye_location(), player:get_look_direction(), player:send_block_change() (blocos falsos por jogador) e player:reset_block() -- veja Métodos Específicos de Jogador para detalhes.
Campos de Entidade Específicos do FMM
Cada tabela de entidade construída dentro de um script do FMM ganha estes campos extras automaticamente (via o LuaEntityEnricher do FMM):
| Campo | Tipo | Notas |
|---|---|---|
entity.is_modeled | boolean | true se esta entidade Bukkit é a entidade subjacente de uma ModeledEntity |
entity.is_prop | boolean | true se esta entidade é um armor stand que dá suporte a uma PropEntity |
entity.model | table ou nil | Preenchido apenas quando is_modeled = true (veja abaixo) |
Quando entity.model está presente, ele expõe:
| Campo / Método | Notas |
|---|---|
model.model_id | O nome do modelo blueprint (ex.: "dragon") |
model.is_dynamic | true se isto é uma DynamicEntity (anexada a uma entidade viva) |
model:play_animation(name, blend, loop) | Toca uma animação nomeada. Retorna true em sucesso |
model:stop_animations() | Para todas as animações atuais |
model:remove() | Remove imediatamente a entidade modelada e todos os seus bones |
on_attack_entity = function(context)
local target = context.event.target
if target and target.is_modeled then
target.model:play_animation("hurt", true, false)
end
end
Campos de Entidade do EliteMobs
Quando o EliteMobs está instalado, o FMM encaminha para o enricher do EliteMobs, então as mesmas tabelas de entidade também expõem:
| Campo | Tipo | Notas |
|---|---|---|
entity.is_elite | boolean | true se a entidade é rastreada pelo EliteMobs |
entity.is_custom_boss | boolean | true se é uma configuração de chefe customizado |
entity.is_significant_boss | boolean | true para chefes customizados com healthMultiplier > 1 (filtra mobs nomeados sem importância) |
entity.elite | table ou nil | Preenchido apenas quando is_elite = true. Contém level, name, health, max_health, health_multiplier, damage_multiplier, is_custom_boss, além de elite:remove() |
context.zones
A API zones é compartilhada entre todos os plugins Nightbreak. Veja context.zones para a referência completa.
context.scheduler
A API scheduler é compartilhada entre todos os plugins Nightbreak. Veja context.scheduler para a referência completa.
context.state
A API state é compartilhada entre todos os plugins Nightbreak. Veja context.state para a referência completa.
context.log
A API de logging é compartilhada entre todos os plugins Nightbreak. Veja context.log para a referência completa.
Modelo de Runtime
Um Runtime Por Instância de Script
Cada entidade prop que tem scripts anexados ganha sua própria instância independente de runtime Lua. Quando o prop spawna, o FMM carrega o código-fonte Lua, avalia-o em um ambiente isolado fresco e armazena a tabela retornada. Quando o prop é removido, o runtime é encerrado.
Para scripts de item, um runtime é criado por par (jogador, itemId). Quando um jogador equipa um item customizado, o FMM cria uma instância de script para esse jogador e tipo de item. Quando o item é desequipado, o runtime é encerrado.
Isso significa:
- Variáveis locais declaradas em escopo de arquivo são privadas àquela instância de script.
context.stateé completamente isolado entre instâncias, mesmo que compartilhem o mesmo arquivo de script.
Propriedade de Tarefas Agendadas
Todas as tarefas criadas através de context.scheduler são de propriedade do runtime que as criou. Quando um prop é removido:
- O runtime encerra.
- Toda tarefa de sua propriedade -- tanto one-shot quanto repetitiva -- é cancelada automaticamente.
- Todas as observações de zona são limpas.
Escopo de Cooldown
O motor de scripting compartilhado expõe context.cooldowns:set_local, :check_local, :set_global e :check_global (veja a referência de cooldowns do MagmaCore). O FMM escopa esses armazenamentos da seguinte forma:
| Tipo de script | Escopo do armazenamento local | Escopo do armazenamento global |
|---|---|---|
| Script de prop | Por ScriptInstance (prop + arquivo de script) | Por PropEntity (compartilhado entre todo script vinculado a esse prop) |
| Script de item | Por tripla (player, itemId, scriptFile) — persiste entre re-equipagens mesmo que a instância de script seja derrubada toda vez que o item sai de um slot ativo | Por jogador (compartilhado entre todo script de item FMM que aquele jogador executa) |
Como scripts de item são derrubados e reconstruídos a cada ciclo de equip/unequip, cooldowns de item são mantidos em um mapa estático chaveado por UUID do jogador, em vez de viverem no ScriptInstance. É por isso que um cooldown de item ainda se aplica depois que você troca o item para fora da hotbar e o coloca de volta.
Orçamento de Execução
Cada invocação de hook e cada invocação de callback é cronometrada. Se uma única chamada demora mais que 50 milissegundos, o script é desabilitado com um aviso no console:
[Lua] my_script.lua took 73ms in 'on_game_tick' (limit: 50ms) -- script disabled to prevent lag.
Para ficar dentro do orçamento:
- Evite loops sem limite dentro dos hooks.
- Mantenha handlers
on_game_tickleves -- eles rodam em cada tick. - Use
context.scheduler:run_repeating(...)para espalhar trabalho entre ticks.
Referência Completa de Hooks
Esta tabela lista todos os hooks disponíveis em scripts de prop e item.
Hooks de Prop (8)
| Hook | Dispara quando | context.event |
|---|---|---|
on_spawn | O prop spawna no mundo | nil |
on_game_tick | A cada tick de servidor (50ms) | nil |
on_destroy | O prop é removido | nil |
on_left_click | Jogador clica com botão esquerdo no prop | evento de dano |
on_right_click | Jogador clica com botão direito no prop | evento de interação |
on_projectile_hit | Projétil atinge o prop | evento de hit de projétil |
on_zone_enter | Jogador entra numa zona observada | nil |
on_zone_leave | Jogador sai de uma zona observada | nil |
Hooks de Item (22)
| Hook | Categoria | Dispara quando | context.event |
|---|---|---|---|
on_attack_entity | Combate | Jogador ataca uma entidade | evento de dano |
on_kill_entity | Combate | Jogador mata uma entidade | evento de morte |
on_take_damage | Combate | Jogador sofre dano | evento de dano |
on_shield_block | Combate | Jogador bloqueia com escudo | evento de dano |
on_shoot_bow | Combate | Jogador atira com arco | evento de tiro de arco |
on_projectile_hit | Combate | Projétil do jogador acerta | evento de hit de projétil |
on_projectile_launch | Combate | Jogador lança projétil | evento de lançamento |
on_right_click | Interação | Jogador clica com botão direito | evento de interação |
on_left_click | Interação | Jogador clica com botão esquerdo | evento de interação |
on_shift_right_click | Interação | Jogador shift+clique direito | evento de interação |
on_shift_left_click | Interação | Jogador shift+clique esquerdo | evento de interação |
on_interact_entity | Interação | Jogador clica com botão direito em entidade | evento de interação com entidade |
on_equip | Equipamento | Item entra em slot ativo | nil |
on_unequip | Equipamento | Item sai de slot ativo | nil |
on_swap_hands | Equipamento | Troca mão principal/secundária | evento de troca |
on_drop | Equipamento | Jogador derruba item | evento de drop |
on_break_block | Utilidade | Jogador quebra bloco | evento de quebra de bloco |
on_consume | Utilidade | Jogador consome item | evento de consumo |
on_item_damage | Utilidade | Item sofre dano de durabilidade | evento de dano de item |
on_fish | Utilidade | Jogador usa vara de pesca | evento de pesca |
on_death | Utilidade | Jogador morre equipado | evento de morte |
on_game_tick | Ciclo de vida | A cada tick enquanto equipado | nil |
Próximos Passos
- Exemplos e Padrões -- scripts completos funcionais para props e itens com guias passo a passo
- Solução de Problemas -- problemas comuns, dicas de debug e checklist de QC
- Primeiros Passos -- estrutura de arquivos, hooks, guia do primeiro script