Texture bébé et random



  • Bonjour,
    J'ai encore deux questions au sujet des mobs.

    1. Est-il possible de mettre une texture "spéciale" aux bébés animaux? Je m'explique: quand le mob est un bébé, il a une certaine texture, puis, quand il devient un adulte, il change de texture et il en a donc une autre. J'ai essayé ceci, dans le render du mob, en essayant les deux propositions d'eclipse pour corriger l'erreur 'isChild' (private boolean isChild et private static final boolean isChild = false), sans aucun succès. Le bébé garde la texture des adultes.

      public ResourceLocation getEntityDeerTextures(EntityDeer entity)
          {
              if (this.isChild)
              {
                  return new ResourceLocation("animalia:textures/entity/deerchild.png");
              }
              else
              {
                  return new ResourceLocation("animalia:textures/entity/deer"  + entity.texture + ".png");
              }
          }
      ```Faut-il ajouter quelque chose d'autre? ou alors je suis complètement à coté de la plaque? ou alors c'est tout simplement impossible?
      
    2. J'ai mit des textures random à mes mob grâce à ce tutoriel (très bon tutoriel soit dit en passant  ;)) sauf que dès que je quitte mon monde et que je me reconnecte, la texture a changé, comme si on avait à nouveau appliquer le random (je ne sais pas si c'est clair). Est-ce normal? Et est-ce corrigeable?
      Les deux class concernées
      La class entity

      public class EntityDeer extends EntityAnimal
      {
          public int texture;
          public EntityDeer(World world)
          {
              super(world);
              texture = this.worldObj.rand.nextInt(2);
              this.setSize(0.7F, 0.7F);
              this.getNavigator().setAvoidsWater(true);
              this.tasks.addTask(0, new EntityAISwimming(this));
              this.tasks.addTask(1, new EntityAIPanic(this, 1.25D));
              this.tasks.addTask(2, new EntityAIMate(this, 1.0D));
              this.tasks.addTask(3, new EntityAITempt(this, 1.2D, Items.wheat, false));
              this.tasks.addTask(4, new EntityAIFollowParent(this, 1.1D));
              this.tasks.addTask(5, new EntityAIWander(this, 1.0D));
              this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
              this.tasks.addTask(7, new EntityAILookIdle(this)); 
          }
      
          public void applyEntityAttributes()
          {
              super.applyEntityAttributes();
              this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(10D);
              this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.8D);
          }
      
          public EntityDeer createChild(EntityAgeable entity)
          {
              return new EntityDeer(this.worldObj);
          }
      
          public boolean isBreedingItem(ItemStack breed)
          {
              return breed != null && breed.getItem() == Items.wheat;
          }
      }
      

      La class render```java
      public class RenderDeer extends RenderLiving
      {
          public RenderDeer(ModelBase model)
          {
              super(model, 0.5F);
          }

      public ResourceLocation getEntityDeerTextures(EntityDeer entity)
          {
              return new ResourceLocation("animalia:textures/entity/deer"  + entity.texture + ".png");
          }

      protected ResourceLocation getEntityTexture(Entity entity)
          {
              return getEntityDeerTextures((EntityDeer)entity);
          }
      }

      
      
      
      

      C'est le même mob que pour la question 1 mais tous les autres mobs avec des texture random ont aussi le problème.
      Merci d'avance  :)



    1. Tu n'es pas à côté de la plaque du tout, le problème est que dans ta fonction "createChild", tu ne crées pas un enfant mais un adulte, il faut que tu mettes la boolean isChild à true lorsque cette fonction est appelée.
    2. Le problème est que l'entité est recréée à chaque fois, il faut que tu utilises les nbt pour sauvegarder la texture (fonctions readFromNBT et writeToNBT de la classe Entity).


  • Merci, mais je n'ai pas trop compris  :s

    1. Je la met où à true? J'ai essayé dans le field (private boolean isChild = true) et aussi dans la fonction ResourceLocation (if (this.isChild) = true), mais pour les deux cas les adultes ont aussi cette texture  😕

    2. Je dois les utiliser comment ces deux fonctions? J'ai essayé comme cela (je me suis inspirée dans la class EntityHorse):

    
     public void writeEntityToNBT (NBTTagCompound tag)
        {
            super.writeEntityToNBT(tag);
        }
    
        public void readEntityFromNBT(NBTTagCompound tag)
        {
            super.readEntityFromNBT(tag);
        }
    

    mais ils changent toujours de texture



    1. Non ce n'est pas comme ça ^^ Copie le constructeur actuel et colle-le dans ta classe, ajoutes "boolean isChild" en argument, puis à la fin de celui-ci, mets "this.isChild = isChild;" puis dans l'autre constructeur, remplace son contenu par "this(world, false);", ensuite, dans ta fonction createChild, rajoute true après l'argument this.worldObj que tu passes à la nouvelle entitée.
    2. Ton int ne va pas se sauvegarder par magie ^^ Dans writeEntityToNBT, il faut que tu fasses "tag.setInteger(je te laisse compléter eclipse est ton ami);" et dans readEntityFromNBT, "texture = tag.readInteger(je te laisse compléter eclipse est ton ami);".


    1. Attention ! Il faudra que tu synchronises ta valeur avec les datawatchers. Sers toi de la classe EntityOcelot, les skins des chats apprivoisés représentent ta demande 😃


    1. Je n'ai pas compris ce qu'il faut exactement rajouter dans la fonction createChild

    2. Effectivement, quand j'ai rajouter ce qu'il fallait dans "writeEntityToNBT" et "readEntityToNBT", le jeu ne voulais plus se sauvegarder, donc j'ai essayé de solutionner ça avec les datawatchers.
      J'ai été regarder dans les class EntityOcelot et RenderOcelot. Voila ce que j'obtient:


    Sauf que petit problème, les mobs apparaissent transparents.
    J'ai modifié le getTameSkin en getSkin et j'ai retiré des "case" dans le render (je ne sais pas si c'est ça qui pose soucis).
    Autre question: les textures random sont inutiles quand on utilise les datawatchers alors?
    Dans les class, il y a ce que j'ai fait pour les deux questions  😉



  • Nan ce n'est pas inutile sinon je n'aurai pas envoyé de messages. Tu as juste oublié d'override la méthode entityInit afin d'enregistrer le datawatcher. Regarde de nouveau la classe de l'entity ocelog car apparemment tu l'as survolée.



  • Merci ça a réglé le problème de transparence 🙂 et effectivement le random est toujours utile, sans lui, j'avais toujours la même texture pour mon mob.
    Pour ceux qui veulent la solution, j'ai utiliser ça

    switch (entity.getSkin())
                {
                    case 0:
                    default:
                        return new ResourceLocation("animalia:textures/entity/deer"  + entity.texture + ".png");
                }
    

    Dans le resourceLocation

    Il me manque plus que la réponse pour la texture du bébé.



  • Pour la texture du bébé, il faut que tu ajoute "boolean isChild" en argument au constructeur. Tu dois ensuite ajouter "this.isChild = isChild;" dans ton constructeur. Ce constructeur permettra de faire spawner l'entité en choisissant si c'est un bébé ou non. Ensuite, tu ajoute un deuxième constructeur :

    public EntityDeer(World world)
    {
        this(world, false)
    }
    
    

    Celui-ci permet de spawner l'entité directement adulte.
    Enfin, dans la fonction createChild, tu spécifie que l'entité est un bébé en faisant "return new EntityDeer(this.worldObj, true);"

    (sources : message de AymericRed, partie 1)


  • Administrateurs

    public ResourceLocation getEntityDeerTextures(EntityDeer entity)
       {
           if (entity.isChild())
           {
               return new ResourceLocation("animalia:textures/entity/deerchild.png");
           }
           else
           {
               return new ResourceLocation("animalia:textures/entity/deer"  + entity.texture + ".png");
           }
       }
    

    Pourquoi faire compliquer quand on peut faire simple ?
    La fonction isChild() renvoie déjà la valeur qu'on veut et se trouve dans EntityAgeable.

    Pas besoin de créer une nouvelle variable booléenne.



  • J'ai réussi pour la texture des bébés  😄  J'ai été regardé dans la class des loups comme eux aussi peuvent avoir des textures différents et j'ai trouvé un truc beaucoup plus simple.

    public ResourceLocation getEntityDeerTextures(EntityDeer entity)
        {
            return entity.isChild() ? new ResourceLocation("animalia:textures/entity/deerchild.png") :  (new ResourceLocation("animalia:textures/entity/deer"  + entity.texture + ".png"));
        }
    

    Par contre, les textures random change toujours dès que je quitte mon monde  😕



  • Il faudrait que tu print ton entity.texture voir ce qu'il renvoit. Refile nous la classe de ton entity qu'on voit un peu tes erreurs.



  • Voici la classe:

    public class EntityDeer extends EntityAnimal 
    {
        public int texture;
        public EntityDeer(World world)
        {
            super(world);
            texture = this.worldObj.rand.nextInt(2);
            this.setSize(0.8F, 1.0F);
            this.getNavigator().setAvoidsWater(true);
            this.tasks.addTask(0, new EntityAISwimming(this));
            this.tasks.addTask(1, new EntityAIPanic(this, 1.25D));
            this.tasks.addTask(2, new EntityAIMate(this, 1.0D));
            this.tasks.addTask(3, new EntityAITempt(this, 1.2D, Items.wheat, false));
            this.tasks.addTask(4, new EntityAIFollowParent(this, 1.1D));
            this.tasks.addTask(5, new EntityAIWander(this, 1.0D));
            this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
            this.tasks.addTask(7, new EntityAILookIdle(this)); 
        }
    
        protected void entityInit()
        {
            super.entityInit();
            this.dataWatcher.addObject(18, Byte.valueOf((byte)0));
        }
    
        public boolean isAIEnabled()
        {
            return true;
        }
    
        public void applyEntityAttributes()
        {
            super.applyEntityAttributes();
            this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(10D);
            this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D);
        }
    
        public EntityDeer createChild(EntityAgeable entity)
        {
            return new EntityDeer(this.worldObj);
        }
    
        public boolean isBreedingItem(ItemStack breed)
        {
            return breed != null && breed.getItem() == Items.wheat;
        }
    
        public void writeEntityToNBT (NBTTagCompound tag)
        {
            super.writeEntityToNBT(tag);
            tag.setInteger("DeerType", this.getSkin());
        }
    
        public void readEntityFromNBT(NBTTagCompound tag)
        {
          super.readEntityFromNBT(tag);
          this.setSkin(tag.getInteger("DeerType"));
        }
    
        public int getSkin()
        {
          return this.dataWatcher.getWatchableObjectByte(18);
        }
    
        public void setSkin(int skin)
        {
          this.dataWatcher.updateObject(18, Byte.valueOf((byte)skin));
        }
    }
    

    Les 4 dernières fonctions et la "protected void entityInit" viennent de l'EntityOcelot


  • Administrateurs

    this.dataWatcher.addObject(18, Byte.valueOf((byte)0));
    ->
    this.dataWatcher.addObject(18, Byte.valueOf((byte)texture));

    et dans la fonction getEntityDeerTextures du rendu remplaces entity.texture par entity.getSkin()



  • Je viens d'essayer ça mais il n'y a plus de texture random (les animaux adultes sont tous les mêmes) quand je remplace entity.texture par entity.getSkin()


  • Administrateurs

    Tu as aussi changé la ligne avec le data watcher ?



  • Si c'est de celle-ci (this.dataWatcher.addObject(18, Byte.valueOf((byte)texture));) dont tu parle, alors oui je l'ai aussi changé


  • Administrateurs

    Ajoutes des System.out.println(texture) / System.out.println(entity.getSkin()) dans le constructeur de la classe de ton entité et dans le code du rendu et envoies les logs.



  • Je dois les coller où exactement dans la class Render? Et dans le constructeur il y a une erreur avec le 'entity', je laisse comme ça et je lance minecraft?
    J'envoie les logs client et serveur?


  • Administrateurs

    Dans la fonction getEntityDeerTextures

    Envoies simplement ce qu'il y a dans la console d'eclipse.