Créer un item générateur de structure



  • Sommaire

    • Introduction

    • Pré-requis

    • (#code)
       [list]
       [*][Les items](#classe1)
       [*][La classe ItemStructureGen](#classe2)
       [*][Les structures](#classe3)
       [/list] [*][Bonus](#bonus)
       [*][Résultat](#resultat)
       [*][Crédits](#credit)
      
       [ancre=intro]#[align][size]Introduction([align][size]Introduction)[/ancre]
      Salut à tous, dans ce tutoriel je vais vous apprendre à créer un item qui, à l'aide d'un clique droit, va faire apparaitre une structure.
      Pour ce qui est de la structure en elle même, je vous réfère au [tutoriel sur les structure](https://www.minecraftforgefrance.fr/showthread.php?tid=1102) d' AlphaSwittleTeam.
      
       [ancre=prerequis]#[align][size]Pré-requis([align][size]Pré-requis)[/ancre]
      [list]
      [*][Créer un item basique](https://www.minecraftforgefrance.fr/showthread.php?tid=588)
      [*][Générer une structure](https://www.minecraftforgefrance.fr/showthread.php?tid=1102)
      [/list] 
       [ancre=code]#[align][size]Code([align][size]Code)[/ancre]
      
       [ancre=classe1][size]***Les items :***[/ancre]
      Tout d'abord rajoutez ceci dans la fonction preInit de votre classe principale:
      ```java
      
       //Déclaration des items
      public static Item gen_totem1;
      public static Item gen_totem2;
      
      //Initialisation
      gen_totem1 = new ItemStructureGen(1).setUnlocalizedName("gen_totem1").setTextureName(Reference.MOD_ID + ":gen_totem1"); 
      gen_totem2 = new ItemStructureGen(2).setUnlocalizedName("gen_totem2").setTextureName(Reference.MOD_ID + ":gen_totem2");
      
       //Enregistrements
      GameRegistry.registerItem(gen_totem1, "gen_totem1");
      GameRegistry.registerItem(gen_totem2, "gen_totem2");
      
      

      Ici, vous avez une erreur sur la classe ItemStructureGen, créez-là.

      [ancre=classe2][size]***La classe ItemStructureGen :***[/ancre]
      Une fois votre classe créée,

      extends Item
      

      Créez son constructeur comme ceci:

      
      public ItemStructureGen(int struct) //Reçoit en argument la  structure(totem1, totem2, ...)
      {
         this.structure = struct; //Enregistrement de la valeur reçue dans la variable structure
      }
      
      //N'oubliez pas de rajouter ceci juste après le { de la classe:
      public final int structure;
      
      

      Maintenant, rajoutez cette fonction:

      
      public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
      {
      
      }
      
      

      Elle va permettre de dire quoi faire quand on fait un clique droit avec l'item en main

      Rajoutez ce code dedans:

      
              switch(structure) 
              {
                  case 1:
                      StructureTotem1.generate(world, x, y+1, z); //Ici, on fait y+1 de manière à ce que quand on fait un clique sur le sol la structure se génère sur le sol et pas dedans
                      return true;
      
                  case 2:
                      StructureTotem2.generate(world, x, y+1, z);
                      return true;
      
                  default:
                      return false;
              }
      

      Donc, on switch la variable structure, si elle est égale à 1, on génère le Totem1 et si elle est égale à 2, on génère le Totem2.
      Ce qui est bien avec cette technique c'est qu'on a très facile pour rajouter d'autres structures.

      La classe ItemStructureGen doit ressembler à ça:

      public class ItemStructureGen extends Item
      {
          public final int structure;
      
          public ItemStructureGen(int struct)
          {
              this.structure = struct;
          }
      
          public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
          {
              switch(structure)
              {
                  case 1:
                      StructureTotem1.generate(world, x, y+1, z);
                      return true;
      
                  case 2:
                      StructureTotem2.generate(world, x, y+1, z);
                      return true;
      
                  default:
                      return false;
              }
          }
      }
      

      Les 2 classes si-dessus ne sont pas encore créés, faites-le.

      [ancre=classe3][size]***Les structures :***[/ancre]
      Pour ma part, je vais créer ces 2 totems:
      [img]http://image.noelshack.com/fichiers/2016/24/1466261783-totem-1.jpg[/img]
      [img]http://image.noelshack.com/fichiers/2016/24/1466261783-totem-2.jpg[/img]

      Ajoutez cette fonction:

      public static boolean generate(World world, int x, int y, int z)
      {
      
      }
      

      Ensuite, ajoutez ceci:

         //netherrack
      world.setBlock(x-1, y, z, Blocks.netherrack);
      world.setBlock(x+1, y, z, Blocks.netherrack);
      world.setBlock(x-1, y+2, z, Blocks.netherrack);
      world.setBlock(x+1, y+2, z, Blocks.netherrack);
      world.setBlock(x, y+1, z, Blocks.netherrack);
      
      //quartz
      world.setBlock(x, y, z, Blocks.quartz_block);
      world.setBlock(x, y+2, z, Blocks.quartz_block);
      
      return true;
      
      

      Encore une fois, allez voir le tutoriel d'AlphaSwittleTeam pour comprendre.

      La classe StructureTotem1 finie:

      public class StructureTotem1
      {
          public static boolean generate(World world, int x, int y, int z)
          {
                   //netherrack
                   world.setBlock(x-1, y, z, Blocks.netherrack);
                   world.setBlock(x+1, y, z, Blocks.netherrack);
                   world.setBlock(x-1, y+2, z, Blocks.netherrack);
                   world.setBlock(x+1, y+2, z, Blocks.netherrack);
                   world.setBlock(x, y+1, z, Blocks.netherrack);
      
                   //quartz
                  world.setBlock(x, y, z, Blocks.quartz_block);
                  world.setBlock(x, y+2, z, Blocks.quartz_block);
      
                  return true;
          }
      }
      

      Et ma classe StructureTotem2:

      public class StructureTotem2
      {
          public static boolean generate(World world, int x, int y, int z)
          {
                   //lapis-lazuli
                   world.setBlock(x-1, y, z, Blocks.lapis_block);
                   world.setBlock(x+1, y, z, Blocks.lapis_block);
                   world.setBlock(x-1, y+2, z, Blocks.lapis_block);
                   world.setBlock(x+1, y+2, z, Blocks.lapis_block);
                   world.setBlock(x, y+1, z, Blocks.lapis_block);
      
                   //dirt
                  world.setBlock(x, y+2, z, Blocks.dirt);
                  world.setBlock(x, y+3, z, Blocks.dirt);
      
                  return true;
          }
      }
      

      [ancre=bonus]#[align][size]Bonus([align][size]Bonus)[/ancre]
      [ancre=bonus1][size]***Supprimer son item après utilisation :***[/ancre]
      Vous pourriez trouver cela un peu cheaté de pouvoir faire apparaître des structures à l'infini avec le même item.
      Voilà comment y remédier.

      Tout d'abord rajouter en dessous de StructureTotem1.generate(...) et StructureTotem2.generate(...) ceci:

      use(itemStack, player);
      

      Créez cette méthode comme ceci:

      private void use(ItemStack itemStack, EntityPlayer player)
          {
              if (!player.capabilities.isCreativeMode) //Si le joueur n'est pas en créatif
              {
                  --itemStack.stackSize; //Décrémentation du stack, suppression de l'item
              }
          }
      

      Votre classe finie doit ressembler à ça:

      public class ItemStructureGen extends Item
      {
          public final int structure;
      
          public ItemStructureGen(int struct)
          {
              this.structure = struct;
          }
      
          public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
          {
              switch(structure)
              {
                  case 1:
                      StructureTotem1.generate(world, x, y+1, z);
                      use(itemStack, player);
                      return true;
      
                  case 2:
                      StructureTotem2.generate(world, x, y+1, z);
                      use(itemStack, player);
                      return true;
      
                  default:
                      return false;
              }
          }
      
          private void use(ItemStack itemStack, EntityPlayer player)
          {
              if (!player.capabilities.isCreativeMode)
              {
                  --itemStack.stackSize;
              }
          }
      }
      

      [ancre=resultat]#[align][size]Résultats([align][size]Résultats)[/ancre]

      [ancre=credit]#[align][size]Crédits([align][size]Crédits)[/ancre]
      Rédaction :
      [list]
      []Minantcraft
      [/list]
      Correction :
      [list]
      [
      ]
      [/list]

      Ce tutoriel de Minecraft Forge France est mis à disposition selon les termes de la licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International

      [align]Retour vers le sommaire des tutoriels[/align][/size][/align][/size][/align][/size][/align][/size][/align][/size][/size][/align][/size][/align][/size][/size][/size][/size][/align][/size][/align][/size][/align][/size][/align][/size][/align][/size][/align]


  • Rédacteurs

    Pour le random tu peux utiliser celui de la variable world, et extends ta classe de génération worldGenerator ne sert à rien, de toute façon tu ne l'enregistre pas comme tel



  • Bonjour alors déjà, bon tutoriel bien expliqué et sans aucune faute, j'ai une petite modification à proposer, tu pourrais remplacer le java Random rand = new Random(); dans la fonction onItemUse par ```java
    Random rand = world.rand

    EDIT : et aussi adapter le tuto pour la 1.8/1.9, le seul truc qui change, c'est x,y,z remplacé par BlockPos.


  • @'AymericRed':

    Bonjour alors déjà, bon tutoriel bien expliqué et sans aucune faute, j'ai une petite modification à proposer, tu pourrais remplacer le java Random rand = new Random(); dans la fonction onItemUse par ```java
    Random rand = world.rand

    Ok je modifie ça.


  • Rédacteurs

    Et à un moment tu dis, "ça vous a créé un constructeur assez dégueulasse", mais c'est pas un constructeur, c'est juste une fonction avec des paramètres



  • @'BrokenSwing':

    Et à un moment tu dis, "ça vous a créé un constructeur assez dégueulasse", mais c'est pas un constructeur, c'est juste une fonction avec des paramètres

    Oui je sais j'ai changé et j'ai aussi enlevé le extends WorldGenerator et le random

    EDIT: J'ai changé "Ajoutez ce constructeur" par "Ajoutez cette fonction"


  • Rédacteurs

    Et un truc de + (désolé xD) mais tu pourrai rendre ta fonction generate(World, int, int, int) static parce que tu n'as aucune utilitée à créer une instance de la classe



  • @'BrokenSwing':

    Et un truc de + (désolé xD) mais tu pourrai rendre ta fonction generate(World, int, int, int) static parce que tu n'as aucune utilitée à créer une instance de la classe

    C'est fait!


  • Rédacteurs

    Mais du coup la fonction dans l'item devient :```java

    public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
    {
    switch(structure)
    {
    case 1:
    StructureTotem1.generate(world, x, y+1, z);
    return true;

    case 2:
    StructureTotem2.generate(world, x, y+1, z);
    return true;

    default:
    return false;
    }
    }



  • @'BrokenSwing':

    Mais du coup la fonction dans l'item devient :```java

    public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
    {
    switch(structure)
    {
    case 1:
    StructureTotem1.generate(world, x, y+1, z);
    return true;

    case 2:
    StructureTotem2.generate(world, x, y+1, z);
    return true;

    default:
    return false;
    }
    }

    OK



  • Tutoriel pas trop mal dans l'ensemble même si un peu plus de précisions sur où placer certaines parties de code n'auraient pas étaient de trop.

    PS : ce serait bien de rajouter le fait que l'item se détruise une fois utilisé sinon ça me paraît un peu cheaté à utiliser.



  • @'SCAREX':

    Tutoriel pas trop mal dans l'ensemble même si un peu plus de précisions sur où placer certaines parties de code n'auraient pas étaient de trop.

    PS : ce serait bien de rajouter le fait que l'item se détruise une fois utilisé sinon ça me paraît un peu cheaté à utiliser.

    C'est pour ça que je met à chaque fin de partie la classe en entière.

    PS: Ça pourrait être un item réservé au créatif qui permet d'avoir la structure sans devoir cherché dans le monde mais je vais voir pour la destruction de l'item dans la partie bonus



  • Un simple if (player.isInCreativeMode()) player.getEquippedItem().stacksize–; est suffisant (pas totalement sûr du code)



  • Tuto fini, avec BONUS.