Vous avez sûrement remarqué que certains blocs ont des metadata, ce qui donne un id du genre 5:1, 5:2 etc… Dans ce tutoriel, vous allez apprendre à utiliser les metadata classiques, qui permettent d’avoir 16 metadata ( de :0 à :15).
L’avantage des metadata est donc de pouvoir mettre 16 blocs sur le même id, cela permet donc d’économiser les ids.
Dans la classe principale
À la suite de vos déclarations de blocs déjà existants, ajoutez un nouveau bloc :
public static Block BlockTutorial, TutorialMetadata;
Ensuite, on crée le bloc de façon normale :
TutorialMetadata = new BlockTutorialMetadata (2001).setHardness(2.0F).setResistance(10.0F)
.setStepSound(Block.soundStoneFootstep).setUnlocalizedName("TutorialMetadata");
La seule différence est que je l’ai pas la fonction pour la texture, elle sera déclarée dans la classe de notre bloc.
Ensuite on enregistre le bloc :
GameRegistry.registerBlock(TutorialMetadata, ItemBlockTutorialMetadata.class, "TutorialMetadata", "ModTutoriel");
TutorialMetadata est le bloc, ItemBlockTutorialMetadata.class et une nouvelle classe que nous allons créer. Il faut savoir que quand vous créez un bloc, vous créez aussi un item qui va avec. Le bloc est ce qui est posé sur la map, et l’item est soit sous forme d’itemstack dans l’inventaire, soit sous forme d’entityItem si vous le jetez par terre. Quand on crée un bloc simple, l’itemblock utilisé est celui par défaut de minecraft, mais lorsqu’on crée un bloc avec des metadata, nous avons besoin de créer notre propre itemblock.
“TutorielMetadata” est le nom du bloc, utilisé pour le système d’itemtracker de FML. “ModTutoriel” est mon modid, aussi utilisé par l’itemtracker de FML.
Créez les deux classes “ItemBlockTutorielMetadata” et “BlockTutorielMetadata”
La classe du bloc
Tout comme un bloc basique, créez le constructeur et faites un extends Block :
package tutoriel.common;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
public class BlockTutorialMetadata extends Block
{
public BlockTutorialMetadata(int id)
{
super(id, Material.rock);
this.setCreativeTab(CreativeTabs.tabBlock);
}
}
Ensuite ajoutez au-dessus du constructeur ceci :
public static String[] type = new String[]{"block1", "block2", "block3", "block4", "block5", "block6", "block7", "block8"};
private Icon[] IconArray;
Ceci est un tableau de chaîne de caractère, je l’ai appelé type, vous pouvez le nommer comme vous voulez. Nous allons utiliser ce tableau pour l’enregistrement de textures, et pour les noms. block1, block2, etc… correspondent aux noms des futurs .png et aux noms non localisés, adaptez-les selon vos besoins.
En dessous, j’ai fait un tableau d’icônes, il va servir pour les textures. (Importez net.minecraft.util.Icon)
Maintenant nous allons ajouter la méthode d’enregistrement d’icône :
public void registerIcons(IconRegister iconregister)
{
IconArray = new Icon[type.length];
for(int i = 0; i < type.length; i++)
{
IconArray[i] = iconregister.registerIcon("modtutoriel:" + type[i]);
}
}
On commence par indiquer la longueur du tableau “IconArray”, elle va être la même que notre tableau type. Ensuite, c’est une petite boucle for, elle va permettre d’enregistrer tous les icônes en fonction de la taille du tableau type. Ainsi, si vous souhaitez ajouter un bloc de plus, il vous suffit de l’ajouter au tableau “type”.
Maintenant il faut ajouter la fonction pour voir les blocs dans la table créative :
@SideOnly(Side.CLIENT)
public void getSubBlocks(int id, CreativeTabs creativeTabs, List list)
{
for(int metadata = 0; metadata < type.length; metadata++)
{
list.add(new ItemStack(id, 1, metadata));
}
}
À nouveau la boucle for nous simplifie la vie, le principe est le même qu’au-dessus. Pour les erreurs, faites ctrl + shift + o pour organiser les importations, pour List, choisissez “java.util.List”
Il ne nous reste plus qu’à finaliser la texture, car pour l’instant notre bloc utilise l’icône “blockIcon” comme il est extends Block. Nous allons donc ajouter la méthode getIcon dans notre bloc :
@SideOnly(Side.CLIENT)
public Icon getIcon(int side, int metadata)
{
return metadata < type.length && metadata >= 0 ? IconArray[metadata] : IconArray[0];
}
Pour ceux qui ont pas l’habitude des conditions ternaires , cela revient à faire ça :
if(metadata < type.length && metadata >= 0)
return IconArray[metadata];
else
return IconArray[0];
La condition “if(metadata < type.length && metadata >= 0)” sert à vérifier que la metadata du bloc ne soit pas supérieure ou inférieure à la taille du tableau “IconArray” car si je crée un bloc qui n’a que 5 metadata par exemple et que le joueur s’amuse à se give le bloc de metadata 6 ou supérieur (avec /give <pseudo><id><quantité>6), l’icone sera IconArray[6], or comme le tableau n’a que 5 case, le jeu va crasher avec un java.lang.ArrayIndexOutOfBoundsException, ce code est donc une prévention contre un crash
Une dernière méthode :
public int damageDropped(int metadata)
{
return metadata;
}
Elle est assez importante, si vous ne la mettez pas tous vos blocs vont dropper le metadata 0, idem pour le “pickupBlock”
La classe de l’item bloc
La classe du bloc est fini, nous allons maintenant nous occuper de la classe de l’item bloc.
Commencer par ajouter extends ItemBlock, puis importez net.minecraft.item.ItemBlock
Ensuite, dans le constructeur, ajoutez this.setHasSubtypes(true);
package tutoriel.common;
import net.minecraft.item.ItemBlock;
public class ItemBlockTutorialMetadata extends ItemBlock
{
public ItemBlockTutorialMetadata(int id)
{
super(id);
this.setHasSubtypes(true);
}
}
Ensuite, ajoutez cette méthode :
public int getMetadata(int metadata)
{
return metadata;
}
Par défaut dans Item.java cette fonction renvoie sur 0, c’est pour ça qu’il est important de la mettre, sinon même avec un bloc d’id <quelque chose=“”>:1, lorsque vous le poserez, il deviendra un bloc de metadata 0. Donc si un jour vous avez ce problème, vous saurez que vous avez oublié de mettre cette fonction (je préviens, car ça m’est déjà arrivé)
Il reste encore à faire la fonction pour le nom, vous allez donc ajouter :
public String getUnlocalizedName(ItemStack stack)
{
int metadata = stack.getItemDamage();
if(metadata > BlockTutorialMetadata.type.length || metadata < 0)
{
metadata = 0;
}
return super.getUnlocalizedName() + "." + BlockTutorialMetadata.type[metadata];
}
Une fois de plus, if(metadata > BlockTutorialMetadata.type.length || metadata < 0) est une condition pour éviter un java.lang.ArrayIndexOutOfBoundsException.
Le nom non localisé sera donc tile.<le nom dans setunlocalizedname(“”)>.<le nom dans le tableau type>.name
Les ressources du bloc (texture + nom)
Allez dans votre dossier forge/mcp/src/minecraft/assets/votre mod id/textures/block/
Créez tout les fichiers .png correspondant aux noms que vous avez mis dans le tableau type.
Retournez dans forge/mcp/src/minecraft/assets/votre mod id/lang, ouvrez le fichier en_US.lang, et ajoutez les noms :
tile.<le nom dans setunlocalizedname(“”)>.<le nom dans le tableau type>.name=le nom localisé
Exemple :
tile.TutorialMetadata.block1.name=Metadata Tutorial 1
tile.TutorialMetadata.block2.name=Metadata Tutorial 2
tile.TutorialMetadata.block3.name=Metadata Tutorial 3
tile.TutorialMetadata.block4.name=Metadata Tutorial 4
tile.TutorialMetadata.block5.name=Metadata Tutorial 5
tile.TutorialMetadata.block6.name=Metadata Tutorial 6
tile.TutorialMetadata.block7.name=Metadata Tutorial 7
tile.TutorialMetadata.block8.name=Metadata Tutorial 8