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.
Demi-dalles
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 hautII.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 !
-
Je test en local demain, si c’est bon je valide.
-
Ok
-
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 -
É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
-
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 ._. -
Tutoriel refusé, je vais m’occuper de refaire un tutoriel correcte sur les dalles.
=> http://www.minecraftforgefrance.fr/showthread.php?tid=156