From 40af906c16eeb5d6fcfd4bdeab333b50dd56ef45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Sat, 9 Jul 2016 14:01:39 +0200 Subject: [PATCH] Saplings logic, hopefully --- src/java/mmm/materials/MSapling.java | 243 +++++++++++++++++++++++ src/java/mmm/materials/MWood.java | 208 ++++++++++++++++++- src/resources/assets/mmm/lang/en_US.lang | 5 + 3 files changed, 452 insertions(+), 4 deletions(-) create mode 100644 src/java/mmm/materials/MSapling.java diff --git a/src/java/mmm/materials/MSapling.java b/src/java/mmm/materials/MSapling.java new file mode 100644 index 0000000..bcf1fae --- /dev/null +++ b/src/java/mmm/materials/MSapling.java @@ -0,0 +1,243 @@ +package mmm.materials; + + +import java.util.Random; + +import mmm.utils.URegistry; +import net.minecraft.block.Block; +import net.minecraft.block.IGrowable; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.PropertyInteger; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +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.World; +import net.minecraftforge.event.terraingen.TerrainGen; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + + + +public class MSapling + extends Block + implements IGrowable +{ + private static final PropertyInteger STAGE = PropertyInteger.create( "stage" , 0 , 15 ); + + public final MWood wood; + + + public MSapling( final MWood wood ) + { + super( Material.PLANTS ); + this.wood = wood; + + this.setTickRandomly( true ); + this.setHardness( 0f ); + this.setSoundType( SoundType.PLANT ); + + this.setDefaultState( this.blockState.getBaseState( ).withProperty( MSapling.STAGE , 0 ) ); + + URegistry.setIdentifiers( this , "materials" , "sapling" , wood.NAME ); + } + + + @Override + protected BlockStateContainer createBlockState( ) + { + return new BlockStateContainer( this , MSapling.STAGE ); + } + + + @Override + public IBlockState getStateFromMeta( final int meta ) + { + return this.getDefaultState( ).withProperty( MSapling.STAGE , meta ); + } + + + @Override + public int getMetaFromState( final IBlockState state ) + { + return state.getValue( MSapling.STAGE ); + } + + + @Override + public int damageDropped( final IBlockState state ) + { + return 0; + } + + + @Override + public boolean canGrow( final World worldIn , final BlockPos pos , final IBlockState state , + final boolean isClient ) + { + return this.wood.getBonemealChance( ) > 0; + } + + + @Override + public boolean canUseBonemeal( final World worldIn , final Random rand , final BlockPos pos , + final IBlockState state ) + { + return worldIn.rand.nextFloat( ) < this.wood.getBonemealChance( ); + } + + + @Override + public void grow( final World worldIn , final Random rand , final BlockPos pos , final IBlockState state ) + { + final int stage = state.getValue( MSapling.STAGE ) + 1; + if ( stage >= this.wood.getSaplingGrowthStages( ) ) { + this.generate( worldIn , rand , pos , state ); + } else { + worldIn.setBlockState( pos , state.withProperty( MSapling.STAGE , stage ) ); + } + } + + + private void generate( final World worldIn , final Random rand , final BlockPos pos , final IBlockState state ) + { + if ( !TerrainGen.saplingGrowTree( worldIn , rand , pos ) ) { + return; + } + + if ( this.wood.getMegaGenerator( ) != null ) { + for ( int x = -1 ; x < 1 ; x++ ) { + for ( int z = -1 ; z < 1 ; z++ ) { + final BlockPos basePos = pos.add( x , 0 , z ); + if ( this.isSameSapling( worldIn , basePos ) // + && this.isSameSapling( worldIn , basePos.add( 1 , 0 , 0 ) ) // + && this.isSameSapling( worldIn , basePos.add( 0 , 0 , 1 ) ) + && this.isSameSapling( worldIn , basePos.add( 1 , 0 , 1 ) ) + && this.generateMega( worldIn , basePos , rand ) ) { + return; + } + } + } + } + + if ( this.wood.canGenerateBigOrSmall( ) ) { + final IBlockState air = Blocks.AIR.getDefaultState( ); + worldIn.setBlockState( pos , air , 4 ); + if ( !this.wood.generateNormalOrBig( worldIn , pos , rand ) ) { + worldIn.setBlockState( pos , state , 4 ); + } + } + } + + + private boolean generateMega( final World worldIn , final BlockPos pos , final Random rand ) + { + final IBlockState air = Blocks.AIR.getDefaultState( ); + + final IBlockState saved[] = new IBlockState[ 4 ]; + for ( int i = 0 , o = 0 ; i < 2 ; i++ ) { + for ( int j = 0 ; j < 2 ; j++ , o++ ) { + final BlockPos bPos = pos.add( i , 0 , j ); + saved[ o ] = worldIn.getBlockState( bPos ); + worldIn.setBlockState( bPos , air , 4 ); + } + } + + final boolean generated = this.wood.generateMega( worldIn , pos , rand ); + if ( !generated ) { + for ( int i = 0 , o = 0 ; i < 2 ; i++ ) { + for ( int j = 0 ; j < 2 ; j++ , o++ ) { + final BlockPos bPos = pos.add( i , 0 , j ); + worldIn.setBlockState( bPos , saved[ o ] , 4 ); + } + } + } + return generated; + } + + + private boolean isSameSapling( final World worldIn , final BlockPos pos ) + { + return worldIn.getBlockState( pos ).getBlock( ) == this; + } + + + @Override + public boolean canReplace( final World world , final BlockPos pos , final EnumFacing side , final ItemStack stack ) + { + return world.getBlockState( pos ).getBlock( ).isReplaceable( world , pos ) + && this.wood.canSaplingStay( world , pos , this.getStateFromMeta( stack.getMetadata( ) ) ); + } + + + @Override + public void neighborChanged( final IBlockState state , final World world , final BlockPos pos , + final Block neighborBlock ) + { + this.checkUproot( world , pos , state ); + } + + + @Override + public void updateTick( final World worldIn , final BlockPos pos , final IBlockState state , final Random rand ) + { + if ( !worldIn.isRemote && this.checkUproot( worldIn , pos , state ) + && this.wood.checkGrowthLight( worldIn.getLightFromNeighbors( pos.up( ) ) ) + && rand.nextFloat( ) <= this.wood.getGrowthChance( ) ) { + this.grow( worldIn , rand , pos , state ); + } + } + + + private boolean checkUproot( final World worldIn , final BlockPos pos , final IBlockState state ) + { + if ( this.wood.canSaplingStay( worldIn , pos , state ) ) { + return true; + } + this.dropBlockAsItem( worldIn , pos , state , 0 ); + worldIn.setBlockState( pos , Blocks.AIR.getDefaultState( ) , 3 ); + return false; + } + + + @Override + public boolean isOpaqueCube( final IBlockState state ) + { + return false; + } + + + @Override + public boolean isFullCube( final IBlockState state ) + { + return false; + } + + + @Override + @SideOnly( Side.CLIENT ) + public BlockRenderLayer getBlockLayer( ) + { + return BlockRenderLayer.CUTOUT; + } + + + @Override + @SideOnly( Side.CLIENT ) + public Block.EnumOffsetType getOffsetType( ) + { + return Block.EnumOffsetType.XZ; + } + + + @Override + public AxisAlignedBB getCollisionBoundingBox( final IBlockState state , final World world , final BlockPos pos ) + { + return Block.NULL_AABB; + } +} diff --git a/src/java/mmm/materials/MWood.java b/src/java/mmm/materials/MWood.java index 50f5aac..5c6ab88 100644 --- a/src/java/mmm/materials/MWood.java +++ b/src/java/mmm/materials/MWood.java @@ -1,13 +1,20 @@ package mmm.materials; +import java.util.Random; + import mmm.utils.I_URecipeRegistrar; import mmm.utils.URegistry; +import net.minecraft.block.Block; import net.minecraft.block.material.MapColor; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenAbstractTree; import net.minecraftforge.fml.common.registry.GameRegistry; @@ -15,26 +22,55 @@ import net.minecraftforge.fml.common.registry.GameRegistry; public class MWood implements I_URecipeRegistrar { + public static interface I_SaplingChecker + { + public boolean canSaplingStay( World worldIn , BlockPos pos , IBlockState state ); + } public final String NAME; - public final MLeaves LEAVES; public final MLog LOG; + public final MLeaves LEAVES; + public final MSapling SAPLING; public final MPlanks PLANKS; private MapColor barkColor = MapColor.WOOD; private MapColor plankColor = MapColor.WOOD; + private int baseFireEncouragement = 5; private int baseFlammability = 5; + private int saplingDropChance = 20; private int fruitDropChance = 0; private Item fruit = null; + private int saplingGrowthStages = 1; + private float bonemealChance = .45f; + private float growthChance = .142f; + private int growthMinLight = 9; + private int growthMaxLight = 16; + private I_SaplingChecker saplingCheck = new I_SaplingChecker( ) { + + @Override + public boolean canSaplingStay( final World worldIn , final BlockPos pos , final IBlockState state ) + { + final Block down = worldIn.getBlockState( pos.down( ) ).getBlock( ); + return down == Blocks.GLASS || down == Blocks.DIRT; + } + + }; + + private WorldGenAbstractTree genNormal; + private WorldGenAbstractTree genBig; + private float genBigChance; + private WorldGenAbstractTree genMega; + public MWood( final String name ) { this.NAME = name; - this.LEAVES = new MLeaves( this ); this.LOG = new MLog( this ); + this.LEAVES = new MLeaves( this ); + this.SAPLING = new MSapling( this ); this.PLANKS = new MPlanks( this ); } @@ -76,15 +112,83 @@ public class MWood } + public MWood setSaplingGrowthStages( final int stages ) + { + this.saplingGrowthStages = stages; + return this; + } + + + public MWood setBonemealChance( final float chance ) + { + this.bonemealChance = chance; + return this; + } + + + public MWood setGrowthChance( final float chance ) + { + this.growthChance = chance; + return this; + } + + + public MWood setGrowthLightConditions( final int min , final int max ) + { + this.growthMinLight = min; + this.growthMaxLight = max; + return this; + } + + + public MWood setSaplingCheck( final I_SaplingChecker check ) + { + this.saplingCheck = check; + return this; + } + + + public MWood setTreeGenerator( final WorldGenAbstractTree generator ) + { + this.genNormal = generator; + return this; + } + + + public MWood setBigTreeGenerator( final WorldGenAbstractTree generator ) + { + this.genBig = generator; + this.genBigChance = .1f; + return this; + } + + + public MWood setBigTreeGenerator( final WorldGenAbstractTree generator , final float chance ) + { + this.genBig = generator; + this.genBigChance = chance; + return this; + } + + + public MWood setMegaTreeGenerator( final WorldGenAbstractTree generator ) + { + this.genMega = generator; + return this; + } + + public MWood register( ) { URegistry.addBlock( this.LOG ); Blocks.FIRE.setFireInfo( this.LOG , this.baseFireEncouragement , this.baseFlammability ); - URegistry.addBlock( this.PLANKS ); - Blocks.FIRE.setFireInfo( this.PLANKS , this.baseFireEncouragement , this.baseFlammability * 4 ); + URegistry.addBlock( this.LEAVES ); Blocks.FIRE.setFireInfo( this.LEAVES , this.baseFireEncouragement * 6 , this.baseFlammability * 12 ); + URegistry.addBlock( this.PLANKS ); + Blocks.FIRE.setFireInfo( this.PLANKS , this.baseFireEncouragement , this.baseFlammability * 4 ); + URegistry.addRecipeRegistrar( this ); return this; } @@ -120,6 +224,102 @@ public class MWood } + public int getSaplingGrowthStages( ) + { + return this.saplingGrowthStages; + } + + + public float getBonemealChance( ) + { + return this.bonemealChance; + } + + + public float getGrowthChance( ) + { + return this.growthChance; + } + + + public boolean checkGrowthLight( final int lightLevel ) + { + return lightLevel >= this.growthMinLight && lightLevel <= this.growthMaxLight; + } + + + public boolean canSaplingStay( final World worldIn , final BlockPos pos , final IBlockState state ) + { + if ( this.saplingCheck != null ) { + return this.saplingCheck.canSaplingStay( worldIn , pos , state ); + } + return true; + } + + + public boolean canGenerateBigOrSmall( ) + { + return this.genNormal != null || this.genBig != null; + } + + + public boolean generateNormalOrBig( final World worldIn , final BlockPos pos , final Random rand ) + { + if ( this.genBig != null + && ( this.genBigChance > 0 && rand.nextFloat( ) < this.genBigChance || this.genNormal == null ) ) { + if ( this.genBig.generate( worldIn , rand , pos ) ) { + return true; + } + } + return this.generateNormal( worldIn , pos , rand ); + } + + + public boolean generateNormal( final World worldIn , final BlockPos pos , final Random rand ) + { + if ( this.genNormal == null ) { + return false; + } + return this.genNormal.generate( worldIn , rand , pos ); + } + + + public boolean generateBig( final World worldIn , final BlockPos pos , final Random rand ) + { + if ( this.genBig == null ) { + return false; + } + return this.genBig.generate( worldIn , rand , pos ); + } + + + public boolean generateMega( final World worldIn , final BlockPos pos , final Random rand ) + { + if ( this.genMega == null ) { + return false; + } + return this.genMega.generate( worldIn , rand , pos ); + } + + + public WorldGenAbstractTree getNormalGenerator( ) + { + return this.genNormal; + } + + + public WorldGenAbstractTree getBigGenerator( ) + { + return this.genBig; + } + + + public WorldGenAbstractTree getMegaGenerator( ) + { + return this.genMega; + } + + @Override public void registerRecipes( ) { diff --git a/src/resources/assets/mmm/lang/en_US.lang b/src/resources/assets/mmm/lang/en_US.lang index 425a810..e1570a0 100644 --- a/src/resources/assets/mmm/lang/en_US.lang +++ b/src/resources/assets/mmm/lang/en_US.lang @@ -64,6 +64,11 @@ item.mmm.materials.ingot.zinc.name=Zinc Ingot item.mmm.materials.nugget.zinc.name=Zinc Nugget tile.mmm.materials.block.zinc.name=Zinc Block +tile.mmm.materials.sapling.hevea.name=Hevea Sapling +tile.mmm.materials.log.hevea.name=Hevea Log +tile.mmm.materials.leaves.hevea.name=Hevea Leaves +tile.mmm.materials.planks.hevea.name=Hevea Wood Planks + tile.mmm.tech.base.alloy_furnace.inactive.name=Alloy Furnace container.mmm.alloy_furnace.contents=Furnace Contents