Saplings logic, hopefully

This commit is contained in:
Emmanuel BENOîT 2016-07-09 14:01:39 +02:00
parent b4aa443c7b
commit 40af906c16
3 changed files with 452 additions and 4 deletions

View file

@ -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;
}
}

View file

@ -1,13 +1,20 @@
package mmm.materials; package mmm.materials;
import java.util.Random;
import mmm.utils.I_URecipeRegistrar; import mmm.utils.I_URecipeRegistrar;
import mmm.utils.URegistry; import mmm.utils.URegistry;
import net.minecraft.block.Block;
import net.minecraft.block.material.MapColor; import net.minecraft.block.material.MapColor;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.init.Items; import net.minecraft.init.Items;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; 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; import net.minecraftforge.fml.common.registry.GameRegistry;
@ -15,26 +22,55 @@ import net.minecraftforge.fml.common.registry.GameRegistry;
public class MWood public class MWood
implements I_URecipeRegistrar implements I_URecipeRegistrar
{ {
public static interface I_SaplingChecker
{
public boolean canSaplingStay( World worldIn , BlockPos pos , IBlockState state );
}
public final String NAME; public final String NAME;
public final MLeaves LEAVES;
public final MLog LOG; public final MLog LOG;
public final MLeaves LEAVES;
public final MSapling SAPLING;
public final MPlanks PLANKS; public final MPlanks PLANKS;
private MapColor barkColor = MapColor.WOOD; private MapColor barkColor = MapColor.WOOD;
private MapColor plankColor = MapColor.WOOD; private MapColor plankColor = MapColor.WOOD;
private int baseFireEncouragement = 5; private int baseFireEncouragement = 5;
private int baseFlammability = 5; private int baseFlammability = 5;
private int saplingDropChance = 20; private int saplingDropChance = 20;
private int fruitDropChance = 0; private int fruitDropChance = 0;
private Item fruit = null; 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 ) public MWood( final String name )
{ {
this.NAME = name; this.NAME = name;
this.LEAVES = new MLeaves( this );
this.LOG = new MLog( this ); this.LOG = new MLog( this );
this.LEAVES = new MLeaves( this );
this.SAPLING = new MSapling( this );
this.PLANKS = new MPlanks( 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( ) public MWood register( )
{ {
URegistry.addBlock( this.LOG ); URegistry.addBlock( this.LOG );
Blocks.FIRE.setFireInfo( this.LOG , this.baseFireEncouragement , this.baseFlammability ); 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 ); URegistry.addBlock( this.LEAVES );
Blocks.FIRE.setFireInfo( this.LEAVES , this.baseFireEncouragement * 6 , this.baseFlammability * 12 ); 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 ); URegistry.addRecipeRegistrar( this );
return 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 @Override
public void registerRecipes( ) public void registerRecipes( )
{ {

View file

@ -64,6 +64,11 @@ item.mmm.materials.ingot.zinc.name=Zinc Ingot
item.mmm.materials.nugget.zinc.name=Zinc Nugget item.mmm.materials.nugget.zinc.name=Zinc Nugget
tile.mmm.materials.block.zinc.name=Zinc Block 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 tile.mmm.tech.base.alloy_furnace.inactive.name=Alloy Furnace
container.mmm.alloy_furnace.contents=Furnace Contents container.mmm.alloy_furnace.contents=Furnace Contents