Improved abstration for flora parameters

This commit is contained in:
Emmanuel BENOîT 2016-07-20 21:09:10 +02:00
parent 2c38bbd4e0
commit eb16333a44
6 changed files with 101 additions and 28 deletions

View file

@ -3,13 +3,13 @@ package mmm.core.api;
import java.util.List; import java.util.List;
import mmm.world.gen.WGFloraParameters; import mmm.core.api.world.I_FloraParameters;
public interface I_FloraRegistrar public interface I_FloraRegistrar
{ {
public void getFloraGeneration( List< WGFloraParameters > output ); public void getFloraGeneration( List< I_FloraParameters > output );
} }

View file

@ -3,13 +3,11 @@ package mmm.core.api.world;
import java.util.List; import java.util.List;
import mmm.world.gen.WGFloraParameters;
public interface I_BiomeWithFlora public interface I_BiomeWithFlora
{ {
public void addFloraParameters( List< WGFloraParameters > output ); public void addFloraParameters( List< I_FloraParameters > output );
} }

View file

@ -0,0 +1,28 @@
package mmm.core.api.world;
import java.util.Random;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public interface I_FloraParameters
{
public IBlockState getBlockState( World world , BlockPos pos , Random random );
public boolean canPlaceInChunk( World world , BlockPos pos );
public int getAmountPerChunk( World world , BlockPos pos , Random random );
public int getPlacementAttempts( World world , BlockPos pos , Random random );
public boolean canPlace( World world , BlockPos pos , Random random );
}

View file

@ -11,6 +11,7 @@ import mmm.core.CRegistry;
import mmm.core.api.I_FloraRegistrar; import mmm.core.api.I_FloraRegistrar;
import mmm.core.api.I_RecipeRegistrar; import mmm.core.api.I_RecipeRegistrar;
import mmm.core.api.blocks.I_StateMapperProvider; import mmm.core.api.blocks.I_StateMapperProvider;
import mmm.core.api.world.I_FloraParameters;
import mmm.utils.UMaths; import mmm.utils.UMaths;
import mmm.world.WLocation; import mmm.world.WLocation;
import mmm.world.WLocationRainfall; import mmm.world.WLocationRainfall;
@ -419,18 +420,18 @@ public class PTomato
@Override @Override
public void getFloraGeneration( final List< WGFloraParameters > output ) public void getFloraGeneration( final List< I_FloraParameters > output )
{ {
output.add( new WGFloraParameters( this.WILD.getDefaultState( ) , 1 , output.add( new WGFloraParameters( this.WILD.getDefaultState( ) , 0.2f ,
WLocation.inOverworld( )// WLocation.inOverworld( )//
.and( new WLocationTemperature( 0.4f , 1f ) ) // .and( new WLocationTemperature( 0.4f , 1f ) ) //
.and( new WLocationRainfall( 0.2f , 0.8f ) ) ) ); .and( new WLocationRainfall( 0.2f , 0.8f ) ) ) );
output.add( new WGFloraParameters( this.WILD.getDefaultState( ) , 1 , output.add( new WGFloraParameters( this.WILD.getDefaultState( ) , 0.6f ,
WLocation.inOverworld( )// WLocation.inOverworld( )//
.and( new WLocationTemperature( 0.7f , 1f ) ) // .and( new WLocationTemperature( 0.7f , 1f ) ) //
.and( new WLocationRainfall( 0.3f , 0.5f ) ) ) ); .and( new WLocationRainfall( 0.3f , 0.5f ) ) ) );
output.add( new WGFloraParameters( // output.add( new WGFloraParameters( //
this.WILD.getDefaultState( ).withProperty( PTomato.WITH_FRUITS , true ) , 1 , this.WILD.getDefaultState( ).withProperty( PTomato.WITH_FRUITS , true ) , 0.3f ,
WLocation.inOverworld( )// WLocation.inOverworld( )//
.and( new WLocationTemperature( 0.8f , 0.9f ) ) // .and( new WLocationTemperature( 0.8f , 0.9f ) ) //
.and( new WLocationRainfall( 0.4f , 0.5f ) ) ) ); .and( new WLocationRainfall( 0.4f , 0.5f ) ) ) );

View file

@ -7,6 +7,7 @@ import java.util.Random;
import mmm.core.CRegistry; import mmm.core.CRegistry;
import mmm.core.api.I_FloraRegistrar; import mmm.core.api.I_FloraRegistrar;
import mmm.core.api.world.I_BiomeWithFlora; import mmm.core.api.world.I_BiomeWithFlora;
import mmm.core.api.world.I_FloraParameters;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -19,12 +20,12 @@ public class WGFlora
extends WorldGenerator extends WorldGenerator
{ {
private final ArrayList< WGFloraParameters > allConditions; private final ArrayList< I_FloraParameters > allConditions;
public WGFlora( ) public WGFlora( )
{ {
final ArrayList< WGFloraParameters > conditions = new ArrayList<>( ); final ArrayList< I_FloraParameters > conditions = new ArrayList<>( );
for ( final I_FloraRegistrar registrar : CRegistry.getFloraRegistrars( ) ) { for ( final I_FloraRegistrar registrar : CRegistry.getFloraRegistrars( ) ) {
registrar.getFloraGeneration( conditions ); registrar.getFloraGeneration( conditions );
} }
@ -35,7 +36,7 @@ public class WGFlora
@Override @Override
public boolean generate( final World worldIn , final Random rand , final BlockPos position ) public boolean generate( final World worldIn , final Random rand , final BlockPos position )
{ {
final ArrayList< WGFloraParameters > candidates = this.getValidFlora( worldIn , position ); final ArrayList< I_FloraParameters > candidates = this.getValidFlora( worldIn , position );
final int nCandidates = candidates.size( ); final int nCandidates = candidates.size( );
if ( nCandidates == 0 ) { if ( nCandidates == 0 ) {
return false; return false;
@ -48,12 +49,11 @@ public class WGFlora
} }
private ArrayList< WGFloraParameters > getValidFlora( final World worldIn , final BlockPos position ) private ArrayList< I_FloraParameters > getValidFlora( final World worldIn , final BlockPos position )
{ {
final ArrayList< WGFloraParameters > output = new ArrayList<>( ); final ArrayList< I_FloraParameters > output = new ArrayList<>( );
for ( final WGFloraParameters item : this.allConditions ) { for ( final I_FloraParameters item : this.allConditions ) {
if ( item.location.checkLocation( worldIn , position.getX( ) >> 4 , position.getZ( ) >> 4 , if ( item.canPlaceInChunk( worldIn , position ) ) {
worldIn.getChunkProvider( ) ) ) {
output.add( item ); output.add( item );
} }
} }
@ -68,9 +68,10 @@ public class WGFlora
private void tryGenerate( final World worldIn , final Random rand , final BlockPos position , private void tryGenerate( final World worldIn , final Random rand , final BlockPos position ,
final WGFloraParameters parameters ) final I_FloraParameters parameters )
{ {
for ( int i = 0 ; i < parameters.perChunk ; ++i ) { final int pc = parameters.getAmountPerChunk( worldIn , position , rand );
for ( int i = 0 ; i < pc ; ++i ) {
final int x = rand.nextInt( 16 ) + 8; final int x = rand.nextInt( 16 ) + 8;
final int z = rand.nextInt( 16 ) + 8; final int z = rand.nextInt( 16 ) + 8;
@ -85,7 +86,7 @@ public class WGFlora
private void tryGeneratePlant( final World worldIn , final Random rand , BlockPos position , private void tryGeneratePlant( final World worldIn , final Random rand , BlockPos position ,
final WGFloraParameters parameters ) final I_FloraParameters parameters )
{ {
IBlockState bs = worldIn.getBlockState( position ); IBlockState bs = worldIn.getBlockState( position );
while ( ( bs.getBlock( ).isAir( bs , worldIn , position ) while ( ( bs.getBlock( ).isAir( bs , worldIn , position )
@ -94,13 +95,14 @@ public class WGFlora
bs = worldIn.getBlockState( position ); bs = worldIn.getBlockState( position );
} }
for ( int i = 0 ; i < 128 ; ++i ) { final int attempts = parameters.getPlacementAttempts( worldIn , position , rand );
for ( int i = 0 ; i < attempts ; ++i ) {
final BlockPos blockpos = position.add( // final BlockPos blockpos = position.add( //
rand.nextInt( 8 ) - rand.nextInt( 8 ) , // rand.nextInt( 8 ) - rand.nextInt( 8 ) , //
rand.nextInt( 4 ) - rand.nextInt( 4 ) , // rand.nextInt( 4 ) - rand.nextInt( 4 ) , //
rand.nextInt( 8 ) - rand.nextInt( 8 ) ); rand.nextInt( 8 ) - rand.nextInt( 8 ) );
if ( parameters.placementCheck.test( worldIn , blockpos ) ) { if ( parameters.canPlace( worldIn , blockpos , rand ) ) {
worldIn.setBlockState( blockpos , parameters.floraType , 2 ); worldIn.setBlockState( blockpos , parameters.getBlockState( worldIn , blockpos , rand ) , 2 );
break; break;
} }
} }

View file

@ -1,19 +1,23 @@
package mmm.world.gen; package mmm.world.gen;
import java.util.Random;
import java.util.function.BiPredicate; import java.util.function.BiPredicate;
import mmm.core.api.world.I_FloraParameters;
import mmm.core.api.world.I_LocationCheck; import mmm.core.api.world.I_LocationCheck;
import mmm.world.WLocation; import mmm.world.WLocation;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockBush; import net.minecraft.block.BlockBush;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World; import net.minecraft.world.World;
public class WGFloraParameters public class WGFloraParameters
implements I_FloraParameters
{ {
private static BiPredicate< World , BlockPos > getDefaultPlacementCheck( final IBlockState bs ) private static BiPredicate< World , BlockPos > getDefaultPlacementCheck( final IBlockState bs )
@ -26,31 +30,31 @@ public class WGFloraParameters
} }
public final IBlockState floraType; public final IBlockState floraType;
public final int perChunk; public final float perChunk;
public final I_LocationCheck location; public final I_LocationCheck location;
public final BiPredicate< World , BlockPos > placementCheck; public final BiPredicate< World , BlockPos > placementCheck;
public WGFloraParameters( final IBlockState floraType , final int perChunk ) public WGFloraParameters( final IBlockState floraType , final float perChunk )
{ {
this( floraType , perChunk , WLocation.anywhere( ) , WGFloraParameters.getDefaultPlacementCheck( floraType ) ); this( floraType , perChunk , WLocation.anywhere( ) , WGFloraParameters.getDefaultPlacementCheck( floraType ) );
} }
public WGFloraParameters( final IBlockState floraType , final int perChunk , public WGFloraParameters( final IBlockState floraType , final float perChunk ,
final BiPredicate< World , BlockPos > placementCheck ) final BiPredicate< World , BlockPos > placementCheck )
{ {
this( floraType , perChunk , WLocation.anywhere( ) , placementCheck ); this( floraType , perChunk , WLocation.anywhere( ) , placementCheck );
} }
public WGFloraParameters( final IBlockState floraType , final int perChunk , final I_LocationCheck location ) public WGFloraParameters( final IBlockState floraType , final float perChunk , final I_LocationCheck location )
{ {
this( floraType , perChunk , location , WGFloraParameters.getDefaultPlacementCheck( floraType ) ); this( floraType , perChunk , location , WGFloraParameters.getDefaultPlacementCheck( floraType ) );
} }
public WGFloraParameters( final IBlockState floraType , final int perChunk , final I_LocationCheck location , public WGFloraParameters( final IBlockState floraType , final float perChunk , final I_LocationCheck location ,
final BiPredicate< World , BlockPos > placementCheck ) final BiPredicate< World , BlockPos > placementCheck )
{ {
this.floraType = floraType; this.floraType = floraType;
@ -59,4 +63,44 @@ public class WGFloraParameters
this.placementCheck = placementCheck; this.placementCheck = placementCheck;
} }
@Override
public IBlockState getBlockState( final World world , final BlockPos pos , final Random random )
{
return this.floraType;
}
@Override
public boolean canPlaceInChunk( World world , BlockPos pos )
{
return this.location.checkLocation( world , pos.getX( ) >> 4 , pos.getZ( ) >> 4 , world.getChunkProvider( ) );
}
@Override
public int getAmountPerChunk( final World world , final BlockPos pos , final Random random )
{
int pc = MathHelper.floor_float( this.perChunk );
final float remainder = this.perChunk - pc;
if ( remainder != 0 && random.nextFloat( ) < remainder ) {
pc++;
}
return pc;
}
@Override
public int getPlacementAttempts( final World world , final BlockPos pos , final Random random )
{
return 128;
}
@Override
public boolean canPlace( final World world , final BlockPos pos , final Random random )
{
return this.placementCheck.test( world , pos );
}
} }