Afficheur de nom sur un item 1.14+ vanilla (Datapack + explications)

Trouvez-vous ces sondages utiles?

  • Oui!

    Votes: 0 0.0%
  • Non.

    Votes: 0 0.0%
  • Jmen fou mdr

    Votes: 0 0.0%
  • La ferme, petit crétin!

    Votes: 2 66.7%
  • ...Pourquoi?

    Votes: 1 33.3%
  • ☣ ☃ ☃ ☃ ☣

    Votes: 0 0.0%

  • Total voters
    3

Eglaios

Crétin de la commu
14 Avril 2018
310
42
89
25
Salut à toute la communauté du forum!
Mon dernier tutoriel portait sur une manipulation de JSON de façon à mettre de la couleur dans des blocs de commandes. Trouvant cela très intéressant, j'ai multiplié les expériences pour finalement aboutir à ceci : un afficheur de nom sur item!

Pour être plus précis, c'est un petit système de trois fonctions permettant à tout joueur d'afficher son nom en tant que "propriétaire" de l'objet dans sa description...
En gros, c'est ça :
Je suis un artiste...
2019-06-24_17.13.31.png
Pour procéder à l'identification, il suffit de dropper un objet, puis une étiquette sur celui-ci. Si l'objet n'est pas déjà identifié (auquel cas un message d'échec s'affichera), celui-ci se verra affublé de votre nom. Si un Lore est déjà présent, le nom sera ajouté à sa suite. L'étiquette ne disparaît pas après utilisation.

Pour éviter les opérations involontaires, l'étiquette ne sera considérée comme valide uniquement si :
-Elle a été lâchée par une entité (Si un contenant comportant une étiquette est cassé, celle-ci, droppée, n'aura pas de tag "Thrower")
-Elle est en mouvement (Encore là, pour éviter que l'action se déclenche

Eh oui, c'est tout à fait possible! Voici la démarche que j'utilise :
Bien sûr, le premier défi est d'extraire le nom du joueur afin de le mettre sur l'objet... Pour cela, j'utilise une technique un peu particulière...

Il faut savoir que les moyens d'extraire le nom d'un joueur sont peu nombreux. En fait, je n'en connais qu'un : le JSON (Bien évidemment). En effet, l'argument JSON "selector" permet de cibler une entité et afficher son nom.
J'utilise ici une pancarte que j'invoque aux positions ~ 0 ~ relatives au joueur déclencheur, ce qui la place dans la couche de bedrock sous ses pieds. Lorsque le processus est complété, je n'ai plus qu'à remplacer la pancarte par un bloc de bedrock.

La technique est simple : J'invoque une pancarte avec l'argument "Selector" sur la première ligne (argument "Text1") visant le joueur ayant déclenché le système. L'argument "Text1" d'une pancarte et "Lore" d'un objet sont tous les deux en JSON, donc compatibles. Je n'ai plus qu'à copier le texte obtenu sur l'objet désiré avec un /data modify et tout est parfait!

Evidemment, les lignes des pancartes ne peuvent afficher qu'un nombre limité de caractères. Cependant, si ceux en trop ne sont pas affichés, ils restent présent dans le tag de bloc; il n'y a donc aucune crainte à avoir de ce côté-là, au cas où un joueur aurait un long nom.
Finalement, comme le transfert de texte est opéré via un /data modify, j'ai également prévu une commande ajoutant le tag "Lore" si l'objet ne le possédait pas déjà (Si le /data modify ne détecte pas le tag déclaré, l'opération n'est pas effectuée).

Donc en gros :
-Une pancarte est invoquée, comportant le nom du joueur sur sa première ligne
-Le texte comportant le nom du joueur est copié directement dans la description de l'objet ciblé.

Evidemment, j'ai ajouté tout un système de tags d'entités pour minimiser les bugs.

Petite précision : les lignes précédées d'un "#" ne sont pas prises en compte par le jeu.
Code:
#Executed each game tick
  execute as @e[type=item,nbt={Thrower:{},Item:{id:"minecraft:name_tag"}},nbt=!{Motion:[0.0,0.0,0.0]},tag=!Invalid] at @s if entity @e[type=item,nbt=!{Item:{id:"minecraft:name_tag"}},distance=...5] at @s run function ownertag:ifbinded
Cette fonction, activée à chaque tick, détecte si une étiquette valide est détectée, puis exécute la fonction "ownertag:ifbinded" en tant que cette étiquette et à sa position
Code:
#Executed from ownertag:main
  execute if data entity @e[type=item,nbt=!{Item:{id:"minecraft:name_tag"}},limit=1,sort=nearest] Item.tag.Bound run tag @s add Invalid
  execute if entity @s[tag=Invalid] run tellraw @p {"text":"This item is already bound!","color":"red"}
  execute if entity @s[tag=!Invalid] run function ownertag:binding
Ici, la fonction ajoute le tag "Invalid" à l'étiquette si l'objet ciblé a déjà été identifié à un joueur (symbolisé par "Bound:1" dans le tag d'item).
Si l'étiquette est invalide, un message d'échec est simplement affiché. Si celle-ci n'en est pas affublée, elle exécute la fonction "ownertag:binding"
Code:
#Executed from ownertag:ifbinded

#Setup
  tag @e[type=item,nbt=!{Item:{id:"minecraft:name_tag"}},limit=1,sort=nearest] add ItemBound
  tag @p add ItemBinding
  execute at @p run setblock ~ 0 ~ minecraft:oak_sign{Text1:"{\"translate\":\"%s's item\",\"with\":[{\"selector\":\"@p[tag=ItemBinding]\"}],\"color\":\"dark_green\",\"italic\":\"false\"}}"}

#Item lore verifying
  execute as @e[tag=ItemBound] unless data entity @s Item.tag.display.Lore run data merge entity @s {Item:{tag:{display:{Lore:[]}}}}

#Item lore adding
  execute at @p run data modify entity @e[tag=ItemBound,limit=1] Item.tag.display.Lore append from block ~ 0 ~ Text1

#Tagging the item as bound
  data merge entity @e[tag=ItemBound,limit=1,sort=nearest] {Item:{tag:{Bound:1}}}

#Reset
  execute at @p run setblock ~ 0 ~ minecraft:bedrock
  tag @e[tag=ItemBound] remove ItemBound
  tag @a[tag=ItemBinding] remove ItemBinding
  tag @s add Invalid
  tellraw @p {"text":"Item successfuly bound to you!","color":"green"}
Cette fonction principale est divisée en cinq partie, exécutées à la suite :

1. La mise en place
Pour faciliter le ciblage des entités, l'objet à modifier se voit affublé du tag "ItemBound", et le joueur concerné, "ItemBinding". Une pancarte comportant le nom du joueur est ensuite placée aux coordonnées ~ 0 ~ depuis le joueur ciblé. Notez qu'ici, j'ai fait une utilisation plus complexe du tag JSON "selector", avec "translate" et "with", me permettant d'ajouter un texte constant en plus.

2. La vérification du Lore
La fonction détecte si l'objet possède déjà un Lore (ce qui, normalement, n'arrive pas, sauf si utilisation d'un autre système de commandes touchant aux lores; cette partie est donc importante). S'il n'en possède pas, la commande lui ajoute un tag "Lore" vierge, afin de pouvoir être affecté par l'étape suivante

3. Le transfert de Lore
Il s'agit de la commande principale du pack : elle transfère le contenu de la première ligne de la pancarte invoquée lors de la mise en place directement dans le Lore de l'objet ("append" permet d'ajouter le nouveau texte à la suite du lore actuel, si existant, plutôt que de le remplacer).

4. Le reset
C'est la dernière partie qui remet les choses comme elles étaient :
-Remplace le panneau par de la bedrock
-Enlève les tags ItemBound et ItemBinding aux entités concernées
Le tag "Invalid" est également ajouté à l'étiquette pour plus de sécurité, et un message de succès est finalement affiché au joueur concerné.

Donc en gros, voici comment je procède.
Maintenant, ce qui est encore plus intéressant, c'est que si le JSON permet l'affichage de noms, l'affichage de scores est également possible! Eh oui, après avoir vu ça, il est tout à fait envisageable de créer un système affichant les statistiques d'un objet, joueur ou autre (dans une certaine mesure)!
Je sens que je pourrais bosser sur un petit pack RPG, moi...


Au fait, le pack est disponible ci-dessous (c'est le fichier ZIP, que vous pouvez mettre directement dans votre .minecraft/saves/<map>/datapacks. Allez dans votre map, puis tapez "/reload" au besoin)
 

Fichiers joints

  • Item Binding Pack 1.14+ by Eglaios.zip
    4.1 KB · Affichages: 537
Dernière édition:
  • J'aime
Reactions: Régis Laspalès