Moteur de script Lua MagmaCore
MagmaCore fournit le bac à sable Lua et l'environnement ScriptInstance des pouvoirs de boss EliteMobs, des scripts de PNJ, des props FreeMinecraftModels et des effets d'enchantements personnalisés. Ils partagent la validation des fichiers et la gestion des ressources, mais les hooks, tables de contexte, portées des temps de recharge et durées de vie dépendent du système qui les exécute. Les requêtes d'enchantement ont aussi un contexte restreint et des limites propres au fournisseur ; consultez leur référence ci-dessous.
Les props FreeMinecraftModels et les scripts de PNJ EliteMobs héritent directement des tables de contexte génériques MagmaCore (context.world, context.zones, context.scheduler, context.cooldowns, context.log, context.event, context.player et context.state) et ajoutent leur table propriétaire (context.prop ou context.npc). Les pouvoirs de boss EliteMobs utilisent le même environnement mais exposent des variantes enrichies propres aux boss pour plusieurs tables (context.world, context.zones, context.cooldowns, context.scheduler, context.log, context.event), ainsi que des outils réservés aux boss : context.players, context.entities, context.vectors, context.settings et context.script.
Actuellement, les plugins suivants utilisent ce moteur :
- EliteMobs -- Pouvoirs Lua pour les boss personnalisés (hooks comme
on_boss_damaged_by_player,on_enter_combat, etc.) et scripts Lua de PNJ pour les comportements d'interaction et de proximité (hooks commeon_npc_interact,on_npc_proximity_enter, etc.) - FreeMinecraftModels -- Scripts Lua pour les props (hooks comme
on_right_click,on_left_click, etc.) et effets d'enchantements personnalisés pour les objets personnalisés
Cette page documente les fonctionnalités du moteur MagmaCore générique utilisées par les scripts FreeMinecraftModels, avec des notes de compatibilité EliteMobs lorsque les mêmes concepts ont des variantes propres aux boss ou aux PNJ. Pour le contexte exact des boss EliteMobs, utilisez les pages Lua d'EliteMobs ; pour celui des PNJ, consultez les scripts Lua de PNJ.
Mini-guide Lua
Si vous êtes complètement nouveau en Lua, voici la syntaxe minimale dont vous avez besoin pour écrire des scripts pour n'importe quel plugin Nightbreak.
Variables
Utilisez local pour stocker une valeur :
local cooldown_key = "fire_burst"
local damage_multiplier = 1.5
local signifie que la variable n'appartient qu'à ce fichier ou ce bloc.
Fonctions
Les fonctions sont des blocs de logique réutilisables :
local function warn_player(player)
player:send_message("&cMove!")
end
Plus tard, vous pouvez l'appeler :
warn_player(some_player)
Vérifications if
Utilisez if quand quelque chose ne doit se produire que dans certains cas :
if context.player == nil then
return
end
Cela signifie « s'il n'y a pas de joueur pour ce hook, on s'arrête ici ».
nil
nil signifie « aucune valeur ». C'est la version Lua de « il n'y a rien ici ».
Vous vérifierez souvent la présence de nil avec :
if context.event ~= nil then
-- do something with the event
end
~= signifie « n'est pas égal à ».
Tables
Lua utilise les tables pour plusieurs usages :
- Listes
- Objets avec clés nommées
- La définition de script finale retournée
Exemple de table avec clés nommées :
local particle = {
particle = "FLAME",
amount = 1,
speed = 0.05
}
Retourner la définition du script
À la fin de chaque fichier de script, vous retournez une seule table :
return {
api_version = 1,
on_spawn = function(context)
end
}
La table retournée est la définition du script. Le chargeur évalue le fichier pour le valider, puis réévalue le code mémorisé pour chaque instance. Les variables locales du fichier appartiennent donc à cette instance, pas à toutes les entités utilisant ce nom de fichier. Modifier le fichier ne change ni une définition chargée ni une instance active ; rechargez-le par le mécanisme du plugin propriétaire.
Commentaires
Utilisez -- pour écrire une note destinée aux humains :
-- This cooldown stops the attack from firing every hit
context.cooldowns:set_local(60, "fire_burst")
Sandbox Lua
Tous les scripts Lua s'exécutent dans un environnement LuaJ sandboxé. Plusieurs globales qui pourraient accéder au système de fichiers ou au runtime Java sont supprimées. Les règles du sandbox sont identiques pour tous les plugins utilisant MagmaCore.
Globales supprimées
Les globales standard Lua suivantes sont définies à nil et ne peuvent pas être utilisées :
| Supprimée | Raison |
|---|---|
debug | Expose l'état interne de la VM |
dofile | Accès au système de fichiers |
io | Accès au système de fichiers |
load | Chargement de code arbitraire |
loadfile | Accès au système de fichiers |
luajava | Accès direct aux classes Java |
module | Système de modules (non nécessaire) |
os | Accès au système d'exploitation |
package | Système de modules (non nécessaire) |
require | Système de modules / accès au système de fichiers |
Bibliothèque standard disponible
L'environnement standard LuaJ fournit les fonctionnalités Lua ordinaires suivantes :
| Catégorie | Fonctions |
|---|---|
| Math | math.abs, math.ceil, math.floor, math.max, math.min, math.random, math.sin, math.cos, math.sqrt, math.pi, et toutes les autres fonctions math.* |
| String | string.byte, string.char, string.find, string.format, string.gsub, string.len, string.lower, string.match, string.rep, string.sub, string.upper, et toutes les autres fonctions string.* |
| Table | table.insert, table.remove, table.sort, table.concat, et toutes les autres fonctions table.* |
| Itérateurs | pairs, ipairs, next |
| Type | type, tostring, tonumber, select, unpack |
| Gestion des erreurs | pcall, xpcall, error, assert |
| Autres | print, rawget, rawset, rawequal, rawlen, setmetatable, getmetatable |
os n'est pas disponibleLa bibliothèque os est entièrement retirée du bac à sable. Utilisez context.world:get_time() pour l'heure du monde dans les interfaces génériques MagmaCore ; les pouvoirs de boss EliteMobs la reçoivent via la base partagée de leur table world. Pour suivre une durée écoulée, stockez des compteurs de ticks dans context.state via le hook on_game_tick.
print écrit dans la console du serveur, mais préférez context.log:info(msg). Chaque interface expose context.log : les scripts FreeMinecraftModels et de PNJ EliteMobs proposent info, warn et error ; les pouvoirs de boss EliteMobs proposent info, warn et debug.
Contrat de fichier
Chaque script Lua doit return une table. Cette table est volontairement stricte.
Champs de premier niveau requis et facultatifs
| Champ | Requis | Type | Notes |
|---|---|---|---|
api_version | Oui | Number | Doit actuellement être 1 |
priority | Non | Number | Vaut 0 par défaut et est converti en entier. Les scripts de boss et de PNJ EliteMobs exécutent les valeurs faibles en premier. FMM valide le champ, mais les props suivent l'ordre de scripts: |
| clés de hook prises en charge | Non | Function | Doit utiliser l'un des noms de hook exacts pris en charge par le plugin |
Règles de validation
- Le fichier doit retourner une table.
api_versionest requis et doit actuellement être1.prioritydoit être numérique si présent.- Chaque clé supplémentaire de premier niveau doit être un nom de hook pris en charge.
- Chaque clé de hook doit pointer vers une fonction.
- Les clés de premier niveau inconnues sont rejetées.
Le validateur Lua accepte priority pour tous les scripts utilisant MagmaCore. EliteMobs l'utilise pour ordonner les scripts de boss et de PNJ. FreeMinecraftModels ne trie actuellement pas par priority : les props suivent l'ordre de la liste scripts: de la configuration. Les enchantements personnalisés utilisent leur catalogue de fournisseur et leur cycle de vie d'action ou de requête.
Où se trouvent les fichiers de script
Chaque fournisseur choisit son dossier. Le moteur générique cherche récursivement les fichiers .lua et exclut les chemins de configuration archivés. Il trie les chemins absolus normalisés, d'abord sans tenir compte de la casse puis selon le chemin exact, choisit le premier fichier par nom en minuscules et signale les doublons ignorés dont le contenu diffère du fichier retenu. Un échec de validation ne fait pas charger un autre doublon. Les recherches enregistrées conservent l'orthographe exacte du nom retenu ; utilisez-la dans les références. Les pouvoirs de boss et catalogues d'enchantements ont leurs propres règles de découverte. Partager un validateur ne rend pas leurs dossiers interchangeables.
Les scripts sont indexés par nom de fichier, pas par chemin. Deux fichiers nommés door.lua dans des sous-dossiers différents constituent la même clé, et un seul est enregistré. Donnez à chaque script un nom de fichier distinct.
Les fonctions utilitaires et les constantes locales doivent vivre au-dessus du return final, et non à l'intérieur de la table retournée, sauf s'il s'agit de véritables hooks.
local ANIMATION_NAME = "idle"
local function do_something(context)
context.log:info("Doing something!")
end
return {
api_version = 1,
priority = 0,
on_spawn = function(context)
do_something(context)
end
}
Noms de hooks communs
Ces noms de hooks apparaissent dans plusieurs environnements Lua. Chaque type de script n'active que le sous-ensemble adapté à son propriétaire : les scripts de props FMM utilisent tous ceux-ci, les pouvoirs de boss EliteMobs utilisent leur liste de hooks de boss et les scripts de PNJ EliteMobs utilisent on_spawn, on_remove, on_game_tick, on_npc_interact, on_npc_proximity_enter, on_npc_proximity_leave, on_zone_enter et on_zone_leave.
| Hook | Quand il se déclenche |
|---|---|
on_spawn | Déclenché par le cycle d'apparition du plugin pour les props FMM, boss et PNJ EliteMobs ; construire un ScriptInstance seul ne le déclenche pas |
on_game_tick | Appelé à chaque tick serveur tant que l'instance initialisée est active et non suspendue |
on_zone_enter | Appelé lorsqu'une zone compatible avec le moteur signale une entrée. Les surveillances FMM et de PNJ EliteMobs suivent les joueurs ; les hooks de zone de premier niveau des boss EliteMobs proviennent des événements de zone EliteScript. |
on_zone_leave | Appelé lorsqu'une zone compatible avec le moteur signale une sortie. Les surveillances FMM et de PNJ EliteMobs suivent les joueurs ; les hooks de zone de premier niveau des boss EliteMobs proviennent des événements de zone EliteScript. |
Syntaxe de méthode : : vs .
En Lua, object:method(arg) est un raccourci pour object.method(object, arg). Les méthodes des tables de contexte MagmaCore retirent ce premier argument implicite : les deux formes fonctionnent donc pour des méthodes comme context.log.info :
context.log:info("hello")
context.log.info("hello") -- same thing
Les fonctions globales de em s'appellent avec . : em.create_location(...), em.zone.create_sphere_zone(...) et em.location.is_protected(...). Les setters d'événement EliteMobs context.event.set_damage_amount(...) et context.event.multiply_damage_amount(...) exigent également .. La documentation utilise : pour les méthodes des tables de contexte et . pour les fonctions ordinaires.
Budget d'exécution
Chaque invocation de hook, chaque callback planifié et l'évaluation initiale du fichier de script lui-même s'exécutent sous un budget d'exécution strict. Le budget est appliqué à l'intérieur de la VM Lua : il s'applique donc pendant que votre code s'exécute encore, et pas seulement en vérifiant l'horloge après coup.
L'environnement ordinaire applique ces limites :
| Limite | Valeur |
|---|---|
| Temps CPU du thread courant | 50 millisecondes |
| Instructions Lua exécutées | 250 000 |
Dépasser une limite déclenche une erreur Lua. Le compteur est contrôlé à chaque instruction Lua ; l'horloge, toutes les 1 024 instructions et au retour de l'appel. Cela n'interrompt pas une méthode Java/Bukkit en cours, et 50 ms de CPU ne constituent pas une échéance de 50 ms de temps réel. Une erreur non interceptée dans un hook ou callback ferme l'instance. À la validation initiale, la définition est rejetée. Si le temps CPU du thread n'est pas disponible, la limite devient 250 millisecondes de temps écoulé, avec le même plafond d'instructions. Les lots de requêtes d'enchantement peuvent imposer des quotas plus petits.
La VM interrompt un while true do end ordinaire pendant les instructions Lua. La boucle consomme néanmoins du temps sur le thread serveur et ferme l'instance si l'erreur se propage. Gardez des boucles bornées malgré cette protection.
Les appels imbriqués partagent un budget unique de 50 ms de CPU et 250 000 instructions pour toute la chaîne, sans allocation distincte par appel.
Pour rester dans le budget :
- Évitez les boucles non bornées dans les hooks.
- Gardez les gestionnaires
on_game_ticklégers -- ils s'exécutent à chaque tick. - Utilisez
context.scheduler:run_repeating(...)pour répartir le travail sur plusieurs ticks. - Limitez le travail coûteux avec
context.cooldownsou un intervalle raisonnable.
Une erreur non interceptée dans un hook ou callback ferme l'instance et annule son travail propre. Corrigez et rechargez la définition, puis laissez le plugin créer une nouvelle instance. Enregistrer le fichier seul ne répare pas l'instance fermée. Les systèmes d'enchantements appliquent aussi leur politique de suppression des échecs.
context.state
Une table Lua simple qui persiste pendant toute la durée de vie de l'instance de script. Utilisez-la pour stocker des drapeaux, des compteurs, des IDs de tâche, des états de bascule et toute donnée que vous souhaitez partager entre les hooks.
return {
api_version = 1,
on_spawn = function(context)
context.state.is_open = false
context.state.click_count = 0
context.state.task_id = nil
end,
on_right_click = function(context)
context.state.click_count = (context.state.click_count or 0) + 1
end
}
Utilisez context.state pour partager des données entre les hooks d'une instance. Ces données restent en mémoire et ne survivent pas aux rechargements ou redémarrages. Les autres tables sont construites à la demande et peuvent contenir des instantanés. FMM garde context.prop en cache, mais lit des champs comme current_location à la demande. Relisez un champ dynamique pour l'actualiser ; une table mémorisée dans une variable ne se met pas à jour seule. Affecter un champ dynamique masque son accesseur.
context.log
Méthodes de journalisation dans la console, disponibles dans chaque interface de script. Les messages génériques log.info portent le préfixe [Lua] ; ajoutez un libellé de script au message pour identifier sa source. Les diagnostics d'erreur identifient le script en échec, mais la journalisation ordinaire n'ajoute pas automatiquement son nom de fichier. Les scripts FreeMinecraftModels et de PNJ EliteMobs proposent info, warn et error ; les pouvoirs de boss EliteMobs proposent info, warn et debug.
| Méthode | Notes |
|---|---|
log:info(message) | Message informatif |
log:warn(message) | Message d'avertissement |
log:error(message) | Message de niveau avertissement (loggé au niveau WARN, identique à log:warn) |
Le context.log d'EliteMobs enregistre debug au lieu de error. Utilisez log:debug(message) pour la sortie de débogage (apparaît au niveau info avec un préfixe debug).
context.log:info("Script loaded!")
context.log:warn("Something unexpected happened")
-- Generic/FMM/NPC logger:
context.log:error("Critical failure in zone setup")
-- EliteMobs boss logger:
context.log:debug("Boss debug detail")
context.cooldowns
La table gère les temps de recharge. Les temps locaux et globaux génériques convertissent chaque tick en 50 ms de temps monotone, y compris pendant les pauses et les TPS faibles. Les temps globaux des boss comptent au contraire les ticks du serveur. Il existe deux portées :
- Les temps de recharge locaux utilisent des clés textuelles exactes dans le stockage du propriétaire, dont la portée est précisée plus bas. Passez
nilpour la clé par défaut,__lua:suivi du nom de fichier. - Les temps de recharge globaux sont partagés par tous les scripts d'une même entité propriétaire lorsque le moteur expose les méthodes globales, par exemple tous les scripts du même prop ou tous les pouvoirs Lua du même boss.
cooldowns:check_local(key?, duration)
Vérifie une clé locale et, si elle est prête, démarre son temps de recharge et retourne true ; sinon retourne false. C'est un appel Lua synchrone. Il ne vérifie ni ne démarre le temps global. Le stockage n'est pas une API de verrouillage entre threads.
| Paramètre | Type | Notes |
|---|---|---|
key | string (facultatif) | Identifiant du temps de recharge. nil sélectionne la clé par défaut. |
duration | int | Durée du cooldown en ticks (20 = 1 seconde) |
on_right_click = function(context)
-- Only allow this action once every 3 seconds
if not context.cooldowns:check_local("interact", 60) then
return
end
-- ... do the action
end
Toutes les interfaces de scripts — pouvoirs de boss, scripts de PNJ et scripts FreeMinecraftModels — utilisent l'ordre commun ci-dessus : check_local(key?, duration). Pour la clé par défaut, passez check_local(nil, 60) ; check_local(60) ne signifie pas un temps de recharge par défaut de 60 ticks. D'anciennes versions expérimentales des PNJ utilisaient check_local(duration, key?) ; adaptez ces anciens scripts de PNJ à l'ordre commun.
cooldowns:local_ready(key?)
Retourne true si le cooldown local a expiré (ou n'a jamais été défini), false s'il est toujours actif.
cooldowns:local_remaining(key?)
Retourne le nombre de ticks restants sur le cooldown local, ou 0 si prêt.
cooldowns:set_local(duration, key?)
Définit un cooldown local sans vérifier si un est déjà actif. Utilisez ceci pour les réinitialisations inconditionnelles de cooldown.
| Paramètre | Type | Notes |
|---|---|---|
duration | int | Durée en ticks. Passez 0 ou négatif pour effacer. |
key | string (facultatif) | Identifiant du temps de recharge. nil sélectionne la clé par défaut. |
cooldowns:global_ready()
Retourne true si le cooldown global (partagé entre tous les scripts sur la même entité) a expiré.
cooldowns:set_global(duration)
Définit le temps global. Sur les tables génériques MagmaCore, zéro ou une durée négative l'efface. Les temps globaux des boss conservent l'expiration la plus tardive : une durée plus courte n'écourte jamais un temps global actif, et zéro ou une durée négative n'a aucun effet. Définir le temps local ne définit pas le global, ni inversement.
| Paramètre | Type | Notes |
|---|---|---|
duration | int | Durée en ticks |
Le « propriétaire » d'un cooldown global dépend du type de script :
- Pouvoirs Lua EliteMobs — partagés par
EliteEntity(un seau par boss).global_ready()/set_global()utilisent le système de cooldown de pouvoir intégré du boss ; les cooldowns locaux sont également partagés entre tous les pouvoirs sur le même boss. - Scripts de PNJ EliteMobs : les temps globaux et clés locales explicites sont partagés par l'unique adaptateur du PNJ. Deux scripts utilisant la même clé locale s'influencent ; une clé omise reste liée au nom de fichier.
- Scripts de props FMM : temps globaux partagés par prop placé ; chaque script possède son adaptateur et son stockage local.
- Actions d'enchantement — temps de recharge globaux partagés par joueur au sein du fournisseur ; les temps de recharge locaux appartiennent au joueur et à l'identifiant d'enchantement et survivent aux échanges d'équipement et aux actions terminées. Consultez les enchantements personnalisés.
context.scheduler
Le planificateur exécute des tâches différées et répétitives. Celles qu'il crée appartiennent à l'instance et sont annulées à sa fermeture. Cela n'annule pas les entités créées, modifications du monde ou minuteurs d'outils séparés d'interface et d'effets. Pendant une pause, une tâche unique arrivée à échéance attend la reprise et une tâche répétitive ignore ses appels suspendus.
Cette section utilise les noms du planificateur MagmaCore (run_later, run_repeating, cancel). Les noms EliteMobs (run_after(ticks, callback), run_every(interval, callback), cancel_task(taskId)) sont acceptés comme alias dans toutes les interfaces ; les deux styles fonctionnent donc dans tous les scripts.
scheduler:run_later(ticks, callback)
Exécute un callback une seule fois après un délai. Retourne un ID de tâche numérique.
| Paramètre | Type | Notes |
|---|---|---|
ticks | int | Délai en ticks serveur (20 ticks = 1 seconde) |
callback | function | Appelé avec un context frais lorsque le délai expire |
context.scheduler:run_later(40, function(delayed_context)
delayed_context.log:info("2 seconds have passed!")
end)
scheduler:run_repeating(delay, interval, callback)
Exécute un callback de manière répétée à un intervalle fixe. Retourne un ID de tâche numérique.
| Paramètre | Type | Notes |
|---|---|---|
delay | int | Délai initial en ticks avant la première exécution |
interval | int | Ticks entre chaque exécution suivante |
callback | function | Appelé avec un context frais à chaque intervalle |
context.state.particle_task = context.scheduler:run_repeating(0, 20, function(tick_context)
tick_context.log:info("Another second passed!")
end)
scheduler:cancel(taskId)
Annule par ID une tâche de cette instance. Un ID inconnu ou appartenant à une autre instance ne fait rien.
| Paramètre | Type | Notes |
|---|---|---|
taskId | int | L'ID de tâche retourné par run_later ou run_repeating |
La fermeture annule automatiquement les tâches propres à l'instance. Annulez-les plus tôt si une interaction ou phase de combat se termine alors que l'instance reste active, par exemple dans on_exit_combat d'un boss. Les deux familles de noms fonctionnent. Utilisez les hooks du plugin propriétaire ; une erreur ferme l'instance sans garantir un hook de nettoyage personnalisé.
Les callbacks reçoivent un nouveau contexte sans l'événement ni l'acteur déclencheurs. Utilisez cet argument plutôt que le contexte externe. Pour retrouver le joueur plus tard, capturez son UUID pendant le hook, puis recherchez-le en vérifiant sa disponibilité. Un contexte externe conservé peut aussi résoudre un champ d'événement à la demande après la fin de l'événement initial.
context.world
La table world permet d'interroger et de modifier le monde Minecraft. Elle capture le monde actuel du propriétaire à sa première construction ; la conserver ne lui fait pas suivre les changements de monde ultérieurs.
Ces méthodes décrivent la table partagée reçue par les props FMM et scripts de PNJ EliteMobs, dont strike_lightning(...) inflige des dégâts. FMM ajoute des outils facultatifs de transport et butin EliteMobs ; consultez context.world : ajouts FreeMinecraftModels. EliteMobs ajoute à ses tables partagées des méthodes de foudre visuelle et d'apparition de PNJ ou boss exigeant un chunk chargé. Les pouvoirs de boss ajoutent ou remplacent ensuite leurs propres méthodes ; consultez EliteMobs : monde et environnement.
Dans les interfaces génériques, context.world accepte à la fois les appels à coordonnées comme strike_lightning(x, y, z) et spawn_particle(name, x, y, z, ...), et les variantes à table de position comme strike_lightning_at_location(loc) et spawn_particle_at_location(loc, ...). Les pouvoirs de boss EliteMobs acceptent aussi les deux styles, mais certaines méthodes à table de position ont un comportement propre aux boss.
Les positions partagées exigent x, y et z. Un monde omis ou introuvable utilise celui de la table. Les appels partagés de particules par position utilisent toujours ce monde capturé ; fournissez une position du même monde. Les convertisseurs propres aux boss et les requêtes em.location.* suivent d'autres règles décrites dans leurs références.
La référence complète de la table de monde documente aussi la recherche d'entités, les requêtes de traversabilité et de protection, la poussière colorée, les impacts sur le terrain et les variantes à table de position.
world.name
Un champ chaîne contenant le nom du monde.
world:get_block_at(x, y, z)
Retourne le nom du matériau du bloc aux coordonnées données en minuscules, par exemple "stone" ou "air". Si le chunk cible n'est pas chargé, retourne "air" au lieu de forcer son chargement.
| Paramètre | Type | Notes |
|---|---|---|
x | int | Coordonnée X du bloc |
y | int | Coordonnée Y du bloc |
z | int | Coordonnée Z du bloc |
world:set_block_at(x, y, z, material)
Définit le bloc aux coordonnées données. S'exécute sur le thread principal et évite de forcer le chargement des chunks.
| Paramètre | Type | Notes |
|---|---|---|
x | int | Coordonnée X du bloc |
y | int | Coordonnée Y du bloc |
z | int | Coordonnée Z du bloc |
material | string | Nom Bukkit Material, en minuscules (par exemple "stone", "air", "oak_planks") |
Retourne true lorsque le nom du matériau est valide et que la modification a été mise en attente, false lorsque le matériau est invalide. Si le chunk cible n'est pas chargé lors de l'exécution de la tâche, la modification du bloc est ignorée.
La protection des régions n'est pas vérifiée automatiquement. Choisissez un matériau de bloc et interrogez la protection appropriée avant le placement ; une demande acceptée ne prouve pas que le bloc a changé.
world:spawn_particle(particle, x, y, z, count, dx, dy, dz, speed)
Fait apparaître des particules à un emplacement.
| Paramètre | Type | Défaut | Notes |
|---|---|---|---|
particle | string | requis | Nom de l'enum Bukkit Particle ; la recherche le passe en majuscules (par exemple "FLAME", "HAPPY_VILLAGER") |
x | number | requis | Coordonnée X |
y | number | requis | Coordonnée Y |
z | number | requis | Coordonnée Z |
count | int | 1 | Nombre de particules |
dx | number | 0 | Dispersion/décalage X |
dy | number | 0 | Dispersion/décalage Y |
dz | number | 0 | Dispersion/décalage Z |
speed | number | 0 | Vitesse des particules |
Certains types de particules nécessitent des données supplémentaires que cette API simple ne prend pas en charge. C'est le cas, par exemple, de DUST et FALLING_DUST. Utilisez des alternatives sans données comme CLOUD, SMOKE, CAMPFIRE_COSY_SMOKE, SNOWFLAKE, FLAME, HAPPY_VILLAGER, HEART, NOTE ou ENCHANT. Pour la poussière colorée, utilisez la méthode dédiée world:spawn_dust(...) de la référence de la table de monde.
Comme l'API simple ne fournit pas d'objets de données de particules Bukkit, les particules qui en exigent peuvent provoquer une exception Bukkit et désactiver l'instance de script. Préférez les noms de particules sans données ci-dessus pour les scripts FMM/MagmaCore.
world:play_sound(sound, x, y, z, volume, pitch)
Joue un son à un emplacement.
| Paramètre | Type | Défaut | Notes |
|---|---|---|---|
sound | string | requis | Nom de l'enum Bukkit Sound (par exemple "ENTITY_EXPERIENCE_ORB_PICKUP") ou une clé de son de resource pack personnalisé (par exemple "mypack:boss.roar") |
x | number | requis | Coordonnée X |
y | number | requis | Coordonnée Y |
z | number | requis | Coordonnée Z |
volume | number | 1.0 | Volume |
pitch | number | 1.0 | Hauteur (pitch) |
Le nom est d'abord comparé aux sons enregistrés de Bukkit (sans tenir compte de la casse, "ENTITY_ARROW_SHOOT" et "entity_arrow_shoot" sont donc identiques). Si rien ne correspond, il est normalisé en clé minuscule avec espace de noms et joué comme son de resource pack personnalisé. Une valeur qui n'est ni un son connu ni une clé avec espace de noms valide ne joue rien au lieu de lever une erreur : une faute de frappe ne fait donc silencieusement rien plutôt que de désactiver votre script.
Il en va de même pour world:play_sound_at_location(loc, sound, volume, pitch).
world:strike_lightning(x, y, z)
Frappe la foudre à un emplacement (visuel et infligeant des dégâts).
| Paramètre | Type | Notes |
|---|---|---|
x | number | Coordonnée X |
y | number | Coordonnée Y |
z | number | Coordonnée Z |
world:get_time()
Retourne le temps actuel du monde en ticks.
world:set_time(ticks)
Définit le temps du monde.
| Paramètre | Type | Notes |
|---|---|---|
ticks | int | Temps du monde (0 = aube, 6000 = midi, 13000 = nuit, 18000 = minuit) |
world:get_nearby_entities(x, y, z, radius)
Retourne un tableau indexé à partir de un de tables d'entités dans une boîte alignée sur les axes et centrée aux coordonnées. Le propriétaire du script n'est pas exclu.
| Paramètre | Type | Notes |
|---|---|---|
x | number | Centre X |
y | number | Centre Y |
z | number | Centre Z |
radius | number | Rayon de recherche (utilisé comme demi-étendue sur les trois axes) |
Ceci retourne TOUTES les entités à portée, y compris les entités non vivantes comme les objets lâchés ou les projectiles. Vérifiez toujours if entity.damage then avant d'appeler les méthodes d'entités vivantes.
world:get_nearby_players(x, y, z, radius)
Retourne un tableau indexé à partir de un de tables joueur dans une boîte alignée sur les axes, avec radius comme demi-étendue sur chacun. Les modes de jeu ne sont pas filtrés.
| Paramètre | Type | Notes |
|---|---|---|
x | number | Centre X |
y | number | Centre Y |
z | number | Centre Z |
radius | number | Rayon de recherche |
world:spawn_entity(entity_type, x, y, z)
Fait apparaître une entité Minecraft vanilla à l'emplacement donné.
| Paramètre | Type | Notes |
|---|---|---|
entity_type | string | Nom du type d'entité Bukkit, en minuscules (par exemple "zombie", "skeleton", "pig") |
x | number | Coordonnée X |
y | number | Coordonnée Y |
z | number | Coordonnée Z |
Retourne une table d'entité avec les méthodes d'entité vivante si nécessaire, ou nil pour un nom d'enum inconnu. Un type valide mais impossible à faire apparaître peut lever une erreur. Aucun contrôle de chargement du chunk n'est effectué.
world:get_highest_block_y(x, z)
Retourne la coordonnée Y du bloc le plus haut selon Bukkit en X/Z. Contrairement à get_block_at, cette requête ne vérifie pas que le chunk est chargé.
| Paramètre | Type | Notes |
|---|---|---|
x | int | Coordonnée X du bloc |
z | int | Coordonnée Z du bloc |
world:raycast(from_x, from_y, from_z, dir_x, dir_y, dir_z, [max_distance], [fluid_mode], [blocks_only], [loaded_only])
Lance un rayon depuis un point dans une direction et retourne des informations sur ce qu'il touche.
| Paramètre | Type | Défaut | Notes |
|---|---|---|---|
from_x | number | requis | Origine X |
from_y | number | requis | Origine Y |
from_z | number | requis | Origine Z |
dir_x | number | requis | Composante X de la direction |
dir_y | number | requis | Composante Y de la direction |
dir_z | number | requis | Composante Z de la direction |
max_distance | number | 50 | Distance maximale du rayon |
fluid_mode | string | "NEVER" | NEVER, SOURCE_ONLY ou ALWAYS |
blocks_only | boolean | false | Ignore les entités et ne trace que les blocs |
loaded_only | boolean | false | Retourne nil au lieu de tracer si un chunk du rectangle englobant le rayon n'est pas chargé |
Avec loaded_only=true, vérifiez aussi que le résultat n'est pas nil. Sinon, un rayon qui ne touche rien retourne une table dont les champs d'impact valent nil :
| Champ | Type | Notes |
|---|---|---|
hit_entity | entity table ou nil | La première entité touchée par le rayon, ou nil si aucune |
hit_location | location table ou nil | Le point exact où le rayon a touché quelque chose |
hit_block | table ou nil | {x, y, z, material} du bloc touché, ou nil si aucun bloc n'a été touché |
Les matériaux sont en minuscules. Le tracé combiné utilise une taille de rayon de 0.5 pour les entités sans les filtrer. Le contrôle des chunks couvre tout le rectangle englobant et peut refuser un chunk éloigné du rayon exact. Un nom de mode de liquide invalide lève une erreur.
world:spawn_firework(x, y, z, colors, [type], [power])
Fait apparaître une fusée de feu d'artifice à l'emplacement donné.
| Paramètre | Type | Défaut | Notes |
|---|---|---|---|
x | number | requis | Coordonnée X |
y | number | requis | Coordonnée Y |
z | number | requis | Coordonnée Z |
colors | table | requis | Tableau de chaînes de couleurs, par exemple {"RED", "BLUE", "WHITE"} |
type | string | "BALL" | Forme du feu d'artifice : "BALL", "BALL_LARGE", "STAR", "BURST", "CREEPER" |
power | int | 1 | Puissance de vol, 0-127 |
-- Example: red and yellow firework burst
context.world:spawn_firework(loc.x, loc.y, loc.z, {"RED", "YELLOW"}, "BURST", 2)
world:place_temporary_block(x, y, z, material, [ticks], [require_air])
Place un bloc temporaire et restaure le BlockData enregistré après une durée positive. L'état complet et l'inventaire du bloc ne sont pas capturés.
| Paramètre | Type | Défaut | Notes |
|---|---|---|---|
x | int | requis | Coordonnée X du bloc |
y | int | requis | Coordonnée Y du bloc |
z | int | requis | Coordonnée Z du bloc |
material | string | requis | Nom Bukkit Material (par exemple "stone", "ice") |
ticks | int | 0 | Durée en ticks avant restauration. Zéro ou une valeur négative place le bloc de façon permanente, sans suivi. |
require_air | boolean | false | Si true, ne place le bloc que si la cible est de l'air |
Retourne false si le matériau est invalide ou si le chunk cible n'est pas chargé. Sinon, retourne true dès que la demande de placement est acceptée. Si require_air vaut true et que le bloc cible n'est pas de l'air, le gestionnaire ignore le remplacement même si la demande elle-même a été acceptée.
Avec une durée positive, le gestionnaire sauvegarde les données d'origine du bloc et les restaure à la fin du minuteur, au déchargement du chunk ou du monde, ou à l'arrêt du plugin. La restauration n'a lieu que si l'emplacement contient toujours le bloc temporaire : une modification ultérieure n'est donc pas écrasée. Poser de nouveau sur un bloc qui contient encore un bloc temporaire relance son minuteur et conserve l'original sauvegardé en premier. Les blocs dotés d'une entité de bloc, comme les coffres et les pancartes, et les blocs déjà détenus par un autre propriétaire de blocs temporaires, comme une réservation d'enchantement, sont ignorés. Casser un bloc temporaire ne lâche rien et met fin au suivi sans restauration ; poser un bloc à cet endroit met aussi fin au suivi.
Ces minuteurs ne sont pas annulés avec le script, et le placement ne vérifie pas automatiquement la protection des régions.
world:drop_item(x, y, z, material, [amount])
Lâche une entité item à l'emplacement donné avec une dispersion naturelle.
| Paramètre | Type | Défaut | Notes |
|---|---|---|---|
x | number | requis | Coordonnée X |
y | number | requis | Coordonnée Y |
z | number | requis | Coordonnée Z |
material | string | requis | Nom Bukkit Material |
amount | int | 1 | Taille de la pile |
Retourne une table d'entité pour l'item lâché, ou nil si le matériau était invalide.
context.zones
La table zones permet aux scripts de créer des zones spatiales et de surveiller les entrées et sorties des joueurs. Les props FMM et les scripts de PNJ EliteMobs utilisent les méthodes génériques create_sphere(...) / create_cylinder(...) / create_cuboid(...) avec watch(...) / unwatch(...) documentées ici, qui déclenchent les hooks on_zone_enter / on_zone_leave. Les zones sont liées à l'instance de script et nettoyées automatiquement à sa destruction. Les pouvoirs de boss EliteMobs utilisent une table de zones distincte avec des méthodes comme get_entities_in_zone(...), get_locations_in_zone(...) et watch_zone(...) ; consultez EliteMobs : zones et ciblage.
zones:create_sphere(x, y, z, radius)
Crée une sphère centrée aux coordonnées et retourne un identifiant numérique, ou nil si le propriétaire n'a pas de monde.
| Paramètre | Type | Notes |
|---|---|---|
x | number | Centre X |
y | number | Centre Y |
z | number | Centre Z |
radius | number | Rayon de la sphère |
zones:create_cylinder(x, y, z, radius, height)
Crée un cylindre et retourne un identifiant numérique, ou nil si le propriétaire n'a pas de monde.
| Paramètre | Type | Notes |
|---|---|---|
x | number | Centre X |
y | number | Centre Y (base) |
z | number | Centre Z |
radius | number | Rayon du cylindre |
height | number | Hauteur du cylindre |
zones:create_cuboid(x, y, z, xSize, ySize, zSize)
Crée un cuboïde et retourne un identifiant numérique, ou nil si le propriétaire n'a pas de monde. Les surveillances génériques testent le point de position du joueur ; les dimensions sont donc des demi-étendues autour du centre. Cela diffère des opérations de chevauchement d'entités et de positions échantillonnées des zones de boss. Si zSize est nul et xSize non nul, la forme partagée remplace Z par xSize.
| Paramètre | Type | Notes |
|---|---|---|
x | number | Centre X |
y | number | Centre Y |
z | number | Centre Z |
xSize | number | Demi-étendue en X |
ySize | number | Demi-étendue en Y |
zSize | number | Demi-étendue en Z |
zones:watch(handle, onEnterCallback, onLeaveCallback)
Active les notifications d'entrée et sortie d'une zone déjà créée. Les paramètres doivent être des fonctions Lua, mais leurs corps ne sont pas appelés directement ; la logique passe par on_zone_enter / on_zone_leave. Le suivi commence à la création : un watch tardif n'annonce pas l'entrée d'un joueur déjà suivi à l'intérieur. Passer nil dans un autre watch n'efface pas un gestionnaire déjà activé.
| Paramètre | Type | Notes |
|---|---|---|
handle | int | Handle de zone provenant d'un appel create_* |
onEnterCallback | function ou nil | Une fonction active le hook on_zone_enter pour cette zone ; son corps est ignoré |
onLeaveCallback | function ou nil | Une fonction active le hook on_zone_leave pour cette zone ; son corps est ignoré |
Retourne true si la surveillance a été configurée avec succès, nil si le handle de zone était invalide.
Les zones sont vérifiées avant on_game_tick avec les points de position des joueurs du monde actuel du propriétaire, pas leurs boîtes complètes. Les sphères exigent un point strictement dans le rayon ; les cylindres, dans le rayon et entre la base incluse et le sommet exclu. Les zones conservent leurs coordonnées et monde de création. Une déconnexion ou suppression de surveillance ne garantit pas un hook de sortie. Limitez le nombre de zones.
zones:unwatch(handle)
Arrête la surveillance d'une zone et nettoie ses ressources.
| Paramètre | Type | Notes |
|---|---|---|
handle | int | Handle de zone dont arrêter la surveillance |
Exemple : zone de déclenchement par proximité
return {
api_version = 1,
on_spawn = function(context)
local loc = context.prop.current_location
if loc == nil then return end
local handle = context.zones:create_sphere(loc.x, loc.y, loc.z, 5)
-- Pass placeholder functions to enable on_zone_enter and on_zone_leave hooks.
-- The placeholder bodies are ignored; the actual logic goes in the hooks below.
context.zones:watch(handle, function() end, function() end)
context.state.zone_handle = handle
end,
on_zone_enter = function(context)
context.log:info("Player entered zone!")
end,
on_zone_leave = function(context)
context.log:info("Player left zone!")
end,
on_destroy = function(context)
if context.state.zone_handle then
context.zones:unwatch(context.state.zone_handle)
end
end
}
context.event
La table event est présente lorsque le hook actuel possède un événement ou un acteur. Les clics de props FMM utilisent un indicateur d'annulation du plugin ; les interactions de PNJ et les hooks de zone génériques peuvent fournir un acteur sans événement Bukkit. Elle n'est pas présente pendant on_game_tick, les callbacks programmés ou les hooks de cycle de vie sans joueur déclencheur.
Les hooks on_projectile_hit des props FMM reçoivent l'événement annulable d'impact de projectile de FreeMinecraftModels : cancel() et uncancel() sont donc présents. Le hook s'exécute après que FMM a traité l'impact : l'annuler n'empêche donc pas un projectile non perforant d'être consommé. Il ne se déclenche pas si un autre plugin a déjà annulé l'impact. context.event.player est le tireur lorsqu'il s'agit d'une entité vivante, qui peut être un mob, et est absent sinon ; context.player n'est défini que si c'est un joueur qui a tiré le projectile. Le hook expose aussi context.projectile, une table d'entité pour le projectile.
Pour les hooks génériques on_zone_enter / on_zone_leave, context.player et context.event.player identifient le joueur qui entre dans la zone ou en sort. Ces hooks ne reposent pas sur un événement Bukkit annulable ; cancel() et uncancel() y sont donc absents.
| Champ / Méthode | Type | Notes |
|---|---|---|
is_cancelled | boolean | État d'annulation à la première résolution de la sous-table d'événement. cancel() et uncancel() ne l'actualisent pas. |
cancel() | method | Annule l'événement ; présent uniquement pour les événements annulables |
uncancel() | method | Désannule l'événement ; présent uniquement pour les événements annulables |
player | entity table | Le joueur impliqué dans l'événement, le cas échéant |
on_right_click = function(context)
if context.event and context.event.cancel then
context.event:cancel() -- prevent the default right-click interaction
end
end
Les scripts de pouvoir EliteMobs ont une table d'événement plus détaillée avec les quantités de dégâts, les causes de dégâts, les références aux attaquants et les méthodes de modification de dégâts. Voir Référence de l'API Lua pour les champs complets de l'événement EliteMobs.
Espace de noms d'aide em
La table em est disponible au chargement du fichier. Ses constructeurs créent des données sans charger de monde, enregistrer de surveillance ou valider une forme complète. Les setters retournés modifient leur table et conservent les tables de position reçues par référence.
| Fonction | Objectif |
|---|---|
em.create_location(x, y, z [, world, yaw, pitch]) | Crée une table de localisation avec un nom de monde, yaw et pitch optionnels. La table retournée possède aussi une méthode .add(dx, dy, dz) qui décale la localisation sur place et se retourne elle-même pour le chaînage. |
em.create_vector(x, y, z) | Crée une table vecteur |
em.zone.create_sphere_zone(radius) | Crée une définition de zone sphérique |
em.zone.create_dome_zone(radius) | Crée une définition de zone dôme |
em.zone.create_cylinder_zone(radius, height) | Crée une définition de zone cylindrique |
em.zone.create_cuboid_zone(x, y, z) | Crée une définition de zone cuboïde |
em.zone.create_cone_zone(length, radius) | Crée une définition de zone conique |
em.zone.create_static_ray_zone(length, thickness) | Crée une définition de zone de rayon statique |
em.zone.create_rotating_ray_zone(length, point_radius, animation_duration) | Crée une définition de zone de rayon rotatif |
em.zone.create_translating_ray_zone(length, point_radius, animation_duration) | Crée une définition de zone de rayon en translation |
em.location.is_in_dungeon(loc) | Vérifie si une localisation est à l'intérieur d'une région de donjon enregistrée (tout propriétaire signalant le type "dungeon") |
em.location.is_protected(loc) | Vérifie si une localisation est à l'intérieur d'une région protégée (WorldGuard, GriefPrevention, régions EM, etc.) |
em.location.owned_by(loc, namespace) | Vérifie si un espace de noms de plugin spécifique possède la localisation (par exemple "EliteMobs") |
em.location.owners(loc) | Tableau des chaînes d'espace de noms qui possèdent la localisation |
em.location.kinds_at(loc) | Tableau des étiquettes de type à la localisation ("elitemobs", "dungeon", "world_package", "open_world_dungeon", catégorie de taille de donjon) |
em.location.has_kind(loc, kind) | Vérifie si la localisation est étiquetée avec le type donné |
MagmaCore fournit des adaptateurs WorldGuard et GriefPrevention. Les consommateurs les initialisent à leur activation ; une requête peut aussi les initialiser à la demande. Les requêtes couvrent les fournisseurs enregistrés, pas tous les plugins possibles. Un adaptateur de régions enregistré en échec signale la position comme protégée. Sans fournisseur ni propriété protégée, la requête retourne false et les avertissements indiquent l'absence de fournisseur.
Dans em.location.*, world doit contenir le nom d'un monde chargé ou {name=...}. Le monde du propriétaire n'est pas utilisé en secours. Un monde absent ou introuvable, ou une entrée nil, donne false ou un tableau vide. Les coordonnées absentes valent zéro, mais des champs numériques mal formés peuvent lever une erreur. Les espaces de noms de propriétaires sont sensibles à la casse, les types ne le sont pas. La propriété seule n'implique ni donjon ni protection. L'ordre des tableaux retournés n'est pas garanti.
Les constructeurs de zones retournent des tables chaînables avec :set_center(loc) (ou :set_origin(loc) / :set_destination(loc) selon le type de zone) :
-- At file scope: create a reusable zone shape
local blast_zone = em.zone.create_sphere_zone(5)
return {
api_version = 1,
on_spawn = function(context)
-- Anchor the zone at call time
blast_zone:set_center(context.boss:get_location())
local entities = context.zones:get_entities_in_zone(blast_zone)
-- ...
end
}
L'espace de noms em est particulièrement utile dans EliteMobs où les définitions de zones sont utilisées avec context.zones:get_entities_in_zone() et context.script. Dans FreeMinecraftModels, les méthodes context.zones:create_sphere(...) / create_cylinder(...) / create_cuboid(...) sont plus couramment utilisées pour les zones simples basées sur la surveillance.
Tables d'entités
Les tables ci-dessous présentent les méthodes communes. La référence complète de l'API Lua couvre aussi les champs de projectiles, les vérifications de trajet, la propriété et les méthodes de protection. Elles s'appliquent aux tables d'entité génériques ; les wrappers propres aux pouvoirs EliteMobs ont leur propre section dans cette référence.
Les tables d'entités proviennent des requêtes sur le monde et des données d'événements. Elles fournissent plusieurs niveaux de champs et de méthodes selon le type d'entité.
Champs de base d'entité
| Champ | Type | Notes |
|---|---|---|
uuid | string | L'UUID de l'entité |
entity_type | string | Le type d'entité (par exemple "player", "zombie", "skeleton", "villager") |
is_valid | boolean | Si la référence à l'entité est toujours valide |
is_dead | boolean | Si l'entité est morte |
is_player | boolean | Si l'entité est un joueur |
is_hostile | boolean | Si l'entité implémente Bukkit Monster, pas son agressivité actuelle |
is_passive | boolean | Si l'entité implémente Bukkit Animals, sans garantir un comportement passif |
current_location | location table | La position actuelle de l'entité (x, y, z, world, yaw, pitch) |
world | string | Le nom du monde dans lequel se trouve l'entité |
Méthodes de base d'entité
| Méthode | Retourne | Notes |
|---|---|---|
teleport(location_table) | void | Exige x, y, z ; un monde omis ou introuvable utilise celui de l'entité. yaw et pitch valent zéro par défaut. Aucun contrôle automatique du trajet ou de la protection. |
remove() | void | Supprime l'entité du monde. N'agit que si l'entité est toujours valide. |
set_silent(flag) | void | Supprime ou réactive les sons de l'entité. |
set_invulnerable(flag) | void | Rend l'entité invulnérable ou vulnérable aux dégâts. |
set_gravity(flag) | void | Active ou désactive la gravité pour l'entité. |
set_glowing(flag) | void | Active/désactive l'effet de contour brillant sur l'entité. |
Champs d'entité vivante
Les entités vivantes (joueurs, mobs, etc.) ont tous les champs de base d'entité plus :
| Champ | Type | Notes |
|---|---|---|
health | number | Santé actuelle |
maximum_health | number | Santé maximale |
name | string | Nom d'affichage |
is_alive | boolean | Si l'entité est en vie |
Méthodes d'entité vivante
| Méthode | Retourne | Notes |
|---|---|---|
damage(amount) | void | Inflige la quantité de dégâts donnée à l'entité |
push(x, y, z) | void | Ajoute immédiatement le vecteur à la vitesse actuelle |
set_facing(x, y, z) | void | Téléporte sur place avec une nouvelle direction de regard |
add_potion_effect(effect, duration, amplifier) | void | Ajoute un effet de potion. effect est une chaîne (par exemple "speed", "slowness", "regeneration"). duration est en ticks. amplifier est le niveau d'effet moins 1 (0 = niveau I). |
remove_potion_effect(effect) | void | Supprime un effet de potion par son nom |
get_scale() | number | Retourne l'échelle effective avec ses modificateurs, ou 1.0 si indisponible |
set_scale(value) | void | Change la valeur de base de l'attribut d'échelle si disponible |
Toutes les entités retournées par get_nearby_entities() ne sont pas des entités vivantes. Vous pouvez utiliser entity.is_player, entity.is_hostile ou entity.is_passive pour filtrer par catégorie, ou vérifier if entity.damage then avant d'appeler les méthodes d'entité vivante comme damage(), push() ou add_potion_effect().
Champs d'intégration de plugins
Les tables peuvent contenir des champs d'intégration. Sans l'enrichisseur correspondant, ils sont absents et valent nil. Les indicateurs de suivi, l'identité du modèle, l'état d'opérateur et la plupart des données imbriquées sont des instantanés ; ils ne suivent pas les changements ultérieurs. Les champs de santé partagés EliteMobs sont lus à la demande, et les méthodes de modèles et permissions interrogent leurs objets à l'appel.
Champs EliteMobs
Disponibles lorsque EliteMobs est installé.
| Champ | Type | Notes |
|---|---|---|
is_elite | boolean | Si l'entité est un elite EliteMobs |
is_custom_boss | boolean | Si l'entité est un boss personnalisé EliteMobs (également disponible dans la sous-table elite) |
is_significant_boss | boolean | Si l'entité est un boss personnalisé avec un multiplicateur de santé supérieur à 1 (c'est-à-dire un affrontement conçu, pas un elite de remplissage) |
elite | table ou nil | Sous-table d'informations sur l'elite (voir ci-dessous). nil si l'entité n'est pas un elite. |
La sous-table elite contient :
| Champ | Type | Notes |
|---|---|---|
elite.level | int | Le niveau de l'elite |
elite.name | string ou nil | Le nom d'affichage de l'élite |
elite.health | number | Santé actuelle |
elite.max_health | number | Santé maximale |
elite.is_custom_boss | boolean | S'il s'agit d'un boss personnalisé (par opposition à un elite naturel) |
elite.health_multiplier | number | Multiplicateur de santé défini en config |
elite.damage_multiplier | number | Multiplicateur de dégâts défini en config |
elite:remove() | void | Retire l'élite par le mécanisme de suppression EliteMobs ; ce n'est pas une mort et cela ne garantit aucun butin |
Exemple : Infliger des dégâts différents aux elites
local entities = context.world:get_nearby_entities(x, y, z, 5)
for _, entity in ipairs(entities) do
if entity.is_elite then
-- Deal double damage to elites
entity:damage(20)
context.log:info("Hit elite: " .. entity.elite.name .. " (level " .. entity.elite.level .. ")")
elseif entity.is_hostile then
entity:damage(10)
end
end
Champs FreeMinecraftModels
Disponibles lorsque FreeMinecraftModels est installé.
| Champ | Type | Notes |
|---|---|---|
is_modeled | boolean | Si l'entité a un modèle FMM attaché (DynamicEntity ou PropEntity) |
is_prop | boolean | Si l'entité est un prop FMM (entité décorative statique) |
model | table ou nil | Sous-table d'informations sur le modèle (voir ci-dessous). nil si l'entité n'est pas modélisée. |
La sous-table model contient :
| Champ | Type | Notes |
|---|---|---|
model.model_id | string ou nil | L'identifiant du blueprint de modèle (par exemple "torch_01") |
model.is_dynamic | boolean | Si l'entité modélisée est une DynamicEntity (modèle de mob/boss) plutôt qu'un prop statique |
model:play_animation(name, [blend], [loop]) | boolean | Accepte une demande d'animation nommée. blend et loop valent false par défaut ; une mise en attente ou une attaque supprimée peut retourner true sans lecture immédiate. La mort terminale refuse la lecture. |
model:stop_animations() | void | Efface les lectures en attente et revient à idle si disponible ; la mort terminale n'est pas affectée. |
model:remove() | void | Supprime l'entité modélisée via le pipeline de suppression approprié de FMM. |
Sur les tables d'entité joueur, l'enrichisseur FreeMinecraftModels ajoute aussi :
| Champ / Méthode | Type | Notes |
|---|---|---|
is_op | boolean | Indique si le joueur est opérateur du serveur. |
has_permission(node) | boolean | Indique si le joueur possède la permission. |
Ces deux valeurs de joueur n'existent que dans les scripts FreeMinecraftModels. Sur les tables partagées construites dans EliteMobs, l'adaptateur FreeMinecraftModels propre à EliteMobs ajoute is_modeled, is_prop et model, mais pas is_op ni has_permission.
Les tables joueur FMM exposent aussi is_holding_elitemobs_item(filename). Il vérifie le tag de nom de fichier EliteMobs en main principale, extension .yml incluse, pas le nom affiché. Une main vide, un autre objet ou une intégration indisponible donne false. L'enrichisseur partagé d'EliteMobs ajoute séparément elite_player avec le palier de combat lorsque les données existent ; l'adaptateur EliteMobs facultatif de FMM n'ajoute pas cette sous-table.
Le pont de modèle, disponible sur n'importe quelle entité, donne à blend et loop la valeur false par défaut. La méthode play_animation de la table prop donne aux deux la valeur true pour une lecture mise en attente et en boucle. blend contrôle la mise en attente ; il ne produit pas de fondu entre les animations.
Exemple : Filtrer les entités par type
local entities = context.world:get_nearby_entities(x, y, z, 10)
for _, entity in ipairs(entities) do
if entity.is_prop then
-- Skip props
elseif entity.is_player then
entity:damage(5)
elseif entity.entity_type == "villager" then
-- Don't hurt villagers
elseif entity.is_elite then
entity:damage(20)
elseif entity.is_hostile then
entity:damage(10)
end
end
Champs spécifiques aux joueurs
Les entités joueur ont tous les champs d'entité et d'entité vivante plus :
| Champ | Type | Notes |
|---|---|---|
game_mode | string | Le mode de jeu du joueur ("creative", "survival", "adventure", "spectator") |
Méthodes spécifiques aux joueurs
Partout où l'API indique « prend en charge les codes couleur », Magmacore fait passer la chaîne par son analyseur MiniMessage intégré. Les anciens codes &, les hexadécimaux &#RRGGBB, <#RRGGBB>, <gradient>, <rainbow> et les autres balises MiniMessage fonctionnent et peuvent être mélangés librement. Kyori Adventure n'est pas une dépendance et aucune API Adventure n'est accessible aux scripts ; vous n'en avez pas besoin.
Les méthodes de texte Lua convertissent le résultat en chaîne utilisant les anciens codes couleur. Les couleurs, dégradés et décorations s'affichent donc correctement, tandis que les balises interactives (<hover>, <click>, <insert>, <font>, <key>, <lang>) sont analysées mais sans effet. Consultez le guide commun des codes couleur pour les formats courants.
| Méthode | Retourne | Notes |
|---|---|---|
send_message(msg) | void | Envoie un message dans le chat au joueur. Prend en charge les codes couleur. |
chat(text) | void | Envoie du texte coloré par le chat Bukkit, y compris les commandes commençant par une barre oblique au nom du joueur |
get_held_item() | table ou nil | Retourne {type, amount, display_name} pour l'objet en main principale du joueur, ou nil si elle est vide. type est le nom du Material Bukkit en majuscules, comme "GOLD_INGOT". |
consume_held_item(amount?) | void | Met en attente la consommation en main principale telle qu'elle sera à l'exécution. Vaut 1 par défaut ; ne conserve pas l'objet vérifié et ne confirme pas le paiement. Donnez une quantité positive ; les valeurs négatives ne sont pas rejetées. |
has_item(material, amount?) | boolean | Retourne true si le joueur a au moins amount (par défaut 1) du matériau donné quelque part dans son inventaire |
get_target_entity([range]) | entity table ou nil | Trace depuis les yeux contre blocs et entités en excluant le joueur, avec une taille de 0.5 pour les entités. Ignore les liquides et blocs traversables ; portée par défaut 50. |
get_eye_location() | location table | Retourne une table de localisation à la hauteur des yeux du joueur |
get_look_direction() | table | Retourne un vecteur de direction {x, y, z} pour la direction du regard du joueur |
send_block_change(x, y, z, material, [ticks]) | boolean | Met en attente un bloc uniquement client, avec restauration après une durée positive. True signifie accepté ; un matériau invalide ou qui n'est pas un bloc donne false. |
reset_block(x, y, z) | boolean | Met en attente la restauration du vrai bloc pour le joueur et retourne true |
sleep(x, y, z) | void | Met en attente un vrai lit blanc et une tentative de sommeil. Au réveil ou à la déconnexion, restaure uniquement BlockData, pas le contenu de l'entité de bloc. |
wake_up() | void | Réveille un joueur endormi. |
Les changements de blocs et restaurations en attente lisent le monde du joueur à leur exécution ; ne comptez pas sur la restauration du bloc prévu après un changement de monde. Le nettoyage du sommeil vérifie après 20 ticks, puis tous les 10 ticks. Ces tâches sont indépendantes de context.scheduler.
Méthodes d'interface joueur
Ces méthodes appartiennent à la table Player partagée. Les tables joueur des pouvoirs de boss ont d'autres signatures d'interface, décrites dans la référence API. Les barres partagées sont indexées par joueur dans la copie MagmaCore du plugin, pas par script. Un minuteur d'expiration ne retire que la barre ou la barre d'action répétée qui l'a lancé : une ancienne expiration n'efface donc pas une barre plus récente. Ces minuteurs Bukkit n'appartiennent pas à context.scheduler.
player:show_boss_bar(text, [color], progress, [ticks])
Remplace la barre de boss partagée de style SOLID. Le progrès est limité à 0..1 ; une couleur invalide devient blanche. Passez nil si vous omettez la couleur pour garder le progrès en troisième argument.
| Paramètre | Type | Défaut | Notes |
|---|---|---|---|
text | string | requis | Le texte à afficher. Prend en charge les codes couleur &. |
color | string | "WHITE" | Couleur de la barre. Une parmi : "RED", "BLUE", "GREEN", "YELLOW", "PURPLE", "PINK", "WHITE" |
progress | number | requis | Quantité de remplissage de 0.0 (vide) à 1.0 (plein) |
ticks | int | -1 | Une valeur positive programme le retrait ; sinon la barre reste jusqu'à être masquée ou remplacée |
player:hide_boss_bar()
Supprime la barre de boss de l'écran du joueur. Ne prend aucun paramètre.
player:show_action_bar(text, [ticks])
Affiche du texte dans la zone d'action bar (au-dessus de la hotbar).
| Paramètre | Type | Défaut | Notes |
|---|---|---|---|
text | string | requis | Le texte à afficher. Prend en charge les codes couleur &. |
ticks | int | -1 | Une valeur positive répète tous les 40 ticks jusqu'à expiration ; sinon envoie une fois. Un nouvel appel annule la répétition précédente. |
player:show_title(title, [subtitle], fade_in, stay, fade_out)
Affiche un écran de titre au joueur.
| Paramètre | Type | Défaut | Notes |
|---|---|---|---|
title | string | requis | Texte du titre principal. Prend en charge les codes couleur &. |
subtitle | string | "" | Texte du sous-titre sous le titre principal. Optionnel. |
fade_in | int | requis | Durée de fondu en entrée en ticks |
stay | int | requis | Combien de temps le titre reste à l'écran en ticks |
fade_out | int | requis | Durée de fondu en sortie en ticks |
Étapes suivantes
Pour les hooks, APIs et workflows spécifiques aux plugins :
- EliteMobs : Premiers pas | Scripts de PNJ | Hooks et cycle de vie | Boss et entités | Monde et environnement | Zones et ciblage
- FreeMinecraftModels : Premiers pas | API des props | Exemples