Saltar al contenido principal

Scripting Lua: Zonas y Objetivos

webapp_banner.jpg

Las funciones Lua de EliteMobs ofrecen dos enfoques complementarios para definir áreas espaciales y resolver objetivos:

  • Zonas nativas (context.zones) -- simples y directas. Se construye una definición de zona como una tabla Lua simple y se consulta para obtener entidades o ubicaciones. Ideal para verificaciones directas de "¿hay algo en esta área?".
  • Utilidades de script (context.script) -- selección de objetivos más completa, handles de zona con métodos watch/contains/entities, generación de partículas, daño y acciones de empuje. Usa los mismos nombres de campo que las Zonas de EliteScript y los Objetivos de EliteScript para mayor familiaridad.

Ambos enfoques son APIs nativas de Lua. Elija el que se ajuste a la complejidad de su poder.


Zonas nativas: context.zones​

Las zonas nativas aceptan tablas Lua simples. Cada consulta crea una forma nueva; un observador conserva una sola forma. Consultar repetidamente un rayo animado reinicia la animación en vez de consultar la forma actual del observador. Utilice un handle de zona de script cuando varias operaciones necesiten la misma forma animada.

Métodos​

MétodoNotas
zones:get_entities_in_zone(zoneDef[, options])Devuelve un array de wrappers de entidad dentro de la zona
zones:get_locations_in_zone(zoneDef[, options])Devuelve un array de tablas de ubicación dentro de la zona
zones:zone_contains(zoneDef, location[, "full"|"border"])Devuelve true si la ubicación está dentro de la zona
zones:watch_zone(zoneDef, callbacks[, options])Registra un observador de zona persistente que se ejecuta cada tick

Campos de definición de zona​

CampoTipoPredeterminadoNotas
kind (o type)string—"sphere", "dome", "cylinder", "cuboid", "cone", "static_ray", "rotating_ray", "translating_ray"
radiusnumber0Radio de la zona (sphere, dome, cylinder, cone)
heightnumber0Altura del cilindro
originlocationubicación del bossOrigen: base del cilindro, vértice del cono o inicio del rayo
destinationlocationubicación del bossPunto final para rayos y conos
x, y, znumber0Dimensiones del cuboide; consulte la limitación de geometría de puntos y entidades
thickness / point_radius / pointRadiusnumber0.5Radio y separación de las muestras del rayo; debe ser positivo
border_radius / borderRadiusnumber1Radio interior que se excluye de la forma exterior
x_border, y_border, z_bordernumber1Dimensiones interiores del cuboide
animation_durationint0Duración de la animación en ticks para rayos animados
pitch_pre_rotation, yaw_pre_rotationnumber0Ángulos de pre-rotación (rayo rotatorio)
pitch_rotation, yaw_rotationnumber0Rotación total durante la animación; el animador actual solo aplica incrementos positivos
origin_end, destination_endlocationubicación del bossPosiciones finales para rayo en traslación
ignores_solid_blocksbooleantrueSi los rayos atraviesan bloques sólidos
lengthnumber0Los constructores lo guardan, pero omitir destination devuelve la ubicación del boss antes de usar este valor; indique un destino explícito

Los campos numéricos y booleanos con guiones bajos también aceptan camelCase (borderRadius, xBorder, animationDuration, pitchPreRotation, ignoresSolidBlocks). Los campos de ubicación origin_end y destination_end requieren sus nombres con guiones bajos. Las tablas Target de EliteScript no sustituyen los campos de ubicación nativos.

kind distingue mayúsculas y minúsculas

kind se compara de forma exacta y debe ir en minúsculas. "SPHERE" o "Sphere" no coinciden con nada: las consultas devuelven una lista vacía sin advertencia en consola.

Indique extremos explícitos para conos y rayos

Si se omite origin o destination, se usa la ubicación actual del boss. El resolvedor de ubicaciones impide que length sustituya un destino omitido. Indique extremos distintos:

local explicit_ray = { kind = "static_ray", origin = context.boss:get_eye_location(),
destination = context.player:get_eye_location() }

Para animar un rayo en traslación, indique origin_end, destination_end y un animation_duration positivo. Un extremo final omitido permanece en su posición inicial. Una duración de cero crea el rayo inicial estático; una duración negativa se rechaza. El último fotograma de la animación termina exactamente en los extremos solicitados.

Mantenga todos los extremos y ubicaciones consultadas en el mundo actual del boss: las consultas nativas de entidades buscan en ese mundo. En una tabla de ubicación, las coordenadas omitidas valen 0; omitir el mundo usa el del boss, pero un nombre de mundo explícito debe estar cargado. Las dimensiones deben ser finitas y positivas. Las pruebas de puntos, muestras de partículas y pruebas de entidades no son equivalentes; las limitaciones de las formas incluyen pruebas esféricas de entidades en domos completos, comprobación de toda la altura de la entidad en cilindros y límites diferentes en cuboides.

Opciones de consulta​

ClaveNotas
filter"player" / "players", "elite" / "elites", "mob" / "mobs", "living" (por defecto)
mode"full" (por defecto) o "border"
coverage0.0 a 1.0 -- fracción de ubicaciones a muestrear (por defecto 1.0)

filter no distingue mayúsculas; los valores desconocidos usan living. mobs incluye entidades vivas que no sean jugadores, también elites. Se excluye al boss, pero no se filtran jugadores por modo de juego. mode reconoce border sin distinguir mayúsculas; otros valores usan full. Coverage muestrea ubicaciones aleatoriamente, no entidades, y no limita los miembros del observador. Use full para rayos: sus ubicaciones de borde no están implementadas y pueden hacer fallar una consulta de ubicaciones.

Callbacks de observación​

ClaveNotas
on_enterfunction(entity) -- se llama cuando una entidad entra en la zona
on_leavefunction(entity) -- se llama cuando una entidad sale de la zona

Ejemplo: consulta básica de esfera​

Ejemplo
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
}

Ejemplo: observación de zona con entrada/salida​

Ejemplo
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:

  • Los callbacks de observadores reciben directamente un wrapper de entidad individual, no a través de context.event
  • Los observadores llaman a sus propios callbacks on_enter / on_leave; no ejecutan los hooks principales on_zone_enter / on_zone_leave del poder
  • Los observadores se limpian automáticamente cuando el boss es eliminado
  • Un observador nativo construye su forma una sola vez. Su centro no sigue al boss, y editar la tabla original no mueve un observador existente. Use consultas nuevas o una zona de script con un objetivo que siga el movimiento.
  • Cada observador se ejecuta cada tick, así que mantenga la lógica del callback ligera
  • La entidad del boss está excluida de las consultas de zona

La primera comprobación ocurre un tick después; las entidades que ya estén dentro activan on_enter. Cancelar o limpiar el observador no envía on_leave a los miembros restantes. En este ejemplo la esfera permanece en la posición de aparición. La lentitud dura 40 ticks desde la entrada; permanecer dentro no la renueva y salir no la elimina antes.


Utilidades de script: context.script​

Las utilidades de script proporcionan resolución de objetivos, handles de zona, vectores relativos, generación de partículas y acciones de combate.

context.script ejecuta el motor de EliteScript

La tabla de especificación se convierte en un mapa Java y se pasa a las clases de objetivos, zonas, vectores relativos y partículas que usan los EliteScripts YAML.

Lo que eso significa en la práctica:

  • Las tablas usan los analizadores documentados en Objetivos de EliteScript, Zonas de EliteScript y Vectores relativos de EliteScript, con sus limitaciones actuales. Aceptar un campo no garantiza que el handle Lua tenga el ciclo de vida de la acción o el contexto heredado necesarios.
  • Los valores de enum son exactamente UPPER_SNAKE_CASE ("NEARBY_PLAYERS", "SPHERE", "ZONE_FULL"), igual que en YAML.
  • Use los nombres YAML canónicos mostrados aquí: Target, Target2, targetType, borderRadius. Sus lectores internos no distinguen mayúsculas.
  • Los valores no válidos pueden provocar advertencias, valores de respaldo o campos ausentes que fallen después. Aceptar la tabla no valida la operación completa.

context.zones tiene un lector de tablas separado con nombres kind en minúsculas, pero usa las mismas clases geométricas. Proporcione tablas no vacías con campos nombrados: un {} Lua vacío se convierte en una lista Java, por lo que incluso script:target({}) falla. Use script:target({targetType = "SELF"}).

Métodos​

MétodoNotas
script:target(spec)Crea un handle de objetivo a partir de una tabla de especificación de objetivo
script:zone(spec)Crea un handle de zona a partir de una tabla de especificación de zona
script:relative_vector(spec[, actionLocation][, zoneHandle])Crea un handle de vector relativo
script:damage(targetHandle, amount[, multiplier])Inflige daño a los objetivos resueltos
script:push(targetHandle, vectorOrHandle[, additive])Empuja los objetivos resueltos
script:set_facing(targetHandle, vectorOrHandle)Establece la dirección de orientación de los objetivos
script:spawn_particles(targetHandle, particleSpec)Genera partículas en las ubicaciones de los objetivos resueltos

damage, push, set_facing y spawn_particles requieren un handle de objetivo, no un array de entidades, y no devuelven ningún resultado. No aplican condiciones, esperas ni filtros de acciones YAML. damage envía la cantidad a Bukkit con el boss como atacante; el multiplicador opcional se aplica al combate contra jugadores, y la pérdida final de salud depende del procesamiento del combate. push resuelve ahora los objetivos y un vector, y aplica ese vector a todos el siguiente tick. Sustituye la velocidad salvo con additive = true, que la suma a la velocidad de ese tick. set_facing aplica inmediatamente una dirección a todos. Compruebe que las direcciones no sean cero ni no finitas.

Métodos del handle de objetivo​

MétodoNotas
handle:entities()Devuelve array de wrappers de entidad
handle:locations()Devuelve array de tablas de ubicación
handle:first_entity()Devuelve la primera entidad o nil
handle:first_location()Devuelve la primera ubicación o nil

Cada método resuelve de nuevo; first_* no consulta una instantánea compartida ni garantiza el resultado más cercano. DIRECT_TARGET es el objetivo capturado por el evento, no el objetivo de combate actual del boss, y no selecciona nada si el evento no proporciona ninguno.

Claves de especificación de objetivo​

ClavePredeterminadoNotas
targetType"SELF"Cualquier tipo de objetivo de EliteScript
range20Semiancho de cada eje de la caja de búsqueda de objetivos cercanos; no se ordenan por distancia
coverage1.0De 0.0 a 1.0. Solo se respeta en objetivos de zona; los valores inferiores a 1.0 en otros tipos se restablecen a 1.0 con una advertencia
offset0,0,0Cadena "x,y,z" separada por comas; este campo EliteScript no admite una tabla vectorial Lua
relativeOffsetningunoEspecificación de vector relativo; sus objetivos de origen y destino determinan la dirección
locationningunoCadena serializada "world,x,y,z,yaw,pitch", para "LOCATION"
locationsningunoArray de cadenas de ubicación serializadas, para "LOCATIONS"
tracktrueSi se deben volver a resolver los objetivos en movimiento

La vía Lua no ejecuta el almacenamiento de objetivos de las acciones YAML. Por eso track = false no fija la ubicación de un objetivo o zona Lua estáticos. Las zonas estáticas resuelven su origen en cada consulta; las animadas conservan sus formas al crearse. Para una zona fija, use LOCATION con coordenadas explícitas o una zona nativa con origin capturado. offset y relativeOffset desplazan todas las ubicaciones que resuelve un handle, incluidas LOCATION, LOCATIONS, SELF_SPAWN, los objetivos basados en entidades y las ubicaciones de zona muestreadas; no mueven las entidades devueltas por entities(), y LANDING_LOCATION e INHERIT_SCRIPT_TARGET los ignoran. full_target() y border_target() de un handle de zona no admiten desplazamiento, así que ponga los desplazamientos en las especificaciones Target y Target2 de la zona. Consulte los atributos compartidos.

El analizador acepta los 17 nombres: SELF, SELF_SPAWN, DIRECT_TARGET, NEARBY_PLAYERS, NEARBY_MOBS, NEARBY_ELITES, WORLD_PLAYERS, ALL_PLAYERS, LOCATION, LOCATIONS, ZONE_FULL, ZONE_BORDER, LANDING_LOCATION, ACTION_TARGET, INHERIT_SCRIPT_TARGET, INHERIT_SCRIPT_ZONE_FULL, INHERIT_SCRIPT_ZONE_BORDER. Los handles Lua independientes no tienen datos de acción heredados ni ubicación de aterrizaje. Evite INHERIT_* y LANDING_LOCATION: pueden fallar al resolverse. ACTION_TARGET solo tiene sentido en un contexto compatible de vector relativo o acción. Consulte las limitaciones de zonas heredadas.

Para ZONE_FULL y ZONE_BORDER, obtenga el objetivo desde un handle de zona; script:target(...) por sí solo no tiene zona. Las funciones Lua de partículas mantienen coverage en 1.0 por defecto; no aplican el 0.3 predeterminado de la acción YAML SPAWN_PARTICLE.

Ejemplo: crear y usar un objetivo​

Ejemplo
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 along each axis
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

-- First resolved entity; this does not promise the nearest player.
local first = nearby:first_entity()
if first then
first:show_title("&cRUN!", "&7The boss is targeting you")
end
end
}

Métodos del handle de zona​

MétodoNotas
handle:full_target([coverage])Devuelve un handle de objetivo para el volumen completo de la zona
handle:border_target([coverage])Devuelve un handle de objetivo para el borde de la zona
handle:full_locations([coverage])Devuelve ubicaciones en el volumen completo de la zona
handle:border_locations([coverage])Devuelve ubicaciones en el borde de la zona
handle:full_entities()Devuelve entidades en el volumen completo de la zona
handle:border_entities()Devuelve entidades en el borde de la zona
handle:contains(location[, "full"|"border"])Devuelve true si la ubicación está dentro de la zona
handle:watch(callbacks[, mode])Observa la zona para eventos de entrada/salida, devuelve ID de tarea

Claves de especificación de zona​

ClavePredeterminadoNotas
shape"CYLINDER""SPHERE", "DOME", "CYLINDER", "CUBOID", "CONE", "STATIC_RAY", "ROTATING_RAY", "TRANSLATING_RAY"
radius5Esfera, domo, cilindro, cono
height1Solo cilindro; en consultas de entidades debe caber toda su altura
x, y, z0Dimensiones del cuboide; consulte la limitación de geometría de puntos y entidades
xBorder, yBorder, zBorder0Dimensiones interiores del cuboide
borderRadius1Radio interior para esfera, domo, cilindro o cono
pointRadius0.5Radio y separación positivos de las muestras del rayo
animationDuration0Duración de la animación en ticks para rayos animados
Target{targetType = "SELF"}Especificación de objetivo central (tabla) -- usa el mismo formato de especificación de objetivo
Target2ningunoSegundo punto. Obligatorio para conos y todas las formas de rayo
FinalTarget, FinalTarget2ningunoPosiciones finales, solo para el rayo en traslación
filter"PLAYER""PLAYER", "ELITE", "LIVING" -- ten en cuenta que aquí van en MAYÚSCULAS, a diferencia de context.zones
ignoresSolidBlockstrueSolo rayos
pitchPreRotation, yawPreRotation0Solo rayo rotatorio
pitchRotation, yawRotation0Solo rayo rotatorio

Las claves que no se aplican a la shape elegida se leen sin dar error y luego se ignoran: un height en una esfera no hace nada.

contains comprueba un punto, no la caja de la entidad. watch usa los mismos callbacks y primera comprobación que los observadores nativos. Cancele el ID devuelto con context.scheduler:cancel_task(id); cancelar no genera callbacks de salida. Una zona de script estática puede seguir a SELF al resolverse cada tick; un handle animado conserva sus formas. borderRadius es el radio interior, no el grosor del borde. Use objetivos completos para rayos.

Ejemplo: zona con daño y partículas​

Ejemplo
return {
api_version = 1,
on_enter_combat = function(context)
-- Create a sphere zone centered on the boss
if context.state.zone_task_id ~= nil then return end
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)

-- First repeat after 20 ticks, then every 20 ticks.
context.state.zone_task_id = context.scheduler:run_repeating(20, 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,
on_exit_combat = function(context)
if context.state.zone_task_id ~= nil then
context.scheduler:cancel_task(context.state.zone_task_id)
context.state.zone_task_id = nil
end
end
}

Este ejemplo daña a los jugadores al mostrar las partículas; no hay una espera de advertencia. Las repeticiones empiezan a los 20 ticks y terminan al salir del combate. El radio interior predeterminado de 1 produce una capa gruesa dentro del radio 6, no un anillo fino.

Claves de especificación de vector relativo​

ClaveNotas
SourceTargetEspecificación del objetivo de origen (tabla)
DestinationTargetEspecificación del objetivo de destino (tabla)
normalizeBooleano, por defecto false; indica si se normaliza el vector
multiplierFactor aplicado después de normalizar, por defecto 1
offsetCadena "x,y,z" separada por comas, por defecto "0,0,0"; no una tabla vectorial Lua

Métodos del handle de vector relativo​

MétodoNotas
handle:resolve()Devuelve la tabla del vector calculado

Indique ambas especificaciones de objetivo. Se usa la primera ubicación de cada una: destino menos origen, normalización opcional, multiplicación y después offset en los ejes del mundo. Los resultados vacíos o en mundos distintos devuelven cero antes del offset; normalizar puntos coincidentes puede producir un vector no finito. ACTION_TARGET usa actionLocation, cuyo valor predeterminado es la ubicación del boss al crear el handle. No se sustituye por cada entidad empujada. Pase un handle de zona como tercer argumento si los objetivos del vector necesitan esa zona.

Ejemplo: empujar objetivos con un vector relativo​

Ejemplo
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
}

Formato de especificación de partículas​

Las especificaciones de partículas pueden ser una cadena, una tabla individual o un array de tablas. Como esta vía ejecuta el motor de partículas de EliteScript, las claves son las de EliteScript documentadas en SPAWN_PARTICLE:

ClavePredeterminadoNotas
particle"FLAME"Nombre de partícula (ej. "FLAME", "DUST", "SMOKE")
amount1Número de partículas. Con 0, el comportamiento direccional depende del tipo de partícula
x, y, z0.01Valores de offset/dispersión, o velocidad cuando amount es 0
speed0.01Velocidad de partículas
red, green, blue255Color de DUST, DUST_COLOR_TRANSITION y partículas que requieren datos Color (0-255); WITCH no usa estos valores
toRed, toGreen, toBlue255Color de destino de transición para DUST_COLOR_TRANSITION
material"STONE"Bloque u objeto mostrado por las partículas que llevan datos de bloque/objeto (BLOCK, ITEM, FALLING_DUST, ...)
relativeVectorningunoUna especificación de vector relativo. Establecerlo fuerza amount a 0 y sobrescribe x/y/z con la dirección resuelta

El tamaño del polvo está fijado en 1. moveToTarget se lee, pero no mueve partículas. Los tipos de datos de partículas no admitidos se omiten con una advertencia. La función desplaza las partículas de zonas y LOCATION / LOCATIONS en +0.5 sobre X y Z; las ubicaciones devueltas por los handles no tienen ese desplazamiento.

Dos conjuntos de claves de partículas distintos

Estas claves de EliteScript no son las mismas que acepta context.world:spawn_particle_at_location(loc, spec). La tabla world tiene su propio lector, más reducido y con valores predeterminados distintos (amount 1, x/y/z/speed 0), sin material ni relativeVector, y además acepta to_red / to_green / to_blue en snake_case. Consulta Mundo y entorno.

Para la lista completa de nombres de partículas, consulte la Referencia de Enums.

Advertencias importantes​

  • Los handles de utilidades de script están vinculados al contexto del evento en el que fueron creados. No los almacene en context.state para usarlos en una llamada posterior a un hook.
  • context.script:zone(...):watch(...) devuelve un ID cancelable con context.scheduler:cancel_task(). context.zones:watch_zone(...) no devuelve nada y se limpia automáticamente con el poder.
  • Los valores de coverage solo se aplican a la resolución basada en ubicaciones, no a consultas de entidades.
  • Los enums de objetivos, formas y filtros usan los mismos nombres UPPER_SNAKE_CASE que EliteScript YAML (ej. "SELF", "NEARBY_PLAYERS", "SPHERE"). Los modos de watch/contains siguen siendo "full" o "border".

Espacio de nombres auxiliar em​

El espacio de nombres em está disponible globalmente en todos los archivos de poder Lua. Proporciona constructores convenientes para ubicaciones, vectores y definiciones de zona.

Constructores de ubicación y vector​

FunciónNotas
em.create_location(x, y, z[, world][, yaw][, pitch])Devuelve una tabla de ubicación con un método add(dx, dy, dz)
em.create_vector(x, y, z)Devuelve una tabla de vector

Helpers de constructor de zonas​

La sub-tabla em.zone proporciona funciones constructoras que devuelven tablas de definición de zona compatibles con context.zones. Cada constructor devuelve una tabla con métodos mutadores encadenables.

FunciónParámetrosMutadores
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 (dimensiones del cuboide):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)
Defina ambos extremos

Los constructores de conos y rayos guardan length, pero el resolvedor nativo usa la ubicación del boss si se omite el destino. Encadene :set_origin(...) y :set_destination(...); no dependa de length para orientar la forma. Los rayos en traslación requieren además origin_end, destination_end y un animation_duration positivo en la tabla devuelta.

Ejemplo​

Ejemplo
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, boss_loc.world)

-- 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
}
información

Cada instancia de script tiene su propio entorno Lua y espacio de nombres em. Los constructores devuelven tablas nuevas; add(...) y los setters de zona modifican la tabla sobre la que se llaman.


Zonas nativas vs. Utilidades de script​

Ambos sistemas trabajan con la misma geometría de zona subyacente. Aquí se indica cuándo usar cada uno:

Caso de usoEnfoque recomendado
Verificación simple de "¿hay algo en esta área?"Zonas nativas (context.zones)
Consulta rápida de entidades con una formaZonas nativas
NEARBY_PLAYERS, ZONE_FULL con coverageUtilidades de script (context.script)
Zonas animadas (rayos rotatorios/en traslación)Handles de zona de script para consultas repetidas; los observadores nativos también conservan una forma animada
Handles de zona con métodos watch/contains/entitiesUtilidades de script
Generación de partículas en ubicaciones de zonaUtilidades de script (spawn_particles)
Acciones de daño y empuje vinculadas a objetivosUtilidades de script (damage, push)
Vectores relativos para efectos direccionalesUtilidades de script (relative_vector)
Combinación de flujo de control Lua con selección de objetivos avanzadaUtilidades de script

Ambas APIs pueden usarse en un poder. Elija según los objetivos y ciclo de vida necesarios: las consultas nativas incluyen por defecto entidades vivas excepto el boss; las zonas de script incluyen jugadores.


Próximos pasos​