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 mmm.world.gen.WGFloraParameters;
import mmm.core.api.world.I_FloraParameters;
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 mmm.world.gen.WGFloraParameters;
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_RecipeRegistrar;
import mmm.core.api.blocks.I_StateMapperProvider;
import mmm.core.api.world.I_FloraParameters;
import mmm.utils.UMaths;
import mmm.world.WLocation;
import mmm.world.WLocationRainfall;
@ -419,18 +420,18 @@ public class PTomato
@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( )//
.and( new WLocationTemperature( 0.4f , 1f ) ) //
.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( )//
.and( new WLocationTemperature( 0.7f , 1f ) ) //
.and( new WLocationRainfall( 0.3f , 0.5f ) ) ) );
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( )//
.and( new WLocationTemperature( 0.8f , 0.9f ) ) //
.and( new WLocationRainfall( 0.4f , 0.5f ) ) ) );

View file

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

View file

@ -1,19 +1,23 @@
package mmm.world.gen;
import java.util.Random;
import java.util.function.BiPredicate;
import mmm.core.api.world.I_FloraParameters;
import mmm.core.api.world.I_LocationCheck;
import mmm.world.WLocation;
import net.minecraft.block.Block;
import net.minecraft.block.BlockBush;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
public class WGFloraParameters
implements I_FloraParameters
{
private static BiPredicate< World , BlockPos > getDefaultPlacementCheck( final IBlockState bs )
@ -26,31 +30,31 @@ public class WGFloraParameters
}
public final IBlockState floraType;
public final int perChunk;
public final float perChunk;
public final I_LocationCheck location;
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 ) );
}
public WGFloraParameters( final IBlockState floraType , final int perChunk ,
public WGFloraParameters( final IBlockState floraType , final float perChunk ,
final BiPredicate< World , BlockPos > 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 ) );
}
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 )
{
this.floraType = floraType;
@ -59,4 +63,44 @@ public class WGFloraParameters
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 );
}
}