Aller au contenu principal

Enchantements personnalisés

EliteMobs et FreeMinecraftModels fournissent des enchantements personnalisés via un système MagmaCore partagé. Chaque plugin gère ses définitions et effets Lua dans son propre dossier enchantments/. Les enchantements natifs de Minecraft restent dans l'espace de noms minecraft:.

Mise à jour des définitions fournies​

Le catalogue restaure les fichiers YAML et Lua fournis qui manquent et ajoute les champs par défaut absents aux définitions fournies existantes. Il conserve les valeurs déjà configurées et le code Lua existant. Cela fonctionne même si le dossier enchantments/ existe déjà.

Le plugin concerné peut d'abord archiver les fichiers correspondant à un format abandonné. Par exemple, EliteMobs conserve les YAML d'enchantement contenant maxLevelV2 avant de générer les valeurs par défaut actuelles. EliteMobs archive aussi les copies non modifiées d'anciens scripts d'enchantement fournis, comme un ancien grappling_hook.lua, afin que la version par défaut actuelle soit écrite à leur place ; un script que vous avez modifié est conservé. Vérifiez vos paramètres personnalisés dans les archives de configuration et réappliquez-les avec les champs actuels. Un DLC mis à jour ou un effet personnalisé nécessite toujours sa propre définition et son code Lua correspondants.

Références dans les objets​

Les effets personnalisés utilisent un identifiant avec espace de noms en minuscules et un niveau entier positif. Cet exemple est une définition d'objet FMM :

enchantments:
- "minecraft:unbreaking,3"
- "elitemobs:critical_strikes,2"

Par exemple, critical_strikes.yml dans le catalogue d'enchantements d'EliteMobs définit elitemobs:critical_strikes. Une définition FMM utilise freeminecraftmodels:. Les sous-dossiers ne font pas partie de l'identifiant ; donnez des noms uniques aux fichiers de contenu.

Le YAML des objets personnalisés EliteMobs conserve les noms Bukkit comme UNBREAKING,3 pour les enchantements natifs et exige des identifiants avec espace de noms pour les effets personnalisés. Ne copiez pas la syntaxe des enchantements natifs de FMM dans un autre plugin sans vérifier son format d'objet.

Le fournisseur installé doit reconnaître l'identifiant. La compatibilité, le type d'objet, l'emplacement, les conflits et les capacités requises proviennent de sa définition. Retirer un fournisseur ne transforme pas son effet personnalisé en enchantement natif.

Format de définition​

Voici la définition Ignition fournie avec FMM, associée à ignition.lua dans le même catalogue d'enchantements :

isEnabled: true
name: Ignition
description: Sets surviving targets on fire after a staff fireball hits.
maxLevel: 3
curse: false
validSlots: [MAINHAND]
itemTypes: [STAFF]
attackKinds: [STAFF_FIREBALL]
requires: []
conflicts: []
stacking: source_item
script: ignition.lua
parameters:
base_ticks: 20
ticks_per_level: 20
return {
api_version = 1,
on_ignition_ticks = function(context)
return math.max(0, math.min(200, context.parameters.base_ticks
+ context.parameters.ticks_per_level * context.enchantment.level))
end
}

Cette requête retourne une durée d'embrasement à FMM. Elle ne s'exécute pas comme un script de prop ou d'objet équipé.

ChampSignification
isEnabledVaut true par défaut ; les définitions désactivées n'entrent pas dans le catalogue
nameNom d'affichage simple obligatoire
descriptionDescription facultative, vide par défaut
maxLevelPlafond positif du niveau d'enchantement ; les objets explicitement définis peuvent le dépasser
curseIndique si l'enchantement est une malédiction ; vaut false par défaut
validSlotsEmplacements d'équipement : HEAD, CHEST, LEGS, FEET, MAINHAND, OFFHAND
itemTypesCatégories acceptées : SWORD, AXE, PICKAXE, SHOVEL, HOE, BOW, CROSSBOW, TRIDENT, MACE, SPEAR, HELMET, CHESTPLATE, LEGGINGS, BOOTS, SHIELD, FISHING_ROD, SHEARS, ELYTRA, WAND, STAFF, OTHER
attackKindsFiltre facultatif d'attaque magique : WAND_MISSILE, STAFF_MELEE, STAFF_FIREBALL
requiresCapacités requises du fournisseur
conflictsAutres identifiants d'enchantement en minuscules avec espace de noms
stackingsource_item par défaut, ou sum_equipped_levels
scriptNom obligatoire de fichier .lua en minuscules, sans dossier
parametersValeurs scalaires nommées ou listes de valeurs scalaires par niveau
setFacultatif. Fait de cet enchantement un ensemble d'objets

Une liste par niveau doit contenir exactement maxLevel entrées. Au-delà de ce niveau, la dernière valeur de la liste est conservée tandis que le script reçoit toujours le niveau réel de l'enchantement. Les paramètres appartiennent à l'effet concerné ; ajouter ici une clé arbitraire ne crée pas de nouvelle mécanique.

Les champs de premier niveau inconnus, identifiants en double, scripts manquants et hooks non pris en charge font rejeter le catalogue candidat. Corrigez le fichier nommé dans l'erreur avant de recharger. Un candidat invalide ne remplace pas le catalogue actif.

Responsabilité des effets​

Partez d'un effet fourni par le plugin qui gérera votre nouvelle définition. Ses hooks et opérations disponibles déterminent ce qu'il peut faire. Les hooks de requête retournent des valeurs comme le nombre de missiles, la probabilité de coup critique ou le bonus de menace. Les hooks d'action traitent les entrées d'objet acceptées et peuvent gérer des effets temporisés.

L'ancienne API FMM context.item et son cycle équipement/déséquipement ne s'appliquent pas ici. Les scripts d'enchantement utilisent leurs propres context.enchantment, context.parameters, informations de source capturées et opérations d'action. Ne renommez pas un ancien script d'objet en supposant que son contexte est compatible.

Livres et enclumes​

Les livres enchantés personnalisés utilisent les mêmes définitions de fournisseur que les objets équipés. Une enclume valide l'objet source, le livre et le résultat complet, y compris les enchantements natifs. Deux niveaux personnalisés égaux se combinent au niveau suivant ; des niveaux inégaux conservent le plus élevé. Chaque enchantement personnalisé modifié ajoute son niveau résultant au coût de réparation natif. Le niveau obtenu doit respecter les contrôles de la définition pour la limite d'enclume, l'emplacement, le type, les capacités et les conflits.

Les livres mixtes doivent transférer chaque entrée native acceptée par le serveur ainsi que leurs entrées personnalisées. Si le serveur refuse une entrée native, l'opération personnalisée est refusée au lieu d'abandonner silencieusement cette partie du livre. Les définitions invalides ou indisponibles empêchent aussi l'aperçu. Les entrées et l'état du fournisseur sont revérifiés à la récupération ; un aperçu visible n'est pas une réservation qui survit à un changement de catalogue.

Référence des requêtes Lua​

Les requêtes numériques exécutent une nouvelle instance de script et la ferment immédiatement après le résultat. Retournez un nombre fini ou nil pour ne rien apporter. L'état et les tâches programmées ne survivent pas à la requête. Une définition en échec est mise en quarantaine jusqu'à un rechargement réussi du catalogue ; épuiser le budget restant de l'appelant ne met pas à lui seul la définition en quarantaine.

ContexteContenu
context.enchantmentid et level réel
context.parametersValeurs de cette définition résolues pour ce niveau
context.inputDonnées scalaires fournies par la mécanique propriétaire ; consultez l'effet fourni pour les clés exactes
context.targetTable Entity ou Living Entity de la cible, ou nil
context.playerJoueur déclencheur lorsque la requête en possède un

FMM fournit on_missile_count, on_missile_damage_factor, on_blast_radius_factor et on_ignition_ticks. Les autres fournisseurs exposent leurs propres hooks numériques. Une définition ne peut déclarer que des hooks acceptés par son fournisseur.

Référence des actions Lua​

Les scripts d'action utilisent les tables partagées du planificateur, des temps de recharge, du monde, des zones, des joueurs et des événements. Ils s'exécutent pour une entrée ou une attaque acceptée et utilisent une source capturée pour les callbacks ultérieurs. Le chat capture le message pendant l'événement de chat, puis l'équipement lors de la distribution sur le thread serveur. Le paramètre facultatif parameters.lifetime_ticks doit être un entier positif ; sans lui, l'activation dure un tick. Les effets programmés nécessitent une durée définie assez longue pour se terminer.

Les activations s'arrêtent à l'expiration de leur durée, à la mort ou à la déconnexion de l'acteur, lorsqu'il change de monde, lorsque le monde propriétaire ou un chunk contenant une de leurs entités gérées est déchargé, ou lorsque le fournisseur est rechargé ou désactivé. Elles peuvent se terminer plus tôt une fois que la dernière entrée n'a plus de travail restant à sa charge. parameters.stop_on_unequip: true arrête également une activation lorsque son objet capturé n'est plus équipé. Les temps de recharge locaux appartiennent au joueur et à l'identifiant d'enchantement ; les temps de recharge globaux appartiennent au joueur au sein du fournisseur. Les deux survivent aux échanges d'équipement, aux activations terminées, aux changements de monde et aux rechargements valides, et sont effacés à la déconnexion ou à l'arrêt du fournisseur.

HookEntrée acceptée
on_attack_entityDégâts natifs de mêlée réussis et positifs avec l'objet en main principale, ou attaque explicitement gérée par un plugin
on_projectile_hitDégâts réussis sur une cible vivante par un projectile d'arc capturé, transmis une fois par projectile et cible, ou impact explicitement géré par un plugin
on_take_damageDégâts positifs au joueur ; les emplacements équipés admissibles sont inspectés
on_right_click, on_left_clickInteraction de la main sans accroupissement
on_shift_right_click, on_shift_left_clickInteraction de la main en étant accroupi ; remplace le hook de clic ordinaire correspondant
on_break_blockDestruction de bloc acceptée par le joueur avec l'objet en main principale
on_chatChat accepté, distribué sur le thread serveur avec le message capturé
on_sneakDébut de l'accroupissement ; les contributions de l'équipement sont collectées par définition
on_projectile_launchMunition enchantée consommée et lancée comme flèche depuis un événement d'arc
on_game_tickTick tant que cette activation reste active
on_zone_enter, on_zone_leaveJoueurs traversant une zone surveillée par cette activation

Ces hooks ne créent pas de moteur de scripts avec équipement/déséquipement. Une définition ne contenant qu'un hook de tick a toujours besoin d'un hook d'entrée pour démarrer son activation. Les hooks natifs d'attaque, de dégâts, de chat et de minage observent des entrées déjà acceptées ; ils ne peuvent pas annuler l'événement original. Les quatre hooks d'interaction exposent un indicateur d'annulation synchrone : context.event:cancel() refuse l'interaction associée avec l'objet et le bloc. Les callbacks programmés ne peuvent pas annuler rétroactivement une entrée.

ContexteContenu
context.enchantmentid, level
context.parametersParamètres de définition résolus pour le niveau
context.playerTable Player de l'acteur actuel
context.targetTable Living Entity de la cible actuellement affectée, ou nil
context.sourceDonnées capturées : item, slot, inventory_slot, equipment, attack_kind, providers ; certaines entrées fournissent aussi ammunition, projectile, message, block, drop_items, sneaking ou equipped_levels
context.itemMéthodes de durabilité et de consommation de l'emplacement capturé lorsqu'un objet d'inventaire reste accessible ; voir les méthodes d'objet
context.actionid (UUID de l'attaque), instance (jeton d'activation), actor (UUID), world (UUID du monde) et méthodes ci-dessous
context.setPour un ensemble d'objets : id, name, level et pieces ; nil sinon

Les instantanés d'objet contiennent material, amount et enchantments. Ce sont des données, pas des objets d'inventaire actifs. Les UUID des données sources sont des chaînes. Pour le minage, source.block contient x, y, z et material en minuscules.

Méthode d'actionRetourComportement
stop()nilArrête cette activation et nettoie le travail dont elle est responsable
has_previous()boolVérifie s'il existe une autre instance active de cet enchantement pour le même joueur
replace_previous()nilArrête ces instances antérieures en conservant celle-ci
damage_target(target_uuid, amount)boolDemande au fournisseur d'appliquer des dégâts finis et positifs attribués à la source capturée ; false en cas de refus
own_entity(uuid)boolEnregistre une entité valide du même monde, autre qu'un joueur, pour suppression au nettoyage ; à utiliser après son apparition
launch_projectile(location, direction, speed, range, ticks, impact, visual?, protected_path?=false)boolLance un projectile scripté géré ; speed/range doivent être finis et positifs, et ticks au moins égal à 1
attribute_projectile(uuid, callback, protect?=false)boolAssocie les dégâts d'un projectile natif géré à un callback défini
place_block(x, y, z, expected_material, block_data)boolPlace un bloc après validation des actions de bloc du joueur, uniquement si le matériau actuel correspond
break_block(x, y, z, expected_material, drop_material?, amount?=1)boolCasse un bloc après validation des actions de bloc du joueur, avec un objet lâché facultatif défini
break_naturally(x, y, z, expected_material)boolCasse avec l'outil capturé et la règle de butin de l'événement de destruction source
temporary_block(x, y, z, block_data, ticks?=0)boolPrend temporairement en charge un bloc chargé, restauré au nettoyage ou après un nombre positif de ticks ; zéro dure jusqu'au nettoyage
can_own_block(x, y, z)boolVérifie que les coordonnées sont chargées et que la prise en charge temporaire est disponible
temporary_gravity(uuid, enabled)boolModifie temporairement la gravité et la restaure au nettoyage
restore_gravity(uuid)boolRestaure en avance la gravité modifiée par cette activation
temporary_scale(uuid, scale)boolModifie temporairement l'échelle d'une entité vivante jusqu'au nettoyage
temporary_potion(uuid, type, ticks, amplifier)boolApplique temporairement un effet de potion avec une durée positive en ticks et un amplificateur non négatif
restore_potion(uuid, type)boolRestaure en avance l'effet de potion modifié par cette activation
ride_rails(speed)boolInstalle le joueur dans un wagonnet que seuls les clients voient et le fait avancer sur les rails connectés du bloc où se trouve le joueur, vers l'extrémité qu'il regarde, à speed blocs par tick (supérieur à 0, au plus 2) ; false si aucun rail ne s'y trouve, si le joueur chevauche déjà quelque chose ou si l'adaptateur NMS du serveur est indisponible

Un trajet sur rails fait partie du travail dont son activation est responsable. S'accroupir, la fin de la voie, une téléportation, la mort, une déconnexion ou tout ce qui éloigne le joueur de plus d'un bloc du wagonnet met fin au trajet, puis à l'activation ; le joueur est déposé là où le wagonnet s'est arrêté, sauf après une téléportation, une mort ou une déconnexion. Arrêter l'activation, notamment par replace_previous(), fait aussi descendre le joueur. Le lifetime_ticks de l'activation s'applique toujours : accordez-lui donc assez de temps pour la voie la plus longue.

Les callbacks d'impact de projectile reçoivent (fresh_context, target_or_nil, location) ; les callbacks visuels reçoivent (fresh_context, location). Les callbacks de dégâts de projectile natif reçoivent (fresh_context, target, native_damage) au tick suivant. Ils remplacent l'application native et doivent appliquer explicitement les dégâts voulus, normalement avec fresh_context.action:damage_target(target.uuid, amount). Avec protect=true sur un projectile natif, les blocs protégés sont filtrés pour les explosions et l'embrasement. Pour les projectiles scriptés, protected_path=true absorbe les trajectoires qui traversent des positions protégées ou non chargées.

Le nettoyage géré se limite aux opérations qui enregistrent cette responsabilité. Les opérations ordinaires world:spawn_entity, entity:set_gravity et world:set_block_at ne bénéficient pas automatiquement du nettoyage de l'action. Les méthodes d'état temporaire gèrent la restauration ; elles ne remplacent pas la vérification de l'autorisation d'un effet hostile ou d'une modification de bloc.

Ensembles d'objets​

Une section set transforme un enchantement en ensemble d'objets. Placez le même enchantement sur chaque pièce. L'ensemble est complet tant que chaque emplacement listé sous pieces contient un objet qui le porte. Un ensemble complet exécute ses hooks une fois par événement. Si une pièce manque, rien ne s'exécute.

name: Crooked's Full Set
maxLevel: 1
validSlots: [HEAD, CHEST, LEGS, FEET]
itemTypes: [HELMET, CHESTPLATE, LEGGINGS, BOOTS]
script: crooked_set.lua
parameters:
lifetime_ticks: 620
stop_on_unequip: true
set:
pieces:
HEAD: Crooked's Hex-Brim
CHEST: Crooked's Warded Wrap
LEGS: Crooked's Bent Hosen
FEET: Crooked's Wayward Soles
lore:
- "&5Crooked's Full Set &7($equippedPieces/$totalPieces)"
- "$setPieces"
- "&7When damaged, has a 5% chance to grant Regeneration I."
return {
api_version = 1,
on_take_damage = function(context)
-- Runs only while all four pieces are worn, once per hit.
context.action:temporary_potion(context.player.uuid, "REGENERATION", 100, 0)
end
}
Champ de l'ensembleSignification
piecesObligatoire. Associe les emplacements d'équipement aux noms des pièces. Lorsque validSlots est défini, il doit inclure l'emplacement de chaque pièce
nameNom utilisé par $setName. Reprend par défaut le name de l'enchantement et accepte les codes de couleur &
loreLes lignes de lore de l'ensemble. Par défaut, le nom de l'ensemble avec son nombre de pièces, puis une ligne par pièce
equippedPieceLigne d'une pièce portée. Vaut &a✔ $pieceName par défaut
missingPieceLigne d'une pièce manquante. Vaut &c✘ $pieceName par défaut

Le lore de l'ensemble accepte ces espaces réservés :

Espace réservéAffiche
$setNameLe nom de l'ensemble
$equippedPiecesLe nombre de pièces que porte le joueur
$totalPiecesLe nombre de pièces de l'ensemble
$setPiecesUne ligne par pièce dans l'ordre des emplacements, tirée de equippedPiece ou missingPiece. Le texte autour de l'espace réservé est répété sur chaque ligne
$pieceName, $pieceSlotDans equippedPiece et missingPiece, le nom de la pièce et son emplacement, comme Head ou Main Hand
$ifSetCompleteN'affiche la ligne que tant que chaque pièce est portée
$ifSetIncompleteN'affiche la ligne que tant qu'une pièce manque

Les objets d'ensemble affichent cette section à la place d'une ligne dans la liste des enchantements personnalisés. Dans EliteMobs, placez $itemSet dans itemLoreStructureV2 de ItemSettings.yml, ou dans le lore d'un objet personnalisé. Sans l'un ni l'autre, l'ensemble suit le lore personnalisé de l'objet. $ifItemSet n'affiche une ligne de la structure que sur les objets d'ensemble. Les objets personnalisés FMM affichent l'ensemble sur la ligne de lore qui contient $itemSet, ou à la suite de leur lore.

La section montre ce que porte le joueur qui détient l'objet et se redessine lorsqu'il équipe ou retire une pièce. Un objet rangé en dehors de l'inventaire d'un joueur garde l'état qu'il affichait en le quittant.

Les hooks d'ensemble diffèrent des hooks d'enchantement ordinaires sur quelques points :

  • Chaque hook d'action du tableau ci-dessus atteint un ensemble complet, quels que soient les emplacements de ses pièces. Un ensemble d'armure peut répondre à on_attack_entity ou on_break_block.
  • L'état complet est vérifié au moment de l'événement. Un projectile vérifie les ensembles portés à son atterrissage, et tout projectile compte, pas seulement les flèches d'arc.
  • on_take_damage définit context.target sur l'attaquant lorsqu'il y en a un.
  • context.source.item et context.item sont la première pièce dans l'ordre des emplacements : HEAD, CHEST, LEGS, FEET, MAINHAND, OFFHAND. Lisez context.source.equipment.MAINHAND pour l'arme ou l'outil tenu.
  • context.set.level est le niveau le plus bas parmi les pièces. context.set.pieces est indexé par emplacement, avec le name et l'inventory_slot de chaque pièce.
  • stop_on_unequip: true arrête une activation d'ensemble dès qu'une pièce est retirée.
  • Les requêtes numériques, comme la menace et le taux de coup critique d'EliteMobs ou les modificateurs de lancer de FMM, comptent un ensemble une seule fois et seulement tant qu'il est complet.

Mise à niveau du contenu existant​

FMM ignore les objets personnalisés avec une liste scripts: non vide ou d'anciennes entrées d'enchantement sans espace de noms. Remplacez ces définitions d'objet par des enchantements avec espace de noms ; les scripts de props restent pris en charge.

Les effets personnalisés EliteMobs utilisent désormais maxLevel et des parameters propres à chaque effet dans le YAML du fournisseur. La configuration des enchantements natifs et de niveau élite suit un format distinct. Consultez la référence des enchantements EliteMobs plutôt que de copier un ancien fichier maxLevelV2 dans une définition de fournisseur.