Scripting Lua: Zonas e Alvos

As funcionalidades Lua do EliteMobs oferecem duas abordagens complementares para definir áreas espaciais e resolver alvos:
- Zonas nativas (
context.zones) -- simples e diretas. Você constrói uma definição de zona como uma tabela Lua simples e a consulta para obter entidades ou localizações. Ideal para verificações diretas de "há algo nesta área?".
- Utilitários de script (
context.script) -- segmentação mais rica, handles de zona com métodos watch/contains/entities, geração de partículas, dano e ações de empurrão. Usa os mesmos nomes de campo que as Zonas do EliteScript e os Alvos do EliteScript para maior familiaridade.
Ambas as abordagens são APIs Lua nativas. Escolha a que se adequa à complexidade do seu poder.
Zonas nativas: context.zones
As zonas nativas permitem definir zonas como tabelas Lua simples e consultá-las diretamente. Sem handles, sem abstração adicional -- apenas uma tabela descrevendo uma forma e uma chamada de método para consultá-la.
Métodos
| Método | Notas |
|---|
zones:get_entities_in_zone(zoneDef, options) | Retorna um array de wrappers de entidade dentro da zona |
zones:get_locations_in_zone(zoneDef, options) | Retorna um array de tabelas de localização dentro da zona |
zones:zone_contains(zoneDef, location[, "full"|"border"]) | Retorna true se a localização está dentro da zona |
zones:watch_zone(zoneDef, callbacks, options) | Registra um observador de zona persistente que dispara a cada tick |
Campos de definição de zona
| Campo | Tipo | Notas |
|---|
kind | string | "sphere", "dome", "cylinder", "cuboid", "cone", "static_ray", "rotating_ray", "translating_ray" |
radius | number | Raio da zona (sphere, dome, cylinder, cone) |
height | number | Altura do cilindro |
origin | location | Localização central (padrão é a localização do boss se omitido) |
destination | location | Ponto final para raios e cones |
x, y, z | number | Semi-extensões do cuboide |
length | number | Comprimento para cones e raios |
thickness / point_radius | number | Espessura do raio |
border_radius | number | Largura da borda (padrão 1) |
x_border, y_border, z_border | number | Larguras de borda do cuboide (padrão 1) |
animation_duration | int | Duração da animação em ticks para raios animados |
pitch_pre_rotation, yaw_pre_rotation | number | Ângulos de pré-rotação (raio rotativo) |
pitch_rotation, yaw_rotation | number | Ângulos de rotação por tick (raio rotativo) |
origin_end, destination_end | location | Posições finais para raio em translação |
ignores_solid_blocks | boolean | Se os raios passam através de blocos sólidos (padrão true) |
Opções de consulta
| Chave | Notas |
|---|
filter | "player" / "players", "elite" / "elites", "mob" / "mobs", "living" (padrão) |
mode | "full" (padrão) ou "border" |
coverage | 0.0 a 1.0 -- fração de localizações a amostrar (padrão 1.0) |
Callbacks de observação
| Chave | Notas |
|---|
on_enter | function(entity) -- chamada quando uma entidade entra na zona |
on_leave | function(entity) -- chamada quando uma entidade sai da zona |
Exemplo: consulta básica de esfera
Exemplo
return {
api_version = 1,
on_spawn = function(context)
-- Store a zone definition for reuse
context.state.danger_zone = {
kind = "sphere",
origin = context.boss:get_location(),
radius = 10
}
end,
on_boss_damaged_by_player = function(context)
-- Update the origin to the boss's current position
context.state.danger_zone.origin = context.boss:get_location()
local players = context.zones:get_entities_in_zone(
context.state.danger_zone,
{ filter = "players" }
)
for _, player in ipairs(players) do
player:send_message("&cYou are in the danger zone!")
end
end
}
Exemplo
return {
api_version = 1,
on_spawn = function(context)
context.zones:watch_zone(
{
kind = "sphere",
origin = context.boss:get_location(),
radius = 8
},
{
on_enter = function(entity)
entity:apply_potion_effect("SLOWNESS", 40, 1)
entity:send_message("&7You feel sluggish near the boss...")
end,
on_leave = function(entity)
entity:send_message("&aYou escape the slowing aura.")
end
},
{ filter = "players", mode = "full" }
)
end
}
Notas sobre observadores:
- Os callbacks de observadores recebem diretamente um único wrapper de entidade, não via
context.event
- Os observadores são limpos automaticamente quando o boss é removido
- Cada observador é executado a cada tick, portanto mantenha a lógica do callback leve
- A entidade do boss é excluída das consultas de zona
Utilitários de script: context.script
Os utilitários de script fornecem resolução de alvos, handles de zona, vetores relativos, geração de partículas e ações de combate. Usam os mesmos nomes de campo que as Zonas do EliteScript e os Alvos do EliteScript para maior familiaridade -- os nomes de enum (como "NEARBY_PLAYERS", "SPHERE", "ZONE_FULL") são idênticos para que autores já familiarizados com EliteScript possam transferir esse conhecimento diretamente.
context.script é uma API Lua nativa. Não é uma ponte para YAML ou para o runtime do EliteScript. Simplesmente reutiliza as mesmas convenções de nomenclatura para que você não precise aprender um segundo conjunto de nomes de enum.
Métodos
| Método | Notas |
|---|
script:target(spec) | Cria um handle de alvo a partir de uma tabela de especificação de alvo |
script:zone(spec) | Cria um handle de zona a partir de uma tabela de especificação de zona |
script:relative_vector(spec[, actionLocation][, zoneHandle]) | Cria um handle de vetor relativo |
script:damage(targetHandle, amount[, multiplier]) | Causa dano aos alvos resolvidos |
script:push(targetHandle, vectorOrHandle[, additive]) | Empurra os alvos resolvidos |
script:set_facing(targetHandle, vectorOrHandle) | Define a direção de orientação dos alvos |
script:spawn_particles(targetHandle, particleSpec) | Gera partículas nas localizações dos alvos resolvidos |
Métodos do handle de alvo
| Método | Notas |
|---|
handle:entities() | Retorna array de wrappers de entidade |
handle:locations() | Retorna array de tabelas de localização |
handle:first_entity() | Retorna a primeira entidade ou nil |
handle:first_location() | Retorna a primeira localização ou nil |
Chaves de especificação de alvo
| Chave | Notas |
|---|
targetType | "SELF", "DIRECT_TARGET", "NEARBY_PLAYERS", "NEARBY_MOBS", "NEARBY_ELITES", "ZONE_FULL", "ZONE_BORDER", "ALL_PLAYERS", "WORLD_PLAYERS", "SELF_SPAWN", "LOCATION" |
range | Alcance para tipos de alvo próximos |
coverage | 0.0 a 1.0 para alvos de zona |
offset | String "x,y,z" ou tabela { x = n, y = n, z = n } |
track | Se deve resolver novamente alvos em movimento |
Exemplo: criar e usar um alvo
Exemplo
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if not context.cooldowns:check_local("roar", 200) then return end
-- Find all players within 20 blocks
local nearby = context.script:target({
targetType = "NEARBY_PLAYERS",
range = 20
})
for _, player in ipairs(nearby:entities()) do
player:send_message("&eThe boss roars in fury!")
end
-- Single-entity access
local closest = nearby:first_entity()
if closest then
closest:show_title("&cRUN!", "&7The boss is targeting you")
end
end
}
Métodos do handle de zona
| Método | Notas |
|---|
handle:full_target([coverage]) | Retorna um handle de alvo para o volume completo da zona |
handle:border_target([coverage]) | Retorna um handle de alvo para a borda da zona |
handle:full_locations([coverage]) | Retorna localizações no volume completo da zona |
handle:border_locations([coverage]) | Retorna localizações na borda da zona |
handle:full_entities() | Retorna entidades no volume completo da zona |
handle:border_entities() | Retorna entidades na borda da zona |
handle:contains(location[, "full"|"border"]) | Retorna true se a localização está dentro da zona |
handle:watch(callbacks[, mode]) | Observa a zona para eventos de entrada/saída, retorna ID de tarefa |
Chaves de especificação de zona
| Chave | Notas |
|---|
shape | "SPHERE", "DOME", "CYLINDER", "CUBOID", "CONE", "STATIC_RAY", "ROTATING_RAY", "TRANSLATING_RAY" |
radius | Raio da zona |
height | Altura do cilindro |
x, y, z | Semi-extensões do cuboide |
borderRadius | Largura da borda |
pointRadius | Espessura do raio |
animationDuration | Duração da animação em ticks para raios animados |
Target | Especificação de alvo central (tabela) -- usa o mesmo formato de especificação de alvo |
Target2 | Segundo ponto para raios e cones |
filter | Filtro de entidade |
ignoresSolidBlocks | boolean |
pitchPreRotation, yawPreRotation | Ângulos de pré-rotação |
pitchRotation, yawRotation | Ângulos de rotação por tick |
Exemplo
return {
api_version = 1,
on_enter_combat = function(context)
-- Create a sphere zone centered on the boss
local zone = context.script:zone({
shape = "SPHERE",
radius = 6,
Target = { targetType = "SELF" }
})
-- Spawn warning particles on the zone border
context.script:spawn_particles(
zone:border_target(0.3),
{ particle = "FLAME", amount = 1, speed = 0.02 }
)
-- Damage all players inside the zone
local targets = zone:full_target()
context.script:damage(targets, 5.0)
-- Repeat every 20 ticks
context.scheduler:run_every(20, function(ctx)
local z = ctx.script:zone({
shape = "SPHERE",
radius = 6,
Target = { targetType = "SELF" }
})
ctx.script:spawn_particles(
z:border_target(0.3),
{ particle = "FLAME", amount = 1, speed = 0.02 }
)
ctx.script:damage(z:full_target(), 5.0)
end)
end
}
Chaves de especificação de vetor relativo
| Chave | Notas |
|---|
SourceTarget | Especificação do alvo de origem (tabela) |
DestinationTarget | Especificação do alvo de destino (tabela) |
normalize | boolean -- se deve normalizar o vetor resultante |
multiplier | Fator de escala aplicado após a normalização |
offset | String "x,y,z" ou tabela { x = n, y = n, z = n } |
Métodos do handle de vetor relativo
| Método | Notas |
|---|
handle:resolve() | Retorna a tabela do vetor calculado |
Exemplo
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if not context.cooldowns:check_local("knockback", 100) then return end
-- Build a vector from the boss toward the attacker
local vec = context.script:relative_vector({
SourceTarget = { targetType = "SELF" },
DestinationTarget = { targetType = "DIRECT_TARGET" },
normalize = true,
multiplier = 2.5
})
-- Push the attacker away
local target = context.script:target({
targetType = "DIRECT_TARGET"
})
context.script:push(target, vec)
end
}
As especificações de partículas podem ser uma string, uma tabela individual ou um array de tabelas:
| Chave | Notas |
|---|
particle | Nome da partícula (ex. "FLAME", "DUST", "SMOKE") |
amount | Número de partículas |
x, y, z | Valores de offset/dispersão |
speed | Velocidade das partículas |
red, green, blue | Cor para DUST / DUST_COLOR_TRANSITION (0-255) |
toRed, toGreen, toBlue | Cor de destino de transição para DUST_COLOR_TRANSITION |
Para a lista completa de nomes de partículas, consulte a Referência de Enums.
Avisos importantes
- Os handles de utilitários de script estão vinculados ao contexto do evento em que foram criados. Não os armazene em
context.state para uso em uma chamada de hook posterior.
watch() de zona retorna um ID de tarefa que pode ser cancelado com context.scheduler:cancel_task().
- Os valores de coverage aplicam-se apenas à resolução baseada em localização, não a consultas de entidades.
- Todos os valores de string usam os mesmos nomes de enum em UPPER_SNAKE_CASE que o YAML do EliteScript (ex.
"SELF", "NEARBY_PLAYERS", "SPHERE").
Namespace auxiliar em
O namespace em está disponível globalmente em todos os arquivos de poder Lua. Fornece construtores convenientes para localizações, vetores e definições de zona.
Construtores de localização e vetor
| Função | Notas |
|---|
em.create_location(x, y, z[, world][, yaw][, pitch]) | Retorna uma tabela de localização com um método add(dx, dy, dz) |
em.create_vector(x, y, z) | Retorna uma tabela de vetor |
Helpers de construtor de zonas
A sub-tabela em.zone fornece funções construtoras que retornam tabelas de definição de zona compatíveis com context.zones. Cada construtor retorna uma tabela com métodos mutadores encadeáveis.
| Função | Parâmetros | Mutadores |
|---|
em.zone.create_sphere_zone(radius) | radius | :set_center(location) |
em.zone.create_dome_zone(radius) | radius | :set_center(location) |
em.zone.create_cylinder_zone(radius, height) | radius, height | :set_center(location) |
em.zone.create_cuboid_zone(x, y, z) | x, y, z (semi-extensões) | :set_center(location) |
em.zone.create_cone_zone(length, radius) | length, radius | :set_origin(location), :set_destination(location) |
em.zone.create_static_ray_zone(length, thickness) | length, thickness | :set_origin(location), :set_destination(location) |
em.zone.create_rotating_ray_zone(length, point_radius, animation_duration) | length, point_radius, animation_duration | :set_origin(location), :set_destination(location) |
em.zone.create_translating_ray_zone(length, point_radius, animation_duration) | length, point_radius, animation_duration | :set_origin(location), :set_destination(location) |
Exemplo
Exemplo
return {
api_version = 1,
on_spawn = function(context)
-- Create a location offset from the boss
local boss_loc = context.boss:get_location()
local above = em.create_location(boss_loc.x, boss_loc.y + 5, boss_loc.z)
-- Create a sphere zone using the builder
local zone = em.zone.create_sphere_zone(10):set_center(boss_loc)
-- Use with native zone queries
local players = context.zones:get_entities_in_zone(zone, { filter = "players" })
for _, p in ipairs(players) do
p:send_message("&cYou are within the boss's aura!")
end
-- Create a directional vector
local push_vec = em.create_vector(0, 1.5, 0)
context.boss:set_velocity_vector(push_vec)
end
}
O namespace em não é por instância -- todas as instâncias de poder Lua compartilham as mesmas funções auxiliares em. As funções são construtores puros e não carregam nenhum estado.
Zonas nativas vs. Utilitários de script
Ambos os sistemas trabalham com a mesma geometria de zona subjacente. Aqui está quando usar cada um:
| Caso de uso | Abordagem recomendada |
|---|
| Verificação simples de "há algo nesta área?" | Zonas nativas (context.zones) |
| Consulta rápida de entidades com uma forma | Zonas nativas |
NEARBY_PLAYERS, ZONE_FULL com coverage | Utilitários de script (context.script) |
| Zonas animadas (raios rotativos/em translação) | Ambos -- as zonas nativas também suportam estas formas |
Handles de zona com métodos watch/contains/entities | Utilitários de script |
| Geração de partículas em localizações de zona | Utilitários de script (spawn_particles) |
| Ações de dano e empurrão vinculadas a alvos | Utilitários de script (damage, push) |
| Vetores relativos para efeitos direcionais | Utilitários de script (relative_vector) |
| Combinar fluxo de controle Lua com segmentação avançada | Utilitários de script |
Na prática, muitos poderes usam ambos. As zonas nativas são ótimas para a verificação inicial de "há jogadores por perto?" em um guard de cooldown, enquanto os utilitários de script lidam com a lógica de ataque complexa que se segue.
Próximos passos