Aller au contenu principal

Script Lua : Zones et ciblage

webapp_banner.jpg

Les fonctions Lua d'EliteMobs offrent deux approches complémentaires pour définir des zones spatiales et résoudre des cibles :

  • Zones natives (context.zones) -- simples et directes. Vous construisez une définition de zone sous forme de table Lua simple et l'interrogez pour obtenir des entités ou des emplacements. Idéal pour les vérifications simples de type « y a-t-il quelque chose dans cette zone ? ».
  • Utilitaires de script (context.script) -- ciblage plus riche, handles de zone avec les méthodes watch/contains/entities, génération de particules, dégâts et actions de poussée. Utilise les mêmes noms de champs que les Zones EliteScript et les Cibles EliteScript pour une plus grande familiarité.

Les deux approches sont des API Lua natives. Choisissez celle qui correspond à la complexité de votre pouvoir.


Zones natives : context.zones

Les zones natives vous permettent de définir des zones sous forme de tables Lua simples et de les interroger directement. Pas de handles, pas d'abstraction supplémentaire -- juste une table décrivant une forme et un appel de méthode pour l'interroger.

Méthodes

MéthodeNotes
zones:get_entities_in_zone(zoneDef, options)Retourne un tableau de wrappers d'entité à l'intérieur de la zone
zones:get_locations_in_zone(zoneDef, options)Retourne un tableau de tables d'emplacement à l'intérieur de la zone
zones:zone_contains(zoneDef, location[, "full"|"border"])Retourne true si l'emplacement est à l'intérieur de la zone
zones:watch_zone(zoneDef, callbacks, options)Enregistre un observateur de zone persistant qui se déclenche à chaque tick

Champs de définition de zone

ChampTypeNotes
kindstring"sphere", "dome", "cylinder", "cuboid", "cone", "static_ray", "rotating_ray", "translating_ray"
radiusnumberRayon de la zone (sphere, dome, cylinder, cone)
heightnumberHauteur du cylindre
originlocationEmplacement central (par défaut l'emplacement du boss si omis)
destinationlocationPoint final pour les rayons et les cônes
x, y, znumberDemi-extensions du cuboïde
lengthnumberLongueur pour les cônes et les rayons
thickness / point_radiusnumberÉpaisseur du rayon
border_radiusnumberLargeur de la bordure (par défaut 1)
x_border, y_border, z_bordernumberLargeurs de bordure du cuboïde (par défaut 1)
animation_durationintDurée de l'animation en ticks pour les rayons animés
pitch_pre_rotation, yaw_pre_rotationnumberAngles de pré-rotation (rayon rotatif)
pitch_rotation, yaw_rotationnumberAngles de rotation par tick (rayon rotatif)
origin_end, destination_endlocationPositions finales pour le rayon en translation
ignores_solid_blocksbooleanSi les rayons traversent les blocs solides (par défaut true)

Options de requête

CléNotes
filter"player" / "players", "elite" / "elites", "mob" / "mobs", "living" (par défaut)
mode"full" (par défaut) ou "border"
coverage0.0 à 1.0 -- fraction des emplacements à échantillonner (par défaut 1.0)

Callbacks d'observation

CléNotes
on_enterfunction(entity) -- appelée quand une entité entre dans la zone
on_leavefunction(entity) -- appelée quand une entité quitte la zone

Exemple : requête de sphère basique

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

Exemple : observation de zone avec entrée/sortie

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

Notes sur les observateurs :

  • Les callbacks d'observateurs reçoivent directement un seul wrapper d'entité, pas via context.event
  • Les observateurs sont nettoyés automatiquement lorsque le boss est supprimé
  • Chaque observateur s'exécute à chaque tick, donc gardez la logique du callback légère
  • L'entité du boss elle-même est exclue des requêtes de zone

Utilitaires de script : context.script

Les utilitaires de script fournissent la résolution de cibles, les handles de zone, les vecteurs relatifs, la génération de particules et les actions de combat. Ils utilisent les mêmes noms de champs que les Zones EliteScript et les Cibles EliteScript pour une plus grande familiarité -- les noms d'enum (comme "NEARBY_PLAYERS", "SPHERE", "ZONE_FULL") sont identiques pour que les auteurs déjà à l'aise avec EliteScript puissent transférer ces connaissances directement.

info

context.script est une API Lua native. Ce n'est pas un pont vers YAML ou vers le runtime EliteScript. Il réutilise simplement les mêmes conventions de nommage pour que vous n'ayez pas à apprendre un second ensemble de noms d'enum.

Méthodes

MéthodeNotes
script:target(spec)Crée un handle de cible à partir d'une table de spécification de cible
script:zone(spec)Crée un handle de zone à partir d'une table de spécification de zone
script:relative_vector(spec[, actionLocation][, zoneHandle])Crée un handle de vecteur relatif
script:damage(targetHandle, amount[, multiplier])Inflige des dégâts aux cibles résolues
script:push(targetHandle, vectorOrHandle[, additive])Pousse les cibles résolues
script:set_facing(targetHandle, vectorOrHandle)Définit la direction d'orientation des cibles
script:spawn_particles(targetHandle, particleSpec)Génère des particules aux emplacements des cibles résolues

Méthodes du handle de cible

MéthodeNotes
handle:entities()Retourne un tableau de wrappers d'entité
handle:locations()Retourne un tableau de tables d'emplacement
handle:first_entity()Retourne la première entité ou nil
handle:first_location()Retourne le premier emplacement ou nil

Clés de spécification de cible

CléNotes
targetType"SELF", "DIRECT_TARGET", "NEARBY_PLAYERS", "NEARBY_MOBS", "NEARBY_ELITES", "ZONE_FULL", "ZONE_BORDER", "ALL_PLAYERS", "WORLD_PLAYERS", "SELF_SPAWN", "LOCATION"
rangePortée pour les types de cible à proximité
coverage0.0 à 1.0 pour les cibles de zone
offsetChaîne "x,y,z" ou table { x = n, y = n, z = n }
trackIndique s'il faut ré-résoudre les cibles en mouvement

Exemple : créer et utiliser une cible

Exemple
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éthodes du handle de zone

MéthodeNotes
handle:full_target([coverage])Retourne un handle de cible pour le volume complet de la zone
handle:border_target([coverage])Retourne un handle de cible pour la bordure de la zone
handle:full_locations([coverage])Retourne les emplacements dans le volume complet de la zone
handle:border_locations([coverage])Retourne les emplacements sur la bordure de la zone
handle:full_entities()Retourne les entités dans le volume complet de la zone
handle:border_entities()Retourne les entités sur la bordure de la zone
handle:contains(location[, "full"|"border"])Retourne true si l'emplacement est à l'intérieur de la zone
handle:watch(callbacks[, mode])Surveille la zone pour les événements d'entrée/sortie, retourne un ID de tâche

Clés de spécification de zone

CléNotes
shape"SPHERE", "DOME", "CYLINDER", "CUBOID", "CONE", "STATIC_RAY", "ROTATING_RAY", "TRANSLATING_RAY"
radiusRayon de la zone
heightHauteur du cylindre
x, y, zDemi-extensions du cuboïde
borderRadiusLargeur de la bordure
pointRadiusÉpaisseur du rayon
animationDurationDurée de l'animation en ticks pour les rayons animés
TargetSpécification de cible centrale (table) -- utilise le même format de spécification de cible
Target2Second point pour les rayons et les cônes
filterFiltre d'entité
ignoresSolidBlocksboolean
pitchPreRotation, yawPreRotationAngles de pré-rotation
pitchRotation, yawRotationAngles de rotation par tick

Exemple : zone avec dégâts et particules

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

Clés de spécification de vecteur relatif

CléNotes
SourceTargetSpécification de la cible source (table)
DestinationTargetSpécification de la cible de destination (table)
normalizeboolean -- indique s'il faut normaliser le vecteur résultant
multiplierFacteur d'échelle appliqué après la normalisation
offsetChaîne "x,y,z" ou table { x = n, y = n, z = n }

Méthodes du handle de vecteur relatif

MéthodeNotes
handle:resolve()Retourne la table du vecteur calculé

Exemple : pousser des cibles avec un vecteur relatif

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

Format de spécification des particules

Les spécifications de particules peuvent être une chaîne, une table unique ou un tableau de tables :

CléNotes
particleNom de la particule (ex. "FLAME", "DUST", "SMOKE")
amountNombre de particules
x, y, zValeurs d'offset/dispersion
speedVitesse des particules
red, green, blueCouleur pour DUST / DUST_COLOR_TRANSITION (0-255)
toRed, toGreen, toBlueCouleur cible de transition pour DUST_COLOR_TRANSITION

Pour la liste complète des noms de particules, consultez la Référence des enums.

Avertissements importants

  • Les handles des utilitaires de script sont liés au contexte d'événement dans lequel ils ont été créés. Ne les stockez pas dans context.state pour une utilisation dans un appel de hook ultérieur.
  • watch() de zone retourne un ID de tâche que vous pouvez annuler avec context.scheduler:cancel_task().
  • Les valeurs de coverage ne s'appliquent qu'à la résolution basée sur les emplacements, pas aux requêtes d'entités.
  • Toutes les valeurs de chaîne utilisent les mêmes noms d'enum en UPPER_SNAKE_CASE que le YAML EliteScript (ex. "SELF", "NEARBY_PLAYERS", "SPHERE").

Espace de noms auxiliaire em

L'espace de noms em est disponible globalement dans tous les fichiers de pouvoir Lua. Il fournit des constructeurs pratiques pour les emplacements, les vecteurs et les définitions de zone.

Constructeurs d'emplacement et de vecteur

FonctionNotes
em.create_location(x, y, z[, world][, yaw][, pitch])Retourne une table d'emplacement avec une méthode add(dx, dy, dz)
em.create_vector(x, y, z)Retourne une table de vecteur

Helpers de constructeur de zones

La sous-table em.zone fournit des fonctions constructrices qui retournent des tables de définition de zone compatibles avec context.zones. Chaque constructeur retourne une table avec des méthodes de mutation chaînables.

FonctionParamètresMutateurs
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 (demi-extensions):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)

Exemple

Exemple
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

L'espace de noms em n'est pas spécifique à une instance -- toutes les instances de pouvoir Lua partagent les mêmes fonctions auxiliaires em. Les fonctions sont des constructeurs purs et ne maintiennent aucun état.


Zones natives vs. Utilitaires de script

Les deux systèmes fonctionnent avec la même géométrie de zone sous-jacente. Voici quand utiliser chacun :

Cas d'utilisationApproche recommandée
Vérification simple « y a-t-il quelque chose dans cette zone ? »Zones natives (context.zones)
Requête rapide d'entités avec une formeZones natives
NEARBY_PLAYERS, ZONE_FULL avec coverageUtilitaires de script (context.script)
Zones animées (rayons rotatifs/en translation)Les deux -- les zones natives supportent aussi ces formes
Handles de zone avec méthodes watch/contains/entitiesUtilitaires de script
Génération de particules aux emplacements de zoneUtilitaires de script (spawn_particles)
Actions de dégâts et de poussée liées au ciblageUtilitaires de script (damage, push)
Vecteurs relatifs pour effets directionnelsUtilitaires de script (relative_vector)
Combiner le flux de contrôle Lua avec un ciblage avancéUtilitaires de script

En pratique, beaucoup de pouvoirs utilisent les deux. Les zones natives sont idéales pour la vérification initiale « des joueurs sont-ils à proximité ? » dans un garde de cooldown, tandis que les utilitaires de script gèrent la logique d'attaque complexe qui suit.


Prochaines étapes