Spawn et Initialisation d'entité



  • Bonjour,

    J'essaye de créer une entité invoquée qui garde un lien vers le joueur l'ayant fait spawn. Pour ce faire j'utilise le code suivant :

    • Dans la méthode onItemUse de l'objet j'instancie l'entité en utilisant un constructeur prenant en compte le joueur.
    • Dans le constructeur j'attribue à une variable de classe l'objet joueur.
    • Dans entityInit j'initialise l'entité et j'ai besoin du summoner.
    • Dans onLivingUpdate je fait bouger mon entité.

    Le problème c'est que dans onLivingUpdate ma variable summoner pointant vers le joueur est correcte MAIS que dans entityInit j'ai un pointeur null. Encore plus bizarre, j'ai l'impression que entityInit est appelée avant le constructeur si j'en crois mes system.out.print() (Sauf si c'est multithreadé auquel cas ça ne vaut rien dire je sais …)

    Quelqu'un pourrait-il m'éclairer sur la façon dont minecraft gère le spawn des mobs svp ?
    Et éventuellement comment faire pour résoudre le soucis ?

    Voila le code (J'ai réduit à un test case pour éviter un post de 2Km) :
    Item :

    @Override
    public boolean onItemUse(ItemStack stack, EntityPlayer player, World w, int x_block , int y_block, int z_block, int face, float par8, float par9, float par10)
       {
    if (w.isRemote)
    return true;
    
    RobotEntity re = new MechaEntity(w, player);
    System.out.println("Created new entity with summoner : " + player.getEntityName());
    
    x_block += Facing.offsetsXForSide[face];
    y_block += Facing.offsetsYForSide[face];
    z_block += Facing.offsetsZForSide[face];
    
    re.setLocationAndAngles(x_block, y_block, z_block, (180 + player.rotationYaw) % 360, 0.0F);
    w.spawnEntityInWorld(re);        
    
           return true;
       }
    

    My custom Entity:

    
    public class MechaEntity extends EntityLiving
    {
       /** Player who summoned the entity **/
       protected EntityPlayer summoner;
    
       public MechaEntity(World w)
       {
           super(w);
           summoner = null;
       }
    
       /**
        * Construct a new entity.
        *
        * @param w World of the entity.
        * @param player Summoner of the entity
        */
       public MechaEntity(World w, EntityPlayer player)
       {
           super(w);
           summoner = player; // Here player isn't null and summoner is initialised
       }
    
       protected void entityInit()
       {
           super.entityInit();
    
           if(worldObj.isRemote)
               System.out.println("Client : " + summoner); // Both print() appears in log and both have null values
           else
               System.out.println("Server : " + summoner);
    
           […]
       }
    
       /**
        * Update entity state, run the AI.
        */
       @Override
       public void onLivingUpdate()
       {
           if(!worldObj.isRemote)
               System.out.println("updt Server : " + summoner); // Here the summoner variable point to a valid player again
    
       […]
       }
    }
    
    

    Merci :rolleyes:



  • Oui, moi aussi j'ai remarqué que chaque fois que je mets quelque chose dans entityInit(), ça me renvoie une NPE 😕 Quant à la solution, aucune idée x)


  • Administrateurs

    La fonction entityInit est une sorte d'event lors du premier tick de l'entité (un tick après son spawn, exemple : l'araigné monté par un squeulette ^^ (en 1.6 uniquement, en 1.7 c'est différent d'après ce que je viens de vérifier :O) )



  • C'est comme cela que je l'avais compris, mais du coup je ne m'explique pas pourquoi les données de la classe initialisée dans le constructeur ne sont pas valide dans cette méthode en particulier …

    Logiquement ça devrait fonctionner si on appelle :

    1. constructeur
    2. entity init
    3. on living update en boucle


  • Je ceois qu'entityInit() est appelé à la fin du constructeur d'Entity. Ça expliquerait les résultats
    Pour vérifier, ctrl+alt+G dans eclipse 😉



  • OOoooooohhhhhhh !!!

    Bien vu, ça explique tout. Par contre eclipse me râle dessus si je veux initialiser mes variable de classe avant d'appeler le constructeur de super 😕 .

    Je vais creuser et voir si je trouve une façon élégante de faire ça … Merci 😉


Log in to reply