Escaliers et demi-dalles



  • Introduction

    Salut !
    Je fais un nouveau tutoriel sur les escaliers et les demi-dalles, un tutoriel assez complexe, contrairement à ce que l'on pourrait croire !

    Difficulté : Facile, Moyen, Difficile

    Escaliers

    Créée d'abord la classe de votre escalier et étendez-la de "BlockStairs" :

    public class BlockStairsTuto extends BlockStairs
    

    N'oubliez pas d'importer "BlockStairs" et d'ajouter le constructeur !
    Pour les fainéants, voici le code de la classe 😛 :
    :::

    package tutoriel.common;
    
    import net.minecraft.block.Block;
    import net.minecraft.block.BlockStairs;
    
    public class BlockStairsTutorial extends BlockStairs
    {
    protected BlockStairsTutorial(int id, Block blocktype, int metadata)
    {
    super(id, blocktype, metadata);
    }
    }
    

    :::

    Dans votre classe principale, déclaré votre bloc normalement changez juste le constructeur :

    StairsTutorial = new BlockStairsTutorial(StairsTutorialID, BlockTutorial, 0).setUnlocalizedName("StairsTutorial");
    

    Pour la résistance et la texture, le bloc utilisera automatiquement celle de BlockTutorial

    *StairsTutorialID: * L'id de votre bloc (les bases 😄 )
    BlockTutorial : Le bloc associer à votre escalier. (la texture et la résistance seront ceux de ce bloc)

    0 : Il s'agit du metadata, si le bloc n'en a pas, mettez 0 sinon mettez le metadata qui correspond.

    Voir sur github

    Demi-dalles

    %(#0000CD)[I.Les blocs 🙂

    Déclarez 2 nouveaux blocs comme ceci :

    public static BlockHalfSlabTuto DemiDalleTuto, DallePleineTuto;
    

    *DemiDalleTuto : *Correspond à votre bloc de demi dalle,
    *DallePleineTuto : *Correspond à 2 demies-dalles accroché.
    Il faut impérativement déclarer ces blocs en tant que "BlockHalfSlabTuto" !

    Je sais, il y a une erreur, nous allons nous nous en occuper plus tard, maintenant allez dans le PreInit et ajouté votre Blocs comme ceci :

    
    BlockDemiDalle = (BlockHalfSlabTuto) (new BlockStepTuto(ID, false))
    BlockDallePleine = (BlockHalfSlabTuto) (new BlockStepTuto(ID, true))
    

    ID correspond à votre ID, ne changez rien d'autre,
    sauf bien sur "BlockDemiDalle" et "BlockDallePleine", qui doivent être vos blocks déclaré plus haut 😉

    %(#0000CD)[II.Les classes 🙂

    BlockStepTuto ou la classe de votre bloc :

    Créée donc une classe BlockStepTuto (encore une fois ce que vous voulez 😉 )

    Et mettez ceci dedans :

    :::

    
    package tutoriel.common;
    
    import java.util.List;
    import java.util.Random;
    
    import net.minecraft.block.Block;
    import net.minecraft.block.BlockHalfSlab;
    import net.minecraft.block.material.Material;
    import net.minecraft.client.renderer.texture.IconRegister;
    import net.minecraft.creativetab.CreativeTabs;
    import net.minecraft.item.ItemStack;
    import net.minecraft.util.Icon;
    import cpw.mods.fml.relauncher.Side;
    import cpw.mods.fml.relauncher.SideOnly;
    
    public class BlockStepTuto extends BlockHalfSlabTuto
    {
    /** The list of the types of step blocks. */
    public static final String[] blockStepTypes = new String[] {"tuto"};
    @SideOnly(Side.CLIENT)
    private Icon theIcon;
    
    public BlockStepTuto(int par1, boolean par2)
    {
    super(par1, par2, Material.rock);
    this.setCreativeTab(CreativeTabs.tabBlock);
    }
    
    @SideOnly(Side.CLIENT)
    
    /**
    * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata
    */
    public Icon getIcon(int par1, int par2)
    {
    int k = par2 & 7;
    
    if (this.isDoubleSlab && (par2 & 8) != 0)
    {
    par1 = 1;
    }
    
    return k == 0 ? (par1 != 1 && par1 != 0 ? this.theIcon : this.blockIcon) : (k == 1 ? ModTutoriel.BlockTutorial.getBlockTextureFromSide(par1) : this.blockIcon);
    }
    
    @SideOnly(Side.CLIENT)
    
    /**
    * When this method is called, your block should register all the icons it needs with the given IconRegister. This
    * is the only chance you get to register icons.
    */
    public void registerIcons(IconRegister par1IconRegister)
    {
    this.blockIcon = par1IconRegister.registerIcon("modtutoriel:tuto_slab_top");
    this.theIcon = par1IconRegister.registerIcon("modtutoriel:tuto_slab_side");
    }
    
    /**
    * Returns the ID of the items to drop on destruction.
    */
    public int idDropped(int par1, Random par2Random, int par3)
    {
    return ModTutoriel.BlockDemiDalle.blockID;
    }
    
    /**
    * Returns an item stack containing a single instance of the current block type. 'i' is the block's subtype/damage
    * and is ignored for blocks which do not support subtypes. Blocks which cannot be harvested should return null.
    */
    protected ItemStack createStackedBlock(int par1)
    {
    return new ItemStack(ModTutoriel.BlockDemiDalle.blockID, 2, par1 & 7);
    }
    
    /**
    * Returns the slab block name with step type.
    */
    public String getFullSlabName(int par1)
    {
    if (par1 < 0 || par1 >= blockStepTypes.length)
    {
    par1 = 0;
    }
    
    return super.getUnlocalizedName() + "." + blockStepTypes[par1];
    }
    
    }
    
    

    :::

    Ligne 19 :

    
    public static final String[] blockStepTypes = new String[] {"tuto"};
    
    

    Changez "tuto" par le nom de votre demi-dalle.

    Ligne 43 :

    
    return k == 0 ? (par1 != 1 && par1 != 0 ? this.theIcon : this.blockIcon) : (k == 1 ? ModTutoriel.BlockTutorial.getBlockTextureFromSide(par1) : this.blockIcon);
    
    

    Changez "ModTutoriel.BlockTutorial" par "ClassePrincipale.BlocParent", BlocParent correspond à comme je vous l'avais expliqué dans les escaliers, un bloc doit être une "extensions" d'un autre bloc.
    Ce bloc doit donc correspondre au bloc qui "donnera" sa texture à votre demi-dalle.

    Ligne 52 à 56 :

    
    public void registerIcons(IconRegister par1IconRegister)
    {
    this.blockIcon = par1IconRegister.registerIcon("modtutoriel:tuto_slab_top");
    this.theIcon = par1IconRegister.registerIcon("modtutoriel:tuto_slab_side");
    }
    
    

    C'est bizarre, mais d'après le jeu, cela correspond aux particules, renommez donc en "votremodidsansmaj:votrebloc"

    *votremodidsansmaj : * Correspond à votre modid sans majuscules
    votrebloc Correspond au bloc que vous avez utilisé en haut comme "BlocParent"

    N'oubliez pas le ":" entre les deux, et il ne doit pas y avoir d'espace !

    Ligne 61 à 64 :

    
    public int idDropped(int par1, Random par2Random, int par3)
    {
    return ModTutoriel.BlockDemiDalle.blockID;
    }
    
    

    Changez "ModTutorial.BlockDemiDalle" par VotreClass.VotreDemiDalle",

    Ligne 70 à 73 :

    
    protected ItemStack createStackedBlock(int par1)
    {
    return new ItemStack(ModTutoriel.BlockDemiDalle.blockID, 2, par1 & 7);
    }
    
    

    Changez "ModTutorial.BlockDemiDalle" par VotreClass.VotreDemiDalle",

    BlockHalfSlabTuto :

    Créée une classe BlockHalfSlabTuto (cela dépend de votre imag… vous connaissez la chanson 😛 ), et mettez dedans :

    :::

    
    package tutoriel.common;
    
    import java.util.List;
    import java.util.Random;
    
    import net.minecraft.block.Block;
    import net.minecraft.block.material.Material;
    import net.minecraft.entity.Entity;
    import net.minecraft.util.AxisAlignedBB;
    import net.minecraft.util.Facing;
    import net.minecraft.world.IBlockAccess;
    import net.minecraft.world.World;
    import cpw.mods.fml.relauncher.Side;
    import cpw.mods.fml.relauncher.SideOnly;
    
    public abstract class BlockHalfSlabTuto extends Block
    {
    protected final boolean isDoubleSlab;
    
    public BlockHalfSlabTuto(int par1, boolean par2, Material par3Material)
    {
    super(par1, par3Material);
    this.isDoubleSlab = par2;
    
    if (par2)
    {
    opaqueCubeLookup[par1] = true;
    }
    else
    {
    this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F);
    }
    
    this.setLightOpacity(255);
    }
    
    /**
    * Updates the blocks bounds based on its current state. Args: world, x, y, z
    */
    public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    {
    if (this.isDoubleSlab)
    {
    this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
    }
    else
    {
    boolean flag = (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) != 0;
    
    if (flag)
    {
    this.setBlockBounds(0.0F, 0.5F, 0.0F, 1.0F, 1.0F, 1.0F);
    }
    else
    {
    this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F);
    }
    }
    }
    
    /**
    * Sets the block's bounds for rendering it as an item
    */
    public void setBlockBoundsForItemRender()
    {
    if (this.isDoubleSlab)
    {
    this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
    }
    else
    {
    this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F);
    }
    }
    
    /**
    * Adds all intersecting collision boxes to a list. (Be sure to only add boxes to the list if they intersect the
    * mask.) Parameters: World, X, Y, Z, mask, list, colliding entity
    */
    public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity)
    {
    this.setBlockBoundsBasedOnState(par1World, par2, par3, par4);
    super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
    }
    
    /**
    * 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 this.isDoubleSlab;
    }
    
    /**
    * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, side, hitX, hitY, hitZ, block metadata
    */
    public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9)
    {
    return this.isDoubleSlab ? par9 : (par5 != 0 && (par5 == 1 || (double)par7 <= 0.5D) ? par9 : par9 | 8);
    }
    
    /**
    * Returns the quantity of items to drop on block destruction.
    */
    public int quantityDropped(Random par1Random)
    {
    return this.isDoubleSlab ? 2 : 1;
    }
    
    /**
    * Determines the damage on the item the block drops. Used in cloth and wood.
    */
    public int damageDropped(int par1)
    {
    return par1 & 7;
    }
    
    /**
    * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
    */
    public boolean renderAsNormalBlock()
    {
    return this.isDoubleSlab;
    }
    
    @SideOnly(Side.CLIENT)
    
    /**
    * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given
    * coordinates. Args: blockAccess, x, y, z, side
    */
    public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
    {
    if (this.isDoubleSlab)
    {
    return super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5);
    }
    else if (par5 != 1 && par5 != 0 && !super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5))
    {
    return false;
    }
    else
    {
    int i1 = par2 + Facing.offsetsXForSide[Facing.oppositeSide[par5]];
    int j1 = par3 + Facing.offsetsYForSide[Facing.oppositeSide[par5]];
    int k1 = par4 + Facing.offsetsZForSide[Facing.oppositeSide[par5]];
    boolean flag = (par1IBlockAccess.getBlockMetadata(i1, j1, k1) & 8) != 0;
    return flag ? (par5 == 0 ? true : (par5 == 1 && super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5) ? true : !isBlockSingleSlab(par1IBlockAccess.getBlockId(par2, par3, par4)) || (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) == 0)) : (par5 == 1 ? true : (par5 == 0 && super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5) ? true : !isBlockSingleSlab(par1IBlockAccess.getBlockId(par2, par3, par4)) || (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) != 0));
    }
    }
    
    @SideOnly(Side.CLIENT)
    
    /**
    * Takes a block ID, returns true if it's the same as the ID for a stone or wooden single slab.
    */
    private static boolean isBlockSingleSlab(int par0)
    {
    return par0 == ModTutoriel.BlockDemiDalle.blockID;
    }
    
    /**
    * Returns the slab block name with step type.
    */
    public abstract String getFullSlabName(int i);
    
    /**
    * Get the block's damage value (for use with pick block).
    */
    public int getDamageValue(World par1World, int par2, int par3, int par4)
    {
    return super.getDamageValue(par1World, par2, par3, par4) & 7;
    }
    
    @SideOnly(Side.CLIENT)
    
    /**
    * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative)
    */
    public int idPicked(World par1World, int par2, int par3, int par4)
    {
    return isBlockSingleSlab(this.blockID) ? this.blockID : (this.blockID == ModTutoriel.BlockDemiDalle.blockID ? ModTutoriel.BlockDemiDalle.blockID : ModTutoriel.BlockDemiDalle.blockID);
    }
    }
    
    

    :::

    Ligne 158 à 161 :

    
    private static boolean isBlockSingleSlab(int par0)
    {
    return par0 == ModTutoriel.BlockDemiDalle.blockID;
    }
    
    

    Changez "ModTutorial.BlockDemiDalle" par VotreClass.VotreDemiDalle",

    Ligne 181 à 184 :

    
    public int idPicked(World par1World, int par2, int par3, int par4)
    {
    return isBlockSingleSlab(this.blockID) ? this.blockID : (this.blockID == ModTutoriel.BlockDemiDalle.blockID ? ModTutoriel.BlockDemiDalle.blockID : ModTutoriel.BlockDemiDalle.blockID);
    }
    
    

    Changez les 3 "ModTutorial.BlockDemiDalle" par VotreClass.VotreDemiDalle", encore une fois 👼

    Voila, ce tuto est fini !

    S'il y a un problème, posté le sur ce sujet !
    Aimez mon message, ceci n'est pas une question ❤ !

    A plus pour d'autres tutos 😄 !



  • Très bon tutoriel !



  • Merci 😄 !


  • Administrateurs

    Je test en local demain, si c'est bon je valide.



  • Ok 🙂


  • Administrateurs

    J'ai déjà corrigé les escalier, je m'occupe des slab demain. Juste pour ça :

    Vous devez donc mettre un bloc de votre classe, BlockTutoriel pour nous, et si vous voulez un block qui existe déjà, mettez : Block.leBloc

    Inutile de précisez, c'est la base de java. Et puis c'est logique, puisqu'il faut indiquez le field du bloc, les blocs vanilles sont tous dans Block.java d'où le Block.field_du_bloc et tes propres blocs sont dans la même classe, donc soit juste field_du_bloc soit this.field_du_bloc

    Ha aussi, pas de metadata = 0.
    Prenez l'habitude de compter en partant de 0 et non 1



  • Non, j'ai essayé 0 et ça a crash ^^___
    Ok, je ferais plus attention, et j'avais mis 1 car cela m'avait fait crasher avec 0 😕


  • Administrateurs

    Étrange, 0 fonctionne très bien chez moi. Tu as quoi dans le crash ? Tu l'as fait avec quel bloc ?



  • Je m'en rappelle plus, excuse moi x)

    C'est pas grave le tout c'est que ça marche 🙂


  • Administrateurs

    Le tutoriel sur les slab est à refaire, il y a plein de code inutile, et de mon côté j'ai un bug de lumière sur les blocs autours de la demi-dalle (peut être car j'ai fais autrement mon code) et il est impossible d’empiler deux slab, donc à revoir.



  • Pour l'empilage, aucun moyen de le faire pour l'instant, et pour les codes inutiles, je m'en occupe !___
    Enfaîte je vois pas bien ce que tu vois comme code inutile ._.


  • Administrateurs

    Tutoriel refusé, je vais m'occuper de refaire un tutoriel correcte sur les dalles.

    => http://www.minecraftforgefrance.fr/showthread.php?tid=156


Log in to reply