Motor de Scripts Lua do MagmaCore
O MagmaCore fornece o sandbox Lua e o runtime ScriptInstance usados pelos poderes de boss e scripts de NPC do EliteMobs, pelos props do FreeMinecraftModels e pelos efeitos de encantamentos personalizados. Partilham a validação dos ficheiros e a gestão das instâncias, mas os hooks, as tabelas de contexto, os âmbitos dos cooldowns e os ciclos de vida dependem do plugin responsável. As consultas de encantamentos também usam um contexto restrito e limites específicos; consulte a referência abaixo.
Os props do FreeMinecraftModels e os scripts de NPC do EliteMobs herdam diretamente as tabelas genéricas do MagmaCore (context.world, context.zones, context.scheduler, context.cooldowns, context.log, context.event, context.player e context.state) e acrescentam context.prop ou context.npc. Os poderes de boss usam o mesmo runtime, mas oferecem variantes próprias de várias tabelas (context.world, context.zones, context.cooldowns, context.scheduler, context.log, context.event), além de context.players, context.entities, context.vectors, context.settings e context.script.
Atualmente, os seguintes plugins usam este motor:
- EliteMobs -- Poderes Lua para bosses personalizados (
on_boss_damaged_by_player,on_enter_combat, etc.) e scripts Lua de NPC para interação e proximidade (on_npc_interact,on_npc_proximity_enter, etc.). - FreeMinecraftModels -- Scripts Lua de props (
on_right_click,on_left_click, etc.) e efeitos de encantamentos personalizados para itens.
Esta página documenta as funcionalidades genéricas do MagmaCore usadas pelo FreeMinecraftModels e as diferenças das variantes de boss e de NPC do EliteMobs. Para o contexto exato dos bosses, consulte as páginas Lua do EliteMobs; para NPCs, consulte Scripts Lua de NPC.
Mini-introdução ao Lua
Se é completamente novo no Lua, esta é a sintaxe mínima necessária para escrever scripts para qualquer plugin do Nightbreak.
Variáveis
Use local para armazenar um valor:
local cooldown_key = "fire_burst"
local damage_multiplier = 1.5
local significa que a variável pertence apenas a este ficheiro ou bloco.
Funções
Funções são blocos de lógica reutilizáveis:
local function warn_player(player)
player:send_message("&cMove!")
end
Depois, pode chamá-la:
warn_player(some_player)
Verificações if
Use if quando algo só deve acontecer em certas condições:
if context.player == nil then
return
end
Isto significa "se não existir um jogador para este hook, pare aqui".
nil
nil significa "sem valor". É a versão Lua de "não há nada aqui".
Vai verificar frequentemente se algo é nil com:
if context.event ~= nil then
-- do something with the event
end
~= significa "não é igual a".
Tabelas
O Lua usa tabelas para várias funções:
- Listas
- Objetos com chaves nomeadas
- A definição final do script que é devolvida
Exemplo de uma tabela com chaves nomeadas:
local particle = {
particle = "FLAME",
amount = 1,
speed = 0.05
}
Devolver a definição do script
No final de cada ficheiro de script, devolve uma tabela:
return {
api_version = 1,
on_spawn = function(context)
end
}
Esta tabela é a definição do script. O carregador avalia o ficheiro para o validar e depois volta a avaliar o código armazenado para cada instância. As variáveis locais do ficheiro pertencem à instância, não a todas as entidades que usam o mesmo nome de ficheiro. Editar o ficheiro não altera uma definição já carregada nem uma instância em execução: recarregue-o através do procedimento do plugin responsável.
Comentários
Use -- para escrever uma nota para humanos:
-- This cooldown stops the attack from firing every hit
context.cooldowns:set_local(60, "fire_burst")
Sandbox Lua
Todos os scripts Lua são executados dentro de um ambiente LuaJ em sandbox. Várias globais que poderiam aceder ao sistema de ficheiros ou ao runtime do Java são removidas. As regras do sandbox são idênticas em todos os plugins que usam o MagmaCore.
Globais Removidas
As seguintes globais predefinidas do Lua são definidas como nil e não podem ser usadas:
| Removida | Motivo |
|---|---|
debug | Expõe o estado interno da VM |
dofile | Acesso ao sistema de ficheiros |
io | Acesso ao sistema de ficheiros |
load | Carregamento de código arbitrário |
loadfile | Acesso ao sistema de ficheiros |
luajava | Acesso direto a classes Java |
module | Sistema de módulos (não necessário) |
os | Acesso ao sistema operacional |
package | Sistema de módulos (não necessário) |
require | Sistema de módulos / acesso ao sistema de ficheiros |
Biblioteca Padrão Disponível
O ambiente standard do LuaJ oferece estas funcionalidades habituais do Lua:
| Categoria | Funções |
|---|---|
| Math | math.abs, math.ceil, math.floor, math.max, math.min, math.random, math.sin, math.cos, math.sqrt, math.pi, e todas as outras funções math.* |
| String | string.byte, string.char, string.find, string.format, string.gsub, string.len, string.lower, string.match, string.rep, string.sub, string.upper, e todas as outras funções string.* |
| Table | table.insert, table.remove, table.sort, table.concat, e todas as outras funções table.* |
| Iteradores | pairs, ipairs, next |
| Tipo | type, tostring, tonumber, select, unpack |
| Tratamento de erros | pcall, xpcall, error, assert |
| Outros | print, rawget, rawset, rawequal, rawlen, setmetatable, getmetatable |
os não está disponívelA biblioteca os foi completamente removida. Use context.world:get_time() para consultar o tempo do mundo nas interfaces genéricas; os poderes de boss também recebem esse método através da base partilhada da tabela de mundo. Para medir intervalos, mantenha contadores de ticks em context.state através de on_game_tick.
print escreve na consola, mas prefira context.log:info(msg). Todos os tipos de script oferecem context.log: FMM e NPCs do EliteMobs têm info, warn e error; os poderes de boss têm info, warn e debug.
Contrato de Ficheiro
Todo o script Lua deve fazer return de uma tabela. Esta tabela é intencionalmente rigorosa.
Campos de Topo Obrigatórios e Opcionais
| Campo | Obrigatório | Tipo | Notas |
|---|---|---|---|
api_version | Sim | Number | Atualmente deve ser 1 |
priority | Não | Number | Predefinição 0, convertido para inteiro. Os bosses e NPCs do EliteMobs executam os valores menores primeiro. O FMM valida o campo, mas executa os scripts de props na ordem da lista scripts: |
| chaves de hook suportadas | Não | Function | Devem usar um dos nomes exatos de hook suportados pelo plugin |
Regras de Validação
- O ficheiro deve devolver uma tabela.
api_versioné obrigatório e atualmente deve ser1.prioritydeve ser numérico, se presente.- Cada chave extra de topo deve ser um nome de hook suportado.
- Cada chave de hook deve apontar para uma função.
- Chaves de topo desconhecidas são rejeitadas.
O validador Lua aceita priority em todos os scripts do MagmaCore. O EliteMobs usa-o na ordem dos scripts de bosses e NPCs. O FMM não ordena por priority: os props seguem a lista scripts: da configuração. Os encantamentos personalizados usam o catálogo do seu fornecedor e o ciclo de vida de ações e consultas.
Onde ficam os ficheiros de script
Cada fornecedor escolhe o seu diretório. O motor genérico procura ficheiros .lua recursivamente, excluindo caminhos de configurações arquivadas. Ordena os caminhos absolutos normalizados primeiro sem distinguir maiúsculas, depois pelo caminho exato; seleciona o primeiro ficheiro de cada nome convertido para minúsculas e regista os duplicados ignorados cujo conteúdo difere do ficheiro selecionado. Se o escolhido falhar na validação, não tenta um duplicado. As referências registadas preservam a grafia real do ficheiro escolhido: use-a nas configurações. Os poderes de boss e os catálogos de encantamentos têm regras próprias de descoberta; partilhar o validador não torna os diretórios intercambiáveis.
Os scripts são identificados pelo nome do ficheiro, não pelo caminho. Dois ficheiros chamados door.lua em subpastas diferentes correspondem à mesma chave, e apenas um deles acaba registado. Dê um nome de ficheiro distinto a cada script.
As funções auxiliares e as constantes locais devem ficar acima do return final, não dentro da tabela devolvida -- a não ser que sejam, de facto, hooks.
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
}
Nomes Comuns de Hooks
Estes nomes aparecem em vários runtimes, mas cada tipo ativa apenas os hooks adequados ao seu proprietário. Os props do FMM usam todos os listados abaixo; os bosses usam a sua lista específica; NPCs do EliteMobs usam on_spawn, on_remove, on_game_tick, on_npc_interact, on_npc_proximity_enter, on_npc_proximity_leave, on_zone_enter e on_zone_leave.
| Hook | Quando dispara |
|---|---|
on_spawn | Disparado pelo ciclo de spawn do plugin para props FMM, bosses e NPCs do EliteMobs; construir uma ScriptInstance não o dispara por si só |
on_game_tick | Chamado a cada tick enquanto a instância inicializada estiver ativa e não estiver pausada |
on_zone_enter | Disparado por uma entrada em zona compatível. FMM e NPCs observam jogadores; os hooks de zona dos bosses vêm dos eventos de zona do EliteScript |
on_zone_leave | Disparado por uma saída de zona compatível. FMM e NPCs observam jogadores; os hooks de zona dos bosses vêm dos eventos de zona do EliteScript |
Sintaxe de Método: : vs .
Em Lua, object:method(arg) é uma abreviatura de object.method(object, arg). Os métodos das tabelas de contexto do MagmaCore removem esse primeiro argumento implícito, pelo que ambas as formas funcionam para métodos como context.log.info:
context.log:info("hello")
context.log.info("hello") -- same thing
As funções globais de em são chamadas com .: em.create_location(...), em.zone.create_sphere_zone(...) e em.location.is_protected(...). Os setters de eventos do EliteMobs context.event.set_damage_amount(...) e context.event.multiply_damage_amount(...) também exigem .. A documentação usa : para métodos de tabelas de contexto e . para funções normais.
Orçamento de Execução
Cada invocação de hook, cada callback agendado e a avaliação inicial do próprio ficheiro de script são executados sob um orçamento rígido de execução. O orçamento é imposto dentro da VM Lua, pelo que se aplica enquanto o seu código ainda está a ser executado, em vez de apenas verificar o relógio depois.
O runtime comum aplica estes limites:
| Limite | Valor |
|---|---|
| Tempo de CPU da thread atual | 50 milissegundos |
| Instruções Lua executadas | 250.000 |
Ultrapassar um limite provoca um erro Lua. O contador de instruções é verificado a cada instrução; o relógio, a cada 1.024 instruções e após o retorno da chamada. Isto não interrompe um método Java/Bukkit em execução, e 50 ms de CPU não são um prazo de 50 ms de tempo real. Um erro não tratado num hook ou callback fecha a instância; durante a validação inicial, rejeita a definição. Sem medição de CPU da thread, o limite passa a 250 milissegundos de tempo decorrido, mantendo o limite de instruções. Lotes de consultas de encantamentos podem impor limites menores.
A VM verifica o orçamento enquanto executa instruções Lua, pelo que while true do end é interrompido. Ainda pode consumir toda a quota de CPU da thread do servidor e desativa o script; esta proteção não justifica ciclos sem limite.
As chamadas encadeadas partilham um único orçamento de 50 ms de CPU e 250.000 instruções para toda a cadeia, sem uma quota independente por chamada.
Para se manter dentro do orçamento:
- Evite loops sem limite dentro de hooks.
- Mantenha os handlers de
on_game_tickleves -- são executados a cada tick. - Use
context.scheduler:run_repeating(...)para distribuir o trabalho ao longo dos ticks. - Execute trabalho caro apenas quando
context.cooldownsou um intervalo razoável o permitir.
Um erro não tratado num hook ou callback fecha a instância e cancela o trabalho pertencente a ela. Corrija e recarregue a definição; depois, o plugin responsável tem de criar uma nova instância. Guardar o ficheiro não recupera a instância fechada. Os fornecedores de encantamentos também aplicam as suas políticas de supressão de falhas.
context.state
Uma tabela Lua comum que persiste durante toda a vida útil da instância do script. Use-a para armazenar flags, contadores, IDs de tarefas, estados de toggle e qualquer dado que precise de partilhar entre hooks.
return {
api_version = 1,
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 partilha dados entre os hooks da instância apenas na memória; não sobrevive a recarregamentos ou reinícios. Outras tabelas são construídas sob demanda e podem conter valores capturados. O FMM mantém context.prop em cache, mas lê campos como current_location sob demanda. Leia novamente um campo dinâmico para obter o valor atual: uma tabela guardada numa variável não se atualiza sozinha. Atribuir um valor a um campo dinâmico oculta o respetivo getter.
context.log
Métodos de log disponíveis em todos os tipos de script. O log.info genérico usa o prefixo [Lua]; inclua um identificador na mensagem se precisar identificar o script. Os diagnósticos de erro identificam o ficheiro, mas as mensagens comuns não recebem o respetivo nome automaticamente. FMM e NPCs oferecem info, warn e error; os poderes de boss oferecem info, warn e debug.
| Método | Notas |
|---|---|
log:info(message) | Mensagem informativa |
log:warn(message) | Mensagem de aviso |
log:error(message) | Mensagem de nível de aviso (registada em nível WARN, igual a log:warn) |
O context.log do EliteMobs regista debug em vez de error. Use log:debug(message) para saída de depuração (aparece como nível info com um prefixo de debug).
context.log:info("Script loaded!")
context.log:warn("Something unexpected happened")
-- Generic/FMM/NPC logger:
context.log:error("Critical failure in zone setup")
-- EliteMobs boss logger:
context.log:debug("Boss debug detail")
context.cooldowns
A tabela gere cooldowns. Os locais e os globais genéricos convertem cada tick configurado em 50 ms de tempo monotónico decorrido, incluindo pausas e períodos de TPS baixo. Os globais dos bosses, por sua vez, contam ticks do servidor. Existem dois âmbitos:
- Cooldowns locais usam chaves string exatas no armazenamento do proprietário, com os âmbitos descritos abaixo. Passe
nilpara usar a chave predefinida:__lua:seguido pelo nome do ficheiro. - Cooldowns globais são partilhados pelos scripts do mesmo proprietário quando o runtime oferece esses métodos, por exemplo os scripts do mesmo prop ou os poderes Lua do mesmo boss.
cooldowns:check_local(key?, duration)
Verifica a chave local e, se estiver pronta, inicia o cooldown e devolve true; caso contrário, devolve false. É uma única chamada Lua síncrona. Não verifica nem inicia o cooldown global. O armazenamento não constitui uma API de bloqueio entre threads.
| Parâmetro | Tipo | Notas |
|---|---|---|
key | string (opcional) | Identificador do cooldown. nil seleciona a chave predefinida. |
duration | int | Duração do cooldown em ticks (20 = 1 segundo) |
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
Todos os tipos de script — bosses, NPCs e FMM — usam check_local(key?, duration). Para a chave predefinida, passe check_local(nil, 60); check_local(60) não significa um cooldown predefinido de 60 ticks. Versões experimentais antigas dos NPCs usavam check_local(duration, key?); atualize esses scripts para a ordem atual.
cooldowns:local_ready(key?)
Devolve true se o cooldown local expirou (ou nunca foi definido), false se ainda estiver ativo.
cooldowns:local_remaining(key?)
Devolve o número de ticks restantes no cooldown local, ou 0 se já estiver pronto.
cooldowns:set_local(duration, key?)
Define um cooldown local sem verificar se já existe um ativo. Use-o para resets incondicionais de cooldown.
| Parâmetro | Tipo | Notas |
|---|---|---|
duration | int | Duração em ticks. Passe 0 ou negativo para limpar. |
key | string (opcional) | Identificador do cooldown. nil seleciona a chave predefinida. |
cooldowns:global_ready()
Devolve true se o cooldown global (partilhado entre todos os scripts da mesma entidade) expirou.
cooldowns:set_global(duration)
Define o cooldown global. Nas tabelas genéricas, zero ou um valor negativo limpa-o. Os globais dos bosses mantêm a expiração mais tardia: uma duração mais curta nunca encurta um cooldown global ativo, e zero ou um valor negativo não faz nada. Definir um cooldown local não define o global, nem o contrário.
| Parâmetro | Tipo | Notas |
|---|---|---|
duration | int | Duração em ticks |
O "dono" de um cooldown global depende do tipo de script:
- Poderes Lua do EliteMobs — partilhados por
EliteEntity(um balde por boss).global_ready()/set_global()usam o sistema embutido de cooldown de poderes do boss; os cooldowns locais também são partilhados entre todos os poderes do mesmo boss. - Scripts de NPC do EliteMobs — os globais e as chaves locais explícitas são partilhados pelo único adaptador do NPC. Dois scripts com a mesma chave local afetam-se um ao outro; as chaves omitidas continuam específicas do ficheiro.
- Scripts de prop do FMM — globais partilhados por prop colocado; cada script tem o seu próprio adaptador e armazenamento local.
- Ações de encantamentos — globais partilhados por jogador dentro do fornecedor; locais pertencem ao jogador e ao ID do encantamento, sobrevivendo a trocas de equipamento e ações concluídas. Consulte encantamentos personalizados.
context.scheduler
O agendador executa tarefas atrasadas e repetidas. As tarefas criadas por ele pertencem à instância e são canceladas no encerramento. Isto não desfaz entidades criadas, alterações no mundo ou temporizadores de outros auxiliares de UI e efeitos. Durante uma pausa, uma tarefa única aguarda a retomada; uma tarefa repetida ignora as chamadas que ocorreriam durante a pausa.
Esta secção usa os nomes do MagmaCore (run_later, run_repeating, cancel). Os nomes do EliteMobs (run_after(ticks, callback), run_every(interval, callback), cancel_task(taskId)) também são aliases aceitos em todos os tipos de script.
scheduler:run_later(ticks, callback)
Executa um callback uma vez após um atraso. Devolve um ID numérico de tarefa.
| Parâmetro | Tipo | Notas |
|---|---|---|
ticks | int | Atraso em ticks de servidor (20 ticks = 1 segundo) |
callback | function | Chamado com um context novo quando o atraso expira |
context.scheduler:run_later(40, function(delayed_context)
delayed_context.log:info("2 seconds have passed!")
end)
scheduler:run_repeating(delay, interval, callback)
Executa um callback repetidamente num intervalo fixo. Devolve um ID numérico de tarefa.
| Parâmetro | Tipo | Notas |
|---|---|---|
delay | int | Atraso inicial em ticks antes da primeira execução |
interval | int | Ticks entre cada execução subsequente |
callback | function | Chamado com um context novo a cada intervalo |
context.state.particle_task = context.scheduler:run_repeating(0, 20, function(tick_context)
tick_context.log:info("Another second passed!")
end)
scheduler:cancel(taskId)
Cancela uma tarefa pertencente à instância pelo ID. Um ID desconhecido ou de outra instância não produz efeito.
| Parâmetro | Tipo | Notas |
|---|---|---|
taskId | int | O ID da tarefa devolvido por run_later ou run_repeating |
O encerramento cancela automaticamente as tarefas da instância. Cancele antes se uma interação ou fase de combate terminar e a instância continuar ativa, por exemplo em on_exit_combat de um boss. Ambas as famílias de nomes funcionam. Use os hooks do plugin responsável; um erro fecha a instância sem garantir a execução de um hook de limpeza personalizado.
Callbacks recebem um contexto novo, sem o evento ou ator original. Use esse argumento. Se precisar do jogador original mais tarde, capture o respetivo UUID durante o hook, resolva-o novamente e verifique se ainda está disponível. Um contexto externo retido também pode resolver um campo de evento sob demanda depois de o evento original terminar.
context.world
A tabela permite consultar e alterar o mundo. Captura o mundo atual do proprietário quando é construída pela primeira vez; guardá-la não a faz acompanhar mudanças posteriores de mundo.
Estes métodos pertencem à tabela partilhada recebida pelos props FMM e NPCs do EliteMobs, incluindo strike_lightning(...) com dano. O FMM acrescenta auxiliares opcionais de transporte e loot do EliteMobs; consulte context.world: adições do FreeMinecraftModels. O EliteMobs acrescenta auxiliares de raios visuais e criação de NPCs e bosses com verificação de chunks carregados. Os poderes de boss substituem ou acrescentam métodos próprios; consulte Mundo e Ambiente do EliteMobs.
As interfaces genéricas aceitam chamadas por coordenadas (strike_lightning(x, y, z), spawn_particle(name, x, y, z, ...)) e por tabela (strike_lightning_at_location(loc), spawn_particle_at_location(loc, ...)). Os bosses também oferecem ambos os estilos, mas alguns métodos têm comportamento específico.
Os argumentos de localização partilhados exigem x, y e z. Um mundo omitido ou não resolvido usa o mundo da tabela. As partículas por localização ainda usam esse mundo capturado: forneça uma localização no mesmo mundo. Os conversores de bosses e as consultas em.location.* seguem regras próprias.
A referência completa da tabela de mundo também documenta a pesquisa de entidades, consultas de passagem e proteção, poeira colorida, impactos no terreno e variantes com tabelas de localização.
world.name
Um campo string contendo o nome do mundo.
world:get_block_at(x, y, z)
Devolve o material do bloco em minúsculas, como "stone" ou "air". Se o chunk não estiver carregado, devolve "air" sem forçar o seu carregamento.
| Parâmetro | Tipo | Notas |
|---|---|---|
x | int | Coordenada X do bloco |
y | int | Coordenada Y do bloco |
z | int | Coordenada Z do bloco |
world:set_block_at(x, y, z, material)
Define o bloco nas coordenadas fornecidas na thread principal, sem forçar o carregamento de chunks.
| Parâmetro | Tipo | Notas |
|---|---|---|
x | int | Coordenada X do bloco |
y | int | Coordenada Y do bloco |
z | int | Coordenada Z do bloco |
material | string | Nome do Material do Bukkit, em minúsculas (ex.: "stone", "air", "oak_planks") |
Devolve true quando o material é válido e a alteração foi colocada na fila; false para material inválido. Se o chunk estiver descarregado quando a tarefa executar, a alteração será ignorada.
Não verifica automaticamente a proteção de regiões. Use um material de bloco e consulte a proteção aplicável antes de colocá-lo. Aceitar a tarefa não prova que o bloco mudou.
world:spawn_particle(particle, x, y, z, count, dx, dy, dz, speed)
Faz spawn de partículas numa localização.
| Parâmetro | Tipo | Predefinição | Notas |
|---|---|---|---|
particle | string | obrigatório | Nome do enum Particle do Bukkit, convertido para maiúsculas na pesquisa, como "FLAME" ou "HAPPY_VILLAGER" |
x | number | obrigatório | Coordenada X |
y | number | obrigatório | Coordenada Y |
z | number | obrigatório | Coordenada Z |
count | int | 1 | Número de partículas |
dx | number | 0 | Espalhamento/offset em X |
dy | number | 0 | Espalhamento/offset em Y |
dz | number | 0 | Espalhamento/offset em Z |
speed | number | 0 | Velocidade da partícula |
Algumas partículas exigem dados adicionais que esta API simples não fornece, como DUST e FALLING_DUST. Use alternativas sem dados: CLOUD, SMOKE, CAMPFIRE_COSY_SMOKE, SNOWFLAKE, FLAME, HAPPY_VILLAGER, HEART, NOTE ou ENCHANT. Para poeira colorida, use world:spawn_dust(...) da referência da tabela de mundo.
Partículas que exigem dados podem lançar uma exceção do Bukkit e desativar a instância. Prefira os nomes sem dados acima em scripts FMM/MagmaCore.
world:play_sound(sound, x, y, z, volume, pitch)
Toca um som numa localização.
| Parâmetro | Tipo | Predefinição | Notas |
|---|---|---|---|
sound | string | obrigatório | Nome do enum Sound do Bukkit (ex.: "ENTITY_EXPERIENCE_ORB_PICKUP") ou uma chave de som personalizado do resource pack (ex.: "mypack:boss.roar") |
x | number | obrigatório | Coordenada X |
y | number | obrigatório | Coordenada Y |
z | number | obrigatório | Coordenada Z |
volume | number | 1.0 | Volume |
pitch | number | 1.0 | Pitch |
O nome é comparado primeiro com os sons registados do Bukkit (sem distinção entre maiúsculas e minúsculas, pelo que "ENTITY_ARROW_SHOOT" e "entity_arrow_shoot" são a mesma coisa). Se nada corresponder, é normalizado para uma chave com namespace em minúsculas e tocado como um som personalizado do resource pack. Um valor que não seja nem um som conhecido nem uma chave com namespace válida não toca nada em vez de gerar um erro, pelo que um erro de escrita simplesmente não faz nada em vez de desativar o seu script.
O mesmo vale para world:play_sound_at_location(loc, sound, volume, pitch).
world:strike_lightning(x, y, z)
Faz cair um raio numa localização (visual e com dano).
| Parâmetro | Tipo | Notas |
|---|---|---|
x | number | Coordenada X |
y | number | Coordenada Y |
z | number | Coordenada Z |
world:get_time()
Devolve o tempo atual do mundo em ticks.
world:set_time(ticks)
Define o tempo do mundo.
| Parâmetro | Tipo | Notas |
|---|---|---|
ticks | int | Tempo do mundo (0 = amanhecer, 6000 = meio-dia, 13000 = noite, 18000 = meia-noite) |
world:get_nearby_entities(x, y, z, radius)
Devolve um array iniciado em 1 com tabelas de entidades dentro de uma caixa alinhada aos eixos e centrada nas coordenadas. Não exclui o proprietário do script.
| Parâmetro | Tipo | Notas |
|---|---|---|
x | number | X central |
y | number | Y central |
z | number | Z central |
radius | number | Raio de pesquisa (usado como meia-extensão nos três eixos) |
Devolve TODAS as entidades no alcance, incluindo não vivas, como itens largados e projéteis. Verifique if entity.damage then antes de chamar métodos de entidades vivas.
world:get_nearby_players(x, y, z, radius)
Devolve um array iniciado em 1 com jogadores dentro de uma caixa alinhada aos eixos; radius é a meia-extensão de cada eixo. Não filtra modos de jogo.
| Parâmetro | Tipo | Notas |
|---|---|---|
x | number | X central |
y | number | Y central |
z | number | Z central |
radius | number | Raio de pesquisa |
world:spawn_entity(entity_type, x, y, z)
Faz spawn de uma entidade vanilla do Minecraft na localização fornecida.
| Parâmetro | Tipo | Notas |
|---|---|---|
entity_type | string | Nome do tipo de entidade do Bukkit, em minúsculas (ex.: "zombie", "skeleton", "pig") |
x | number | Coordenada X |
y | number | Coordenada Y |
z | number | Coordenada Z |
Devolve uma tabela de entidade com métodos de entidade viva quando aplicável, ou nil para um nome de enum desconhecido. Um tipo válido que não pode ser criado pode lançar erro. Não verifica se o chunk está carregado.
world:get_highest_block_y(x, z)
Devolve a altura do bloco mais alto segundo o Bukkit para X/Z. Ao contrário de get_block_at, não verifica se o chunk está carregado.
| Parâmetro | Tipo | Notas |
|---|---|---|
x | int | Coordenada X do bloco |
z | int | Coordenada Z do bloco |
world:raycast(from_x, from_y, from_z, dir_x, dir_y, dir_z, [max_distance], [fluid_mode], [blocks_only], [loaded_only])
Lança um raio a partir de um ponto numa direção e devolve informações sobre o que ele atinge.
| Parâmetro | Tipo | Predefinição | Notas |
|---|---|---|---|
from_x | number | obrigatório | X de origem |
from_y | number | obrigatório | Y de origem |
from_z | number | obrigatório | Z de origem |
dir_x | number | obrigatório | Componente X da direção |
dir_y | number | obrigatório | Componente Y da direção |
dir_z | number | obrigatório | Componente Z da direção |
max_distance | number | 50 | Distância máxima do raio |
fluid_mode | string | "NEVER" | NEVER, SOURCE_ONLY ou ALWAYS |
blocks_only | boolean | false | Ignora entidades e consulta apenas blocos |
loaded_only | boolean | false | Devolve nil sem traçar o raio se algum chunk do retângulo que o delimita estiver descarregado |
Com loaded_only=true, verifique também se o resultado é nil. Caso contrário, um raio que não atinge nada devolve uma tabela com campos de colisão nil:
| Campo | Tipo | Notas |
|---|---|---|
hit_entity | tabela de entidade ou nil | A primeira entidade atingida pelo raio, ou nil se nenhuma |
hit_location | tabela de localização ou nil | O ponto exato onde o raio atingiu algo |
hit_block | tabela ou nil | {x, y, z, material} do bloco atingido, ou nil se nenhum bloco foi atingido |
Os materiais de blocos são devolvidos em minúsculas. O traçado combinado usa tamanho de raio de entidade 0.5, sem filtro de entidades. A verificação de chunks cobre todo o retângulo delimitador e pode rejeitar um chunk afastado do raio exato. Um nome de modo de fluido inválido lança erro.
world:spawn_firework(x, y, z, colors, [type], [power])
Faz spawn de um foguete de fogo de artifício na localização fornecida.
| Parâmetro | Tipo | Predefinição | Notas |
|---|---|---|---|
x | number | obrigatório | Coordenada X |
y | number | obrigatório | Coordenada Y |
z | number | obrigatório | Coordenada Z |
colors | table | obrigatório | Array de strings de cor, ex.: {"RED", "BLUE", "WHITE"} |
type | string | "BALL" | Formato do fogo: "BALL", "BALL_LARGE", "STAR", "BURST", "CREEPER" |
power | int | 1 | Potência de voo, 0-127 |
-- Example: red and yellow firework burst
context.world:spawn_firework(loc.x, loc.y, loc.z, {"RED", "YELLOW"}, "BURST", 2)
world:place_temporary_block(x, y, z, material, [ticks], [require_air])
Coloca um bloco temporário e restaura o seu BlockData guardado após uma duração positiva. Não captura o estado completo nem o inventário do bloco.
| Parâmetro | Tipo | Predefinição | Notas |
|---|---|---|---|
x | int | obrigatório | Coordenada X do bloco |
y | int | obrigatório | Coordenada Y do bloco |
z | int | obrigatório | Coordenada Z do bloco |
material | string | obrigatório | Nome do Material do Bukkit (ex.: "stone", "ice") |
ticks | int | 0 | Duração em ticks até à restauração. Zero ou negativo coloca o bloco de forma permanente, sem acompanhamento. |
require_air | boolean | false | Se true, só coloca o bloco se o alvo for ar |
Devolve false para material inválido ou chunk descarregado. Caso contrário, devolve true quando o pedido é aceite. Com require_air=true, um bloco que não seja ar impede a substituição, embora o pedido tenha sido aceite.
Com ticks positivos, o gestor guarda o BlockData original e restaura-o quando o temporizador termina, quando o chunk ou o mundo é descarregado ou quando o plugin é encerrado. Só restaura enquanto o bloco ainda contém o bloco temporário, pelo que uma edição posterior não é substituída. Voltar a colocar sobre um bloco que ainda contém um bloco temporário reinicia o temporizador e mantém o primeiro original guardado. Os blocos com block entities, como baús e placas, e os blocos já pertencentes a outro dono de blocos temporários, como uma reserva de encantamento, são ignorados. Partir um bloco temporário não gera drops e encerra o acompanhamento sem restaurar; colocar um bloco ali também encerra o acompanhamento.
Estes temporizadores não são cancelados com o script Lua, e a colocação não verifica automaticamente a proteção de regiões.
world:drop_item(x, y, z, material, [amount])
Larga uma entidade de item na localização fornecida com dispersão natural.
| Parâmetro | Tipo | Predefinição | Notas |
|---|---|---|---|
x | number | obrigatório | Coordenada X |
y | number | obrigatório | Coordenada Y |
z | number | obrigatório | Coordenada Z |
material | string | obrigatório | Nome do Material do Bukkit |
amount | int | 1 | Tamanho da pilha |
Devolve uma tabela de entidade para o item largado, ou nil se o material era inválido.
context.zones
A tabela permite criar zonas e observar entradas e saídas de jogadores. Os props FMM e os NPCs do EliteMobs usam create_sphere(...), create_cylinder(...), create_cuboid(...), watch(...) e unwatch(...), disparando on_zone_enter e on_zone_leave. As zonas pertencem à instância e são removidas automaticamente no encerramento. Os bosses usam uma tabela própria com get_entities_in_zone(...), get_locations_in_zone(...) e watch_zone(...); consulte Zonas e Alvos do EliteMobs.
zones:create_sphere(x, y, z, radius)
Cria uma esfera centrada nas coordenadas. Devolve um identificador numérico, ou nil se o proprietário não tiver mundo.
| Parâmetro | Tipo | Notas |
|---|---|---|
x | number | X central |
y | number | Y central |
z | number | Z central |
radius | number | Raio da esfera |
zones:create_cylinder(x, y, z, radius, height)
Cria um cilindro. Devolve um identificador numérico, ou nil se o proprietário não tiver mundo.
| Parâmetro | Tipo | Notas |
|---|---|---|
x | number | X central |
y | number | Y central (base) |
z | number | Z central |
radius | number | Raio do cilindro |
height | number | Altura do cilindro |
zones:create_cuboid(x, y, z, xSize, ySize, zSize)
Cria um cuboide. Devolve um identificador numérico, ou nil se o proprietário não tiver mundo. A observação genérica testa o ponto de localização do jogador; os tamanhos são meias-extensões em torno do centro. Isto difere das operações com sobreposição de entidades e pontos amostrados das zonas de bosses. Se zSize for zero e xSize não, a forma partilhada usa xSize para Z.
| Parâmetro | Tipo | Notas |
|---|---|---|
x | number | X central |
y | number | Y central |
z | number | Z central |
xSize | number | Meia-extensão em X |
ySize | number | Meia-extensão em Y |
zSize | number | Meia-extensão em Z |
zones:watch(handle, onEnterCallback, onLeaveCallback)
Ativa os eventos de entrada e saída de uma zona já criada. Os parâmetros devem ser funções Lua, mas os seus corpos não são chamados: a lógica é executada em on_zone_enter e on_zone_leave. O acompanhamento começa na criação da zona; adicionar watch depois não gera uma entrada para quem já está dentro. Passar nil numa chamada posterior não limpa um disparador já ativado.
| Parâmetro | Tipo | Notas |
|---|---|---|
handle | int | Handle de zona devolvido por uma chamada create_* |
onEnterCallback | function ou nil | Uma função ativa on_zone_enter; o seu corpo é ignorado |
onLeaveCallback | function ou nil | Uma função ativa on_zone_leave; o seu corpo é ignorado |
Devolve true se a observação foi configurada com sucesso, nil se o handle da zona era inválido.
As verificações são executadas antes de on_game_tick, usando o ponto de localização dos jogadores no mundo atual do proprietário, não as suas caixas completas. As esferas exigem pontos estritamente dentro do raio; os cilindros exigem pontos dentro do raio, com a base incluída e o topo excluído. As zonas retêm as coordenadas e o mundo da criação. Sair do servidor ou remover a observação não garante um hook de saída. Mantenha um número razoável de zonas.
zones:unwatch(handle)
Deixa de observar uma zona e liberta os seus recursos.
| Parâmetro | Tipo | Notas |
|---|---|---|
handle | int | Handle da zona cuja observação deve terminar |
Exemplo: Zona-gatilho por proximidade
return {
api_version = 1,
on_spawn = function(context)
local loc = context.prop.current_location
if loc == nil then return end
local handle = context.zones:create_sphere(loc.x, loc.y, loc.z, 5)
-- Pass placeholder functions to enable on_zone_enter and on_zone_leave hooks.
-- The placeholder bodies are ignored; the actual logic goes in the hooks below.
context.zones:watch(handle, function() end, function() end)
context.state.zone_handle = handle
end,
on_zone_enter = function(context)
context.log:info("Player entered zone!")
end,
on_zone_leave = function(context)
context.log:info("Player left zone!")
end,
on_destroy = function(context)
if context.state.zone_handle then
context.zones:unwatch(context.state.zone_handle)
end
end
}
context.event
A tabela aparece quando o hook tem um evento ou ator. Cliques em props FMM usam uma flag de cancelamento do plugin; interações de NPC e hooks genéricos de zona podem fornecer um ator sem evento Bukkit. A tabela não aparece em on_game_tick, callbacks agendados ou hooks de ciclo de vida sem jogador de origem.
Os hooks on_projectile_hit de props FMM recebem o evento cancelável de impacto de projétil do FreeMinecraftModels, pelo que cancel() e uncancel() estão disponíveis. O hook é executado depois de o FMM processar o impacto, portanto cancelar não impede que um projétil sem perfuração seja consumido. Não dispara quando outro plugin já cancelou o impacto. context.event.player é o atirador quando este é uma entidade viva, o que pode ser um mob, e fica ausente nos outros casos; context.player só é definido quando um jogador disparou o projétil. O hook também expõe context.projectile como tabela de entidade do projétil.
Nos hooks genéricos on_zone_enter e on_zone_leave, context.player e context.event.player identificam o jogador. Não existe evento Bukkit cancelável nesses hooks; portanto, cancel() e uncancel() não estão disponíveis.
| Campo / Método | Tipo | Notas |
|---|---|---|
is_cancelled | boolean | Estado capturado quando a subtabela de evento foi resolvida pela primeira vez. cancel() e uncancel() não o atualizam |
cancel() | método | Cancela o evento; disponível apenas em eventos canceláveis |
uncancel() | método | Remove o cancelamento; disponível apenas em eventos canceláveis |
player | tabela de entidade | O jogador envolvido no evento, se houver |
on_right_click = function(context)
if context.event and context.event.cancel then
context.event:cancel() -- prevent the default right-click interaction
end
end
Os scripts de poder do EliteMobs têm uma tabela de evento mais detalhada com quantidades de dano, causas de dano, referências ao causador do dano e métodos de modificação de dano. Consulte a Referência da API Lua para os campos completos de evento do EliteMobs.
Namespace Auxiliar em
A tabela em está disponível durante o carregamento do ficheiro. Os seus construtores criam dados sem carregar mundos, registar observações ou validar uma forma completa. Os setters alteram a própria tabela e mantêm por referência as tabelas de localização fornecidas.
| Função | Propósito |
|---|---|
em.create_location(x, y, z [, world, yaw, pitch]) | Cria uma tabela de localização com nome de mundo, yaw e pitch opcionais. A tabela devolvida também tem um método .add(dx, dy, dz) que desloca a localização no lugar e devolve-se a si própria para encadeamento. |
em.create_vector(x, y, z) | Cria uma tabela de vetor |
em.zone.create_sphere_zone(radius) | Cria uma definição de zona esférica |
em.zone.create_dome_zone(radius) | Cria uma definição de zona em domo |
em.zone.create_cylinder_zone(radius, height) | Cria uma definição de zona cilíndrica |
em.zone.create_cuboid_zone(x, y, z) | Cria uma definição de zona cuboide |
em.zone.create_cone_zone(length, radius) | Cria uma definição de zona cônica |
em.zone.create_static_ray_zone(length, thickness) | Cria uma definição de zona de raio estático |
em.zone.create_rotating_ray_zone(length, point_radius, animation_duration) | Cria uma definição de zona de raio rotativo |
em.zone.create_translating_ray_zone(length, point_radius, animation_duration) | Cria uma definição de zona de raio em translação |
em.location.is_in_dungeon(loc) | Verifica se uma localização está dentro de alguma região de masmorra registada (qualquer proprietário que reporte o tipo "dungeon") |
em.location.is_protected(loc) | Verifica se uma localização está dentro de alguma região protegida (WorldGuard, GriefPrevention, regiões EM, etc.) |
em.location.owned_by(loc, namespace) | Verifica se um namespace de plugin específico possui a localização (ex.: "EliteMobs") |
em.location.owners(loc) | Array de strings de namespace que possuem a localização |
em.location.kinds_at(loc) | Array de tags de tipo na localização ("elitemobs", "dungeon", "world_package", "open_world_dungeon", categoria de tamanho de masmorra) |
em.location.has_kind(loc, kind) | Verifica se a localização está marcada com o tipo fornecido |
O MagmaCore inclui adaptadores de WorldGuard e GriefPrevention. Os consumidores inicializam-nos ao ativar; uma consulta de proteção também pode inicializá-los sob demanda. As consultas abrangem fornecedores registados, não todos os plugins possíveis. Um adaptador de região registado que falha indica que a região está protegida. Sem fornecedor nem propriedade de proteção, a consulta devolve false; os avisos identificam fornecedores em falta.
Em em.location.*, forneça em world o nome de um mundo carregado ou {name=...}. Não existe fallback para o mundo do proprietário. Um mundo em falta ou não resolvido, ou uma entrada nil, devolve false ou um array vazio. As coordenadas em falta usam zero; campos numéricos malformados podem lançar erro. Os namespaces de proprietários distinguem maiúsculas; as tags de tipo não. A propriedade não implica participação em masmorra nem proteção. A ordem dos arrays não é garantida.
Os construtores de zona devolvem tabelas encadeáveis com :set_center(loc) (ou :set_origin(loc) / :set_destination(loc) dependendo do tipo de zona):
-- 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
}
O namespace em é particularmente útil no EliteMobs, onde definições de zona são usadas com context.zones:get_entities_in_zone() e context.script. No FreeMinecraftModels, os métodos context.zones:create_sphere(...) / create_cylinder(...) / create_cuboid(...) são mais usados para zonas simples baseadas em observação (watch).
Tabelas de Entidade
As tabelas abaixo apresentam os métodos comuns. A referência completa da API Lua também cobre campos de projéteis, verificações de caminhos, propriedade e proteção. Aplicam-se às tabelas genéricas; wrappers específicos dos poderes do EliteMobs têm uma secção própria nessa referência.
As consultas ao mundo e os dados de eventos devolvem tabelas de entidade com campos e métodos em camadas, conforme o tipo de entidade.
Campos Base da Entidade
| Campo | Tipo | Notas |
|---|---|---|
uuid | string | O UUID da entidade |
entity_type | string | O tipo da entidade (ex.: "player", "zombie", "skeleton", "villager") |
is_valid | boolean | Se a referência da entidade ainda é válida |
is_dead | boolean | Se a entidade está morta |
is_player | boolean | Se a entidade é um jogador |
is_hostile | boolean | Se implementa Monster do Bukkit, independentemente da agressividade atual |
is_passive | boolean | Se implementa Animals do Bukkit; não garante comportamento passivo |
current_location | tabela de localização | A posição atual da entidade (x, y, z, world, yaw, pitch) |
world | string | O nome do mundo em que a entidade está |
Métodos Base da Entidade
| Método | Devolve | Notas |
|---|---|---|
teleport(location_table) | void | Exige x, y e z; mundo omitido ou não resolvido usa o mundo da entidade. yaw e pitch usam zero por predefinição. Não verifica automaticamente caminhos nem proteção. |
remove() | void | Remove a entidade do mundo. Só age se a entidade ainda for válida. |
set_silent(flag) | void | Suprime ou reativa os sons da entidade. |
set_invulnerable(flag) | void | Torna a entidade invulnerável ou vulnerável a dano. |
set_gravity(flag) | void | Ativa ou desativa a gravidade para a entidade. |
set_glowing(flag) | void | Alterna o efeito de contorno brilhante na entidade. |
Campos da Entidade Viva
Entidades vivas (jogadores, mobs, etc.) têm todos os campos base de entidade mais:
| Campo | Tipo | Notas |
|---|---|---|
health | number | Vida atual |
maximum_health | number | Vida máxima |
name | string | Nome apresentado |
is_alive | boolean | Se a entidade está viva |
Métodos da Entidade Viva
| Método | Devolve | Notas |
|---|---|---|
damage(amount) | void | Causa a quantidade de dano fornecida à entidade |
push(x, y, z) | void | Soma imediatamente o vetor à velocidade atual |
set_facing(x, y, z) | void | Teletransporta na mesma posição com uma nova direção |
add_potion_effect(effect, duration, amplifier) | void | Adiciona um efeito de poção. effect é uma string (ex.: "speed", "slowness", "regeneration"). duration é em ticks. amplifier é o nível do efeito menos 1 (0 = nível I). |
remove_potion_effect(effect) | void | Remove um efeito de poção pelo nome |
get_scale() | number | Devolve a escala efetiva, incluindo modificadores, ou 1.0 se indisponível |
set_scale(value) | void | Altera o valor base do atributo de escala, quando disponível |
Nem todas as entidades devolvidas por get_nearby_entities() são entidades vivas. Pode usar entity.is_player, entity.is_hostile ou entity.is_passive para filtrar por categoria, ou verificar if entity.damage then antes de chamar métodos de entidade viva como damage(), push() ou add_potion_effect().
Campos de Integração de Plugins
As tabelas podem incluir campos de integração. Sem o componente que os acrescenta, ficam em falta e são lidos como nil. As flags de rastreio, a identidade do modelo, o estado de operador e a maioria dos dados aninhados são capturados na construção; não acompanham mudanças posteriores. Os campos partilhados de vida do EliteMobs são lidos sob demanda; métodos de modelos e permissões consultam os objetos correspondentes em cada chamada.
Campos do EliteMobs
Disponíveis quando o EliteMobs está instalado.
| Campo | Tipo | Notas |
|---|---|---|
is_elite | boolean | Se a entidade é uma elite do EliteMobs |
is_custom_boss | boolean | Se a entidade é um boss personalizado do EliteMobs (também disponível dentro da subtabela elite) |
is_significant_boss | boolean | Se a entidade é um boss personalizado com multiplicador de vida acima de 1 (ou seja, um encontro concebido, não uma elite filler) |
elite | tabela ou nil | Subtabela de informações da elite (consulte abaixo). nil se a entidade não for uma elite. |
A subtabela elite contém:
| Campo | Tipo | Notas |
|---|---|---|
elite.level | int | O nível da elite |
elite.name | string ou nil | O nome apresentado da elite |
elite.health | number | Vida atual |
elite.max_health | number | Vida máxima |
elite.is_custom_boss | boolean | Se é um boss personalizado (em oposição a uma elite natural) |
elite.health_multiplier | number | Multiplicador de vida definido na config |
elite.damage_multiplier | number | Multiplicador de dano definido na config |
elite:remove() | void | Remove através da rotina de remoção do EliteMobs; não equivale a matar nem garante loot |
Exemplo: Causar dano diferente a elites
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
Campos do FreeMinecraftModels
Disponíveis quando o FreeMinecraftModels está instalado.
| Campo | Tipo | Notas |
|---|---|---|
is_modeled | boolean | Se a entidade tem um modelo FMM anexado (DynamicEntity ou PropEntity) |
is_prop | boolean | Se a entidade é um prop FMM (entidade decorativa estática) |
model | tabela ou nil | Subtabela de informações do modelo (consulte abaixo). nil se a entidade não tiver modelo. |
A subtabela model contém:
| Campo | Tipo | Notas |
|---|---|---|
model.model_id | string ou nil | O ID do blueprint do modelo (ex.: "torch_01") |
model.is_dynamic | boolean | Se a entidade modelada é um DynamicEntity (modelo de mob/boss) em vez de um prop estático |
model:play_animation(name, [blend], [loop]) | boolean | Aceita um pedido de animação. blend e loop usam false por predefinição. Colocar na fila ou suprimir um ataque pode devolver true sem reprodução imediata. O estado terminal de morte rejeita a reprodução. |
model:stop_animations() | void | Limpa a fila e regressa à animação inativa quando disponível; não altera o estado terminal de morte. |
model:remove() | void | Remove a entidade modelada pelo pipeline adequado de remoção do FMM. |
Nas tabelas de jogadores, a integração FMM também acrescenta:
| Campo / Método | Tipo | Notas |
|---|---|---|
is_op | boolean | Se o jogador é operador do servidor |
has_permission(node) | boolean | Se o jogador tem a permissão |
Estes dois valores de jogador existem apenas em scripts do FreeMinecraftModels. Em tabelas partilhadas construídas dentro do EliteMobs, o próprio adaptador do EliteMobs para o FreeMinecraftModels acrescenta is_modeled, is_prop e model, mas não is_op nem has_permission.
Tabelas de jogador FMM também oferecem is_holding_elitemobs_item(filename). Verifica a tag de nome de ficheiro do EliteMobs na mão principal, incluindo .yml, não o nome apresentado. Mão vazia, outros itens ou integração indisponível devolvem false. A integração partilhada do próprio EliteMobs acrescenta separadamente elite_player, com o tier de combate quando disponível; o adaptador opcional do FMM não acrescenta essa subtabela.
A ponte de modelo usa false como predefinição de blend e loop. Na tabela de prop, play_animation usa true para ambos, permitindo reprodução em fila e em loop. blend controla a fila, não uma transição gradual entre animações.
Exemplo: Filtrar entidades por tipo
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
Campos Específicos de Jogador
Entidades de jogador têm todos os campos de entidade e entidade viva mais:
| Campo | Tipo | Notas |
|---|---|---|
game_mode | string | O modo de jogo do jogador ("creative", "survival", "adventure", "spectator") |
Métodos Específicos de Jogador
Sempre que a API disser "suporta códigos de cor", o Magmacore passa a string pelo seu parser MiniMessage integrado. Códigos legados &, hex &#RRGGBB, <#RRGGBB>, <gradient>, <rainbow> e o restante do conjunto de tags do MiniMessage funcionam todos e podem ser misturados livremente. O Kyori Adventure não é uma dependência e nenhuma API do Adventure está disponível para scripts -- não precisa dela.
Os métodos de texto do Lua convertem para uma string com códigos de cor legados, então cores, gradientes e decorações renderizam corretamente, enquanto tags interativas (<hover>, <click>, <insert>, <font>, <key>, <lang>) são analisadas mas não têm efeito. Consulte Códigos de Cor para a lista completa de tags.
| Método | Devolve | Notas |
|---|---|---|
send_message(msg) | void | Envia uma mensagem de chat ao jogador. Suporta códigos de cor. |
chat(text) | void | Envia texto com cores pelo chat Bukkit do jogador, incluindo comandos com barra executados como esse jogador |
get_held_item() | tabela ou nil | Devolve {type, amount, display_name} da mão principal, ou nil se vazia. type é o Material Bukkit em maiúsculas, como "GOLD_INGOT". |
consume_held_item(amount?) | void | Coloca na fila o consumo da mão principal no estado existente quando a tarefa for executada. Predefinição 1; não retém um item previamente verificado nem confirma pagamento. Forneça uma quantidade positiva: valores negativos não são rejeitados. |
has_item(material, amount?) | boolean | Devolve true se o jogador tem pelo menos amount (predefinição 1) do material fornecido em qualquer lugar do inventário |
get_target_entity([range]) | tabela de entidade ou nil | Traça dos olhos contra blocos e entidades, excluindo o jogador, com tamanho de raio de entidade 0.5. Ignora fluidos e blocos atravessáveis; alcance predefinido 50. |
get_eye_location() | tabela de localização | Devolve uma tabela de localização na altura dos olhos do jogador |
get_look_direction() | tabela | Devolve um vetor de direção {x, y, z} para onde o jogador está a olhar |
send_block_change(x, y, z, material, [ticks]) | boolean | Coloca na fila um bloco visível apenas no cliente, com restauração após ticks positivos. True significa que foi colocado na fila; material inválido ou que não seja bloco devolve false. |
reset_block(x, y, z) | boolean | Coloca na fila a restauração visual do bloco real para o jogador e devolve true |
sleep(x, y, z) | void | Coloca na fila uma cama branca real e uma tentativa de dormir. Ao acordar ou sair do servidor, restaura apenas BlockData, não o conteúdo de blocos. |
wake_up() | void | Acorda um jogador adormecido. |
As alterações e restaurações colocadas na fila leem o mundo do jogador ao serem executadas; não dependa delas para restaurar o bloco pretendido após uma mudança de mundo. A limpeza do sono verifica após 20 ticks e depois a cada 10. Estas tarefas não pertencem a context.scheduler.
Métodos de UI do Jogador
Estes são os métodos da tabela partilhada de jogador. As tabelas de jogadores dos poderes de boss têm assinaturas diferentes, listadas na referência da API. As barras partilhadas são identificadas pelo jogador dentro da cópia do MagmaCore do plugin responsável, não pelo script. Um temporizador de expiração remove apenas a barra ou a action bar repetida que o iniciou, pelo que uma expiração antiga não limpa uma mais recente. Os seus temporizadores Bukkit não pertencem a context.scheduler.
player:show_boss_bar(text, [color], progress, [ticks])
Substitui a barra partilhada sólida do jogador. O progresso é limitado a 0..1; uma cor inválida torna-se branca. Passe nil para omitir a cor, mantendo o progresso no terceiro argumento.
| Parâmetro | Tipo | Predefinição | Notas |
|---|---|---|---|
text | string | obrigatório | O texto a apresentar. Suporta códigos de cor &. |
color | string | "WHITE" | Cor da barra. Uma de: "RED", "BLUE", "GREEN", "YELLOW", "PURPLE", "PINK", "WHITE" |
progress | number | obrigatório | Quantidade preenchida de 0.0 (vazio) a 1.0 (cheio) |
ticks | int | -1 | Valores positivos agendam a remoção; caso contrário, fica até ser ocultada ou substituída |
player:hide_boss_bar()
Remove a barra de boss do ecrã do jogador. Não recebe parâmetros.
player:show_action_bar(text, [ticks])
Mostra texto na área da action bar (acima da hotbar).
| Parâmetro | Tipo | Predefinição | Notas |
|---|---|---|---|
text | string | obrigatório | O texto a apresentar. Suporta códigos de cor &. |
ticks | int | -1 | Valores positivos repetem a cada 40 ticks até expirar; caso contrário, envia uma vez. Uma nova chamada cancela a tarefa repetida anterior. |
player:show_title(title, [subtitle], fade_in, stay, fade_out)
Mostra um ecrã de título ao jogador.
| Parâmetro | Tipo | Predefinição | Notas |
|---|---|---|---|
title | string | obrigatório | Texto principal do título. Suporta códigos de cor &. |
subtitle | string | "" | Texto do subtítulo abaixo do título principal. Opcional. |
fade_in | int | obrigatório | Duração do fade-in em ticks |
stay | int | obrigatório | Quanto tempo o título permanece no ecrã em ticks |
fade_out | int | obrigatório | Duração do fade-out em ticks |
Próximos Passos
Para hooks, APIs e fluxos de trabalho específicos de cada plugin:
- EliteMobs: Primeiros Passos | Scripts de NPC | Hooks e Ciclo de Vida | Bosses e Entidades | Mundo e Ambiente | Zonas e Alvos
- FreeMinecraftModels: Primeiros Passos | API de Props | Exemplos