Jump to content

Problems with block using grass shading


candlemaster

Recommended Posts

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Losing a significant amount of money to scammers can be a bizarre experience that leaves you feeling helpless and betrayed. This was the situation I found myself in after investing over a hundred thousand dollars in a crypto platform that turned out to be a scam. I was introduced to this platform by a friend of my cousin, and everything seemed legitimate until it was too late for me to realize that I had been duped. The days following the realization of my loss were some of the darkest I have ever experienced. I was consumed by feelings of depression and desperation as I tried everything in my power to retrieve my hard-earned money. I reached out to various authorities and sought advice from friends and family, but it seemed like there was no way to recover what I had lost. It was during this time that a friend mentioned a platform called Wizard Web Recovery that specialized in recovering funds lost to scams. At first, I was skeptical and hesitant to trust another company with my money, but I was running out of options and decided to give them a chance. Looking back, this decision turned out to be the best one I could have made. From the moment I contacted Wizard Web Recovery, I was impressed by their dedication to helping me recover my funds. Their team of experts guided me through the process step by step, explaining each stage clearly and answering all of my questions along the way. They kept me informed of their progress and worked tirelessly to ensure that my case was given the attention it deserved. I was amazed at how quickly Wizard Web Recovery was able to track down the scammers and retrieve my money. Within a relatively short period, I received the news that my funds had been successfully recovered, and I couldn't believe it. It felt like a weight had been lifted off my shoulders, and I was filled with gratitude for the team at Wizard Web Recovery who had made it possible.    
    • my game crashed and I have no idea why here is a link to the pastebin of the crash https://pastebin.com/vv89r9vC
    • ok apparently the issue is even stupider than that. the folder the server was in was called "𝓯𝓻𝓮𝓪𝓴𝔂 server" and apparently the special characters in the folder name break the whole damn thing. this is the stupidest thing in the history of ever
    • Thanks, but now I have the 3d model in hand (and in inventory bcz I won't need that anymore) but now when I try to throw it, it doesnt rotate and its just the end of the trident not the head part. Edit: I removed the 3d custom model. I use the original minecraft files. Json and etc. In minecraft the rendering is made in code. I sent the code in the first message. I have mostly the code. But I don't know how to register the renderers like minecraft do. For example, in minecraft there are 2 jsons: trident_in_hand and trident_throwing , I have both of them. They don't render while I have the item in hand. That's the main problem. I checked the code but I still can't figure out how to register and render the entity basically, in hand
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.