package slimeknights.tconstruct.world.block; import net.minecraft.block.BlockDirt; import net.minecraft.block.BlockGrass; import net.minecraft.block.SoundType; import net.minecraft.block.properties.PropertyEnum; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; import net.minecraft.util.IStringSerializable; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.EnumPlantType; import net.minecraftforge.common.IPlantable; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import java.util.List; import java.util.Locale; import java.util.Random; import javax.annotation.Nonnull; import slimeknights.mantle.block.EnumBlock; import slimeknights.tconstruct.library.TinkerRegistry; import slimeknights.tconstruct.world.TinkerWorld; public class BlockSlimeGrass extends BlockGrass { public static PropertyEnum<DirtType> TYPE = PropertyEnum.create("type", DirtType.class); public static PropertyEnum<FoliageType> FOLIAGE = PropertyEnum.create("foliage", FoliageType.class); public BlockSlimeGrass() { this.setCreativeTab(TinkerRegistry.tabWorld); this.setHardness(0.65f); this.setSoundType(SoundType.PLANT); this.slipperiness += 0.05f; } @SideOnly(Side.CLIENT) @Override public void getSubBlocks(@Nonnull Item itemIn, CreativeTabs tab, List<ItemStack> list) { for(FoliageType grass : FoliageType.values()) { for(DirtType type : DirtType.values()) { list.add(new ItemStack(this, 1, getMetaFromState(getDefaultState().withProperty(TYPE, type).withProperty(FOLIAGE, grass)))); } } } @Override public void grow(@Nonnull World worldIn, @Nonnull Random rand, @Nonnull BlockPos pos, @Nonnull IBlockState state) { BlockPos blockpos1 = pos.up(); int i = 0; while(i < 128) { BlockPos blockpos2 = blockpos1; int j = 0; while(true) { if(j < i / 16) { blockpos2 = blockpos2.add(rand.nextInt(3) - 1, (rand.nextInt(3) - 1) * rand.nextInt(3) / 2, rand.nextInt(3) - 1); if(worldIn.getBlockState(blockpos2.down()).getBlock() == this && !worldIn.getBlockState(blockpos2).getBlock().isNormalCube(state)) { ++j; continue; } } else if(worldIn.isAirBlock(blockpos2)) { IBlockState plantState; if(rand.nextInt(8) == 0) { plantState = TinkerWorld.slimeGrassTall.getDefaultState().withProperty(BlockTallSlimeGrass.TYPE, BlockTallSlimeGrass.SlimePlantType.FERN); } else { plantState = TinkerWorld.slimeGrassTall.getDefaultState().withProperty(BlockTallSlimeGrass.TYPE, BlockTallSlimeGrass.SlimePlantType.TALL_GRASS); } plantState = plantState.withProperty(BlockTallSlimeGrass.FOLIAGE, state.getValue(FOLIAGE)); if(TinkerWorld.slimeGrassTall.canBlockStay(worldIn, blockpos2, plantState)) { worldIn.setBlockState(blockpos2, plantState, 3); } } ++i; break; } } } @Override public void updateTick(World worldIn, @Nonnull BlockPos pos, IBlockState state, @Nonnull Random rand) { if(worldIn.isRemote) { return; } // spread to surrounding blocks 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(worldIn.getLightFromNeighbors(blockpos.up()) >= 4 && iblockstate.getLightOpacity(worldIn, pos.up()) <= 2) { convert(worldIn, blockpos, iblockstate1, state.getValue(FOLIAGE)); } } } } public void convert(World world, BlockPos pos, IBlockState state, FoliageType foliageType) { IBlockState newState = getStateFromDirt(state); if(newState != null) { world.setBlockState(pos, newState.withProperty(FOLIAGE, foliageType)); } } @Nonnull @Override protected BlockStateContainer createBlockState() { return new BlockStateContainer(this, TYPE, FOLIAGE, BlockGrass.SNOWY); } @Nonnull @Override public IBlockState getStateFromMeta(int meta) { if(meta > 14) { meta = 0; } return this.getDefaultState().withProperty(TYPE, DirtType.values()[meta % 5]).withProperty(FOLIAGE, FoliageType.values()[meta / 5]); } @Override public int getMetaFromState(IBlockState state) { DirtType type = state.getValue(TYPE); FoliageType grass = state.getValue(FOLIAGE); //type goes from 0-5, grass goes from 0-2 resulting in 0-5, 6-10, 11-15 return type.ordinal() + grass.ordinal() * 5; } @Override public int damageDropped(IBlockState state) { DirtType type = state.getValue(TYPE); if(type == DirtType.VANILLA) { return 0; } return getDirtState(state).getValue(BlockSlimeDirt.TYPE).getMeta(); } @Override public Item getItemDropped(IBlockState state, @Nonnull Random rand, int fortune) { return Item.getItemFromBlock(getDirtState(state).getBlock()); } @Nonnull @Override public ItemStack getPickBlock(@Nonnull IBlockState state, RayTraceResult target, @Nonnull World world, @Nonnull BlockPos pos, EntityPlayer player) { return this.getSilkTouchDrop(world.getBlockState(pos)); } /** Returns the blockstate for the dirt underneath the grass */ public IBlockState getDirtState(IBlockState grassState) { DirtType type = grassState.getValue(TYPE); switch(type) { case VANILLA: return Blocks.DIRT.getDefaultState(); case GREEN: return TinkerWorld.slimeDirt.getStateFromMeta(BlockSlimeDirt.DirtType.GREEN.getMeta()); case BLUE: return TinkerWorld.slimeDirt.getStateFromMeta(BlockSlimeDirt.DirtType.BLUE.getMeta()); case PURPLE: return TinkerWorld.slimeDirt.getStateFromMeta(BlockSlimeDirt.DirtType.PURPLE.getMeta()); case MAGMA: return TinkerWorld.slimeDirt.getStateFromMeta(BlockSlimeDirt.DirtType.MAGMA.getMeta()); } return TinkerWorld.slimeDirt.getStateFromMeta(BlockSlimeDirt.DirtType.GREEN.getMeta()); } /** Returns the grass blockstate for the given dirt type or null */ public IBlockState getStateFromDirt(IBlockState dirtState) { // vanilla dirt? if(dirtState.getBlock() == Blocks.DIRT && dirtState.getValue(BlockDirt.VARIANT) == BlockDirt.DirtType.DIRT) { return this.getDefaultState().withProperty(TYPE, DirtType.VANILLA); } // slimedirt block? if(dirtState.getBlock() == TinkerWorld.slimeDirt) { // green slimedirt if(dirtState.getValue(BlockSlimeDirt.TYPE) == BlockSlimeDirt.DirtType.GREEN) { return this.getDefaultState().withProperty(TYPE, DirtType.GREEN); } // blue slimedirt else if(dirtState.getValue(BlockSlimeDirt.TYPE) == BlockSlimeDirt.DirtType.BLUE) { return this.getDefaultState().withProperty(TYPE, DirtType.BLUE); } // purple slimedirt else if(dirtState.getValue(BlockSlimeDirt.TYPE) == BlockSlimeDirt.DirtType.PURPLE) { return this.getDefaultState().withProperty(TYPE, DirtType.PURPLE); } // magma slimedirt else if(dirtState.getValue(BlockSlimeDirt.TYPE) == BlockSlimeDirt.DirtType.MAGMA) { return this.getDefaultState().withProperty(TYPE, DirtType.MAGMA); } } return null; } @Override public boolean canSustainPlant(@Nonnull IBlockState state, @Nonnull IBlockAccess world, BlockPos pos, @Nonnull EnumFacing direction, IPlantable plantable) { // can sustain both slimeplants and normal plants return plantable.getPlantType(world, pos) == TinkerWorld.slimePlantType || plantable.getPlantType(world, pos) == EnumPlantType.Plains; } public enum FoliageType implements IStringSerializable, EnumBlock.IEnumMeta { BLUE, PURPLE, ORANGE; public static FoliageType getValFromMeta(int meta) { if(meta < 0 || meta >= values().length) { meta = 0; } return values()[meta]; } @Override public int getMeta() { return ordinal(); } @Override public String getName() { return this.toString().toLowerCase(Locale.US); } } public enum DirtType implements IStringSerializable { VANILLA, GREEN, BLUE, PURPLE, MAGMA; @Override public String getName() { return this.toString().toLowerCase(Locale.US); } } }