Navigation

    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    1. Home
    2. DiabolicaTrix
    • Profile
    • Following 0
    • Followers 0
    • Topics 24
    • Posts 432
    • Best 16
    • Groups 2

    DiabolicaTrix

    @DiabolicaTrix

    Correcteurs Moddeurs confirmés

    51
    Reputation
    1555
    Profile views
    432
    Posts
    0
    Followers
    0
    Following
    Joined Last Online
    Website dtrix.dev Location Québec Age 19

    DiabolicaTrix Follow
    Moddeurs confirmés Correcteurs

    Best posts made by DiabolicaTrix

    • Utiliser les capabilities

      Sommaire

      • Introduction
      • Pré-requis
      • Code
        • Packet
        • Classe Principale
        • ScheduledPacketTask
        • Le provider, le storage et la factory
        • L’event handler
      • Bonus
      • Résultat
      • Crédits

      Introduction

      Bonjour, dans ce tutoriel, je vais vous montrer comment utiliser le nouveau système de “capabilities” ou capacité qui remplace les Extended Entity Properties des versions précédentes. Les capacités ont la même fonction que les EEP, elles servent à sauvegarder des données “dans” une entité. NB: Le système de Extended Entity Properties est déprécié depuis la 1.8.

      Pré-requis

      • Avoir des bases en Java
      • Savoir manipuler les packets
      • Savoir utiliser les events

      Code

      Packet :

      Je vous invite donc à créer une nouvelle classe pour notre Packet, je vais la nommer “PacketCapabilitiesTutoriel” pour ce tutoriel. Vous devez implémenter IMessage dans votre classe et ajouter les méthodes non-implémentées. Ça devrait vous donner ça:

      public class PacketCapabilitiesTutoriel implements IMessage
      {
          @Override
          public void fromBytes(ByteBuf buf)
          {
      
          }
      
          @Override
          public void toBytes(ByteBuf buf)
          {
      
          }
      }
      

      Pour cet exemple, je vais faire un système de monnaie comme Gugu42 a fait dans son tutoriel sur les Extended Entity Properties. Donc, on crée une nouvelle variable public de type int en haut de notre classe. Ensuite, à l’aide du ByteBuf, on la convertie en byte et on la récupère, il ne faut pas oublier de créer un constructeur vide et un constructeur avec les valeurs nécessaires sinon ça ne fonctionnera pas.

      public int money;
      
      public PacketCapabilitiesTutoriel(int money)
      {
              this.money = money;
      }
      
      public PacketCapabilitiesTutoriel() {}
      
      @Override
      public void fromBytes(ByteBuf buf)
      {
          this.money = buf.readInt();
      }
      
      @Override
      public void toBytes(ByteBuf buf)
      {
          buf.writeInt(this.money);
      }
      

      Il ne nous manque plus que les Handlers, c’est relativement simple, on crée deux classes statiques à l’intérieur de notre classe. Les handlers doivent implémenter IMessageHandler, le premier sera nommé ClientHandler et le deuxième ServerHandler.

      public static class ServerHandler implements IMessageHandler <PacketCapabilitiesTutoriel, IMessage>{
      
          @Override
          public IMessage onMessage(PacketCapabilitiesTutoriel message, MessageContext ctx)
          {
              //Nous reviendrons sur cette ligne plus tard.
              MinecraftServer.getServer().addScheduledTask(new ScheduledPacketTask(ctx.getServerHandler().playerEntity, message));
              return null;
          }
      
      }
      
      @SideOnly(Side.CLIENT)
      public static class ClientHandler implements IMessageHandler <PacketCapabilitiesTutoriel, IMessage>{
      
          @Override
          public IMessage onMessage(PacketCapabilitiesTutoriel message, MessageContext ctx)
          {
              //Nous reviendrons sur cette ligne plus tard.
              Minecraft.getMinecraft().addScheduledTask(new ScheduledPacketTask(null, message));
              return null;
          }
      }
      

      Classe Principale :

      Il y a plusieurs choses à faire ici. Premièrement, vous devez enregistrer le packet:

      network.registerMessage(PacketCapabilitiesTutoriel.ClientHandler.class, PacketCapabilitiesTutoriel.class, 3, Side.CLIENT);
      network.registerMessage(PacketCapabilitiesTutoriel.ServerHandler.class, PacketCapabilitiesTutoriel.class, 3, Side.SERVER);
      

      Ensuite, vous devez ajouter le code ci-dessous en haut de votre classe.

          @CapabilityInject(TutoCapabilities.class)
          public static final Capability<TutoCapabilities> TUTO_CAP = null;
      

      Et finalement, vous devez enregistrer votre capacité dans le init:

      TutoCapabilities.register();
      

      ScheduledPacketTask:

      J’ai créé cette classe pour rendre mon code plus lisible, mais vous pouvez très bien la mettre directement dans vos paramètres comme n’importe quel “runnable”. Implémentez Runnable dans votre classe et ajoutez les méthodes non-implémentées. Vous devez ensuite créer un constructeur avec les paramètres nécessaires. Pour la rendre compatible client et serveur, j’ai mis un paramètre EntityPlayer, il sera null pour le client et défini pour le serveur. Ça devrait donner ça:

      public class ScheduledPacketTask implements Runnable
      {
          private EntityPlayer player;
          private PacketCapabilitiesTutoriel message;
      
          public ScheduledPacketTask(EntityPlayer player, PacketCapabilitiesTutoriel message)
          {
              this.player = player;
              this.message = message;
          }
      
          @Override
          public void run()
          {
              //Condition ternaire pour récupérer le joueur selon le côté.
              EntityPlayer player = this.player == null ? getPlayer() : this.player;
              //On revient sur cette ligne plus tard.
              player.getCapability(ModTutoriel.TUTO_CAP, null).setMoney(message.money);
          }
      
          @SideOnly(Side.CLIENT)
          private EntityPlayer getPlayer()
          {
              return Minecraft.getMinecraft().thePlayer;
          }
      
      }
      

      Le provider, le storage et la factory :

      Je vous invite maintenant à créer une classe qui implémente ICapabilityProvider et INBTSerializable. Ajoutez les méthodes non-implémentées et ça devrait vous donner ceci:

      public class TutoCapabilities implements ICapabilityProvider, INBTSerializable<NBTTagCompound> {
          @Override
          public boolean hasCapability(Capability capability, EnumFacing facing)
          {
              return false;
          }
      
          @Override
          public <T> T getCapability(Capability <T>capability, EnumFacing facing)
          {
              return null;
          }
      
          @Override
          public NBTTagCompound serializeNBT()
          {
              return null;
          }
      
          @Override
          public void deserializeNBT(NBTTagCompound compound)
          {
      
          }
      }
      

      Maintenant, nous allons modifier les méthodes hasCapability et getCapability pour les adapter à notre code et pour qu’elles retournent les bonnes valeurs. Premièrement, on doit modifier le return de hasCapability pour que ça retourne la véritable valeur et non simplement false.

      return ModTutoriel.TUTO_CAP != null && capability == ModTutoriel.TUTO_CAP;
      

      On vérifie que la capacité ne soit pas nulle et que ce soit bien la nôtre. Si oui, on retourne true, sinon on retourne false. Ensuite, on change le return de getCapability pour retourner l’instance de la classe en faisant les mêmes vérifications que plus haut.

      return ModTutoriel.TUTO_CAP != null && capability == ModTutoriel.TUTO_CAP ? (T)this : null;
      

      Ensuite, il faut modifier les méthodes deserializeNBT et serializeNBT, elles servent à sauvegarder les valeurs. Dans le deserializeNBT, nous devons créer un nouvel objet NBTTagCompound, qui va stocker nos valeurs. Ensuite, on doit ajouter notre valeur dans le compound et finalement, on le retourne.

      @Override
      public NBTTagCompound serializeNBT()
      {
          NBTTagCompound compound = new NBTTagCompound();
          compound.setInteger("Money", this.getMoney());
          return compound;
      }
      

      Et dans la méthode deserialize, on récupère le tag et on met à jour la valeur avec celui-ci.

      @Override
      public void deserializeNBT(NBTTagCompound compound)
      {
          this.setMoney(compound.getInteger("Money"));
      }
      

      Après, on crée la variable public de type int et on crée un getter/setter pour celle-ci.

      public int money;
      
      public void setMoney(int money)
      {
          this.money = money;
      }
      
      public int getMoney()
      {
          return this.money;
      }
      

      Maintenant, on va créer deux classes statiques dans notre classe comme avec les packets. Les deux sont inutiles, mais elles sont nécessaires pour que cela fonctionne. NB: Elles ne sont pas inutiles, mais elles ne nous servent pas. Elles servent seulement quand l’entité n’appartient pas à Minecraft.

      public static class Storage implements Capability.IStorage<TutoCapabilities> {
      
          @Override
          public NBTBase writeNBT(Capability<TutoCapabilities> capability, TutoCapabilities instance, EnumFacing side)
          {
              return null;
          }
      
          @Override
          public void readNBT(Capability<TutoCapabilities> capability, TutoCapabilities instance, EnumFacing side, NBTBase nbt)
          {
      
          }
      
      }
      
      public static class Factory implements Callable<TutoCapabilities> {
          @Override
          public TutoCapabilities call() throws Exception
          {
              return null;
          }
      }
      

      Finalement, nous devons créer deux méthodes: sync, register et un constructeur. La méthode sync sert à synchroniser entre le client et le serveur, elle doit être appelée quand on modifie une valeur. La méthode register, elle, doit être statique et est appelée depuis la classe principale, elle sert à enregistrer la capacité. Le constructeur, lui, est appelé quand on attache la capacité au joueur. Il faut aussi créer une nouvelle variable de type EntityPlayer pour pouvoir récupérer le joueur dans notre méthode sync.

      private EntityPlayer player;
      
      public static void register()
      {
          CapabilityManager.INSTANCE.register(TutoCapabilities.class, new TutoCapabilities.Storage(), new TutoCapabilities.Factory());
      }
      
      public TutoCapabilities(EntityPlayer player)
      {
          this.money = 0;
          this.player = player;
      }
      
      public void sync()
      {
          PacketCapabilitiesTutoriel packet = new PacketCapabilitiesTutoriel(this.getMoney());
          if(!this.player.worldObj.isRemote)
          {
              EntityPlayerMP playerMP = (EntityPlayerMP)player;
              ModTutoriel.network.sendTo(packet, playerMP);
          }
          else
          {
              ModTutoriel.network.sendToServer(packet);
          }
      }
      

      L’event handler :

      Je ne décrirai pas comment enregistrer un event handler, je vais seulement expliquer les events à utiliser. Si vous ne savez pas comment utiliser les events, je vous invite à aller voir le tutoriel sur ceux-ci dans les pré-requis. Le premier event à utiliser est le PlayerEvent.Clone, il est appelé quand le joueur est cloné. Le joueur est cloné quand il change de dimension et quand il meurt. Dans notre cas, on veut exécuter l’event seulement à la mort du joueur. Dans l’event, vous avez accès à plusieurs variables: original, entityPlayer et wasDeath. Nous aurons besoin des trois, le premier est l’instance du joueur qui est mort, le deuxième est l’instance du nouveau joueur qui respawn et le dernier est un boolean qui est à true si l’event est appelé à la suite de la mort du joueur.

          @SubscribeEvent
          public void onPlayerCloned(PlayerEvent.Clone event)
          {
              if(event.wasDeath)
              {
                  if(event.original.hasCapability(ModTutoriel.TUTO_CAP, null))
                  {
                      TutoCapabilities cap = event.original.getCapability(ModTutoriel.TUTO_CAP, null);
                      TutoCapabilities newCap = event.entityPlayer.getCapability(ModTutoriel.TUTO_CAP, null);
                      newCap.setMoney(cap.getMoney());
                  }
              }
          }
      

      Le deuxième event à utiliser est le PlayerRespawnEvent, il est appelé quand le joueur respawn, mais après le PlayerEvent.Clone et le prochain event. Dans cet event, nous allons synchroniser, tout simplement.

      @SubscribeEvent
      public void onPlayerRespawn(PlayerRespawnEvent event) 
      {
          if(!event.player.worldObj.isRemote)
          {
              event.player.getCapability(ModTutoriel.TUTO_CAP, null).sync();
          }
      }
      

      Et finalement, le dernier event à utiliser est le AttachCapabilitiesEvent.Entity, il est appelé quand les autres capacités sont attachées aux entités. C’est à ce moment que l’on doit attacher notre capacité à notre joueur.

      @SubscribeEvent
      public void onAttachCapability(AttachCapabilitiesEvent.Entity event)
      {
          if(event.getEntity() instanceof EntityPlayer)
          {
              event.addCapability(new ResourceLocation(ModTutoriel.MODID + ":TUTO_CAP"), new TutoCapabilities((EntityPlayer) event.getEntity()));
          }
      }
      

      Bonus

      Aucun bonus pour le moment, mais n’hésitez pas à le demander si vous avez une idée.

      Résultat

      Je ne peux pas prendre de screenshot du résultat, puisque le but est de sauvegarder des données. Le résultat est simplement que les données sont sauvegardées après la mort et après la déconnexion.

      Crédits

      Rédaction :

      • ☆DiabolicaTrix☆

      Correction :

      • ☆Toutoune1008☆

      Mentions spéciales :

      • diesieben07
      • Lexmanos

      Creative Commons
      Ce tutoriel de Minecraft Forge France est mis à disposition selon les termes de la licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International

      retourRetour vers le sommaire des tutoriels

      posted in Autres
      DiabolicaTrix
      DiabolicaTrix
    • RE: Afficher une image lors de la connexion.

      Premièrement, RenderGameOverlayEvent n’est pas un Gui. À moins que tu veules dessiner l’image directement dans l’écran sans que le puisse bouger son curseur. En gros, le RenderGameOverlay permet de dessiner quelque chose sur l’écran sans que le jeu du joueur soit affecté. Ex.: Le menu F3.

      Si tu veux que le joueur puisse intéragir avec l’image, tu dois créer un GuiScreen (qui extends Gui donc tu peux aussi utiliser Gui directement) que tu affiches à la connexion du joueur. Tu vas surement avoir des problèmes de NPE quand tu vas arriver à cette étape. Tu ne dois pas utiliser d’events comme EntityJoinWorld ou PlayerLoggedIn, mais un TickHandler avec un boolean que tu mets sur true quand il accepte et que tu remets sur false à sa déconnexion.

      EDIT: J’écrivais mon message quand tu as répondu.

      posted in 1.8.x
      DiabolicaTrix
      DiabolicaTrix
    • RE: Récupérer les packets envoyés au joueur ?

      Aussi, fait attention à la convention, Une variable doit commencer par une lettre minuscule et si il y a un deuxieme mot le deuxieme commence par une lettre majuscule exemple: lastHealth. Tu dois les écrires préférablement en Anglais.

      posted in 1.7.x
      DiabolicaTrix
      DiabolicaTrix
    • RE: Bug Minecraft

      Il peut le mettre mais ce n’est pas dans la section support pour les moddeurs, il n’y a donc pas de section Résolu, donc pas de tri, donc pas vraiment besoin.

      posted in Support pour les utilisateurs
      DiabolicaTrix
      DiabolicaTrix
    • RE: Plusieurs textures pour un même modèle custom d'une entité

      Ah ouais c’est vrai ce que robin a dit, tu peux mettre ton addobject dans le constructeur de l’entité, mais si tu veux pas touché parce que ça marche c’est pas grave ^^
      Par contre je te faisait modifier des trucs car je n’avais pas vu que tu avais dit que ça fonctionnait 😛

      Pour la sauvegarde, c’est simple:

      Dans ton EntityMoto tu ajoutes ces deux méthodes:

      public void writeEntityToNBT(NBTTagCompound nbt) {
      super.writeEntityToNBT(nbt);
      DataWatcher dw = this.getDataWatcher();
      nbt.setString("EntityMotoTexture", dw.getWatchableObjectString(30));
      }
      
      public void readEntityFromNBT(NBTTagCompound nbt) {
      super.readEntityFromNBT(nbt);
      DataWatcher dw = this.getDataWatcher();
      dw.updateObject(30, nbt.getString("EntityMotoTexture"));
      }
      

      Et c’est bon! la première écrit la valeur du datawatcher dans les tags nbt de l’entité et la seconde récupère le même tag et update le datawatcher avec.

      posted in 1.7.x
      DiabolicaTrix
      DiabolicaTrix
    • RE: Création de minerai

      Fait attention à override pour être certain d’utiliser la bonne méthode.

      posted in 1.8.x
      DiabolicaTrix
      DiabolicaTrix
    • RE: Block XRay

      Tu peux aussi essayer de mettre le code ci-dessous à la place de isTranslucent:

      public boolean isOpaqueCube()
      {
      return false;
      }
      
      public boolean renderAsNormalBlock()
      {
      return false;
      }
      
      
      posted in 1.8.x
      DiabolicaTrix
      DiabolicaTrix
    • RE: Drops
      @Override
      public Item getItemDropped(int meta, Random random, int fortune) {
      return ClassePrincipale.TonITem;
      }
      

      Et si tu veux la quantité:

      @Override
      public int quantityDropped(int meta, int fortune, Random random) {
      return quantitéminimum + random.nextInt(fortune + quantitémaximum);
      }
      
      posted in 1.7.x
      DiabolicaTrix
      DiabolicaTrix
    • RE: Minecraft Frame Undecorated

      J’avais justement cherché pour PlayerEvent mais je n’avais pas importé le bon, fait attention d’importer celui de fml.

      @SubscribeEvent
      public void onPlayerDisconnect(PlayerEvent.PlayerLoggedOutEvent event) {}
      
      posted in 1.7.x
      DiabolicaTrix
      DiabolicaTrix
    • RE: Afficher une image lors de la connexion.

      largeur / 2 - largeur de ton image
      hauteur / 2 - la hauteur de ton image

      posted in 1.8.x
      DiabolicaTrix
      DiabolicaTrix

    Latest posts made by DiabolicaTrix

    • RE: MFFJam édition étoilée

      Je participe seul, voici le dépôt : https://github.com/DiabolicaTrix/mffjametoilee

      posted in Annonces et règles
      DiabolicaTrix
      DiabolicaTrix
    • RE: [1.15.x] Créer un item basique

      Bravo, très bien rédigé ! J’ai corrigé quelques erreurs, il pourra bientôt être publié !

      posted in Les items
      DiabolicaTrix
      DiabolicaTrix
    • RE: Première édition de la MFFJam

      Mon repo:
      https://github.com/DiabolicaTrix/MFFJam1

      posted in Annonces et règles
      DiabolicaTrix
      DiabolicaTrix
    • RE: [1.12.2] Showcase Mod

      Après quelques années d’absence, je remets le mod à jour pour la 1.12.2. J’ai complètement refait le mod à partir de zéro et il devrait donc être mieux fait et plus fonctionnel. Toutes les fonctionnalités qui étaient présentes dans les précédentes versions le sont aussi dans celle-ci. Prenez note que la version 1.10.2 est toujours disponible sur curseforge, mais elle est archivée (je ne la recommande pas, par contre).

      posted in Mods en developpement
      DiabolicaTrix
      DiabolicaTrix
    • RE: Machine Craft Custom [ Forge 1.7.10 ]

      Je t’invite à regarder les tutoriels présents sur le forum, et à revenir si tu as un problème.

      posted in Sans suite
      DiabolicaTrix
      DiabolicaTrix
    • Mods/Plugins d'économie

      Bonjour à tous!

      Pour mettre à jour mon mod (Showcase Mod), que je n’ai pas pu toucher depuis 2016, j’ai besoin de quelques informations. Puisque je n’ai pas joué/developpé sur Minecraft depuis 2016, je ne connais ni la 1.11, ni la 1.12. J’aimerais rendre mon mod compatible avec les mods d’économie que les serveurs utilisent majoritement. Seulement, je ne connais pas assez l’écosystème actuel de Minecraft pour pouvoir trouver mes réponses. C’est pourquoi je solicite aujourd’hui votre aide. Si vous connaissez un mod d’économie qui est utilisé par plusieurs serveurs (ou bien un plugin Sponge), j’aimerais bien que vous me faites signe soit en réponse à ce post ou en MP, comme vous préférez.

      Merci à tous!

      posted in Discussion générale
      DiabolicaTrix
      DiabolicaTrix
    • RE: Backpack

      Désolé, mais si ça ne fonctionne pas, tu as forcément quelque chose de manquant… Je ne comprends toujours pas ce que tu veux dire par "en game bh"é

      posted in 1.7.x
      DiabolicaTrix
      DiabolicaTrix
    • RE: Backpack

      Est-ce qu’on peut avoir plus d’informations? Voir ton code? De plus, je ne suis pas certain de comprendre ton problème.

      posted in 1.7.x
      DiabolicaTrix
      DiabolicaTrix
    • RE: Es-tu plus membre ou joueur ?

      UEFI

      Spotify ou Deezer?

      posted in Le salon libre
      DiabolicaTrix
      DiabolicaTrix
    • RE: Le jeu de la présence

      12

      posted in Le salon libre
      DiabolicaTrix
      DiabolicaTrix
    Design by Woryk
    Contact / Mentions Légales / Faire un don

    MINECRAFT FORGE FRANCE © 2018

    Powered by NodeBB