Plusieurs textures pour un même modèle custom d'une entité


  • Correcteurs

    Voilà,

    Donc mon but n'est pas d'avoir une texture random à chaque spawn mais bien utiliser un item différent pour faire spawn une même entité mais dont la texture est différente.  (en l'occurence une entité montable vesant office de véhicule)
    On m'a conseillé le datawatcher (qui à ce que j'ai compris fait en sorte que le serveur rappelle au client ce qu'il a fait auparavant).

    J'vous montre mes classes et puis vous me direz si y'a moyen d'y caler des lignes ou si je dois refaire ça d'une manière plus appropriée.

    Dites moi si il faut d'autres classes, il me semble que ces deux là sont les concernées.


  • Correcteurs

    Ok donc example que ton meta data 1 et ton metadata 2 sont deux entités moto et que tu veux mettre la texture bleu et la texture rouge.

    dans ton onItemUse:

    @Override
    public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
    {
    int metadata = stack.getItemDamage();
    if(metadata == 1)
    {
    EntityMarketPNJ e = new EntityMarketPNJ(world);
       if(!world.isRemote)
           {
        e.setPosition(x, y + 1.0F, z);
        world.spawnEntityInWorld(e);
        stack.stackSize–;
           }
       else
       {
        DataWatcher dw = e.getDataWatcher();
        dw.updateObject(20, "bleu");
       }
           return true;
    }
    else if(metadata == 2)
    {
    EntityMarketPNJ e = new EntityMarketPNJ(world);
       if(!world.isRemote)
           {
        e.setPosition(x, y + 1.0F, z);
        world.spawnEntityInWorld(e);
        stack.stackSize--;
           }
       else
       {
        DataWatcher dw = e.getDataWatcher();
        dw.updateObject(20, "rouge");
       }
           return true;
    }
    return false;
    }
    

    Il faut que tu mettes ceci dans ton event handler de forge:

    @SubscribeEvent
    public void handleConstruction(EntityConstructing event)
    {
       if(event.entity instanceof EntityMoto)
       {
           DataWatcher dw = event.entity.getDataWatcher();
           dw.addObject(20, "couleurpardefaut");
       }
    }
    

    Dans ton render:

    public class RenderMoto extends RenderLiving
    {
    
       public RenderMoto(ModelBase model, float shadow)
       {
           super(model, shadow);
       }
    
    private ResourceLocation getMotoTexture(EntityMoto moto)
       {
    DataWatcher dw = moto.getDataWatcher();
           return new ResourceLocation("Modpg:textures/entity/" + dw.getWatchableObjectString(20) + ".png");
       }
    
       @Override
       protected ResourceLocation getEntityTexture(Entity entity)
       {
           return this.getMotoTexture((EntityMoto)entity);
       }
    }
    

    Je n'ai pas testé, c'est possible qu'il y est des erreurs.


  • Correcteurs

    D'acc, cette méthode ne m'autorise qu'une texture en plus?

    (je check si ça marche chez moi, je vois qu'on ne met pas ```java
    [size=smallEntityMarketPNJ][size=small e ][size=small=] [size=smallnew] [size=smallEntityMarketPNJ]size=small;

    
    Edit:
    
    En fait, là tu me passes du code pour m'aider mais je ne le comprends pas vraiment.
    Notamment comment quand j'utilise mon item, le jeu comprend que je veux faire apparaitre mon entité avec telle texture et pas l'autre.
    ça va me créer un item différent?
    
    Re-Edit: Han ok en fait y'a deux items différents dans ton exemple, ma faute

  • Correcteurs

    Merde le EntityMarketPNJ tu peux le remplacer par EntityMoto. En fait j'étais encore en train de construire le post pour les explications mais je vais les mettre ici.

    En fait dans ta méthode onItemUse tu n'as qu'à vérifier le metadata comme tu le fais déjà sauf que tu dois sortir ton objet (EntityMoto) de la condition car tu dois mettre a jour le datawatcher à partir du serveur. Donc tu crée une nouvelle instance de EntityMoto, si c'est le client tu le fais spawn et si c'est le serveur, tu mets a jour le datawatcher pour la couleur que tu veux. Ensuite dans ton render, tu récupère le datawatcher et tu l'inclus dans la texture donc si tu change la valeur du datawatcher la texture va changer.



  • Euh ce n'est pas une bonne idée de confier au client le spawn de l'EntityMoto ^^'


  • Correcteurs

    Bon comme j'ai un crash me suis de suite dis que j'ai mal fais niveau eventHandler

    Dans am classe principale j'ai

    public void Init(FMLInitializationEvent event)
    {
    MinecraftForge.EVENT_BUS.register(new LivingEventHandler());
    […]
    

    Et dans ce LivingEventHandler

    public class LivingEventHandler
    {
    @SubscribeEvent
    public void handleConstruction(EntityConstructing event)
    {
      if(event.entity instanceof EntityMoto)
      {
          DataWatcher dw = event.entity.getDataWatcher();
          dw.addObject(20, "couleurpardefaut");
      }
    }
    […]
    

    Autre possibilité, c'est que tu parles de client et serveur, la base du DataWatcher, donc quand je teste ça sur Eclipse je suis sensé lancer un test serveur nan? (Parce que ça je ne sais pas faire non plus… Si j'ose dire)

    Edit: Voilà ce que j'ai fais de ma classe ItemMonture afin de tester tout ça

    Du coup je vois que le code prédédent fonctionne (les 3 derniers metadata spawnent bien l'entité voulue), par contre le nouveau me fait crash.
    Y'a aussi le coup de bleu, rouge, couleurpardefaut, je dois mettre le nom de ma texture? (ce que tu expliques dans ta dernière réponse, je veux juste savoir si j'ai compris ou si chui en mode boulet ce soir)


  • Correcteurs

    Peux-tu envoyer ton crash report stp?

    Pour le bleu, rouge et couleurpardefaut, tu as vu juste j'avais oublié de le dire mais c'est bien le nom de la texture.


  • Correcteurs



  • Ligne 18 de ta classe LivingEventHandler ?
    Apparemment l'id choisie du DataWatcher n'est pas le bon, c'est bizarre….


  • Correcteurs

    J'avais édit justement pour les mettre mais tu es plus rapide que moi.


  • Correcteurs

    Essaie de créer un nouveau monde. ou de changer les ids pour un autre.



  • Le problème c'est que le bout de classe d'EventHandler que tu m'as donné ne possède même pas 18 lignes x)
    Passe moi la ligne 18 précisément, juste la ligne 18 ^^


  • Correcteurs

    @'DiabolicaTrix':

    Essaie de créer un nouveau monde. ou de changer les ids pour un autre.

    Ok bonne nouvelle, j'ai mis l'id à 30 et changé le world, plus de crash.
    Ceci dit ce qui spawn est invisible, montable, mais invisible.

    Edit: Si la ligne 18 est bien "       dw.addObject(30, "Moto");         "

    Edit2: Rectification

    J'avais oublié de changer l'Id du render pour "30".
    Ceci dit mon metadata 0 et 1 font spawn une moto ayant la même texture.
    Bien que:

       e.setPosition(x, y + 1.0F, z);    world.spawnEntityInWorld(e);    stack.stackSize--;       }   else   {    DataWatcher dw = e.getDataWatcher();    dw.updateObject(30, "Moto1");   }       return true; }

    Que j'ai bien rafraichis mes fichiers de textures et qu'elle sont très facilement différenciable (simplement la palette de couleur opposée)


  • Correcteurs

    C'est étange, tu peux renvoyer tes code (render+EntityMoto surtout)


  • Correcteurs

    Les voici, je te préviens, la classe de la moto est une jungle je pense.

    Ps: Pas taper.


  • Correcteurs

    Es-tu sur que la texture existe? Au pire fais un System.out.println(dw.getWatchableObjectString(30)) pour voir si ça donne bien moto.


  • Correcteurs

    Ouaip niveau des textures je suis sûr que tout est bon. Fichier entity, textures: Moto et Moto1

    Pour le println metadata 0 me donne Moto
                         metadata 1 me donne Moto1

    Donc là je vois pas.
    Le problème ne vient pas du fait que le render renvoie toujours à Moto? (Mec qui gratte au risque de dire une bêtise)


  • Correcteurs

    Par contre personellement mon ressource location ressemble à ça: new ResourceLocation("t4pro", "textures/entity/steve.png");

    Donc essaie: return new RessourceLocation("Modpg", "textures/entity/Moto.png"


  • Correcteurs

    Avec

    return new ResourceLocation("Modpg:textures/entity/" + dw.getWatchableObjectString(30) + ".png");
    

    ou

    return new ResourceLocation("Modpg", ":textures/entity/" + dw.getWatchableObjectString(30) + ".png");
    

    mes entités ont une texture, la même, c'est à dire "Moto".

    Edit:

    avec

     return new ResourceLocation("Modpg", "textures/entity/" + dw.getWatchableObjectString(30) + ".png");
    

    aucune texture trouvée

    Edit:
    PAR CONTRE
    dans l'event handler quand je mets Moto1 ça me met la texture Moto1 pour les deux.
    A toi de me dire ce que t'en penses =d


  • Correcteurs

    Et bien dans ce cas, ça veut dire que le datawatcher n'est pas updaté. essaie de mettre un sysout dans le dw.update.