I am working on a mod that adds blocks to the game and I have one more block to do until the block is finished.
What I have as an example of what I'm going on about is that I have made a custom block and the grass_top texture renders white.
Here is a mod src that I am temporarily using to do what I can to make this block, as I have made the block but the grass doesn't render but only one color.
What it does is it adds one block and one thrown entity:
As my block updates it's light when placed and it returns that the material is grass and also the map color itself is also grass, it doesn't make sense to me how come my block does not work with the default minecraft grass_top texture being some color of green.
The only texture color I get from using the default texture is grey using grass_top.png and it should be rendering green.
This may not be that helpful given that many things have changed since 1.6.4 (especially rendering) but there is a method in the Block class called "colorMultiplier" which returns the color used to shade a block (all blocks use this method but most do not override the default value of 16777215 or RGB(255,255,255)). The method for grass blocks looks like this; it averages the biome color over a 3x3 area (this will most likely not work in 1.11.2 if copied as-is but you can look at its BlockGrass class, which I presume has a similar if not identical method):
public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
int var5 = 0;
int var6 = 0;
int var7 = 0;
for (int var8 = -1; var8 <= 1; ++var8)
{
for (int var9 = -1; var9 <= 1; ++var9)
{
int var10 = par1IBlockAccess.getBiomeGenForCoords(par2 + var9, par4 + var8).getBiomeGrassColor();
var5 += (var10 & 16711680) >> 16;
var6 += (var10 & 65280) >> 8;
var7 += var10 & 255;
}
}
return (var5 / 9 & 255) << 16 | (var6 / 9 & 255) << 8 | var7 / 9 & 255;
}
There is also another method, "getRenderColor", which is used to determine the color of items (I noticed that your code has "import net.minecraft.world.ColorizerGrass;" but you never reference ColorizerGrass):
public int getBlockColor()
{
double var1 = 0.5D;
double var3 = 1.0D;
return ColorizerGrass.getGrassColor(var1, var3);
}
public int getRenderColor(int par1)
{
return this.getBlockColor();
}
Also, you could try extending BlockGrass instead of Block and override the appropriate methods.
This is not so in the newer version as the method has been removed and replaced or the method exists and would logically occur as deprecated or not.
I have looked at other .json models to where grass_top is the texture being the block or what it would be that way in the first photo.
the .json model code is different between the two photos, although when built and played with in the game using the same model in the first photo resulting in it rendering the way it does.
The code for the .json model in the first photo logically does have code specific to as the model having tint:
What it does is it updates the light level according to the block and then reflects that it's material is grass while at the same time not being a snowy block that way.
The code that is considerable of a 3x3 or expandable area of the block recognizing it's surrounding occuring as what's logical that way, although then based on the occurance of other blocks and the consideration of it facing upwards or downwards that way.
Which logically does explain that this is not a recursive loop being what is logically that way:
public class BlockGrass extends Block implements IGrowable
{
public static final PropertyBool SNOWY = PropertyBool.create("snowy");
protected BlockGrass()
{
super(Material.GRASS);
this.setDefaultState(this.blockState.getBaseState().withProperty(SNOWY, Boolean.valueOf(false)));
this.setTickRandomly(true);
this.setCreativeTab(CreativeTabs.BUILDING_BLOCKS);
}
/**
* Get the actual Block state of this Block at the given position. This applies properties not visible in the
* metadata, such as fence connections.
*/
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos)
{
Block block = worldIn.getBlockState(pos.up()).getBlock();
return state.withProperty(SNOWY, Boolean.valueOf(block == Blocks.SNOW || block == Blocks.SNOW_LAYER));
}
public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
{
if (!worldIn.isRemote)
{
if (worldIn.getLightFromNeighbors(pos.up()) < 4 && worldIn.getBlockState(pos.up()).getLightOpacity(worldIn, pos.up()) > 2)
{
worldIn.setBlockState(pos, Blocks.DIRT.getDefaultState());
}
else
{
if (worldIn.getLightFromNeighbors(pos.up()) >= 9)
{
for (int i = 0; i < 4; ++i)
{
BlockPos blockpos = pos.add(rand.nextInt(3) - 1, rand.nextInt(5) - 3, rand.nextInt(3) - 1);
if (blockpos.getY() >= 0 && blockpos.getY() < 256 && !worldIn.isBlockLoaded(blockpos))
{
return;
}
IBlockState iblockstate = worldIn.getBlockState(blockpos.up());
IBlockState iblockstate1 = worldIn.getBlockState(blockpos);
if (iblockstate1.getBlock() == Blocks.DIRT && iblockstate1.getValue(BlockDirt.VARIANT) == BlockDirt.DirtType.DIRT && worldIn.getLightFromNeighbors(blockpos.up()) >= 4 && iblockstate.getLightOpacity(worldIn, pos.up()) <= 2)
{
worldIn.setBlockState(blockpos, Blocks.GRASS.getDefaultState());
}
}
}
}
}
}
/**
* Get the Item that this Block should drop when harvested.
*/
public Item getItemDropped(IBlockState state, Random rand, int fortune)
{
return Blocks.DIRT.getItemDropped(Blocks.DIRT.getDefaultState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.DIRT), rand, fortune);
}
/**
* Whether this IGrowable can grow
*/
public boolean canGrow(World worldIn, BlockPos pos, IBlockState state, boolean isClient)
{
return true;
}
public boolean canUseBonemeal(World worldIn, Random rand, BlockPos pos, IBlockState state)
{
return true;
}
public void grow(World worldIn, Random rand, BlockPos pos, IBlockState state)
{
BlockPos blockpos = pos.up();
for (int i = 0; i < 128; ++i)
{
BlockPos blockpos1 = blockpos;
int j = 0;
while (true)
{
if (j >= i / 16)
{
if (worldIn.isAirBlock(blockpos1))
{
if (rand.nextInt(8) == 0)
{
worldIn.getBiome(blockpos1).plantFlower(worldIn, rand, blockpos1);
}
else
{
IBlockState iblockstate1 = Blocks.TALLGRASS.getDefaultState().withProperty(BlockTallGrass.TYPE, BlockTallGrass.EnumType.GRASS);
if (Blocks.TALLGRASS.canBlockStay(worldIn, blockpos1, iblockstate1))
{
worldIn.setBlockState(blockpos1, iblockstate1, 3);
}
}
}
break;
}
blockpos1 = blockpos1.add(rand.nextInt(3) - 1, (rand.nextInt(3) - 1) * rand.nextInt(3) / 2, rand.nextInt(3) - 1);
if (worldIn.getBlockState(blockpos1.down()).getBlock() != Blocks.GRASS || worldIn.getBlockState(blockpos1).isNormalCube())
{
break;
}
++j;
}
}
}
@SideOnly(Side.CLIENT)
public BlockRenderLayer getBlockLayer()
{
return BlockRenderLayer.CUTOUT_MIPPED;
}
/**
* Convert the BlockState into the correct metadata value
*/
public int getMetaFromState(IBlockState state)
{
return 0;
}
protected BlockStateContainer createBlockState()
{
return new BlockStateContainer(this, new IProperty[] {SNOWY});
}
}
I am working on a mod that adds blocks to the game and I have one more block to do until the block is finished.
What I have as an example of what I'm going on about is that I have made a custom block and the grass_top texture renders white.
Here is a mod src that I am temporarily using to do what I can to make this block, as I have made the block but the grass doesn't render but only one color.
What it does is it adds one block and one thrown entity:
https://www.dropbox.com/s/dlkuta8wakmr5rd/src.zip?dl=0
If someone can get this mod src to work I would be very thankful and enjoy the ability to know how this grass texture stuff works.
Here's what it does when I use the default Minecraft grass top texture:
Here is a photo of what it does when I use my texture not being the default one and somewhere there's something that way:
Here is the code for the grass block that is some form of grass or something that way:
package aku.example.blocks;
import aku.example.Reference;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDirt;
import net.minecraft.block.BlockGrass;
import net.minecraft.block.BlockTallGrass;
import net.minecraft.block.IGrowable;
import net.minecraft.block.material.MapColor;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.ColorizerGrass;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class grass_covering extends Block
{
public static final PropertyDirection FACING = PropertyDirection.create("facing");
protected static final AxisAlignedBB UP_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.87D, 1.0D);
protected static final AxisAlignedBB NORTH_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.87D, 1.0D);
protected static final AxisAlignedBB EAST_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.87D, 1.0D);
protected static final AxisAlignedBB SOUTH_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.87D, 1.0D);
protected static final AxisAlignedBB WEST_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.87D, 1.0D);
protected static final AxisAlignedBB DOWN_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.87D, 1.0D);
public grass_covering()
{
super(Material.GRASS);
setTickRandomly(true);
this.setHardness(0.4F);
setUnlocalizedName(Reference.EBlock.grasscovering.getUnlocalizedName());
setRegistryName(Reference.EBlock.grasscovering.getRegistryName());
this.setCreativeTab(CreativeTabs.REDSTONE);
}
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos)
{
switch ((EnumFacing)state.getValue(FACING))
{
case DOWN:
return DOWN_AABB;
case NORTH:
return NORTH_AABB;
case EAST:
return EAST_AABB;
case SOUTH:
return SOUTH_AABB;
case WEST:
return WEST_AABB;
default:
return UP_AABB;
}
}
public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
{
return this.getDefaultState().withProperty(FACING, facing);
}
public IBlockState getStateFromMeta(int meta)
{
IBlockState iblockstate = this.getDefaultState();
iblockstate = iblockstate.withProperty(FACING, EnumFacing.getFront(meta));
return iblockstate;
}
public int getMetaFromState(IBlockState state)
{
return ((EnumFacing)state.getValue(FACING)).getIndex();
}
protected BlockStateContainer createBlockState()
{
return new BlockStateContainer(this, new IProperty[] {FACING});
}
public IBlockState withRotation(IBlockState state, Rotation rot)
{
return state.withProperty(FACING, rot.rotate((EnumFacing) state.getValue(FACING)));
}
public IBlockState withMirror(IBlockState state, Mirror mirrorIn)
{
return state.withProperty(FACING, mirrorIn.mirror((EnumFacing) state.getValue(FACING)));
}
public void onEntityWalk(World worldIn, BlockPos pos, Entity entityIn)
{
if (entityIn instanceof EntityLivingBase)
{
worldIn.setBlockToAir(pos);
}
super.onEntityWalk(worldIn, pos, entityIn);
}
public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, IBlockState state, Entity entity)
{
EnumFacing enumfacing = (EnumFacing)state.getValue(FACING);
double d0 = pos.getX() + 0.5D;
double d1 = pos.getY() + 0.8D;
double d2 = pos.getZ() + 0.5D;
worldIn.setBlockToAir(pos);
worldIn.spawnParticle(EnumParticleTypes.BLOCK_CRACK, d0, d1, d2, 0.0D, 0.0D, 0.0D, Block.getIdFromBlock(Blocks.LEAVES));
}
public static boolean isFullCube()
{
return false;
}
public boolean isOpaqueCube(IBlockState state)
{
return false;
}
public BlockRenderLayer getBlockLayer()
{
return BlockRenderLayer.CUTOUT;
}
public boolean blocksLight(IBlockState state)
{
return true;
}
public boolean isSolid(IBlockState state)
{
return true;
}
public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
{
return super.canPlaceBlockAt(worldIn, pos) ? this.canBlockStay(worldIn, pos) : false;
}
public boolean canBlockStay(World world, BlockPos pos)
{
for(EnumFacing facing : EnumFacing.HORIZONTALS)
{
BlockPos posOff = pos.offset(facing);
IBlockState blockstate = world.getBlockState(posOff);
if(blockstate.getBlock().isSideSolid(blockstate, world, posOff, facing.getOpposite()) || blockstate.getBlock() == this)
return true;
}
return false;
}
public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
{
if (!worldIn.isRemote)
{
if (worldIn.getLightFromNeighbors(pos.up()) < 4 && worldIn.getBlockState(pos.up()).getLightOpacity(worldIn, pos.up()) > 2)
{
worldIn.setBlockState(pos, Blocks.DIRT.getDefaultState());
}
else if (worldIn.getLightFromNeighbors(pos.up()) >= 9)
{
for (int i = 0; i < 4; i++)
{
BlockPos blockpos = pos.add(rand.nextInt(3) - 1, rand.nextInt(5) - 3, rand.nextInt(3) - 1);
if (blockpos.getY() >= 0 && blockpos.getY() < 256 && !worldIn.isBlockLoaded(blockpos))
{
return;
}
IBlockState iblockstate = worldIn.getBlockState(blockpos.up());
IBlockState iblockstate1 = worldIn.getBlockState(blockpos);
if (iblockstate1.getBlock() == Blocks.DIRT && iblockstate1.getValue(BlockDirt.VARIANT) == BlockDirt.DirtType.DIRT && worldIn.getLightFromNeighbors(blockpos.up()) >= 4 && iblockstate.getLightOpacity(worldIn, pos.up()) <= 2)
{
worldIn.setBlockState(blockpos, Blocks.GRASS.getDefaultState());
}
}
}
}
}
public MapColor getMapColor(IBlockState state)
{
return MapColor.GRASS;
}
}
As my block updates it's light when placed and it returns that the material is grass and also the map color itself is also grass, it doesn't make sense to me how come my block does not work with the default minecraft grass_top texture being some color of green.
The only texture color I get from using the default texture is grey using grass_top.png and it should be rendering green.
This may not be that helpful given that many things have changed since 1.6.4 (especially rendering) but there is a method in the Block class called "colorMultiplier" which returns the color used to shade a block (all blocks use this method but most do not override the default value of 16777215 or RGB(255,255,255)). The method for grass blocks looks like this; it averages the biome color over a 3x3 area (this will most likely not work in 1.11.2 if copied as-is but you can look at its BlockGrass class, which I presume has a similar if not identical method):
There is also another method, "getRenderColor", which is used to determine the color of items (I noticed that your code has "import net.minecraft.world.ColorizerGrass;" but you never reference ColorizerGrass):
Also, you could try extending BlockGrass instead of Block and override the appropriate methods.
TheMasterCaver's First World - possibly the most caved-out world in Minecraft history - includes world download.
TheMasterCaver's World - my own version of Minecraft largely based on my views of how the game should have evolved since 1.6.4.
Why do I still play in 1.6.4?
This is not so in the newer version as the method has been removed and replaced or the method exists and would logically occur as deprecated or not.
I have looked at other .json models to where grass_top is the texture being the block or what it would be that way in the first photo.
the .json model code is different between the two photos, although when built and played with in the game using the same model in the first photo resulting in it rendering the way it does.
The code for the .json model in the first photo logically does have code specific to as the model having tint:
What it does is it updates the light level according to the block and then reflects that it's material is grass while at the same time not being a snowy block that way.
The code that is considerable of a 3x3 or expandable area of the block recognizing it's surrounding occuring as what's logical that way, although then based on the occurance of other blocks and the consideration of it facing upwards or downwards that way.
Which logically does explain that this is not a recursive loop being what is logically that way: