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 permiten definir zonas como tablas Lua simples y consultarlas directamente. Sin handles, sin abstracción adicional -- solo una tabla que describe una forma y una llamada a método para consultarla.

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

CampoTipoNotas
kindstring"sphere", "dome", "cylinder", "cuboid", "cone", "static_ray", "rotating_ray", "translating_ray"
radiusnumberRadio de la zona (sphere, dome, cylinder, cone)
heightnumberAltura del cilindro
originlocationUbicación central (por defecto la ubicación del boss si se omite)
destinationlocationPunto final para rayos y conos
x, y, znumberSemi-extensiones del cuboide
lengthnumberLongitud para conos y rayos
thickness / point_radiusnumberGrosor del rayo
border_radiusnumberAncho del borde (por defecto 1)
x_border, y_border, z_bordernumberAnchos de borde del cuboide (por defecto 1)
animation_durationintDuración de la animación en ticks para rayos animados
pitch_pre_rotation, yaw_pre_rotationnumberÁngulos de pre-rotación (rayo rotatorio)
pitch_rotation, yaw_rotationnumberÁngulos de rotación por tick (rayo rotatorio)
origin_end, destination_endlocationPosiciones finales para rayo en traslación
ignores_solid_blocksbooleanSi los rayos atraviesan bloques sólidos (por defecto true)

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)

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 se limpian automáticamente cuando el boss es eliminado
  • 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

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. Usan los mismos nombres de campo que las Zonas de EliteScript y los Objetivos de EliteScript para mayor familiaridad -- los nombres de enum (como "NEARBY_PLAYERS", "SPHERE", "ZONE_FULL") son idénticos para que los autores que ya están familiarizados con EliteScript puedan transferir ese conocimiento directamente.

info

context.script es una API nativa de Lua. No es un puente hacia YAML o hacia el runtime de EliteScript. Simplemente reutiliza las mismas convenciones de nombres para que no tenga que aprender un segundo conjunto de nombres de enum.

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

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

Claves de especificación de objetivo

ClaveNotas
targetType"SELF", "DIRECT_TARGET", "NEARBY_PLAYERS", "NEARBY_MOBS", "NEARBY_ELITES", "ZONE_FULL", "ZONE_BORDER", "ALL_PLAYERS", "WORLD_PLAYERS", "SELF_SPAWN", "LOCATION"
rangeAlcance para tipos de objetivo cercanos
coverage0.0 a 1.0 para objetivos de zona
offsetCadena "x,y,z" o tabla { x = n, y = n, z = n }
trackSi se deben volver a resolver los objetivos en movimiento

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

ClaveNotas
shape"SPHERE", "DOME", "CYLINDER", "CUBOID", "CONE", "STATIC_RAY", "ROTATING_RAY", "TRANSLATING_RAY"
radiusRadio de la zona
heightAltura del cilindro
x, y, zSemi-extensiones del cuboide
borderRadiusAncho del borde
pointRadiusGrosor del rayo
animationDurationDuración de la animación en ticks para rayos animados
TargetEspecificación de objetivo central (tabla) -- usa el mismo formato de especificación de objetivo
Target2Segundo punto para rayos y conos
filterFiltro de entidad
ignoresSolidBlocksboolean
pitchPreRotation, yawPreRotationÁngulos de pre-rotación
pitchRotation, yawRotationÁngulos de rotación por tick

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

Claves de especificación de vector relativo

ClaveNotas
SourceTargetEspecificación del objetivo de origen (tabla)
DestinationTargetEspecificación del objetivo de destino (tabla)
normalizeboolean -- si se debe normalizar el vector resultante
multiplierFactor de escala aplicado después de la normalización
offsetCadena "x,y,z" o tabla { x = n, y = n, z = n }

Métodos del handle de vector relativo

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

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:

ClaveNotas
particleNombre de partícula (ej. "FLAME", "DUST", "SMOKE")
amountNúmero de partículas
x, y, zValores de offset/dispersión
speedVelocidad de partículas
red, green, blueColor para DUST / DUST_COLOR_TRANSITION (0-255)
toRed, toGreen, toBlueColor de destino de transición para DUST_COLOR_TRANSITION

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.
  • watch() de zona devuelve un ID de tarea que puede cancelar con context.scheduler:cancel_task().
  • Los valores de coverage solo se aplican a la resolución basada en ubicaciones, no a consultas de entidades.
  • Todos los valores de cadena usan los mismos nombres de enum en UPPER_SNAKE_CASE que EliteScript YAML (ej. "SELF", "NEARBY_PLAYERS", "SPHERE").

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 (semi-extensiones):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)

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)

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

El espacio de nombres em no es por instancia -- todas las instancias de poder Lua comparten las mismas funciones auxiliares de em. Las funciones son constructores puros y no mantienen ningún estado.


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)Ambos -- las zonas nativas también soportan estas formas
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

En la práctica, muchos poderes usan ambos. Las zonas nativas son excelentes para la verificación inicial de "¿hay jugadores cerca?" en un guard de cooldown, mientras que las utilidades de script manejan la lógica de ataque compleja que sigue.


Próximos pasos