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 acceptent des tables Lua simples. Chaque requête crée une nouvelle forme ; un observateur conserve une seule forme. Des requêtes répétées sur un rayon animé redémarrent donc l'animation au lieu de lire la forme actuelle de l'observateur. Utilisez un handle de zone de script lorsque plusieurs opérations doivent partager la même forme animée.

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​

ChampTypeDéfautNotes
kind (ou type)string—"sphere", "dome", "cylinder", "cuboid", "cone", "static_ray", "rotating_ray", "translating_ray"
radiusnumber0Rayon de la zone (sphere, dome, cylinder, cone)
heightnumber0Hauteur du cylindre
originlocationemplacement du bossOrigine : base du cylindre, pointe du cône ou départ du rayon
destinationlocationemplacement du bossPoint final pour les rayons et les cônes
x, y, znumber0Dimensions du cuboïde ; voir la limitation géométrique des points et entités
thickness / point_radius / pointRadiusnumber0.5Rayon et espacement des échantillons du rayon ; valeur positive requise
border_radius / borderRadiusnumber1Rayon intérieur exclu de la forme extérieure
x_border, y_border, z_bordernumber1Dimensions intérieures du cuboïde
animation_durationint0Durée de l'animation en ticks pour les rayons animés
pitch_pre_rotation, yaw_pre_rotationnumber0Angles de pré-rotation (rayon rotatif)
pitch_rotation, yaw_rotationnumber0Rotation totale pendant l'animation ; l'animateur actuel n'applique que les incréments positifs
origin_end, destination_endlocationemplacement du bossPositions finales pour le rayon en translation
ignores_solid_blocksbooleantrueSi les rayons traversent les blocs solides
lengthnumber0Stocké par les constructeurs, mais une destination omise devient la position du boss avant ce recours ; fournissez une destination explicite

Les champs numériques et booléens avec des traits de soulignement acceptent aussi le camelCase (borderRadius, xBorder, animationDuration, pitchPreRotation, ignoresSolidBlocks). Les emplacements origin_end et destination_end exigent leurs noms avec traits de soulignement. Les tables EliteScript Target ne remplacent pas les champs d'emplacement natifs.

kind est sensible à la casse

kind est comparé exactement et doit être en minuscules. "SPHERE" ou "Sphere" ne correspondent à rien : les requêtes renvoient une liste vide sans avertissement en console.

Donnez des extrémités explicites aux cônes et rayons

Omettre origin ou destination utilise la position actuelle du boss. Le résolveur d'emplacements empêche length de remplacer une destination omise. Fournissez des extrémités distinctes :

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

Pour animer un rayon en translation, fournissez origin_end, destination_end et un animation_duration positif. Une extrémité finale omise reste à sa position de départ. Une durée nulle crée le rayon initial statique ; une durée négative est rejetée. La dernière image de l'animation se termine exactement aux extrémités demandées.

Gardez les extrémités et les emplacements interrogés dans le monde actuel du boss : les requêtes natives d'entités parcourent ce monde. Dans une table d'emplacement, les coordonnées omises valent 0 ; omettre le monde utilise celui du boss, mais un nom explicite doit désigner un monde chargé. Les dimensions doivent être finies et positives. Les tests de points, les échantillons de particules et les tests d'entités diffèrent ; les limites des formes comprennent des tests sphériques d'entités pour les dômes complets, la vérification de toute la hauteur de l'entité dans les cylindres et des limites différentes pour les cuboïdes.

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)

filter ignore la casse ; une valeur inconnue utilise living. mobs inclut les entités vivantes non joueuses, y compris les elites. Le boss est exclu, mais les joueurs ne sont pas filtrés selon leur mode de jeu. mode reconnaît border sans distinction de casse ; les autres valeurs utilisent full. Coverage échantillonne aléatoirement des emplacements, pas des entités, et ne limite pas les membres d'un observateur. Utilisez full pour les rayons : leurs emplacements de bordure ne sont pas pris en charge et peuvent faire échouer une requête d'emplacements.

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 appellent leurs propres callbacks on_enter / on_leave ; ils n'invoquent pas les hooks de premier niveau on_zone_enter / on_zone_leave du pouvoir
  • Les observateurs sont nettoyés automatiquement lorsque le boss est supprimé
  • Un observateur natif construit sa forme une seule fois. Son centre ne suit pas le boss, et modifier la table initiale ne déplace pas un observateur existant. Utilisez de nouvelles requêtes ou une zone de script avec une cible suivie pour une zone mobile.
  • 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

La première vérification arrive un tick plus tard ; les entités déjà présentes déclenchent on_enter. L'annulation ou le nettoyage n'envoie pas on_leave aux membres restants. Ici, la sphère reste à la position d'apparition. La lenteur dure 40 ticks après l'entrée ; rester dedans ne la renouvelle pas et sortir ne la retire pas plus tôt.


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.

context.script exécute le moteur EliteScript

La table de spécification est convertie en map Java puis transmise aux classes de cibles, zones, vecteurs relatifs et particules utilisées par les EliteScripts YAML.

Ce que cela signifie en pratique :

  • Les tables utilisent les analyseurs documentés dans Cibles EliteScript, Zones EliteScript et Vecteurs relatifs EliteScript, avec leurs limites actuelles. Un champ accepté ne garantit pas que le handle Lua possède le cycle de vie d'action ou le contexte hérité nécessaire.
  • Les valeurs d'enum sont en UPPER_SNAKE_CASE exact ("NEARBY_PLAYERS", "SPHERE", "ZONE_FULL"), comme en YAML.
  • Utilisez les noms YAML canoniques indiqués ici : Target, Target2, targetType, borderRadius. Leurs lecteurs internes ignorent la casse.
  • Les valeurs invalides peuvent produire des avertissements, des valeurs de repli ou des champs absents qui échouent ensuite. Accepter la table ne valide pas l'opération entière.

context.zones possède un lecteur de tables distinct avec des noms kind en minuscules, mais utilise les mêmes classes géométriques. Fournissez des tables non vides avec des champs nommés : un {} Lua vide devient une liste Java, donc même script:target({}) échoue. Utilisez script:target({targetType = "SELF"}).

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

damage, push, set_facing et spawn_particles exigent un handle de cible, pas un tableau d'entités, et ne renvoient rien. Ils n'appliquent pas les conditions, attentes ou filtres des actions YAML. damage transmet le montant à Bukkit avec le boss comme attaquant ; le multiplicateur facultatif s'applique au combat contre les joueurs et la perte de santé finale dépend du traitement du combat. push résout les cibles et un vecteur immédiatement, puis applique ce même vecteur à toutes les cibles au tick suivant. Il remplace la vélocité sauf avec additive = true, qui l'ajoute à la vélocité de ce tick. set_facing applique une direction à toutes les cibles immédiatement. Évitez les directions nulles ou non finies.

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

Chaque méthode résout à nouveau ; first_* ne lit pas un instantané partagé et ne garantit pas le résultat le plus proche. DIRECT_TARGET désigne la cible capturée par l'événement, pas la cible de combat actuelle du boss, et ne sélectionne rien si l'événement n'en fournit aucune.

Clés de spécification de cible​

CléDéfautNotes
targetType"SELF"Tout type de cible EliteScript
range20Demi-largeur sur chaque axe de la boîte de recherche ; les résultats ne sont pas triés par distance
coverage1.00.0 à 1.0. Uniquement pour les cibles de zone ; les valeurs inférieures à 1.0 sur d'autres types sont remises à 1.0 avec un avertissement
offset0,0,0Chaîne "x,y,z" séparée par des virgules ; ce champ EliteScript n'accepte pas de table vectorielle Lua
relativeOffsetaucunSpécification de vecteur relatif ; ses cibles source et destination déterminent la direction
locationaucunChaîne sérialisée "world,x,y,z,yaw,pitch", pour "LOCATION"
locationsaucunTableau de chaînes d'emplacement sérialisées, pour "LOCATIONS"
tracktrueIndique s'il faut ré-résoudre les cibles en mouvement

La voie Lua n'exécute pas la mise en cache des cibles des actions YAML. track = false ne fixe donc pas l'emplacement d'une cible ou zone Lua statique. Les handles statiques résolvent leurs origines à chaque requête ; les handles animés conservent leurs formes dès leur création. Pour une zone fixe, utilisez LOCATION avec des coordonnées explicites ou une zone native avec un origin capturé. offset et relativeOffset déplacent chaque emplacement résolu par un handle, y compris LOCATION, LOCATIONS, SELF_SPAWN, les cibles basées sur des entités et les emplacements échantillonnés d'une zone ; ils ne déplacent pas les entités renvoyées par entities(), et LANDING_LOCATION et INHERIT_SCRIPT_TARGET les ignorent. full_target() et border_target() d'un handle de zone n'acceptent pas d'offset : placez donc les offsets dans les spécifications Target et Target2 de la zone. Voir les attributs partagés.

L'analyseur accepte les 17 noms : 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. Les handles Lua autonomes ne fournissent ni données d'action héritées ni point d'atterrissage. Évitez INHERIT_* et LANDING_LOCATION, qui peuvent échouer à la résolution. ACTION_TARGET nécessite un contexte de vecteur relatif ou d'action compatible. Voir les limites des zones héritées.

Pour ZONE_FULL et ZONE_BORDER, obtenez la cible depuis un handle de zone ; script:target(...) seul n'a pas de zone. Les fonctions Lua de particules gardent la couverture par défaut de 1.0 ; elles n'appliquent pas le 0.3 par défaut de l'action YAML SPAWN_PARTICLE.

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 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é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éDéfautNotes
shape"CYLINDER""SPHERE", "DOME", "CYLINDER", "CUBOID", "CONE", "STATIC_RAY", "ROTATING_RAY", "TRANSLATING_RAY"
radius5Sphère, dôme, cylindre, cône
height1Cylindre uniquement ; doit contenir toute la hauteur de l'entité pour les requêtes d'entités
x, y, z0Dimensions du cuboïde ; voir la limitation géométrique des points et entités
xBorder, yBorder, zBorder0Dimensions intérieures du cuboïde
borderRadius1Rayon intérieur pour sphère / dôme / cylindre / cône
pointRadius0.5Rayon et espacement positifs des échantillons du rayon
animationDuration0Durée de l'animation en ticks pour les rayons animés
Target{targetType = "SELF"}Spécification de cible centrale (table) -- utilise le même format de spécification de cible
Target2aucunSecond point. Requis pour les cônes et toutes les formes de rayon
FinalTarget, FinalTarget2aucunPositions finales, rayon en translation uniquement
filter"PLAYER""PLAYER", "ELITE", "LIVING" — notez qu'ils sont en MAJUSCULES ici, contrairement à context.zones
ignoresSolidBlockstrueRayons uniquement
pitchPreRotation, yawPreRotation0Rayon rotatif uniquement
pitchRotation, yawRotation0Rayon rotatif uniquement

Les clés qui ne s'appliquent pas à la shape choisie sont lues sans protestation puis ignorées — un height sur une sphère ne fait rien.

contains teste un point, pas la boîte de l'entité. watch utilise les mêmes callbacks et la même première vérification que les observateurs natifs. Annulez l'ID renvoyé avec context.scheduler:cancel_task(id) ; l'annulation n'émet pas de callbacks de sortie. Une zone de script statique peut suivre SELF en le résolvant chaque tick ; un handle animé conserve ses formes. borderRadius est le rayon intérieur, pas l'épaisseur du bord. Utilisez les cibles complètes pour les rayons.

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

Cet exemple inflige les dégâts dès l'affichage des particules ; il n'y a aucun délai d'avertissement. Les répétitions commencent après 20 ticks et cessent à la sortie du combat. Le rayon intérieur par défaut de 1 crée une coque épaisse dans le rayon 6, pas un anneau fin.

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)
normalizeBooléen, false par défaut ; indique s'il faut normaliser le vecteur
multiplierFacteur appliqué après normalisation, 1 par défaut
offsetChaîne "x,y,z" séparée par des virgules, "0,0,0" par défaut ; pas une table vectorielle Lua

Méthodes du handle de vecteur relatif​

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

Fournissez les deux spécifications de cible. La résolution prend le premier emplacement de chacune : destination moins source, normalisation facultative, multiplication, puis offset sur les axes du monde. Des résultats vides ou des mondes différents renvoient zéro avant l'offset ; normaliser des points confondus peut produire un vecteur non fini. ACTION_TARGET utilise actionLocation, par défaut la position du boss capturée à la création du handle. Elle n'est pas remplacée pour chaque entité poussée. Passez un handle de zone comme troisième argument si les cibles du vecteur ont besoin de cette zone.

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. Comme ce chemin exécute le moteur de particules d'EliteScript, les clés sont celles d'EliteScript documentées sous SPAWN_PARTICLE :

CléDéfautNotes
particle"FLAME"Nom de la particule (ex. "FLAME", "DUST", "SMOKE")
amount1Nombre de particules. Avec 0, le comportement directionnel dépend du type de particule
x, y, z0.01Valeurs d'offset/dispersion, ou vélocité lorsque amount vaut 0
speed0.01Vitesse des particules
red, green, blue255Couleur pour DUST, DUST_COLOR_TRANSITION et les particules exigeant des données Color (0-255) ; WITCH n'utilise pas ces valeurs
toRed, toGreen, toBlue255Couleur cible de transition pour DUST_COLOR_TRANSITION
material"STONE"Bloc ou objet affiché par les particules portant des données de bloc/objet (BLOCK, ITEM, FALLING_DUST, ...)
relativeVectoraucunUne spécification de vecteur relatif. La définir force amount à 0 et écrase x/y/z par la direction résolue

La taille de la poussière est fixée à 1. moveToTarget est lu mais ne déplace pas les particules. Les types de données non pris en charge sont ignorés avec un avertissement. La fonction décale les particules des zones et de LOCATION / LOCATIONS de +0.5 sur X et Z ; les emplacements renvoyés par les handles ne sont pas décalés.

Deux jeux de clés de particules différents

Ces clés EliteScript ne sont pas les mêmes que celles acceptées par context.world:spawn_particle_at_location(loc, spec). La table world possède son propre lecteur plus réduit, avec des valeurs par défaut différentes (amount 1, x/y/z/speed 0), sans material ni relativeVector, et il accepte en plus to_red / to_green / to_blue en snake_case. Voir Monde et Environnement.

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.
  • context.script:zone(...):watch(...) renvoie un ID annulable avec context.scheduler:cancel_task(). context.zones:watch_zone(...) ne renvoie rien et est nettoyé automatiquement avec le pouvoir.
  • Les valeurs de coverage ne s'appliquent qu'à la résolution basée sur les emplacements, pas aux requêtes d'entités.
  • Les enums des cibles, formes et filtres utilisent les noms UPPER_SNAKE_CASE du YAML EliteScript (ex. "SELF", "NEARBY_PLAYERS", "SPHERE"). Les modes watch/contains restent "full" ou "border".

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 (dimensions du cuboïde):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)
Définissez les deux extrémités

Les constructeurs de cônes et rayons stockent length, mais le résolveur natif utilise la position du boss si la destination est omise. Chaînez :set_origin(...) et :set_destination(...) ; ne comptez pas sur length pour orienter la forme. Les rayons en translation nécessitent aussi origin_end, destination_end et un animation_duration positif dans la table renvoyée.

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

Chaque instance de script possède son environnement Lua et son espace em. Ces constructeurs renvoient de nouvelles tables ; la méthode add(...) et les setters de zone modifient la table sur laquelle ils sont appelés.


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)Handles de zone de script pour les lectures répétées ; les observateurs natifs peuvent aussi conserver une forme animée
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

Les deux API peuvent être utilisées dans un pouvoir. Choisissez selon les cibles et le cycle de vie nécessaires : les requêtes natives ciblent par défaut les entités vivantes sauf le boss ; les zones de script ciblent les joueurs.


Prochaines étapes​