diff --git a/src/java/mmm/materials/MQuicksand.java b/src/java/mmm/materials/MQuicksand.java index 837d200..5ade103 100644 --- a/src/java/mmm/materials/MQuicksand.java +++ b/src/java/mmm/materials/MQuicksand.java @@ -1,6 +1,7 @@ package mmm.materials; +import mmm.utils.I_UTrapBlock; import mmm.utils.URegistry; import net.minecraft.block.Block; import net.minecraft.block.BlockFalling; @@ -21,6 +22,7 @@ import net.minecraftforge.common.IPlantable; public class MQuicksand extends BlockFalling + implements I_UTrapBlock { public final IBlockState forType; @@ -36,6 +38,13 @@ public class MQuicksand } + @Override + public IBlockState getReplacedBlock( ) + { + return this.forType; + } + + @Override public MapColor getMapColor( IBlockState state ) { diff --git a/src/java/mmm/utils/I_UTrapBlock.java b/src/java/mmm/utils/I_UTrapBlock.java new file mode 100644 index 0000000..a7c2d4b --- /dev/null +++ b/src/java/mmm/utils/I_UTrapBlock.java @@ -0,0 +1,13 @@ +package mmm.utils; + + +import net.minecraft.block.state.IBlockState; + + + +public interface I_UTrapBlock +{ + + public IBlockState getReplacedBlock( ); + +} diff --git a/src/java/mmm/utils/URegistry.java b/src/java/mmm/utils/URegistry.java index 062157e..c0a4a06 100644 --- a/src/java/mmm/utils/URegistry.java +++ b/src/java/mmm/utils/URegistry.java @@ -156,6 +156,9 @@ public class URegistry URegistry.addRecipeRegistrar( block ); URegistry.addOreGenerationRegistrar( block ); + if ( block instanceof I_UTrapBlock ) { + UTrapBlocks.INSTANCE.register( (I_UTrapBlock) block ); + } if ( blockItem != null ) { URegistry.addItem( blockItem , registerItemModel ); diff --git a/src/java/mmm/utils/UTrapBlocks.java b/src/java/mmm/utils/UTrapBlocks.java new file mode 100644 index 0000000..bbb71cd --- /dev/null +++ b/src/java/mmm/utils/UTrapBlocks.java @@ -0,0 +1,30 @@ +package mmm.utils; + + +import java.util.List; + +import com.google.common.collect.ArrayListMultimap; + +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; + + + +public enum UTrapBlocks { + INSTANCE; + + private final ArrayListMultimap< IBlockState , IBlockState > replacements = ArrayListMultimap.create( ); + + + public void register( final I_UTrapBlock block ) + { + this.replacements.put( block.getReplacedBlock( ) , ( (Block) block ).getDefaultState( ) ); + } + + + public List< IBlockState > getReplacements( final IBlockState blockState ) + { + return this.replacements.get( blockState ); + } + +} diff --git a/src/java/mmm/world/WDefaultGenWatcher.java b/src/java/mmm/world/WDefaultGenWatcher.java index 39cf69c..465633e 100644 --- a/src/java/mmm/world/WDefaultGenWatcher.java +++ b/src/java/mmm/world/WDefaultGenWatcher.java @@ -1,8 +1,12 @@ package mmm.world; +import mmm.world.biome.I_WBTrappedBiome; +import mmm.world.gen.WGTrapBlocks; import net.minecraft.util.math.BlockPos; import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.BiomeDesert; +import net.minecraft.world.biome.BiomeSwamp; import net.minecraftforge.event.terraingen.PopulateChunkEvent; import net.minecraftforge.fml.common.eventhandler.Event.Result; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -23,4 +27,31 @@ public class WDefaultGenWatcher } } + + @SubscribeEvent + public void afterPopulate( final PopulateChunkEvent.Post event ) + { + if ( event.isHasVillageGenerated( ) ) { + return; + } + + final BlockPos bp = new BlockPos( event.getChunkX( ) * 16 , 0 , event.getChunkZ( ) * 16 ); + final net.minecraft.world.World world = event.getWorld( ); + final Biome biome = world.getBiomeGenForCoords( bp ); + // FIXME hardcoding is bad + + final WGTrapBlocks traps; + if ( biome instanceof BiomeDesert ) { + traps = new WGTrapBlocks( false , .05f ); + } else if ( biome instanceof BiomeSwamp ) { + traps = new WGTrapBlocks( false , .1f ); + } else if ( biome instanceof I_WBTrappedBiome ) { + traps = new WGTrapBlocks( false , ( (I_WBTrappedBiome) biome ).getTrapBlockChance( ) ); + } else { + return; + } + + traps.generate( world , event.getRand( ) , bp ); + } + } diff --git a/src/java/mmm/world/World.java b/src/java/mmm/world/World.java index d45bff6..d914af3 100644 --- a/src/java/mmm/world/World.java +++ b/src/java/mmm/world/World.java @@ -21,7 +21,10 @@ public class World { static { - MinecraftForge.TERRAIN_GEN_BUS.register( new WDefaultGenWatcher( ) ); + WDefaultGenWatcher dgw = new WDefaultGenWatcher( ); + MinecraftForge.TERRAIN_GEN_BUS.register( dgw ); + MinecraftForge.EVENT_BUS.register( dgw ); + WBiomeHelper helper; helper = new WBiomeHelper( WBLimestoneMountains::new ); @@ -71,7 +74,7 @@ public class World .setElevation( -.2f , .1f ) // .setWeather( .95f , .95f ) // .setWaterColor( 0xe0ffae ) // Same as vanilla swamps - .setType( BiomeType.WARM , 40 ) // FIXME + .setType( BiomeType.WARM , 3 ) // .register( ); } diff --git a/src/java/mmm/world/biome/I_WBTrappedBiome.java b/src/java/mmm/world/biome/I_WBTrappedBiome.java new file mode 100644 index 0000000..ccd86ca --- /dev/null +++ b/src/java/mmm/world/biome/I_WBTrappedBiome.java @@ -0,0 +1,7 @@ +package mmm.world.biome; + + +public interface I_WBTrappedBiome +{ + public float getTrapBlockChance( ); +} diff --git a/src/java/mmm/world/gen/WGTrapBlocks.java b/src/java/mmm/world/gen/WGTrapBlocks.java new file mode 100644 index 0000000..805d1c1 --- /dev/null +++ b/src/java/mmm/world/gen/WGTrapBlocks.java @@ -0,0 +1,100 @@ +package mmm.world.gen; + + +import java.util.List; +import java.util.Random; + +import mmm.utils.UTrapBlocks; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; + + + +public class WGTrapBlocks + extends WorldGenerator +{ + + private final float chance; + + + public WGTrapBlocks( final boolean notify , final float chance ) + { + super( notify ); + this.chance = chance; + } + + + @Override + public boolean generate( final World worldIn , final Random rand , final BlockPos position ) + { + if ( rand.nextFloat( ) > this.chance ) { + return false; + } + + // Select radius and centre + final int radius = 2 + rand.nextInt( 2 ); + final int space = 16 - radius * 2; + final BlockPos.MutableBlockPos check = new BlockPos.MutableBlockPos( + position.getX( ) + radius + rand.nextInt( space ) , // + 255 , // + position.getZ( ) + radius + rand.nextInt( space ) ); + + // Find the ground + final int minDepth = Math.max( 0 , worldIn.getSeaLevel( ) - 20 ); + boolean found = false; + while ( check.getY( ) > minDepth ) { + final Material material = worldIn.getBlockState( check ).getMaterial( ); + if ( material.isLiquid( ) ) { + return false; + } + if ( material != Material.AIR ) { + found = true; + break; + } + check.setY( check.getY( ) - 1 ); + } + if ( !found ) { + return false; + } + + // Displace the centre vertically + if ( check.getY( ) > radius / 2 && check.getY( ) < 255 - radius / 2 ) { + check.setY( check.getY( ) - radius / 2 + rand.nextInt( radius ) ); + } + + // Replace blocks + BlockPos bp = new BlockPos( check ); + int sqr = radius * radius; + for ( int x = -radius ; x <= radius ; x++ ) { + for ( int y = -radius ; y <= radius ; y++ ) { + for ( int z = -radius ; z <= radius ; z++ ) { + if ( x * x + y * y + z * z > sqr + rand.nextInt( 2 ) ) { + continue; + } + + final BlockPos pos = bp.add( x , y , z ); + final IBlockState atPos = worldIn.getBlockState( pos ); + final List< IBlockState > replacements = UTrapBlocks.INSTANCE.getReplacements( atPos ); + final int nReplacements = replacements.size( ); + if ( nReplacements == 0 ) { + continue; + } + + int repIndex; + if ( nReplacements == 1 ) { + repIndex = 0; + } else { + repIndex = rand.nextInt( nReplacements ); + } + this.setBlockAndNotifyAdequately( worldIn , pos , replacements.get( repIndex ) ); + } + } + } + + return true; + } + +}