Créer un buisson récoltable



  • Sommaire

    Introduction

    Bonjour à tous c'est Fox, aujourd'hui je voulais rapidement contribuer à ce site fort sympathique en vous montrant comment créer un buisson récoltable, exemple fraise, cassis etc... En version 1.8 de Minecraft.

    Pré-requis

    • Une classe principale où vous enregistrez vos bloques et vos items pour ma pars "MainRegistry".
    • Une seconde classe, là où vous enregistrez la texture de vos bloques et items ("ClientProxy").
    • Une troisième classe qui sera celle de vos buissons ("BaseBerry").

    Code

    MainRegistry

    Comme d'habitude on vas commencer par déclarer nos deux bloques, une version avec fraise qui sera celle affichée dans l'onglet créatif et l'autre sans (non affichée). Et un item qui sera la bée.

    public static Block strawberryBush = new BaseBerry().setCreativeTab(VotreTab); //Avec Fraise
    public static Block strawberrySimple = new BaseBerry(); //Sans fraise
    public static Item strawberry = new ItemFood(2, false); //La fraise
    

    Personnellement je détache les noms non localisés pour faciliter les changements mais si ce n'est pas votre cas vous pouvez simplement rajouter le paramètre ".setUnlocalizedName(String)" à la fin de la déclaration du bloque ou d'item.

    strawberryBush.setUnlocalizedName("StrawberryBush");
    strawberrySimple.setUnlocalizedName("StrawberrySimple");
    strawberry.setUnlocalizedName("Strawberry");
    

    Et pour finir vous devez l'enregistrer dans le jeu avec le nom de votre fichier ".json" dans votre dossier "blockstates" ou le dossier "models/item" pour les items :

    GameRegistry.registerBlock(strawberryBush, "bush_strawberry"); //.json
    GameRegistry.registerBlock(strawberrySimple, "simple_strawberry"); //.json
    GameRegistry.registerItem(strawberry, "strawberry"); //.json
    

    Maintenant on vas enregistrer nos textures dans la classe "ClientProxy".

    ClientProxy

    Voilà maintenant qu'on est là on a juste à taper ce long et compliqué bout de code pour pas grand chose :

    Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(Item.getItemFromBlock(MainRegistry.strawberryBush), 0, new ModelResourceLocation("VotreMODID:bush_strawberry", "inventory"));
    
    Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(Item.getItemFromBlock(MainRegistry.strawberrySimple), 0, new ModelResourceLocation("VotreMODID:simple_strawberry", "inventory"));
    
    Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(EmotionItems.strawberry, 0, new ModelResourceLocation("VotreMODID:strawberry", "inventory"));
    

    Et maintenant passons aux choses sérieuses dans la classe "BaseBerry".

    [ancre=classe3]***- BaseBerry -***
    Dans cette nouvelle classe on vas déjà définir sont extension, sont matériel, sont son au marché, sont tick et sont block de sélection.

    public class BaseBerry extends BlockBush //Extension de BlockBush
    {
        public BaseBerry() 
        {
            super(Material.plants); //Sont matériel
            this.setStepSound(soundTypeGrass); //Sont son au marché
            this.setTickRandomly(true); //Sont tick
            this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); //Sont block de sélection
        }
    }
    

    On vas ensuite définir les bloques sur les quels le buisson vas pouvoir rester en place.

    public class BaseBerry extends BlockBush //Extension de BlockBush
    {
        public BaseBerry() 
        {
            super(Material.plants); //Sont matériel
            this.setStepSound(soundTypeGrass); //Sont son au marché
            this.setTickRandomly(true); //Sont tick
            this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); //Sont block de sélection
        }
    
        public boolean canPlaceBlockAt(World world, BlockPos pos)
        {
            return super.canPlaceBlockAt(world, pos) && world.getBlockState(pos.down()).getBlock().canSustainPlant(world,
            pos.down(), net.minecraft.util.EnumFacing.UP, this);
        }
    
        protected boolean canPlaceBlockOn(Block ground)
        {
            return ground == Blocks.grass || ground == Blocks.dirt || ground == Blocks.farmland;
        }
    }
    

    Maintenant nous allons définir ce qu'il ce passeras lorsque le joueur fais un clique droit sur le bloque. Pour ça rien de plus simple, il y a juste à appeler la fonction "onBlockActivated" définie dans la classe "Block" de Minecraft.

    public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumFacing side, float
    hitX, float hitY, float hitZ)
    {
        if (this == MainRegistry.strawberryBush) //Et pas strawberrySimple
        {
            world.setBlockState(pos, MainRegistry.strawberrySimple.getDefaultState());
            dropBerry(world, pos);
        }
        return null == null;
    }
    

    Vue que la fonction dropBerry s'affiche en rouge on vas la créer :

    protected void dropBerry(World world, BlockPos pos)
    {
        if (this == MainRegistry.strawberrySimple || this == MainRegistry.strawberryBush)
        {
            spawnAsEntity(world, pos, new ItemStack(MainRegistry.strawberry, 1 + RANDOM.nextInt(2))); //Le nombre drop
        }
    }
    

    Après la fonction dropBerry place à makeBerry qui dit seulement que quand appelée, remplace "strawberrySimple" le buisson sans les fraises par "strawberryBush" celui avec, que des noms originaux au passage :

    protected void makeBerry(World world, BlockPos pos)
    {
        if (this == EmotionBlocks.strawberrySimple)
        {
            world.setBlockState(pos, EmotionBlocks.strawberryBush.getDefaultState());
        }
    }
    

    Utilisons maintenant la fonction "onBlockHarvested" elle aussi définie dans la classe "Block" de Minecraft. Ce qu'on vas lui demander et simple, donne nous les bées et le buisson sans quand on récupères ce dernier.

    public void onBlockHarvested(World world, BlockPos pos, IBlockState state, EntityPlayer player)
    {
        if (this == EmotionBlocks.strawberryBush)
        {
            spawnAsEntity(world, pos, new ItemStack(Item.getItemFromBlock(this), 1));
            spawnAsEntity(world, pos, new ItemStack(EmotionItems.strawberry, 1 + RANDOM.nextInt(2)));
        }
    }
    

    Et enfin ajoutons une fonction une fois de plus définie dans la classe "Block" qui va faire en sorte de compter les ticks pour, au bout d'un certain temps, recréer des bées. D'où la nécessité de définir le tick de la classe à random.

    public void updateTick(World world, BlockPos pos, IBlockState state, Random rand)
    {
        super.updateTick(world, pos, state, rand);
        int i = 1;
    
        if (i < 20)
        {
            if (rand.nextInt((int)(5.0F) + 1) == 0)
            {
                if (this == EmotionBlocks.strawberrySimple)
                {
                    makeBerry(world, pos);
                }
            }
        }
    }
    

    Et voilà c'en est fini, vous pouvez maintenant créer vos fichiers ".json", vos textures et en avant Guingamp ! (comme disent les moyenâgeux)

    Bonus

    blockstates

    bush_strawberry.json

    {
        "variants": 
        { 
            "normal": { "model": "MODID:bush_strawberry" } 
        }
    }
    

    simple_strawberry.json

    {
        "variants": 
        { 
            "normal": { "model": "MODID:simple_strawberry" } 
        }
    }
    

    block

    bush_strawberry.json

    {
        "parent": "block/cross",
        "textures": 
        {
            "cross": "MODID:blocks/bush_strawberry"
        }
    }
    

    simple_strawberry.json

    {
        "parent": "block/cross",
        "textures": 
        {
            "cross": "MODID:blocks/simple_strawberry"
        }
    }
    

    item

    bush_strawberry.json

    {
        "parent": "builtin/generated", 
        "textures": 
        { 
            "layer0": "MODID:blocks/bush_strawberry" 
        }, 
        "display": 
        { 
            "thirdperson": 
            { 
                "rotation": [ -90, 0, 0 ], 
                "translation": [ 0, 1, -3 ], 
                "scale": [ 0.55, 0.55, 0.55 ] 
            }, 
            "firstperson": 
            { 
                "rotation": [ 0, -135, 25 ],
                "translation": [ 0, 4, 2 ], 
                "scale": [ 1.7, 1.7, 1.7 ] 
            }
        }
    }
    

    simple_strawberry.json

    {
        "parent": "builtin/generated", 
        "textures": 
        { 
            "layer0": "MODID:blocks/simple_strawberry" 
        }, 
        "display": 
        { 
            "thirdperson": 
            { 
                "rotation": [ -90, 0, 0 ], 
                "translation": [ 0, 1, -3 ], 
                "scale": [ 0.55, 0.55, 0.55 ] 
            }, 
            "firstperson": 
            { 
                "rotation": [ 0, -135, 25 ],
                "translation": [ 0, 4, 2 ], 
                "scale": [ 1.7, 1.7, 1.7 ] 
            }
        }
    }
    

    strawberry.json

    {
        "parent": "builtin/generated", 
        "textures": 
        { 
            "layer0": "MODID:items/strawberry" 
        }, 
        "display": 
        { 
            "thirdperson": 
            { 
                "rotation": [ -90, 0, 0 ], 
                "translation": [ 0, 1, -3 ], 
                "scale": [ 0.55, 0.55, 0.55 ] 
            }, 
            "firstperson": 
            { 
                "rotation": [ 0, -135, 25 ],
                "translation": [ 0, 4, 2 ], 
                "scale": [ 1.7, 1.7, 1.7 ] 
            }
        }
    }
    

    Résultat

    Crédits

    Rédaction :

    EmotionFox


    Ce tutoriel de EmotionFox publié sur 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

    Retour vers le sommaire des tutoriels



  • Ps: Il y a quelques "EmotionBlocks.strawberryBush" qui persiste dans le code, malheureusement je ne peu pas le modifier il faudra donc le remplacer manuellement par "MainRegistry.strawberryBush" ou le nom de votre classe principale.

    Ps2: Désolé pour toutes les fautes avec bloque et bloques, j'ai plus souvent l'habitude de l'écrire en anglais x)


  • Administrateurs

    Bloque = verbe bloquer.
    bloc = le bloc, celui que tu devrais normalement utiliser x)
    Je faisais aussi l'erreur il y a un ou deux ans.



  • J'attendrais pas de l'apprendre ^^ Je l’abandonne et puis c'est tout, j'écrirais block maintenant 😄



  • Petit correction à la fonction onBlockHarvested qui doit plus ressembler à ça :

    public void onBlockHarvested(World world, BlockPos pos, IBlockState state, EntityPlayer player)
    {
    if (this == MODID.strawberryBush)
    {
    spawnAsEntity(world, pos, new ItemStack(Item.getItemFromBlock(MODID.strawberrySimple), 1)); //Ici spécifier le bloc
    spawnAsEntity(world, pos, new ItemStack(MODID.strawberry, 1 + RANDOM.nextInt(2))); //Drop d'item
    }
    }
    

    A rajouter aussi la fonction getItemDropped de la classe "Block" par Minecraft :

    public Item getItemDropped(IBlockState state, Random rand, int fortune)
    {
    if (this == MODID.strawberryBush)
    {
    return null;
    }
    
    return Item.getItemFromBlock(this);
    }
    


  • Si l'on est en 1.7.10 le code change ??


  • Administrateurs

    Oui, les blockstate n'existaient pas en 1.7 donc le code est différent.



  • Tu pourrais en faire un tuto robin ??

    Envoyé de mon 4016X en utilisant Tapatalk


  • Administrateurs

    Non, je ne ferai plus de tutoriel 1.7. Je me concentre maintenant sur la 1.8 et bientôt 1.9.



  • Le tuto marche en 1.7.10 ou pas ? 
    Merci ! 
    clement.



  • Voilà j'ai voulu le mettre en 1.7.10 tous fonction sauf quand je fait le clique droit dessus sa remais bien le block en mode sans orange mais sa me drop rien

    package fr.darkvince.ultrav2.Fruit;
    
    import java.util.Random;
    
    import fr.darkvince.ultrav2.Main;
    import net.minecraft.block.Block;
    import net.minecraft.block.BlockBush;
    import net.minecraft.block.material.Material;
    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;
    import net.minecraftforge.common.util.ForgeDirection;
    
    public class BlockOrange extends BlockBush
    {
    public BlockOrange() 
    {
    super(Material.plants);
    this.setStepSound(soundTypeGrass); 
    this.setTickRandomly(true); 
    this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); 
    }
    
    public boolean canPlaceBlockAt(World world, int x, int y, int z)
       {
           return super.canPlaceBlockAt(world, x, y, z) && world.getBlock(x, y - 1, z).canSustainPlant(world, x, y - 1, x, ForgeDirection.UP, this);
       }
    
    protected boolean canPlaceBlockOn(Block ground)
    {
    return ground == Blocks.grass || ground == Blocks.dirt || ground == Blocks.farmland;
    }
    
    public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int par6, float par7, float par8, float par9) {
    if (this == Main.BlockOrangeBush)
    {
    world.setBlock(x, y, z , Main.BlockOrange);
    dropBerry(world, x, y, x);
    }
    return null == null;
    }
    
    protected void dropBerry(World world, int x, int y, int z)
    {
    if (this == Main.BlockOrange || this == Main.BlockOrangeBush)
    {
    dropBlockAsItem(world, x, y, z, new ItemStack(Main.Orange, 1));
    }
    }
    
    protected void makeBerry(World world, int x, int y, int z)
    {
    if (this == Main.BlockOrange)
    {
    world.setBlock(x, y, z, Main.BlockOrangeBush);
    }
    }
    public void onBlockHarvested(World world,int x, int y, int z, int p_149681_5_, EntityPlayer player)
    {
    if (this == Main.BlockOrangeBush)
    {
    dropBlockAsItem(world, x, y, z, new ItemStack(Main.BlockOrange, 1));
    dropBlockAsItem(world, x, y, z, new ItemStack(Main.Orange, 1));
    dropBlockAsItem(world, x, y, z, new ItemStack(Main.BlockOrangeBush, 0));
    }
    }
    public void updateTick(World world, int x, int y, int z, Random rand)
    {
    super.updateTick(world, x, y, z, rand);
    int i = 1;
    
    if (i < 20)
    {
    if (rand.nextInt((int)(5.0F) + 1) == 0)
    {
    if (this == Main.BlockOrange)
    {
    makeBerry(world, x, y, z);
    }
    }
    }
    }
    }
    

    Désolé mais les espace s'enleve a chaque fois