Trees - Fixed requirements / replacements

This commit is contained in:
Emmanuel BENOîT 2016-07-09 23:30:50 +02:00
parent 86a0a14605
commit 2a0e58a343
3 changed files with 93 additions and 26 deletions

View file

@ -3,10 +3,17 @@ package mmm.world.trees;
import java.util.Random; import java.util.Random;
import mmm.materials.MSapling;
import mmm.materials.MTree; import mmm.materials.MTree;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockBush;
import net.minecraft.block.BlockFlower;
import net.minecraft.block.BlockLeaves;
import net.minecraft.block.BlockSapling;
import net.minecraft.block.BlockVine;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenAbstractTree; import net.minecraft.world.gen.feature.WorldGenAbstractTree;
@ -16,13 +23,25 @@ import net.minecraft.world.gen.feature.WorldGenAbstractTree;
public abstract class A_WTTreeGenerator public abstract class A_WTTreeGenerator
extends WorldGenAbstractTree extends WorldGenAbstractTree
{ {
public static enum E_BlockRequirement {
/** Require / replace empty (air) block */
EMPTY ,
/** Require / replace air, leaves, vines, etc. */
SOFT ,
/** Require / replace vanilla */
VANILLA ,
/** Anything but bedrock can do, unless it has a TE */
HARD
}
public static class RuntimeData public static class RuntimeData
{ {
public final BlockPos corner; public final BlockPos corner;
public final int xSize; public final int xSize;
public final int zSize; public final int zSize;
public final int height; public final int height;
protected boolean mustBeEmpty[]; protected E_BlockRequirement require[];
protected E_BlockRequirement replace[];
protected IBlockState blocks[]; protected IBlockState blocks[];
@ -43,7 +62,8 @@ public abstract class A_WTTreeGenerator
private void allocateData( ) private void allocateData( )
{ {
this.mustBeEmpty = new boolean[ this.xSize * this.zSize * this.height ]; this.require = new E_BlockRequirement[ this.xSize * this.zSize * this.height ];
this.replace = new E_BlockRequirement[ this.xSize * this.zSize * this.height ];
this.blocks = new IBlockState[ this.xSize * this.zSize * this.height ]; this.blocks = new IBlockState[ this.xSize * this.zSize * this.height ];
} }
@ -54,9 +74,15 @@ public abstract class A_WTTreeGenerator
} }
public boolean mustBeEmpty( final int i , final int j , final int k ) public E_BlockRequirement requires( final int i , final int j , final int k )
{ {
return this.mustBeEmpty[ this.getOffset( i , j , k ) ]; return this.require[ this.getOffset( i , j , k ) ];
}
public E_BlockRequirement replaces( final int i , final int j , final int k )
{
return this.replace[ this.getOffset( i , j , k ) ];
} }
@ -66,18 +92,19 @@ public abstract class A_WTTreeGenerator
} }
public void setBlock( final int i , final int j , final int k , final Block block , final boolean mustBeEmpty ) public void setBlock( final int i , final int j , final int k , final Block block ,
final E_BlockRequirement replace )
{ {
this.setBlock( i , j , k , block.getDefaultState( ) , mustBeEmpty ); this.setBlock( i , j , k , block.getDefaultState( ) , replace );
} }
public void setBlock( final int i , final int j , final int k , final IBlockState block , public void setBlock( final int i , final int j , final int k , final IBlockState block ,
final boolean mustBeEmpty ) final E_BlockRequirement replace )
{ {
final int offset = this.getOffset( i , j , k ); final int offset = this.getOffset( i , j , k );
this.blocks[ offset ] = block; this.blocks[ offset ] = block;
this.mustBeEmpty[ offset ] = mustBeEmpty; this.replace[ offset ] = replace;
} }
@ -85,13 +112,14 @@ public abstract class A_WTTreeGenerator
{ {
final int offset = this.getOffset( i , j , k ); final int offset = this.getOffset( i , j , k );
this.blocks[ offset ] = null; this.blocks[ offset ] = null;
this.mustBeEmpty[ offset ] = false; this.require[ offset ] = null;
this.replace[ offset ] = null;
} }
public void setEmptyRequirement( final int i , final int j , final int k , final boolean empty ) public void setRequirement( final int i , final int j , final int k , final E_BlockRequirement requirement )
{ {
this.mustBeEmpty[ this.getOffset( i , j , k ) ] = empty; this.require[ this.getOffset( i , j , k ) ] = requirement;
} }
@ -171,11 +199,13 @@ public abstract class A_WTTreeGenerator
for ( int i = 0 ; i < rtd.xSize ; i++ ) { for ( int i = 0 ; i < rtd.xSize ; i++ ) {
for ( int j = 0 ; j < rtd.height ; j++ ) { for ( int j = 0 ; j < rtd.height ; j++ ) {
for ( int k = 0 ; k < rtd.zSize ; k++ ) { for ( int k = 0 ; k < rtd.zSize ; k++ ) {
if ( !rtd.mustBeEmpty( i , j , k ) ) { final E_BlockRequirement req = rtd.requires( i , j , k );
if ( req == null ) {
continue; continue;
} }
mbp.setPos( rtd.corner.getX( ) + i , rtd.corner.getY( ) + j , rtd.corner.getZ( ) + k ); mbp.setPos( rtd.corner.getX( ) + i , rtd.corner.getY( ) + j , rtd.corner.getZ( ) + k );
if ( !this.isReplaceable( worldIn , mbp ) ) { if ( !this.checkRequirement( worldIn , mbp , req ) ) {
return false; return false;
} }
} }
@ -188,18 +218,52 @@ public abstract class A_WTTreeGenerator
final IBlockState state = rtd.getBlockState( i , j , k ); final IBlockState state = rtd.getBlockState( i , j , k );
if ( state != null ) { if ( state != null ) {
final BlockPos blockPos = rtd.corner.add( i , j , k ); final BlockPos blockPos = rtd.corner.add( i , j , k );
if ( rtd.mustBeEmpty( i , j , k ) final E_BlockRequirement rep = rtd.replaces( i , j , k );
|| worldIn.getBlockState( blockPos ).getMaterial( ) == Material.AIR ) { if ( rep == null ) {
System.err.println( "REP IS NULL, STATE IS " + state );
continue;
}
if ( this.checkRequirement( worldIn , blockPos , rep ) ) {
this.setBlockAndNotifyAdequately( worldIn , blockPos , state ); this.setBlockAndNotifyAdequately( worldIn , blockPos , state );
} }
} }
} }
} }
} }
return true; return true;
} }
private boolean checkRequirement( final World worldIn , final BlockPos pos , final E_BlockRequirement requirement )
{
switch ( requirement ) {
case EMPTY:
return worldIn.getBlockState( pos ).getMaterial( ) == Material.AIR;
case SOFT: {
final IBlockState state = worldIn.getBlockState( pos );
final Block block = worldIn.getBlockState( pos ).getBlock( );
// FIXME: don't hardcode this
return state.getMaterial( ) == Material.AIR || block instanceof BlockLeaves
|| block instanceof BlockFlower || block instanceof BlockBush || block instanceof BlockVine
|| block instanceof BlockSapling || block instanceof MSapling;
}
case VANILLA:
return this.isReplaceable( worldIn , pos );
case HARD: {
final IBlockState state = worldIn.getBlockState( pos );
final Block block = worldIn.getBlockState( pos ).getBlock( );
return block != Blocks.BEDROCK && block != Blocks.BARRIER && !block.hasTileEntity( state );
}
}
return false;
}
protected abstract RuntimeData determineTreeSize( BlockPos position , Random rand ); protected abstract RuntimeData determineTreeSize( BlockPos position , Random rand );

View file

@ -39,7 +39,15 @@ public class WTBambooGenerator
{ {
// Trunk // Trunk
for ( int y = 0 ; y < rtd.height ; y++ ) { for ( int y = 0 ; y < rtd.height ; y++ ) {
rtd.setBlock( 2 , y , 2 , this.getWood( ).LOG , true ); rtd.setBlock( 2 , y , 2 , this.getWood( ).LOG , E_BlockRequirement.VANILLA );
rtd.setRequirement( 2 , y , 2 , E_BlockRequirement.VANILLA );
}
// Don't share the top space
for ( int x = 1 ; x <= 3 ; x++ ) {
for ( int z = 1 ; z <= 3 ; z++ ) {
rtd.setRequirement( x , rtd.height - 1 , z , E_BlockRequirement.SOFT );
}
} }
// Leaves // Leaves
@ -52,19 +60,13 @@ public class WTBambooGenerator
for ( int x = -2 ; x <= 2 ; x++ ) { for ( int x = -2 ; x <= 2 ; x++ ) {
for ( int z = -2 ; z <= 2 ; z++ ) { for ( int z = -2 ; z <= 2 ; z++ ) {
if ( ( x != 0 || z != 0 ) && x * x + z * z <= sqRadius + rand.nextInt( 2 ) ) { if ( ( x != 0 || z != 0 ) && x * x + z * z <= sqRadius + rand.nextInt( 2 ) ) {
rtd.setBlock( x + 2 , ringY , z + 2 , leaves , false ); rtd.setBlock( x + 2 , ringY , z + 2 , leaves , E_BlockRequirement.SOFT );
} }
} }
} }
ringY += 1 + rand.nextInt( 3 ); ringY += 1 + rand.nextInt( 3 );
} }
// Don't share the top space
for ( int x = 1 ; x <= 3 ; x++ ) {
for ( int z = 1 ; z <= 3 ; z++ ) {
rtd.setEmptyRequirement( x , rtd.height - 1 , z , true );
}
}
} }
} }

View file

@ -46,7 +46,7 @@ public class WTHeveaGenerator
for ( int x = -radius ; x <= radius ; x++ ) { for ( int x = -radius ; x <= radius ; x++ ) {
for ( int z = -radius ; z <= radius ; z++ ) { for ( int z = -radius ; z <= radius ; z++ ) {
if ( ( x != 0 || z != 0 ) && x * x + z * z <= rSquare ) { if ( ( x != 0 || z != 0 ) && x * x + z * z <= rSquare ) {
rtd.setBlock( centre + x , y , centre + z , leaves , false ); rtd.setBlock( centre + x , y , centre + z , leaves , E_BlockRequirement.SOFT );
} }
} }
} }
@ -61,7 +61,7 @@ public class WTHeveaGenerator
for ( int x = -radius ; x <= radius ; x++ ) { for ( int x = -radius ; x <= radius ; x++ ) {
for ( int z = -radius ; z <= radius ; z++ ) { for ( int z = -radius ; z <= radius ; z++ ) {
if ( ( x != centre || z != centre || y >= trunkHeight ) && x * x + z * z <= rSquare ) { if ( ( x != centre || z != centre || y >= trunkHeight ) && x * x + z * z <= rSquare ) {
rtd.setBlock( centre + x , y , centre + z , leaves , y == rtd.height - 1 ); rtd.setBlock( centre + x , y , centre + z , leaves , E_BlockRequirement.SOFT );
} }
} }
} }
@ -72,7 +72,8 @@ public class WTHeveaGenerator
// Trunk // Trunk
for ( int y = 0 ; y < trunkHeight ; y++ ) { for ( int y = 0 ; y < trunkHeight ; y++ ) {
rtd.setBlock( centre , y , centre , this.getWood( ).LOG , true ); rtd.setBlock( centre , y , centre , this.getWood( ).LOG , E_BlockRequirement.VANILLA );
rtd.setRequirement( centre , y , centre , E_BlockRequirement.VANILLA );
} }
} }