candlemaster Posted October 17, 2013 Posted October 17, 2013 I'm making a "grass cover" block, which is meant to mimic the behavior of snow (except melting) but look like grass. So far I have the snow behavior working perfectly, but the grass shading has problem to be a bit challenging. The top of the block uses the correct color, but the sides are all completely gray! What am I doing wrong? Here's the source code for the block: package hvh.mod.coverblocks; import java.util.Random; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.texture.IconRegister; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.Icon; import net.minecraft.world.ColorizerFoliage; import net.minecraft.world.ColorizerGrass; import net.minecraft.world.EnumSkyBlock; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class BlockGrassCover extends Block { public BlockGrassCover(int id) { super(id, Material.grass); setHardness(0.3f); setStepSound(soundGrassFootstep); setCreativeTab(CreativeTabs.tabDecorations); } /** * 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. */ @SideOnly(Side.CLIENT) public void registerIcons(IconRegister par1IconRegister) { this.blockIcon = par1IconRegister.registerIcon("grass_top"); } /** * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been * cleared to be reused) */ public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { int l = par1World.getBlockMetadata(par2, par3, par4) & 7; float f = 0.125F; return AxisAlignedBB.getAABBPool().getAABB((double)par2 + this.minX, (double)par3 + this.minY, (double)par4 + this.minZ, (double)par2 + this.maxX, (double)((float)par3 + (float)l * f), (double)par4 + this.maxZ); } /** * 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; } /** * Sets the block's bounds for rendering it as an item */ public void setBlockBoundsForItemRender() { this.setBlockBoundsForSnowDepth(0); } /** * 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) { this.setBlockBoundsForSnowDepth(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); } /** * calls setBlockBounds based on the depth of the snow. Int is any values 0x0-0x7, usually this blocks metadata. */ protected void setBlockBoundsForSnowDepth(int par1) { int j = par1 & 7; float f = (float)(2 * (1 + j)) / 16.0F; this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, f, 1.0F); } /** * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z */ public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { int l = par1World.getBlockId(par2, par3 - 1, par4); Block block = Block.blocksList[l]; if (block == null) return false; if (block == this) return true; if (block == this && (par1World.getBlockMetadata(par2, par3 - 1, par4) & 7) == 7) return true; if (!block.isLeaves(par1World, par2, par3 - 1, par4) && !Block.blocksList[l].isOpaqueCube()) return false; return par1World.getBlockMaterial(par2, par3 - 1, par4).blocksMovement(); } /** * 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 blockID */ public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { this.canSnowStay(par1World, par2, par3, par4); } /** * Checks if this snow block can stay at this location. */ private boolean canSnowStay(World par1World, int par2, int par3, int par4) { if (!this.canPlaceBlockAt(par1World, par2, par3, par4)) { par1World.setBlockToAir(par2, par3, par4); return false; } else { return true; } } /** * Called when the player destroys a block with an item that can harvest it. (i, j, k) are the coordinates of the * block and l is the block's subtype/damage. */ public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6) { super.harvestBlock(par1World, par2EntityPlayer, par3, par4, par5, par6); par1World.setBlockToAir(par3, par4, par5); } /** * Returns the quantity of items to drop on block destruction. */ public int quantityDropped(Random par1Random) { return 0; } @Override public int quantityDropped(int meta, int fortune, Random random) { return 0; } @SideOnly(Side.CLIENT) public int getBlockColor() { double d0 = 0.5D; double d1 = 1.0D; return ColorizerGrass.getGrassColor(d0, d1); } @SideOnly(Side.CLIENT) /** * Returns the color this block should be rendered. Used by leaves. */ public int getRenderColor(int par1) { return this.getBlockColor(); } /** * Returns a integer with hex for 0xrrggbb with this color multiplied against the blocks color. Note only called * when first determining what to render. */ @SideOnly(Side.CLIENT) public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { int i1 = 0; int j1 = 0; int k1 = 0; for (int l1 = -1; l1 <= 1; ++l1) { for (int i2 = -1; i2 <= 1; ++i2) { int j2 = par1IBlockAccess.getBiomeGenForCoords(par2 + i2, par4 + l1).getBiomeGrassColor(); i1 += (j2 & 16711680) >> 16; j1 += (j2 & 65280) >> 8; k1 += j2 & 255; } } return (i1 / 9 & 255) << 16 | (j1 / 9 & 255) << 8 | k1 / 9 & 255; } @SideOnly(Side.CLIENT) public static Icon getIconSideOverlay() { return CoverBlocksMod.grassCover.getIcon(0, 0); } } Any advice? Thanks in advance. Quote
robustus Posted October 18, 2013 Posted October 18, 2013 This is because the grass block is a specially rendered block because of the overlay textures. If you look in the RenderBlocks minecraft class you can see how its done. They however do a check to make sure its a vanilla grass block before they render the side texture properly. You can copy most of the code they use to do the grass block and do your own custom render. It depends how far down the modding rabbit hole you want to go really. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.