Plantes & Metadatas



  • Salutation, je viens de rencontré un problème qui est le suivent:

    J'ai une plante qui pouce de la même manière que la canne a sucre, elle fonctionne très bien, mais voila, il faut que j'en fasse 8 autres.
    Je pourrai faire une classe item et bloc pour chacune des 8 autre plante vous me direz, mais sa prendrai de la place dans le système "d'ID", alors voila:
    Comment je peu faire pour mètre tout se bazar en métadata ? sachant que les 9 blocs et items n’ont pas la même textures.
    Au total 1 items avec 9 metadata et un bloc avec 9 metadata (de 0 a 8). le metadata 4 item sera lié avec le metadata 4 bloc, 7 avec 7 et ect.

    Class du bloc::::

    package sevenno_addons.common.block;
    
    import java.util.Random;
    
    import net.minecraft.block.Block;
    import net.minecraft.block.material.Material;
    import net.minecraft.item.Item;
    import net.minecraft.util.AxisAlignedBB;
    import net.minecraft.world.IBlockAccess;
    import net.minecraft.world.World;
    import net.minecraftforge.common.EnumPlantType;
    import net.minecraftforge.common.IPlantable;
    import net.minecraftforge.common.util.ForgeDirection;
    import sevenno_addons.common.item.SAItemList;
    import cpw.mods.fml.relauncher.Side;
    import cpw.mods.fml.relauncher.SideOnly;
    
    public class CoalReedBlock extends Block implements IPlantable
    {
       protected CoalReedBlock()
       {
           super(Material.plants);
           float f = 0.375F;
           this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 1.0F, 0.5F + f);
           this.setTickRandomly(true);
       }
    
       //Ticks the block if it's been scheduled
    
       public void updateTick(World world, int par2, int par3, int par4, Random random)
       {
           if (world.getBlock(par2, par3 - 1, par4) == SABlockList.CoalReedBlock || this.checkBlockCoordValid(world, par2, par3, par4))
           {
               if (world.isAirBlock(par2, par3 + 1, par4))
               {
                   int l;
    
                   for (l = 1; world.getBlock(par2, par3 - l, par4) == this; ++l)
                   {
                       ;
                   }
    
                   if (l < 3)
                   {
                       int i1 = world.getBlockMetadata(par2, par3, par4);
    
                       if (i1 == 15)
                       {
                        world.setBlock(par2, par3 + 1, par4, this);
                        world.setBlockMetadataWithNotify(par2, par3, par4, 0, 4);
                       }
                       else
                       {
                        world.setBlockMetadataWithNotify(par2, par3, par4, i1 + 1, 4);
                       }
                   }
               }
           }
       }
    
       //Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
    
       public boolean canPlaceBlockAt(World world, int x, int y, int z)
       {
           Block block = world.getBlock(x, y - 1, z);
        if (block == this)
        {
        return block == SABlockList.CoalReedBlock;
        }
        return block == SABlockList.SPReedBooster;
       }
    
       //Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
       //their own) Args: x, y, z, neighbor Block
    
       public void onNeighborBlockChange(World world, int x, int y, int z, Block block)
       {
           this.checkBlockCoordValid(world, x, y, z);
       }
    
       protected final boolean checkBlockCoordValid(World world, int x, int y, int z)
       {
           if (!this.canBlockStay(world, x, y, z))
           {
               this.dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0);
               world.setBlockToAir(x, y, z);
               return false;
           }
           else
           {
               return true;
           }
       }
    
       //Can this block stay at this position.  Similar to canPlaceBlockAt except gets checked often with plants.
    
       public boolean canBlockStay(World world, int x, int y, int z)
       {
           return this.canPlaceBlockAt(world, x, y, z);
       }
    
       public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
       {
           return null;
       }
    
       public Item getItemDropped(int par1, Random random, int par3)
       {
           return SAItemList.CoalReed;
       }
    
       //Is this block (a) opaque and (b) a full 1m cube?  This determines whether or not to render the shared face of two
       //adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
    
       public boolean isOpaqueCube()
       {
           return false;
       }
    
       //If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
    
       public boolean renderAsNormalBlock()
       {
           return false;
       }
    
       //The type of render function that is called for this block
    
       public int getRenderType()
       {
           return 1;
       }
    
       //Gets an item for the block being called on. Args: world, x, y, z
    
       @SideOnly(Side.CLIENT)
       public Item getItem(World world, int x, int y, int z)
       {
           return SAItemList.CoalReed;
       }
    
       @Override
       public EnumPlantType getPlantType(IBlockAccess world, int x, int y, int z)
       {
           return EnumPlantType.Beach;
       }
    
       @Override
       public Block getPlant(IBlockAccess world, int x, int y, int z)
       {
           return this;
       }
    
       @Override
       public int getPlantMetadata(IBlockAccess world, int x, int y, int z)
       {
           return world.getBlockMetadata(x, y, z);
       }
    }
    

    :::

    Class de l'item::::

    package sevenno_addons.common.item;
    
    import net.minecraft.block.Block;
    import net.minecraft.entity.Entity;
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.init.Blocks;
    import net.minecraft.item.Item;
    import net.minecraft.item.ItemStack;
    import net.minecraft.world.World;
    
    public class CoalReed extends Item
    {
       private Block field_150935_a;
       private static final String __OBFID = "CL_00001773";
    
       public CoalReed(Block p_i45329_1_)
       {
           this.field_150935_a = p_i45329_1_;
       }
    
       //Callback for item usage. If the item does something special on right clicking, he will have one of those. Return
       //True if something happen and false if it don't. This is for ITEMS, not BLOCKS
    
       public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10)
       {
           Block block = par3World.getBlock(par4, par5, par6);
    
           if (block == Blocks.snow_layer && (par3World.getBlockMetadata(par4, par5, par6) & 7) < 1)
           {
               par7 = 1;
           }
           else if (block != Blocks.vine && block != Blocks.tallgrass && block != Blocks.deadbush)
           {
               if (par7 == 0)
               {
                   –par5;
               }
    
               if (par7 == 1)
               {
                   ++par5;
               }
    
               if (par7 == 2)
               {
                   --par6;
               }
    
               if (par7 == 3)
               {
                   ++par6;
               }
    
               if (par7 == 4)
               {
                   --par4;
               }
    
               if (par7 == 5)
               {
                   ++par4;
               }
           }
    
           if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack))
           {
               return false;
           }
           else if (par1ItemStack.stackSize == 0)
           {
               return false;
           }
           else
           {
               if (par3World.canPlaceEntityOnSide(this.field_150935_a, par4, par5, par6, false, par7, (Entity)null, par1ItemStack))
               {
                   int i1 = this.field_150935_a.onBlockPlaced(par3World, par4, par5, par6, par7, par8, par9, par10, 0);
    
                   if (par3World.setBlock(par4, par5, par6, this.field_150935_a, i1, 3))
                   {
                       if (par3World.getBlock(par4, par5, par6) == this.field_150935_a)
                       {
                           this.field_150935_a.onBlockPlacedBy(par3World, par4, par5, par6, par2EntityPlayer, par1ItemStack);
                           this.field_150935_a.onPostBlockPlaced(par3World, par4, par5, par6, i1);
                       }
    
                       par3World.playSoundEffect((double)((float)par4 + 0.5F), (double)((float)par5 + 0.5F), (double)((float)par6 + 0.5F), this.field_150935_a.stepSound.func_150496_b(), (this.field_150935_a.stepSound.getVolume() + 1.0F) / 2.0F, this.field_150935_a.stepSound.getPitch() * 0.8F);
                       --par1ItemStack.stackSize;
                   }
               }
    
               return true;
           }
       }
    }
    

    :::

    Merci d'avance;
    Cordialement.


  • Rédacteurs

    Il va te falloir une dernière class pour différencier tes différents métadata.

    d'abord mets dans un tableau le nom des différents metadata

    
    public static String[] type = new String[]{"coal", "iron", etc ….};
    
    

    ensuite tu doit dire que le bloc a plusieurs metadatas

    
    @SideOnly(Side.CLIENT)
    public void getSubBlocks(Item Item, CreativeTabs creativeTabs, List list)
    {
    for(int metadata = 0; metadata < type.length; metadata++)
    {
    list.add(new ItemStack(id, 1, metadata));
    }
    }
    
    

    ensuite tu dit quel metedata drops lorsque le bloc casse

    
    public int damageDropped(int metadata)
    {
    return metadata;
    }
    
    

    après quoi tu doit enregistrer tes textures

    
    public void registerIcons(IconRegister iconregister)
    {
    coal= iconregister.registerIcon("modid:texturename");
    etc ...
    }
    
    

    oublie pas d'enregistrer les icones :

    
    private Icon coal, etc ...:
    
    

    une fois tout ça fait tu attribue la texture en fonctions du metadata

    
    @SideOnly(Side.CLIENT)
    public Icon getIcon(int side, int metadata)
    {
    switch(metadata)
    {
    case 0:
    return coal;
    case 1:
    return ...;
    }
    }
    
    

    Pour la class de ton block c'est fait, reste la class de l'itemblock

    
    public class nom_de_la_classe extends ItemBlock
    {
    
    public nom_de_la_classe (Block block)
    {
    super(block);
    this.setHasSubtypes(true);
    }
    
    public int getMetadata(int metadata)
    {
    return metadata;
    }
    
    public String getUnlocalizedName(ItemStack stack)
    {
    int metadata = stack.getItemDamage();
    if(metadata > nom_de_la_classe_de_ton_block .type.length || metadata < 0)
    {
    metadata = 0;
    }
    return super.getUnlocalizedName() + "." + nom_de_la_classe_de_ton_block .type[metadata];
    }
    }
    
    

    oublie pas de mettre le nom de tes classes.
    Enfin pour l'item il suffit juste de mettre des items damage , tu n'a rien besoin de plus que de déclarer les item damage:

    
    private String[] type = new String[]{"coalreed", "ironreed", etc …};
    private Icon[] IconArray;
    
    

    ensuite ces méthodes permettent de différencier les différents métadata et leur attribuer leur textures

    
    public int getMetadata(int metadata)
    {
    return metadata;
    }
    
    public String getUnlocalizedName(ItemStack stack)
    {
    int metadata = stack.getItemDamage();
    if(metadata > type.length || metadata < 0)
    {
    metadata = 0;
    }
    return super.getUnlocalizedName() + "." + type[metadata];
    }
    
    public void registerIcons(IconRegister iconregister)
    {
    IconArray = new Icon[type.length];
    for(int i = 0; i < type.length; i++)
    {
    IconArray* = iconregister.registerIcon("modid:" + type*);
    }
    }
    
    @SideOnly(Side.CLIENT)
    public void getSubItems(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 getIconFromDamage(int metadata)
    {
    return metadata < type.length && metadata >= 0 ? IconArray[metadata] : IconArray[0];
    }
    
    

    Enfin il ne te reste juste à obtenir le metadata et l'intégrer dans ta méthode "onItemUse" afin de pourvoir avoir chaque metadata de ton bloc.

    Je ne suis pas encore passé en 1.7.2 donc il se peut que quelqu'une de ces méthode ne marches plus ou nécessite quelque modification mais j'ai essayé de m'adapter au nouveau système de la 1.7 . J'espère que ça t'aura aidé

    Cordialement
    Phenix246



  • Merci beaucoup a toi, je regarde sa tout de suite :).


  • Rédacteurs

    J'ai oublié de te donné la systaxe du gameRegystry:

    
    GameRegistry.registerBlock(Block, ItemBlock .class, String <name, modid);<br="">```</name,>


  • ok thx 😉


  • Moddeurs confirmés Rédacteurs Administrateurs

    Le problème c'est que sa plante utilise déjà le metadata pour le niveau de pousse.
    Le plus simple serait de sauvegarder le niveau de pousse dans le tile entity plutôt que dans le metadata de la plante.



  • Bon … je comprend plus rien avec se que dit robin :s.
    Il n'y a pas plutop possibilité de prendre les classe que j'ai créer comme "modèle" ? comme sa les autre items est blocs reprenne juste le modèle, mais la texture change et les drope aussi.


    EDIT: Bon au pire je vais posté un sujet dans "recrutement" la sa dépasse se que je peu faire pour le moment.



  • Je vais réexpliquer ce qu'a dis robin :

    En gros, tu as ta plante qui utilise les meta-data pour sa progression ( Viens juste d'être planté / prêt a être récolté, et tout les niveau intermédiaires ).

    Le soucis, c'est que du coup, les meta-data sont déjà occupés.

    Donc, en faisant une TileEntity ( Entité de block ), tu peux enregistrer une variable, qui remplacera la meta-data utilisé pour que la plante pousse, et avoir des meta-data sur ton block.



  • @'Gugu42':

    Je vais réexpliquer ce qu'a dis robin :

    En gros, tu as ta plante qui utilise les meta-data pour sa progression ( Viens juste d'être planté / prêt a être récolté, et tout les niveau intermédiaires ).

    Le soucis, c'est que du coup, les meta-data sont déjà occupés.

    Donc, en faisant une TileEntity ( Entité de block ), tu peux enregistrer une variable, qui remplacera la meta-data utilisé pour que la plante pousse, et avoir des meta-data sur ton block.

    Yep, sa je l'est compris après sur Team Speak hier, merci a toi de l'avoir dit :), comme sa j'aurai une trace écrit pour m'en souvenir ^^'.

    Mais au final je vais laissais comme sais, je ne vais pas mètre de metadata, mais sa pourrai faire sujet d'un bon tutoriel, comme pour les personnes dans mon cas ;).

    Cordialement.

    PS: je mais en résolue du coup ou non ?
    PS²: j'essaierai peut-être de les mètre en metadata en 1.8.x :).


Log in to reply