Mod  Résolu Créer une TNT

Discussion dans 'Support modding' créé par Flow Arg, 8 Juin 2019.

  1. Flow Arg

    Flow Arg Nouveau

    Inscrit:
    8 Juin 2019
    Messages:
    12
    J'aime reçus:
    0
    Bonjour,

    Je viens sur ce forum car j'ai un problème. J'ai au préalable fait mes recherches sur Internet et forums, sans obtenir ce que je voulais.
    Dans le cadre de mon mod, je souhaite créer une TNT, je me suis donc occupé de register le block, ses textures, jusque la pas de problèmes. Si joint mon dossier src pour avoir l'entièreté du code.
    Les problèmes :
    1) quand je met la tnt dans un dispenser, elle drop mais ne s'allume pas
    2) quand je veux la faire exploser avec par exemple un flint and steel, elle prend la texture de la TNT de base de Minecraft et non de la mienne.

    Voici mes infos :
    J'utilise intellij idea community de JetBrains dernière mise a jour comme ide
    Mon JDK est a jour (java 8)
    Je code sur MinecraftForge 1.12.2-14.23.5.2705

    J'espère que quelqu'un saura m'aider !

    En vous souhaitant une agréable journée,

    Flow Arg
     

    Fichiers attachés:

    • src.zip
      Taille de fichier:
      95.6 KB
      Affichages:
      19
    #1 Flow Arg, 8 Juin 2019
    Dernière édition: 8 Juin 2019
  2. robin4002

    robin4002 Étudiant en informatique
    Staff Responsable technique Responsable forum

    Inscrit:
    12 Novembre 2012
    Messages:
    16 389
    J'aime reçus:
    2 613
    Salut,

    Pour le point 1, il faut enregistrer une action personnalisé de dispenser. Je ne sais plus exactement comment il faut faire, donc je te laisser chercher sur google.
    Pour le point 2, c'est normal, puisque tu fais apparaître une entité de TNT normal lorsque ta TNT est déclenché.
    Il faut créer une entité TNT personnalisé et enregistré un rendu personnalisé.
     
    Flow Arg apprécie ceci.
  3. Flow Arg

    Flow Arg Nouveau

    Inscrit:
    8 Juin 2019
    Messages:
    12
    J'aime reçus:
    0
    Salut, je retiens tes propositions, je vais chercher comment faire tout ça !!
     
  4. ShE3py

    ShE3py Développeur en autodidacte

    Inscrit:
    26 Septembre 2015
    Messages:
    978
    J'aime reçus:
    163
    Ante-post-scriptum: Robin a déjà répondu, mais je ne vais quand même pas gâcher ce beau pavé ^c^

    Bonjour,

    Suffit de copier ce qu'il y a dans le code source de Minecraft. Jette un coup d'œil à BlockTNT#explode(World, BlockPos, EntityLivingBase), c'est lui qui fait apparaître l'entité (lorsque la TNT est activée, le bloc se transforme en une entité), il faut je pense que tu créés une nouvelle entité qui hérite d'EntityTNTPrimed et que tu changes la texture de celle-ci.

    Comme la méthode est privée, soit tu passes à coups d'access transformers pour pouvoir l'override, soit tu copy-pasta cette méthode dans la classe de ta TNT, changes l'entité invoquée par la tienne, et tu surcharges toutes les méthodes qui font appel à cette fonction, sinon certaines portions du code vont appeler la méthode parente, pas ce que tu veux.
    Ces méthodes ressemblent plus ou moins à :
    • #onExplosionDestroy(World, BlockPos, Explosion)
    • #explode(World, BlockPos)
    • #onBlockActivated(IBlockState, World, BlockPos, EntityPlayer, EnumHand, EnumFacing, float, float, float)
    • #onEntityCollision(IBlockState, World, BlockPos, Entity)
    Pour le dispenser, tu dois utiliser BlockDispenser#registerDispenseBehavior(IItemProvider, IBehaviorDispenseItem).
    Pour la TNT classique, cet appel est fait comme ça :
    Code:
    BlockDispenser.registerDispenseBehavior(Blocks.TNT, new BehaviorDefaultDispenseItem() {
       /**
        * Dispense the specified stack, play the dispense sound and spawn particles.
        */
       protected ItemStack dispenseStack(IBlockSource source, ItemStack stack) {
          World world = source.getWorld();
          BlockPos blockpos = source.getBlockPos().offset(source.getBlockState().get(BlockDispenser.FACING));
          EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double)blockpos.getX() + 0.5D, (double)blockpos.getY(), (double)blockpos.getZ() + 0.5D, (EntityLivingBase)null);
          world.spawnEntity(entitytntprimed);
          world.playSound((EntityPlayer)null, entitytntprimed.posX, entitytntprimed.posY, entitytntprimed.posZ, SoundEvents.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1.0F, 1.0F);
          stack.shrink(1);
          return stack;
       }
    });
    Comme toujours, il te suffit de copy pasta, en remplaçant l'entité invoquée par la tienne. La fonction est appelée par le Boostrap, après l'enregistrement des blocs donc je pense que tu peux directement appeler la fonction en même temps que tu enregistres tes blocs.

    Bon, sinon ton code source fait mal aux yeux ;
    1. Tu enregistres tes items et tes blocs dans le proxy client. Il fait comment le serveur pour les avoir ? Enregistre-les dans le proxy commun.

    2. Les classes enregistrement les items, blocs et recipes (init/) utilisent un singleton, public static final ModFoo INSTANCE = new ModFoo(). C'est complètement inutile, il te suffit de déclarer toutes tes variables/méthodes statique. Tu économiseras ainsi une quantité extrêmement négligeable de mémoire et de vitesse, mais cela augmentera le plaisir charnel que te procurera la lecture du code.

    3. Évite les fonctions qui appellent une autre fonction avec une seule instruction en plus, style migre les évènements liés aux registres dans tes classes qui contiennent tous les éléments, on s'y perd un peu. Faut aller à contre-courant pour trouver d'où sont appelées tes fonctions, je n'imagine pas à quoi ça ressemble dans ta tête.
      Par exemple, dans ModBlocks#registerModels(ModelRegistryEvent), tu itères sur tous tes blocs pour n'appeler qu'une fonction qui fait elle-même une ligne. Et quitte à faire un truc tout con, autant exposer son savoir :
      Code:
      blocks.forEach(this::registerModel);

    Bon je m'emporte un peu, n'hésite pas à me dire où je t'ai perdu.
    Sur ce 666ème message, cordialement,
    ShE3py.
     
    robin4002 et Flow Arg aiment ça.
  5. Flow Arg

    Flow Arg Nouveau

    Inscrit:
    8 Juin 2019
    Messages:
    12
    J'aime reçus:
    0
    Salut, merci d'avoir pris le temps d'écrire ce pavé pour moi, au niveau du dispenser, il ne reconnait pas BlockDispenser#registerDispenseBehavior
    le reste est bien reconnu mais pas registerDispenseBehavior.

    Flow Arg
     
    #5 Flow Arg, 8 Juin 2019
    Dernière édition: 8 Juin 2019
  6. robin4002

    robin4002 Étudiant en informatique
    Staff Responsable technique Responsable forum

    Inscrit:
    12 Novembre 2012
    Messages:
    16 389
    J'aime reçus:
    2 613
    Ça valait largement le coup de poster ta réponse qui est bien plus détaillé, merci ShE3py !

    Flow Arg, tu as bien mis un . à la place du # ? (le # c'est une notation de la Java doc, on utilise pas pour dire que c'est la méthode registerDispenseBehavior qui est dans la classe BlockDispenser)
     
  7. Flow Arg

    Flow Arg Nouveau

    Inscrit:
    8 Juin 2019
    Messages:
    12
    J'aime reçus:
    0
    Oui oui, c'est bien un .
     
  8. ShE3py

    ShE3py Développeur en autodidacte

    Inscrit:
    26 Septembre 2015
    Messages:
    978
    J'aime reçus:
    163
    Mon workspace est en 1.13, regarde dans la classe (deux fois CTRL + N sous IntelliJ, BlockDispenser) si la fonction a pas changée de nom ou si tu peux accéder directement au registre ;
    Code:
    BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObj(item, behavior)
     
    Flow Arg apprécie ceci.
  9. Flow Arg

    Flow Arg Nouveau

    Inscrit:
    8 Juin 2019
    Messages:
    12
    J'aime reçus:
    0
    ja'ai réussi a accéder via ton code mais autre chose n'allai pas :
    .get(BlockDispenser.FACING)); ne passe pas.
     
  10. ShE3py

    ShE3py Développeur en autodidacte

    Inscrit:
    26 Septembre 2015
    Messages:
    978
    J'aime reçus:
    163
    Copie-colle celui de ta version, en l'occurrence il est dans la classe Bootstrap (pareil, deux fois CTRL + N, par contre y'en a plusieurs prend bien celui de net.minecraft.init), puis tu fais rechercher (CTRL + F), Blocks.TNT et normalement si tout ce passe bien tu devrais arriver sur l'enregistrement du comportement vanilla. Tu copies-colles et change la classe de l'entité.

    Après le modding si tu veux reprendre quelque chose déjà existant c'est toujours du copier-coller du code source original, si tu cherches comment utiliser un objet le mieux c'est de rechercher les termes (CTRL + F ou H selon l'IDE), comme ça tu verras tous les endroits où cet objet est appelé.
     
    Flow Arg apprécie ceci.

Partager cette page