Scripting Lua: Zonas y Objetivos
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étodo | Notas |
|---|---|
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
| Campo | Tipo | Predeterminado | Notas |
|---|---|---|---|
kind (o type) | string | — | "sphere", "dome", "cylinder", "cuboid", "cone", "static_ray", "rotating_ray", "translating_ray" |
radius | number | 0 | Radio de la zona (sphere, dome, cylinder, cone) |
height | number | 0 | Altura del cilindro |
origin | location | ubicación del boss | Origen: base del cilindro, vértice del cono o inicio del rayo |
destination | location | ubicación del boss | Punto final para rayos y conos |
x, y, z | number | 0 | Dimensiones del cuboide; consulte la limitación de geometría de puntos y entidades |
thickness / point_radius / pointRadius | number | 0.5 | Radio y separación de las muestras del rayo; debe ser positivo |
border_radius / borderRadius | number | 1 | Radio interior que se excluye de la forma exterior |
x_border, y_border, z_border | number | 1 | Dimensiones interiores del cuboide |
animation_duration | int | 0 | Duración de la animación en ticks para rayos animados |
pitch_pre_rotation, yaw_pre_rotation | number | 0 | Ángulos de pre-rotación (rayo rotatorio) |
pitch_rotation, yaw_rotation | number | 0 | Rotación total durante la animación; el animador actual solo aplica incrementos positivos |
origin_end, destination_end | location | ubicación del boss | Posiciones finales para rayo en traslación |
ignores_solid_blocks | boolean | true | Si los rayos atraviesan bloques sólidos |
length | number | 0 | Los 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úsculaskind 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.
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
| Clave | Notas |
|---|---|
filter | "player" / "players", "elite" / "elites", "mob" / "mobs", "living" (por defecto) |
mode | "full" (por defecto) o "border" |
coverage | 0.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
| Clave | Notas |
|---|---|
on_enter | function(entity) -- se llama cuando una entidad entra en la zona |
on_leave | function(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 principaleson_zone_enter/on_zone_leavedel 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 EliteScriptLa 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étodo | Notas |
|---|---|
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étodo | Notas |
|---|---|
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
| Clave | Predeterminado | Notas |
|---|---|---|
targetType | "SELF" | Cualquier tipo de objetivo de EliteScript |
range | 20 | Semiancho de cada eje de la caja de búsqueda de objetivos cercanos; no se ordenan por distancia |
coverage | 1.0 | De 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 |
offset | 0,0,0 | Cadena "x,y,z" separada por comas; este campo EliteScript no admite una tabla vectorial Lua |
relativeOffset | ninguno | Especificación de vector relativo; sus objetivos de origen y destino determinan la dirección |
location | ninguno | Cadena serializada "world,x,y,z,yaw,pitch", para "LOCATION" |
locations | ninguno | Array de cadenas de ubicación serializadas, para "LOCATIONS" |
track | true | Si 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étodo | Notas |
|---|---|
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
| Clave | Predeterminado | Notas |
|---|---|---|
shape | "CYLINDER" | "SPHERE", "DOME", "CYLINDER", "CUBOID", "CONE", "STATIC_RAY", "ROTATING_RAY", "TRANSLATING_RAY" |
radius | 5 | Esfera, domo, cilindro, cono |
height | 1 | Solo cilindro; en consultas de entidades debe caber toda su altura |
x, y, z | 0 | Dimensiones del cuboide; consulte la limitación de geometría de puntos y entidades |
xBorder, yBorder, zBorder | 0 | Dimensiones interiores del cuboide |
borderRadius | 1 | Radio interior para esfera, domo, cilindro o cono |
pointRadius | 0.5 | Radio y separación positivos de las muestras del rayo |
animationDuration | 0 | Duració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 |
Target2 | ninguno | Segundo punto. Obligatorio para conos y todas las formas de rayo |
FinalTarget, FinalTarget2 | ninguno | Posiciones 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 |
ignoresSolidBlocks | true | Solo rayos |
pitchPreRotation, yawPreRotation | 0 | Solo rayo rotatorio |
pitchRotation, yawRotation | 0 | Solo 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
| Clave | Notas |
|---|---|
SourceTarget | Especificación del objetivo de origen (tabla) |
DestinationTarget | Especificación del objetivo de destino (tabla) |
normalize | Booleano, por defecto false; indica si se normaliza el vector |
multiplier | Factor aplicado después de normalizar, por defecto 1 |
offset | Cadena "x,y,z" separada por comas, por defecto "0,0,0"; no una tabla vectorial Lua |
Métodos del handle de vector relativo
| Método | Notas |
|---|---|
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:
| Clave | Predeterminado | Notas |
|---|---|---|
particle | "FLAME" | Nombre de partícula (ej. "FLAME", "DUST", "SMOKE") |
amount | 1 | Número de partículas. Con 0, el comportamiento direccional depende del tipo de partícula |
x, y, z | 0.01 | Valores de offset/dispersión, o velocidad cuando amount es 0 |
speed | 0.01 | Velocidad de partículas |
red, green, blue | 255 | Color de DUST, DUST_COLOR_TRANSITION y partículas que requieren datos Color (0-255); WITCH no usa estos valores |
toRed, toGreen, toBlue | 255 | Color 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, ...) |
relativeVector | ninguno | Una 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.
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.statepara usarlos en una llamada posterior a un hook. context.script:zone(...):watch(...)devuelve un ID cancelable concontext.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ón | Notas |
|---|---|
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ón | 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 (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) |
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
}
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 uso | Enfoque recomendado |
|---|---|
| Verificación simple de "¿hay algo en esta área?" | Zonas nativas (context.zones) |
| Consulta rápida de entidades con una forma | Zonas nativas |
NEARBY_PLAYERS, ZONE_FULL con coverage | Utilidades 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/entities | Utilidades de script |
| Generación de partículas en ubicaciones de zona | Utilidades de script (spawn_particles) |
| Acciones de daño y empuje vinculadas a objetivos | Utilidades de script (damage, push) |
| Vectores relativos para efectos direccionales | Utilidades de script (relative_vector) |
| Combinación de flujo de control Lua con selección de objetivos avanzada | Utilidades 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
- Ejemplos y Patrones -- poderes funcionales completos que puede estudiar y adaptar
- Scripts de NPC -- hooks de proximidad de NPC para entrada y salida simples
- Referencia de Enums -- valores válidos para Particle, Sound, Material y otras constantes de cadena
