package blusunrize.immersiveengineering.common.blocks.plant; import blusunrize.immersiveengineering.ImmersiveEngineering; import blusunrize.immersiveengineering.common.IEContent; import blusunrize.immersiveengineering.common.blocks.BlockIEBase; import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IIEMetaBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockBush; import net.minecraft.block.IGrowable; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.PropertyEnum; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.block.statemap.StateMapperBase; import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.Blocks; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.EnumPlantType; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import java.util.ArrayList; import java.util.List; import java.util.Random; public class BlockIECrop<E extends Enum<E> & BlockIEBase.IBlockEnum> extends BlockBush implements IGrowable, IIEMetaBlock { protected static IProperty[] tempProperties; protected static BlockRenderLayer currentRenderLayer; public final String name; public final PropertyEnum<E> property; public final E[] enumValues; public BlockIECrop(String name, PropertyEnum<E> mainProperty) { super(setTempProperties(Material.PLANTS, mainProperty)); this.name = name; this.property = mainProperty; this.enumValues = mainProperty.getValueClass().getEnumConstants(); this.setDefaultState(getInitDefaultState()); this.setUnlocalizedName(ImmersiveEngineering.MODID+"."+name); this.setTickRandomly(true); this.setCreativeTab(null); this.setHardness(0.0F); this.setSoundType(SoundType.PLANT); this.disableStats(); ImmersiveEngineering.registerBlockByFullName(this, new ItemBlock(this), ImmersiveEngineering.MODID+":"+name); IEContent.registeredIEBlocks.add(this); } @Override public String getIEBlockName() { return this.name; } @Override public Enum[] getMetaEnums() { return enumValues; } @Override public IBlockState getInventoryState(int meta) { IBlockState state = this.blockState.getBaseState().withProperty(this.property, enumValues[meta]); return state; } @Override public IProperty getMetaProperty() { return this.property; } @Override public boolean useCustomStateMapper() { return false; } @Override public String getCustomStateMapping(int meta, boolean itemBlock) { return null; } @Override @SideOnly(Side.CLIENT) public StateMapperBase getCustomMapper() { return null; } @Override public boolean appendPropertiesToState() { return true; } protected static Material setTempProperties(Material material, PropertyEnum<?> property) { tempProperties=new IProperty[1]; tempProperties[0] = property; return material; } protected BlockStateContainer createNotTempBlockState() { IProperty[] array = new IProperty[1]; array[0] = this.property; return new BlockStateContainer(this, array); } protected IBlockState getInitDefaultState() { IBlockState state = this.blockState.getBaseState().withProperty(this.property, enumValues[0]); return state; } public void onIEBlockPlacedBy(World world, BlockPos pos, IBlockState state, EnumFacing side, float hitX, float hitY, float hitZ, EntityLivingBase placer, ItemStack stack) { } @Override protected BlockStateContainer createBlockState() { return this.property!=null?createNotTempBlockState(): new BlockStateContainer(this, tempProperties); } @Override public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) { super.onBlockPlacedBy(worldIn, pos, state, placer, stack); } @Override public int getMetaFromState(IBlockState state) { return state.getValue(this.property).getMeta(); } @Override public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos pos) { return state; } @Override public IBlockState getStateFromMeta(int meta) { IBlockState state = this.getDefaultState().withProperty(this.property, fromMeta(meta)); return state; } protected E fromMeta(int meta) { if(meta<0||meta>=enumValues.length) meta = 0; return enumValues[meta]; } public int getMinMeta(int meta) { return meta<=4?0:5; } public int getMaxMeta(int meta) { return meta<=4?4:5; } @Override public boolean canBlockStay(World world, BlockPos pos, IBlockState state) { boolean b = super.canBlockStay(world, pos, state); if(this.getMetaFromState(state)==5) { IBlockState stateBelow = world.getBlockState(pos.add(0,-1,0)); b = stateBelow.getBlock().equals(this)&&this.getMetaFromState(stateBelow)==getMaxMeta(0); } return b; } @Override protected boolean canSustainBush(IBlockState state) { return state.getBlock() == Blocks.FARMLAND; } @Override public EnumPlantType getPlantType(net.minecraft.world.IBlockAccess world, BlockPos pos) { return EnumPlantType.Crop; } static final AxisAlignedBB box0 = new AxisAlignedBB(0,0,0, 1,.375f,1); static final AxisAlignedBB box1 = new AxisAlignedBB(0,0,0, 1,.625f,1); static final AxisAlignedBB box2 = new AxisAlignedBB(0,0,0, 1,.875f,1); @Override public AxisAlignedBB getSelectedBoundingBox(IBlockState state, World world, BlockPos pos) { int meta = this.getMetaFromState(world.getBlockState(pos)); return meta==0?box0: meta==1?box1: meta==2?box2: FULL_BLOCK_AABB; } @Override public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { ArrayList<ItemStack> ret = new ArrayList<ItemStack>(); int meta = this.getMetaFromState(state); if(meta>=4) { Random rand = world instanceof World ? ((World)world).rand : RANDOM; for (int i=0; i<3+fortune; ++i) if(rand.nextInt(8) <= meta) ret.add(new ItemStack(IEContent.itemMaterial,1,4)); ret.add(new ItemStack(IEContent.itemSeeds,1,0)); } return ret; } @Override public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block) { super.neighborChanged(state, world, pos, block); if(this.getMetaFromState(state)<getMaxMeta(0)) world.notifyBlockOfStateChange(pos.add(0,1,0), this); } @Override public void updateTick (World world, BlockPos pos, IBlockState state, Random random) { this.checkAndDropBlock(world, pos, state); int light = world.getLight(pos); if(light >= 12) { int meta = this.getMetaFromState(state); if(meta>4) return; float growth = this.getGrowthSpeed(world, pos, state, light); if(random.nextInt((int)(50F/growth)+1) == 0) { if(this.getMaxMeta(meta) != meta) { meta++; world.setBlockState(pos, this.getStateFromMeta(meta)); } if(meta>3 && world.isAirBlock(pos.add(0,1,0))) world.setBlockState(pos.add(0,1,0), this.getStateFromMeta(meta+1)); } } } float getGrowthSpeed(World world, BlockPos pos, IBlockState sate, int light) { float growth = 0.125f * (light - 11); if(world.canBlockSeeSky(pos)) growth += 2f; IBlockState soil = world.getBlockState(pos.add(0,-1,0)); if(soil.getBlock().isFertile(world,pos.add(0,-1,0))) growth *= 1.5f; return 1f + growth; } @Override public boolean canPlaceBlockAt(World worldIn, BlockPos pos) { IBlockState soil = worldIn.getBlockState(pos.down()); return super.canPlaceBlockAt(worldIn, pos) && soil.getBlock().canSustainPlant(soil, worldIn, pos.down(), net.minecraft.util.EnumFacing.UP, this); } //isNotGrown @Override public boolean canGrow(World world, BlockPos pos, IBlockState state, boolean isClient) { int meta = this.getMetaFromState(state); if(meta<getMaxMeta(meta)) return true; else return meta==4 && !world.getBlockState(pos.add(0,1,0)).getBlock().equals(this); } //canBonemeal @Override public boolean canUseBonemeal(World world, Random rand, BlockPos pos, IBlockState state) { int meta = this.getMetaFromState(state); if(meta<getMaxMeta(meta)) return true; else return meta==4 && !world.getBlockState(pos.add(0,1,0)).getBlock().equals(this); } @Override public void grow(World world, Random rand, BlockPos pos, IBlockState state) { int meta = this.getMetaFromState(state); if(meta<getMaxMeta(meta)) { int span = getMaxMeta(meta)-meta; int newMeta = meta+rand.nextInt(span)+1; if(newMeta!=meta) world.setBlockState(pos, this.getStateFromMeta(newMeta)); meta = newMeta; } if(meta==4 && world.isAirBlock(pos.add(0,1,0))) world.setBlockState(pos.add(0,1,0), this.getStateFromMeta(meta+1)); } }