Flow Arg

Développeur Java
8 Juin 2019
14
0
12
France
flowarg.github.io
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 joints

  • src.zip
    95.6 KB · Affichages: 394
Dernière édition:

robin4002

Expert en informatique et systèmes d'information
Staff
Responsable technique
Responsable forum
12 Novembre 2012
20 857
157
3 002
347
26
Alsace
www.minecraftforgefrance.fr
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é.
 
  • J'aime
Reactions: Flow Arg

Flow Arg

Développeur Java
8 Juin 2019
14
0
12
France
flowarg.github.io
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é.

Salut, je retiens tes propositions, je vais chercher comment faire tout ça !!
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 129
162
461
247
21
Mìlhüsa
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.
 

Flow Arg

Développeur Java
8 Juin 2019
14
0
12
France
flowarg.github.io
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.

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
 
Dernière édition:

robin4002

Expert en informatique et systèmes d'information
Staff
Responsable technique
Responsable forum
12 Novembre 2012
20 857
157
3 002
347
26
Alsace
www.minecraftforgefrance.fr
Ç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)
 

Flow Arg

Développeur Java
8 Juin 2019
14
0
12
France
flowarg.github.io
Ç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)

Oui oui, c'est bien un .
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 129
162
461
247
21
Mìlhüsa
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)
 
  • J'aime
Reactions: Flow Arg

Flow Arg

Développeur Java
8 Juin 2019
14
0
12
France
flowarg.github.io
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)

ja'ai réussi a accéder via ton code mais autre chose n'allai pas :
.get(BlockDispenser.FACING)); ne passe pas.
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 129
162
461
247
21
Mìlhüsa
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é.
 
  • J'aime
Reactions: Flow Arg