• S'inscrire
    • Se connecter
    • Recherche
    • Récent
    • Mots-clés
    • Populaire
    • Utilisateurs
    • Groupes

    Résolu Instancier une entité à partir d'un nom ou du UUID

    1.9.x et 1.10.x
    1.10.x
    3
    8
    1908
    Charger plus de messages
    • Du plus ancien au plus récent
    • Du plus récent au plus ancien
    • Les plus votés
    Répondre
    • Répondre à l'aide d'un nouveau sujet
    Se connecter pour répondre
    Ce sujet a été supprimé. Seuls les utilisateurs avec les droits d'administration peuvent le voir.
    • Sorax
      Sorax dernière édition par

      Bonjour !

      Je vous explique un peu le problème, j’essaie de faire un système de bestiaire pour mon projet, pour le moment ça fonctionne plutôt bien, chaque jour a son bestiaire, la synchronisation entre client et serveur et ok, bref le plus “dur” est fait. Je passe donc à la partie GUI. Et voici mon plan :

      • Afficher le rendu de l’entité
      • Afficher quelques informations (comme les points de vie, la vitesse, etc…)

      Et voici un aperçu de ce que mon système de bestiaire fait :

      Quand un entité meurt et que c’est une créature
      alors
        ajouter la créature au bestiaire en créant une fiche de créature avec le nom de la créature (pour le moment)
        (ici je lance un événement pour notifier que j’ai ajouté une créature au bestiaire, ça me sert à lancer un message dans le chat)
      fin

      Mais au moment d’arriver à la GUI, je tombe sur un problème, je n’ai aucune instance de cette entité. Et pour cause, on ne peut pas sauvegarder une entité sous un nbt (ou j’ai pas trouvé de moyen de le faire). Et je ne peux donc pas utiliser le rendu d’une entité qui n’existe plus.

      J’ai donc réfléchi à plusieurs solution, et je me demandais si avec le UUID on ne pouvait pas recréer une instance de l’entité. Mais pareil, dans mes recherches, je n’ai trouvé que le moyen de récupérer une entité dans le monde grâce au UUID mais pas de créer une instance de cette entité.

      Pour le moment, la seule solution que je trouve est d’utiliser la réflexivité de java. C’est à dire de sauvegarder le nom de la class de l’entité dans mes nbttag et de recréer l’instance avec Class. Mais c’est pour moi pas du tout élégant.

      Avez vous une idée de comment je pourrais y arriver ? Est-ce que ma solution est la bonne et qu’il n’y en a pas d’autre ? (je pense que ça peu marcher, mais j’aime pas trop utiliser la réflexivité).

      1 réponse Dernière réponse Répondre Citer 0
      • Benjamin Loison
        Benjamin Loison dernière édition par

        Ca sent le projet Dofus à plein nez ^^ !

        Je pense que dans ton cas la réflexion est le mieux à utiliser, cependant il faut le faire intelligemment, lors de ton event il te faut get le nom de la classe et la remettre sous-forme de string dans un Extended Entity Properties et puis lors du gui tu lis ses EEP et tu fais générer les classes (entité côté client) ou tu lis des variables que tu as défini comme publiques dans tes classes d’entités (ce que je ferai) 😉

        >! Développeur de Altis-Life (Arma III) sur Minecraft !
        >! Site web     : https://lemnoslife.com

        1 réponse Dernière réponse Répondre Citer 0
        • robin4002
          robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par

          Le principale problème c’est que tu veux récupérer l’instance lors de la mort, or l’instance de l’entité n’existe plus après sa mort.
          Si ce qu’il te faut c’est juste le nom + d’autres informations, alors autant créer une nouvelle classe pour stocker ça et les envoyer via un paquet.

          1 réponse Dernière réponse Répondre Citer 0
          • Sorax
            Sorax dernière édition par

            @'Benjamin:

            Ca sent le projet Dofus à plein nez ^^ !

            Je pense que dans ton cas la réflexion est le mieux à utiliser, cependant il faut le faire intelligemment, lors de ton event il te faut get le nom de la classe et la remettre sous-forme de string dans un Extended Entity Properties et puis lors du gui tu lis ses EEP et tu fais générer les classes (entité côté client) ou tu lis des variables que tu as défini comme publiques dans tes classes d’entités (ce que je ferai) 😉

            Pas du tout pour dofus, je suis occupé de faire un mod type RPG très très inspiré de The Witcher 3. Mais sinon c’est un peu comme ça que j’imaginais faire la chose aussi à l’exception que je voudrais que ça fonctionne pour tout EntityCreature, mais ça change pas grand chose à la solution.

            @‘robin4002’:

            Le principale problème c’est que tu veux récupérer l’instance lors de la mort, or l’instance de l’entité n’existe plus après sa mort.
            Si ce qu’il te faut c’est juste le nom + d’autres informations, alors autant créer une nouvelle classe pour stocker ça et les envoyer via un paquet.

            C’est exactement ça que j’ai pour le moment, j’ai une class BestiaryCard qui s’occupe de récupérer les infos comme le nom, la vie max, et pourquoi pas plus (j’ai pas trop réfléchi à ce qui peut être intéressant sur un mob ^^]. Le truc c’est que je voudrais pouvoir ajouter sur la gui un rendu de la créature. J’ai regardé comment on le faisait dans GuiInventory et j’ai vu qu’on avait besoin de l’instance de l’entité.

            1 réponse Dernière réponse Répondre Citer 0
            • robin4002
              robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par

              D’accord, je comprend mieux le problème.
              Donc oui il faut créer une nouvelle instance, suffit de mettre comme world FMLClientHandler.instance().getClientWorld() puis tu mets des coordonnées bidon (0,0,0).

              1 réponse Dernière réponse Répondre Citer 0
              • Sorax
                Sorax dernière édition par

                J’ai réussi à avoir un truc qui marche de temps en temps, j’ai un NullPointerException qui se lance de temps en temps :

                Caused by: java.lang.NullPointerException
                at net.minecraft.entity.Entity.getTeam(Entity.java:2435) ~[Entity.class:?]
                at net.minecraft.entity.Entity.isInvisibleToPlayer(Entity.java:2427) ~[Entity.class:?]
                at net.minecraft.client.renderer.entity.RenderLivingBase.canRenderName(RenderLivingBase.java:506) ~[RenderLivingBase.class:?]
                at net.minecraft.client.renderer.entity.RenderLiving.canRenderName(RenderLiving.java:26) ~[RenderLiving.class:?]
                at net.minecraft.client.renderer.entity.RenderLiving.canRenderName(RenderLiving.java:16) ~[RenderLiving.class:?]
                at net.minecraft.client.renderer.entity.RenderLivingBase.renderName(RenderLivingBase.java:488) ~[RenderLivingBase.class:?]
                

                C’est causé par cette méthode :

                @Nullable
                   public Team getTeam()
                   {
                       return this.worldObj.getScoreboard().getPlayersTeam(this.getCachedUniqueIdString());
                   }
                

                A mon avis c’est à cause du worldObj car je crée une instance de l’entité côté client :

                @SideOnly(Side.CLIENT)
                private EntityCreature createCreature(String type) {
                try {
                return (EntityCreature) Class.forName(type).getConstructor(World.class).newInstance(FMLClientHandler.instance().getWorldClient());
                } catch (InstantiationException e) {
                e.printStackTrace();
                } catch (IllegalAccessException e) {
                e.printStackTrace();
                } catch (IllegalArgumentException e) {
                e.printStackTrace();
                } catch (InvocationTargetException e) {
                e.printStackTrace();
                } catch (NoSuchMethodException e) {
                e.printStackTrace();
                } catch (SecurityException e) {
                e.printStackTrace();
                } catch (ClassNotFoundException e) {
                e.printStackTrace();
                }
                return null;
                }
                

                Du coup je me demande si je suis pas obligé de l’instancier à la fois côté client et serveur.

                1 réponse Dernière réponse Répondre Citer 0
                • robin4002
                  robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par

                  à mon avis c’est plutôt getScoreboard qui renvoie null au lieu de renvoyer la valeur voulu.
                  Il n’y a aucune raison pour que FMLClientHandler.instance().getWorldClient() soit null.

                  1 réponse Dernière réponse Répondre Citer 0
                  • Sorax
                    Sorax dernière édition par

                    Bon finalement j’ai trouvé une façon d’instancier facilement une entité à partir du nom :

                    @SideOnly(Side.CLIENT)
                    private EntityCreature createCreature(String type) {
                           EntityCreature creature = (EntityCreature) EntityList.createEntityByName(type, FMLClientHandler.instance().getWorldClient());
                           return creature;
                    }
                    

                    Pour le peut te test que j’ai fais, ça ne crash pas. Merci de vos réponses !

                    1 réponse Dernière réponse Répondre Citer 0
                    • 1 / 1
                    • Premier message
                      Dernier message
                    Design by Woryk
                    Contact / Mentions Légales

                    MINECRAFT FORGE FRANCE © 2018

                    Powered by NodeBB