Les metadata de bloc


  • Administrateurs

    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
    

    Rendu final

    Voir les changements sur Github
    Bloc avec metadata



  • Salut !
    J'ai eu un petit bug avec le block register, il me sort une nullPointerException. Je cite l'erreur :

    2013-07-22 23:16:42 [SEVERE] [ForgeModLoader] Caught an exception during block registration
    java.lang.NullPointerException
    at cpw.mods.fml.common.registry.ItemData.setName(ItemData.java:158)
    at cpw.mods.fml.common.registry.GameData.setName(GameData.java:255)
    at cpw.mods.fml.common.registry.GameRegistry.registerItem(GameRegistry.java:150)
    at cpw.mods.fml.common.registry.GameRegistry.registerBlock(GameRegistry.java:227)
    

    Voici mon code :

    DoorBlock = new DoorBlock(605).setHardness(5.0F).setResistance(2000.0F).setStepSound(Block.soundMetalFootstep).setUnlocalizedName("DoorBlock");
    GameRegistry.registerBlock(DoorBlock, ItemBlockDoorBlock.class, "DoorBlock", "WirestoneCore");
    output("Bloc et sous-blocs 'DoorBlock' initialisés !");
    

    Sinon très bon tuto !

    P.S : Je ne sais pas trop où poster ça puisque ça va dans le support mais c'est lié à ce tutoriel donc bon 😕


  • Administrateurs

    Les portes utilise déjà les metadata pour la direction de la porte, tu ne peux pas mettre des portes en metadata.



  • Non non, si je dis ça c'est que c'est pas une porte ^^. Ce sont des blocs.

    (Pour explication, ce sont des blocs avec des textures qui se suivent, cela permet de faire des portes à piston avec une texture uniforme)


  • Administrateurs

    Je peux avoir les logs complets et ta classe principale complète ?



  • Bien sûr ! Je t'avertis ça crève un peu les yeux, j'ai pas suivi l'ordre précis de tes tutos, j'ai tout groupé en fait. Par exemple les register seront à côté de la déclaration du bloc.
    Tout est commenté donc tu devrais pouvoir t'y retrouver ^^
    Voici la classe principale : (j'ai enlevé le package et les import)


    Ma classe ItemBlockBlockDoor :

    package fr.wirestone.mainmod;
    
    import net.minecraft.item.ItemBlock;
    import net.minecraft.item.ItemBlock;
    import net.minecraft.item.ItemStack;
    
    public class ItemBlockDoorBlock extends ItemBlock{
    public ItemBlockDoorBlock(int id){
    super(id);
    this.setHasSubtypes(true);
    }
    public int getMetadata(int metadata){
    return metadata;
    }
    public String getUnlocalizedName(ItemStack stack){
    int metadata = stack.getItemDamage();
    if(metadata > DoorBlock.type.length || metadata < 0){
    metadata = 0;
    }
    return super.getUnlocalizedName() + "." + DoorBlock.type[metadata];
    }
    }
    

    Et voici la totalité du log :

    juil. 23, 2013 2:41:35 PM net.minecraft.launchwrapper.LogWrapper log
    INFO: Using tweak class name cpw.mods.fml.common.launcher.FMLTweaker
    2013-07-23 14:41:35 [INFO] [ForgeModLoader] Forge Mod Loader version 6.2.19.789 for Minecraft 1.6.2 loading
    2013-07-23 14:41:35 [INFO] [ForgeModLoader] Java is Java HotSpot(TM) Client VM, version 1.7.0_25, running on Windows 7:x86:6.1, installed at C:\Program Files\Java\jre7
    2013-07-23 14:41:35 [INFO] [ForgeModLoader] Managed to load a deobfuscated Minecraft name- we are in a deobfuscated environment. Skipping runtime deobfuscation
    2013-07-23 14:41:35 [INFO] [STDOUT] Loaded 39 rules from AccessTransformer config file fml_at.cfg
    2013-07-23 14:41:35 [INFO] [STDOUT] Loaded 107 rules from AccessTransformer config file forge_at.cfg
    2013-07-23 14:41:36 [SEVERE] [ForgeModLoader] The binary patch set is missing. Things are probably about to go very wrong.
    2013-07-23 14:41:36 [INFO] [ForgeModLoader] Launching wrapped minecraft
    2013-07-23 14:41:39 [INFO] [Minecraft-Client] Setting user: Player946
    2013-07-23 14:41:39 [INFO] [Minecraft-Client] (Session ID is null)
    2013-07-23 14:41:43 [INFO] [Minecraft-Client] LWJGL Version: 2.9.0
    2013-07-23 14:41:45 [INFO] [Minecraft-Client] Reloading ResourceManager: Default
    2013-07-23 14:41:46 [INFO] [STDOUT]
    2013-07-23 14:41:46 [INFO] [STDOUT] Starting up SoundSystem…
    2013-07-23 14:41:46 [INFO] [STDOUT] Initializing LWJGL OpenAL
    2013-07-23 14:41:46 [INFO] [STDOUT] (The LWJGL binding of OpenAL. For more information, see http://www.lwjgl.org)
    2013-07-23 14:41:46 [INFO] [MinecraftForge] Attempting early MinecraftForge initialization
    2013-07-23 14:41:46 [INFO] [STDOUT] MinecraftForge v9.10.0.789 Initialized
    2013-07-23 14:41:46 [INFO] [ForgeModLoader] MinecraftForge v9.10.0.789 Initialized
    2013-07-23 14:41:47 [INFO] [STDOUT] Replaced 101 ore recipies
    2013-07-23 14:41:47 [INFO] [STDOUT] OpenAL initialized.
    2013-07-23 14:41:47 [INFO] [STDOUT]
    2013-07-23 14:41:47 [INFO] [MinecraftForge] Completed early MinecraftForge initialization
    2013-07-23 14:41:47 [INFO] [ForgeModLoader] Reading custom logging properties from C:\Users\Arthur\Documents\Dropbox\Programmation\Java\forge-9.10.0.789\mcp\jars\config\logging.properties
    2013-07-23 14:41:47 [OFF] [ForgeModLoader] Logging level for ForgeModLoader logging is set to ALL
    2013-07-23 14:41:48 [INFO] [ForgeModLoader] Searching C:\Users\Arthur\Documents\Dropbox\Programmation\Java\forge-9.10.0.789\mcp\jars\mods for mods
    2013-07-23 14:41:56 [INFO] [ForgeModLoader] Forge Mod Loader has identified 4 mods to load
    2013-07-23 14:41:56 [INFO] [mcp] Activating mod mcp
    2013-07-23 14:41:56 [INFO] [FML] Activating mod FML
    2013-07-23 14:41:56 [INFO] [Forge] Activating mod Forge
    2013-07-23 14:41:56 [INFO] [WiremodCore] Activating mod WiremodCore
    2013-07-23 14:41:56 [INFO] [ForgeModLoader] Registering Forge Packet Handler
    2013-07-23 14:41:56 [INFO] [ForgeModLoader] Succeeded registering Forge Packet Handler
    2013-07-23 14:41:56 [INFO] [ForgeModLoader] Configured a dormant chunk cache size of 0
    2013-07-23 14:41:56 [INFO] [STDOUT] –--------------------------
    2013-07-23 14:41:56 [INFO] [STDOUT] WirestoneCore par Arthur340
    2013-07-23 14:41:56 [INFO] [STDOUT] –--------------------------
    2013-07-23 14:41:56 [INFO] [STDOUT]
    2013-07-23 14:41:56 [INFO] [STDOUT] –> Initialisation globale du mod en cours !
    2013-07-23 14:41:56 [INFO] [STDOUT]
    2013-07-23 14:41:56 [INFO] [STDOUT] [WIRESTONE] Initialisation des blocs…
    2013-07-23 14:41:56 [INFO] [STDOUT] [WIRESTONE] Bloc 'InvisibleBlock' initialisé !
    2013-07-23 14:41:56 [INFO] [STDOUT] [WIRESTONE] Bloc 'Fan' initialisé !
    2013-07-23 14:41:56 [INFO] [STDOUT] [WIRESTONE] Bloc 'Grid' initialisé !
    2013-07-23 14:41:56 [INFO] [STDOUT] [WIRESTONE] Bloc 'Neon' initialisé !
    2013-07-23 14:41:56 [INFO] [STDOUT] [WIRESTONE] Bloc 'WarningBlock' initialisé !
    2013-07-23 14:41:56 [SEVERE] [ForgeModLoader] Caught an exception during block registration
    java.lang.NullPointerException
    at cpw.mods.fml.common.registry.ItemData.setName(ItemData.java:158)
    at cpw.mods.fml.common.registry.GameData.setName(GameData.java:255)
    at cpw.mods.fml.common.registry.GameRegistry.registerItem(GameRegistry.java:150)
    at cpw.mods.fml.common.registry.GameRegistry.registerBlock(GameRegistry.java:227)
    at fr.wirestone.mainmod.WirestoneMain.PreInit(WirestoneMain.java:72)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at cpw.mods.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:540)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.google.common.eventbus.EventHandler.handleEvent(EventHandler.java:74)
    at com.google.common.eventbus.SynchronizedEventHandler.handleEvent(SynchronizedEventHandler.java:45)
    at com.google.common.eventbus.EventBus.dispatch(EventBus.java:313)
    at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:296)
    at com.google.common.eventbus.EventBus.post(EventBus.java:267)
    at cpw.mods.fml.common.LoadController.sendEventToModContainer(LoadController.java:193)
    at cpw.mods.fml.common.LoadController.propogateStateMessage(LoadController.java:173)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.google.common.eventbus.EventHandler.handleEvent(EventHandler.java:74)
    at com.google.common.eventbus.SynchronizedEventHandler.handleEvent(SynchronizedEventHandler.java:45)
    at com.google.common.eventbus.EventBus.dispatch(EventBus.java:313)
    at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:296)
    at com.google.common.eventbus.EventBus.post(EventBus.java:267)
    at cpw.mods.fml.common.LoadController.distributeStateMessage(LoadController.java:104)
    at cpw.mods.fml.common.Loader.loadMods(Loader.java:521)
    at cpw.mods.fml.client.FMLClientHandler.beginMinecraftLoading(FMLClientHandler.java:172)
    at net.minecraft.client.Minecraft.startGame(Minecraft.java:470)
    at net.minecraft.client.Minecraft.func_99999_d(Minecraft.java:796)
    at net.minecraft.client.main.Main.main(Main.java:93)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:57)
    at net.minecraft.launchwrapper.Launch.main(Launch.java:18)
    2013-07-23 14:41:56 [SEVERE] [ForgeModLoader] Fatal errors were detected during the transition from PREINITIALIZATION to INITIALIZATION. Loading cannot continue
    2013-07-23 14:41:56 [SEVERE] [ForgeModLoader]
    mcp{8.04} [Minecraft Coder Pack] (minecraft.jar) Unloaded->Constructed->Pre-initialized
    FML{6.2.19.789} [Forge Mod Loader] (coremods) Unloaded->Constructed->Pre-initialized
    Forge{9.10.0.789} [Minecraft Forge] (coremods) Unloaded->Constructed->Pre-initialized
    WiremodCore{1.0} [Wirestone Core] (bin) Unloaded->Constructed->Errored
    2013-07-23 14:41:56 [SEVERE] [ForgeModLoader] The following problems were captured during this phase
    2013-07-23 14:41:56 [SEVERE] [ForgeModLoader] Caught exception from WiremodCore
    cpw.mods.fml.common.LoaderException: java.lang.NullPointerException
    at cpw.mods.fml.common.registry.GameRegistry.registerBlock(GameRegistry.java:232)
    at fr.wirestone.mainmod.WirestoneMain.PreInit(WirestoneMain.java:72)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at cpw.mods.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:540)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.google.common.eventbus.EventHandler.handleEvent(EventHandler.java:74)
    at com.google.common.eventbus.SynchronizedEventHandler.handleEvent(SynchronizedEventHandler.java:45)
    at com.google.common.eventbus.EventBus.dispatch(EventBus.java:313)
    at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:296)
    at com.google.common.eventbus.EventBus.post(EventBus.java:267)
    at cpw.mods.fml.common.LoadController.sendEventToModContainer(LoadController.java:193)
    at cpw.mods.fml.common.LoadController.propogateStateMessage(LoadController.java:173)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.google.common.eventbus.EventHandler.handleEvent(EventHandler.java:74)
    at com.google.common.eventbus.SynchronizedEventHandler.handleEvent(SynchronizedEventHandler.java:45)
    at com.google.common.eventbus.EventBus.dispatch(EventBus.java:313)
    at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:296)
    at com.google.common.eventbus.EventBus.post(EventBus.java:267)
    at cpw.mods.fml.common.LoadController.distributeStateMessage(LoadController.java:104)
    at cpw.mods.fml.common.Loader.loadMods(Loader.java:521)
    at cpw.mods.fml.client.FMLClientHandler.beginMinecraftLoading(FMLClientHandler.java:172)
    at net.minecraft.client.Minecraft.startGame(Minecraft.java:470)
    at net.minecraft.client.Minecraft.func_99999_d(Minecraft.java:796)
    at net.minecraft.client.main.Main.main(Main.java:93)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:57)
    at net.minecraft.launchwrapper.Launch.main(Launch.java:18)
    Caused by: java.lang.NullPointerException
    at cpw.mods.fml.common.registry.ItemData.setName(ItemData.java:158)
    at cpw.mods.fml.common.registry.GameData.setName(GameData.java:255)
    at cpw.mods.fml.common.registry.GameRegistry.registerItem(GameRegistry.java:150)
    at cpw.mods.fml.common.registry.GameRegistry.registerBlock(GameRegistry.java:227)
    … 38 more
    2013-07-23 14:41:56 [INFO] [STDOUT] –-- Minecraft Crash Report ----
    2013-07-23 14:41:56 [INFO] [STDOUT] // I blame Dinnerbone.
    2013-07-23 14:41:56 [INFO] [STDOUT]
    2013-07-23 14:41:56 [INFO] [STDOUT] Time: 23/07/13 14:41
    2013-07-23 14:41:56 [INFO] [STDOUT] Description: There was a severe problem during mod loading that has caused the game to fail
    2013-07-23 14:41:56 [INFO] [STDOUT]
    2013-07-23 14:41:56 [INFO] [STDOUT] cpw.mods.fml.common.LoaderException: java.lang.NullPointerException
    2013-07-23 14:41:56 [INFO] [STDOUT] at cpw.mods.fml.common.registry.GameRegistry.registerBlock(GameRegistry.java:232)
    2013-07-23 14:41:56 [INFO] [STDOUT] at fr.wirestone.mainmod.WirestoneMain.PreInit(WirestoneMain.java:72)
    2013-07-23 14:41:56 [INFO] [STDOUT] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    2013-07-23 14:41:56 [INFO] [STDOUT] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    2013-07-23 14:41:56 [INFO] [STDOUT] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    2013-07-23 14:41:56 [INFO] [STDOUT] at java.lang.reflect.Method.invoke(Unknown Source)
    2013-07-23 14:41:56 [INFO] [STDOUT] at cpw.mods.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:540)
    2013-07-23 14:41:56 [INFO] [STDOUT] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    2013-07-23 14:41:56 [INFO] [STDOUT] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    2013-07-23 14:41:56 [INFO] [STDOUT] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    2013-07-23 14:41:56 [INFO] [STDOUT] at java.lang.reflect.Method.invoke(Unknown Source)
    2013-07-23 14:41:56 [INFO] [STDOUT] at com.google.common.eventbus.EventHandler.handleEvent(EventHandler.java:74)
    2013-07-23 14:41:56 [INFO] [STDOUT] at com.google.common.eventbus.SynchronizedEventHandler.handleEvent(SynchronizedEventHandler.java:45)
    2013-07-23 14:41:56 [INFO] [STDOUT] at com.google.common.eventbus.EventBus.dispatch(EventBus.java:313)
    2013-07-23 14:41:56 [INFO] [STDOUT] at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:296)
    2013-07-23 14:41:56 [INFO] [STDOUT] at com.google.common.eventbus.EventBus.post(EventBus.java:267)
    2013-07-23 14:41:56 [INFO] [STDOUT] at cpw.mods.fml.common.LoadController.sendEventToModContainer(LoadController.java:193)
    2013-07-23 14:41:56 [INFO] [STDOUT] at cpw.mods.fml.common.LoadController.propogateStateMessage(LoadController.java:173)
    2013-07-23 14:41:56 [INFO] [STDOUT] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    2013-07-23 14:41:56 [INFO] [STDOUT] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    2013-07-23 14:41:56 [INFO] [STDOUT] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    2013-07-23 14:41:56 [INFO] [STDOUT] at java.lang.reflect.Method.invoke(Unknown Source)
    2013-07-23 14:41:56 [INFO] [STDOUT] at com.google.common.eventbus.EventHandler.handleEvent(EventHandler.java:74)
    2013-07-23 14:41:56 [INFO] [STDOUT] at com.google.common.eventbus.SynchronizedEventHandler.handleEvent(SynchronizedEventHandler.java:45)
    2013-07-23 14:41:56 [INFO] [STDOUT] at com.google.common.eventbus.EventBus.dispatch(EventBus.java:313)
    2013-07-23 14:41:56 [INFO] [STDOUT] at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:296)
    2013-07-23 14:41:56 [INFO] [STDOUT] at com.google.common.eventbus.EventBus.post(EventBus.java:267)
    2013-07-23 14:41:56 [INFO] [STDOUT] at cpw.mods.fml.common.LoadController.distributeStateMessage(LoadController.java:104)
    2013-07-23 14:41:56 [INFO] [STDOUT] at cpw.mods.fml.common.Loader.loadMods(Loader.java:521)
    2013-07-23 14:41:56 [INFO] [STDOUT] at cpw.mods.fml.client.FMLClientHandler.beginMinecraftLoading(FMLClientHandler.java:172)
    2013-07-23 14:41:56 [INFO] [STDOUT] at net.minecraft.client.Minecraft.startGame(Minecraft.java:470)
    2013-07-23 14:41:56 [INFO] [STDOUT] at net.minecraft.client.Minecraft.func_99999_d(Minecraft.java:796)
    2013-07-23 14:41:56 [INFO] [STDOUT] at net.minecraft.client.main.Main.main(Main.java:93)
    2013-07-23 14:41:56 [INFO] [STDOUT] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    2013-07-23 14:41:56 [INFO] [STDOUT] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    2013-07-23 14:41:56 [INFO] [STDOUT] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    2013-07-23 14:41:56 [INFO] [STDOUT] at java.lang.reflect.Method.invoke(Unknown Source)
    2013-07-23 14:41:56 [INFO] [STDOUT] at net.minecraft.launchwrapper.Launch.launch(Launch.java:57)
    2013-07-23 14:41:56 [INFO] [STDOUT] at net.minecraft.launchwrapper.Launch.main(Launch.java:18)
    2013-07-23 14:41:56 [INFO] [STDOUT] Caused by: java.lang.NullPointerException
    2013-07-23 14:41:56 [INFO] [STDOUT] at cpw.mods.fml.common.registry.ItemData.setName(ItemData.java:158)
    2013-07-23 14:41:56 [INFO] [STDOUT] at cpw.mods.fml.common.registry.GameData.setName(GameData.java:255)
    2013-07-23 14:41:56 [INFO] [STDOUT] at cpw.mods.fml.common.registry.GameRegistry.registerItem(GameRegistry.java:150)
    2013-07-23 14:41:56 [INFO] [STDOUT] at cpw.mods.fml.common.registry.GameRegistry.registerBlock(GameRegistry.java:227)
    2013-07-23 14:41:56 [INFO] [STDOUT] … 38 more
    2013-07-23 14:41:56 [INFO] [STDOUT]
    2013-07-23 14:41:56 [INFO] [STDOUT]
    2013-07-23 14:41:56 [INFO] [STDOUT] A detailed walkthrough of the error, its code path and all known details is as follows:
    2013-07-23 14:41:56 [INFO] [STDOUT] –-------------------------------------------------------------------------------------
    2013-07-23 14:41:56 [INFO] [STDOUT]
    2013-07-23 14:41:56 [INFO] [STDOUT] – System Details --
    2013-07-23 14:41:56 [INFO] [STDOUT] Details:
    2013-07-23 14:41:56 [INFO] [STDOUT] Minecraft Version: 1.6.2
    2013-07-23 14:41:56 [INFO] [STDOUT] Operating System: Windows 7 (x86) version 6.1
    2013-07-23 14:41:56 [INFO] [STDOUT] Java Version: 1.7.0_25, Oracle Corporation
    2013-07-23 14:41:56 [INFO] [STDOUT] Java VM Version: Java HotSpot(TM) Client VM (mixed mode), Oracle Corporation
    2013-07-23 14:41:56 [INFO] [STDOUT] Memory: 930898024 bytes (887 MB) / 1060372480 bytes (1011 MB) up to 1060372480 bytes (1011 MB)
    2013-07-23 14:41:56 [INFO] [STDOUT] JVM Flags: 3 total; -Xincgc -Xmx1024M -Xms1024M
    2013-07-23 14:41:56 [INFO] [STDOUT] AABB Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used
    2013-07-23 14:41:56 [INFO] [STDOUT] Suspicious classes: FML and Forge are installed
    2013-07-23 14:41:56 [INFO] [STDOUT] IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
    2013-07-23 14:41:56 [INFO] [STDOUT] FML: MCP v8.04 FML v6.2.19.789 Minecraft Forge 9.10.0.789 4 mods loaded, 4 mods active
    2013-07-23 14:41:56 [INFO] [STDOUT] mcp{8.04} [Minecraft Coder Pack] (minecraft.jar) Unloaded->Constructed->Pre-initialized
    2013-07-23 14:41:56 [INFO] [STDOUT] FML{6.2.19.789} [Forge Mod Loader] (coremods) Unloaded->Constructed->Pre-initialized
    2013-07-23 14:41:56 [INFO] [STDOUT] Forge{9.10.0.789} [Minecraft Forge] (coremods) Unloaded->Constructed->Pre-initialized
    2013-07-23 14:41:56 [INFO] [STDOUT] WiremodCore{1.0} [Wirestone Core] (bin) Unloaded->Constructed->Errored
    2013-07-23 14:41:56 [INFO] [STDOUT] #@!@# Game crashed! Crash report saved to: #@!@# C:\Users\Arthur\Documents\Dropbox\Programmation\Java\forge-9.10.0.789\mcp\jars\.\crash-reports\crash-2013-07-23_14.41.56-client.txt
    AL lib: (EE) alc_cleanup: 1 device not closed
    
    

  • Administrateurs

    Les balises code sont plus lisible que quote.
    @Mod(modid = "WiremodCore" ….
    GameRegistry.registerBlock(DoorBlock, ItemBlockDoorBlock.class, "DoorBlock", "WirestoneCore");
    Heureusement que j'ai précisé qu'il faut mettre le modid ^^



  • Je le crois pas !! :honte: :s

    Merci beaucoup ! Heu du coup tu peux supprimer mes messages nan ? Ca fait un peu désordre dans le topic du tutoriel ^^

    Quand j'y pense… L'erreur la plus idiote du monde et en plus j'ai re-vérifié 5 fois avant de poster ce message 😮



  • Les balises code sont plus lisible que quote.

    Les balise code_java sont plus lisible que code



  • Heu tu les utilises comment ?


  • Administrateurs

    (code_java) mais avec des crochets. Mais il faudrait encore l'améliorer, car il déforme le forum si le code est trop long.



  • ha oui en effet le code java est beaucoup mieux, je vais le mettre sur mon tuto.



  • Salut,

    Voila je me sent plus a l'aise avec le "modding" et java en general.

    Aussi en tant que développeur il y a une chose qui me chiffonne dans ton code. c'est la répétition des lignes de code . Aussi je propose un code alternatif qui apporte deux chose:

    • une classe unique pour tout les block
    • toute les variables sont initialisé dans la classe principal du mod

    Voici la classe MyBlock pour tout les block

    
    public class MyBlock extends Block
    {
    private String dossierResource = null;
    public String[] type; //Important "type" n'est plus static.
    private Icon[] IconArray;
    
    public UlBlock(String pNom, int pId, Material pMaterial,float pDureté ,float pRésistance,StepSound Son, String pDossierResource,String[] pType)
    {
    super(pId, pMaterial);
    this.dossierResource =pDossierResource;
    this.setCreativeTab(CreativeTabs.tabBlock);
    this.setHardness(pDureté).setResistance(pRésistance).setStepSound(Son).setUnlocalizedName(pNom);
    this.type = pType;
    }
    
    public void registerIcons(IconRegister iconregister)
    {
    IconArray = new Icon[type.length];
    for(int i = 0; i < type.length; i++)
    {
    IconArray* = iconregister.registerIcon(dossierResource.toLowerCase()+":" + type*);
    }
    }
    
    @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));
    }
    }
    
    @SideOnly(Side.CLIENT)
    public Icon getIcon(int side, int metadata)
    {
    if(metadata < type.length && metadata >= 0)
    return IconArray[metadata];
    else
    return IconArray[0];
    }
    
    }
    
    

    Voici les classe ItemBlock
    Remplacer

    
    public String getUnlocalizedName(ItemStack stack)
    {
    int metadata = stack.getItemDamage();
    
    if(metadata > UlMetal.type.length || metadata < 0)
    {
    metadata = 0;
    }
    
    return super.getUnlocalizedName() + "." + UlMetal.type[metadata];
    }
    
    
    
    public class ModTutoriel
    {
    […]
    
    public static String[] typePierre = new String[]{"block1", "block2", "block3", "block4", "block5", "block6", "block7", "block8"};
    
    //Blocks
    public static Block UlPierre;
    
    […]
    
    @EventHandler
    public void PreInit(FMLPreInitializationEvent event)
    // place des configurations et achievements, compléter et enregistrer nos blocs et items.
    {
    //Configuration
    
    //Son
    
    //Onglet créative
    
    //Blocks
    TutorialMetadata= new TutorialMetadata("TutorialMetadata", 2001,Material.rock,2.0F,10.0F,Block.soundStoneFootstep,"ModTutoriel","alMetadata",typePierre);
    
    //Enregistrement des blocs - Blocks registry
    GameRegistry.registerBlock(TutorialMetadata, UlItemMetadata.class, "UlItemMetadata", "ModTutoriel");;
    
    //Items
    
    //Enregistrement des Items - Items registry
    
    //Achievements
    }
    
    @EventHandler
    public void Init(FMLInitializationEvent event)
    //enregistrement des tileEntity, des Entity, des rendu, etc
    {
    ///////////////////////////////////////////////////////////////////////////////
    
    //Registry
    
    //Mobs
    
    //Render
    proxy.registerRender();
    
    //NetWork
    
    //Recipe
    //GameRegistry.addRecipe(new ItemStack(BlockTutorial), new Object[]{"XXX", "ZYZ", "XXX", 'X', Block.blockLapis, 'Y', new ItemStack(Item.dyePowder, 1, 15), 'Z', new ItemStack(Item.dyePowder, 1, 6)});
    //GameRegistry.addRecipe(new ItemStack(UlPierre, 4, 2), new Object[]{"XXX", "XXX", " ", 'X', Block.stone});
    //GameRegistry.addRecipe(new ItemStack(UlSable, 4, 1), new Object[]{"XXX", "XXX", 'X', Block.dirt});
    
    for(int i = 0; i < 16; i++)
    {
    GameRegistry.addShapelessRecipe(new ItemStack(UlPierre, 1, i), new Object[]{ Block.stone, new ItemStack(UlColorant, 1, i)});
    GameRegistry.addShapelessRecipe(new ItemStack(UlMetal, 1, i), new Object[]{ Block.blockIron , new ItemStack(UlColorant, 1, i)});
    GameRegistry.addShapelessRecipe(new ItemStack(UlSable, 1, i), new Object[]{ Block.sand , new ItemStack(UlColorant, 1, i)});
    GameRegistry.addShapelessRecipe(new ItemStack(UlVerre, 1, i), new Object[]{ Block.glass , new ItemStack(UlColorant, 1, i)});
    
    }
    
    }
    
    @EventHandler
    public void PostInit(FMLPostInitializationEvent event)
    //enregistrements de langages ou de recettes
    {
    //Intégration avec les autres mods
    
    }
    
    


  • Salut,

    Voila je me sent plus a l'aise avec le "modding" et java en general.

    Aussi en tant que développeur il y a une chose qui me chiffonne dans ton code. c'est la répétition des lignes de code . Aussi je propose un code alternatif qui apporte deux chose:

    • une classe unique pour tout les block
    • toute les variables sont initialisé dans la classe principal du mod

    Voici la classe MyBlock pour tout les block

    public class MyBlock extends Block
    {
        private String dossierResource = null;
        public String[] type; // Important "type" n'est plus static.
        private Icon[] IconArray;
    
        public MyBlock(String pNom, int pId, Material pMaterial, float pDureté, float pRésistance, StepSound Son, String pDossierResource, String[] pType)
        {
            super(pId, pMaterial);
            this.dossierResource = pDossierResource;
            this.setCreativeTab(CreativeTabs.tabBlock);
            this.setHardness(pDureté).setResistance(pRésistance).setStepSound(Son).setUnlocalizedName(pNom);
            this.type = pType;
        }
    
        public void registerIcons(IconRegister iconregister)
        {
            IconArray = new Icon[type.length];
            for(int i = 0; i < type.length; i++)
            {
                IconArray[i] = iconregister.registerIcon(dossierResource.toLowerCase() + ":" + type[i]);
            }
        }
    
        @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));
            }
        }
    
        @SideOnly(Side.CLIENT)
        public Icon getIcon(int side, int metadata)
        {
            if(metadata < type.length && metadata >= 0)
                return IconArray[metadata];
            else
                return IconArray[0];
        }
    
    }
    

    Pour les classe ItemBlock, remplacer:

        public String getUnlocalizedName(ItemStack stack)
        {
            int metadata = stack.getItemDamage();
            if(metadata > BlockTutorialMetadata.type.length || metadata < 0)
            {
                metadata = 0;
            }
            return super.getUnlocalizedName() + "." + BlockTutorialMetadata.type[metadata];
        }
    

    par :

        public String getUnlocalizedName(ItemStack stack)
        {
            int metadata = stack.getItemDamage();
            if(metadata > BlockTutorialMetadata.type.length || metadata < 0)
            {
                metadata = 0;
            }
            return super.getUnlocalizedName() + "." + ModTutoriel.type[metadata];
        }
    

    En faite je deplace le tableau "Type" dans la classe du mod

    voici la classe du mod

    public class ModTutoriel
    {
    […]
    
    public static String[] typeBlock = new String[]{"block1", "block2", "block3", "block4", "block5", "block6", "block7", "block8"};
    
    //Blocks
    public static Block UlPierre;
    
    […]
    
    @EventHandler
    public void PreInit(FMLPreInitializationEvent event)
    // place des configurations et achievements, compléter et enregistrer nos blocs et items.
    {
    //Configuration
    
    //Son
    
    //Onglet créative
    
    //Blocks
    TutorialMetadata= new MyBlock("TutorialMetadata", 2001,Material.rock,2.0F,10.0F,Block.soundStoneFootstep,"ModTutoriel","alMetadata",typeBlock );
    
    //Enregistrement des blocs - Blocks registry
    GameRegistry.registerBlock(TutorialMetadata, ItemBlockTutorialMetadata.class, "TutorialMetadata", "ModTutoriel");;
    
    […]
    

    On pourrait pousser le vis en faisant une seul classe pour les block simples et les block metadata en détectant si le tableau "Type" est null ou vide par exemple

    J'avais penser faire la même chose avec les classe "ItemBlock" mais c'est un tit peut plus difficile puisque apparemment elles sont instancier a la volé .

    voila voila voila , je sais pas si ca va être utile mais je suis plutôt contant de moi 😛

    ps: j'espere pas avoir fait d'erreur en transposant mon code avec les nom des variables et classes du tuto d'origine.


  • Administrateurs

    J'ai mis des code_java pour une meilleur lisibilité (il faudrait que je vois avec Woryk pour les améliorer encore aussi, barre défilante sur le codé et éviter les déformations avec les codes trop long)

    Par contre tu as dû te fail avec l'ItemBlock, car je ne vois pas de différence (et du fait que type n'est plus static il me semble que ça peut pas marcher avec le code actuelle)

    Ton code pourra être utile pour de nombreuse personne, je le laisse donc. En revanche, je préfère avoir une classe par bloc pour les autres fonctions que nous verrons plus tard pour rendre le bloc plus complexe.



  • ulysse je comprend tout à fait ton point de vue mais je pense que si les développeurs de Mojang ont choisi de faire une classe/bloc c'est pas pour rien. Ce ne sont pourtant pas des débutants en programmation.
    Je ne comprend pas pourquoi moi non plus mais il doit bien y avoir une raison 🙂



  • Je ne comprend pas pourquoi moi non plus mais il doit bien y avoir une raison

    Sans doute s'ils veulent faire une modification sur un bloc qui nécessite un changement de l'extension



  • Peut être… Ou alors pour mieux s'y retrouver, je sais pas.



  • @'robin4002':

    J'ai mis des code_java pour une meilleur lisibilité (il faudrait que je vois avec Woryk pour les améliorer encore aussi, barre défilante sur le codé et éviter les déformations avec les codes trop long)

    Tu parle de balises pour écrire le code dans les post ?

    @'robin4002':

    Par contre tu as dû te fail avec l'ItemBlock, car je ne vois pas de différence (et du fait que type n'est plus static il me semble que ça peut pas marcher avec le code actuelle)

    effectivement c'est pas TutorialMetedata (la classe du block) mais ModTutoriel ( classe du mod ) . J'ai rectifier dans le post . Et apparemment ca marche chez moi aussi non je ne me serait pas permis d'avoir publié ce code.

    Pas évident de faire un post comme ca , je suis encore loin de pouvoir rédiger des tutu comme toi , mais ca viendra .


  • Administrateurs

    Oui les balises dans le postes.
    Et pour le code, comme ça oui ça fonctionne, mais sans la avant que tu rectifie la modification de l'ItemBlock ça pouvait pas fonctionner