Problème avec le Teleporter de ma dimension


  • Administrateurs

    Hello !

    J'ai réussi à créer ma dimension sous Minecraft 1.9.
    Le seul bémol étant que le jeu crash à cause du Teleporter. (Stacktrace disponible ici) (Classe de mon Teleporter ici)
    Donc selon le stacktrace, cela viendrait de cette ligne :

    
                d6 = (double)(blockpattern$patternhelper.getPos().getY() + 1) - entityIn.getLastPortalVec().yCoord * (double)blockpattern$patternhelper.func_181119_e();
    
    

    En l'ayant décortiqué un peu (donc en ayant fait des retours à la ligne pour voir où le crash provient précisément sur cette ligne), j'ai vu que c'était :

    
    entityIn.getLastPortalVec()
    
    

    qui était null. Or, il semble pourtant initialisé puisqu'il est utilisé pour aller dans le Nether.

    J'avais donc ajouté des null check sur cette ligne et une ligne plus bas qui utilise ce "entityIn.getLastPortalVec()", ce qui m'a permis d'aller dans ma dimension sans problème. Mais en voulant revenir dans le monde normal, j'ai eu un Null Pointer Exception à la ligne :

    
                if (blockpattern$patternhelper.getFinger().getOpposite() == entityIn.getTeleportDirection())
    
    

    Visiblement, il semble y avoir un problème avec le système de téléportation de dimension à dimension. Mais malheureusement, je sèche.

    C'est pourquoi je viens solliciter votre aide. 😉

    Si il manque des détails n'hésitez pas à me le dire, que je puisse tout vous donner concernant le problème.

    EDIT : Le code est une réutilisation du Teleporter de base. Comme le font les tutos pour créer sa dimension (1.5.2 ~ 1.8).



  • Dans ce code : "entityIn.getLastPortalVec().yCoord" c'est quelle variable qui est nulle ? L'entité ou le vecteur ?


  • Administrateurs

    À ma grande surprise, c'est le yCoord qui cause le NPE, alors que c'est un Double….


  • Moddeurs confirmés Rédacteurs Administrateurs

    Non, le npe est sur getLastPortalVec()


  • Administrateurs

    Pourtant il me sélectionne bien le yCoord quand je clique sur le lien dans le stacktrace… Mais soit.


  • Moddeurs confirmés Rédacteurs Administrateurs

    Le stacktrace indique toujours la ligne juste après l'objet null. Car c'est lorsqu'il a voulu avoir la valeur de cette variable qu'il y a eu le npe.


  • Administrateurs

    Bon à savoir.
    Du coup, j'ai testé avec le Teleporter de Minecraft et y'a le même problème.


  • Administrateurs

    Bon, après avoir mit des try/catch un peu partout (précisément là où les getLastPortalVec() et getTeleporterDirection() sont appelés), cela semble fonctionner. Bien que le jeu met un peu plus de temps à aller dans la dimension que dans le Nether. (Probablement à cause du spam de stacktrace dans la console)

    Je ne passe pas de suite le sujet en résolu tout de suite, car il se peut que des cas de récidive se pointent.



  • Est-ce que tu peux renvoyer ta classe ? Pour essayer d'enlever les try/catch car ils ralentissent très certainement le jeux


  • Administrateurs

    Je sais bien 😕 Mais en attendant de trouver d'où ça vient précisément je n'ai pas le choix hélas…

    Voilà la classe : http://pastebin.com/8U7FBA7P



  • Envoi la classe du block de ton portail, d'après ce que je vois, le vecteur est changé dans la fonction du block


  • Administrateurs

    Voilà la classe du block portal : http://pastebin.com/P3ZrHLMP



  • public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, IBlockState state, Entity entityIn) {
    if (!entityIn.isRiding() && !entityIn.isBeingRidden() && entityIn.isNonBoss() && ((entityIn instanceof EntityPlayerMP))) {
    entityIn.setPortal(pos); // rajoute cette ligne et normalement ce sera bon
    EntityPlayerMP thePlayer = (EntityPlayerMP) entityIn;
    if (thePlayer.timeUntilPortal > 0) {
    thePlayer.timeUntilPortal = 20;
    } else if (thePlayer.dimension != Configs.dimensionID) {
    thePlayer.timeUntilPortal = 20;
    thePlayer.mcServer.getPlayerList().transferPlayerToDimension(thePlayer, Configs.dimensionID, new RDTeleporter(thePlayer.mcServer.worldServerForDimension(Configs.dimensionID)));
    } else {
    thePlayer.timeUntilPortal = 20;
    thePlayer.mcServer.getPlayerList().transferPlayerToDimension(thePlayer, 0, new RDTeleporter(thePlayer.mcServer.worldServerForDimension(0)));
    }
    }
    }
    

    Au fait, tu n'es pas obligé de recopier la classe Size car celle de BlockPortal est statique et publique donc tu peux y accéder.


  • Administrateurs

    Oui je sais. Mais je pensais qu'utiliser celui de la classe BlockPortal causerait des soucis de cast. Donc dans le doute, je l'ai aussi recopié.



  • Du coup la fonction rajoutée dans le code change quelque chose ?


  • Administrateurs

    Non justement 😕



  • Renvoi le rapport de crash et la classe du Teleporter et du Block


  • Administrateurs

    Je viens de me rendre compte surtout que la classe Size semble aussi gérer le block qui va avec le portail, genre dans le Size de BlockPortal y'a la mention du Blocks.obsidian. du coup j'ai keep le custom Size.
    Je t'envoie tout ça :
    http://pastebin.com/WnZK4SmW - BlockRumblePortal
    http://pastebin.com/z4k1vqh0 - RDTeleporter



  • Tu n'as pas rajouté cette ligne "entityIn.setPortal(pos);" et il manque le rapport de crash


  • Administrateurs

    Je n'utilise pas le setPortal(pos) car il utilise le portail vers le nether.

    
       public void setPortal(BlockPos pos)
       {
           if (this.timeUntilPortal > 0)
           {
               this.timeUntilPortal = this.getPortalCooldown();
           }
           else
           {
               if (!this.worldObj.isRemote && !pos.equals(this.lastPortalPos))
               {
                   this.lastPortalPos = new BlockPos(pos);
                   BlockPattern.PatternHelper blockpattern$patternhelper = Blocks.portal.func_181089_f(this.worldObj, this.lastPortalPos);
                   double d0 = blockpattern$patternhelper.getFinger().getAxis() == EnumFacing.Axis.X ? (double)blockpattern$patternhelper.getPos().getZ() : (double)blockpattern$patternhelper.getPos().getX();
                   double d1 = blockpattern$patternhelper.getFinger().getAxis() == EnumFacing.Axis.X ? this.posZ : this.posX;
                   d1 = Math.abs(MathHelper.func_181160_c(d1 - (double)(blockpattern$patternhelper.getFinger().rotateY().getAxisDirection() == EnumFacing.AxisDirection.NEGATIVE ? 1 : 0), d0, d0 - (double)blockpattern$patternhelper.func_181118_d()));
                   double d2 = MathHelper.func_181160_c(this.posY - 1.0D, (double)blockpattern$patternhelper.getPos().getY(), (double)(blockpattern$patternhelper.getPos().getY() - blockpattern$patternhelper.func_181119_e()));
                   this.lastPortalVec = new Vec3d(d1, d2, 0.0D);
                   this.teleportDirection = blockpattern$patternhelper.getFinger();
               }
    
               this.inPortal = true;
           }
       }
    
    

    Et le rapport de crash ne diffère en rien de ceux que j'ai envoyé.


Log in to reply