From 595d622c171d0148d3923dffffaa0f961cc9db8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Thu, 16 Jun 2016 11:34:13 +0200 Subject: [PATCH] Ore generation framework (ish) + copper ore generation, obviously --- src/java/mmm/materials/MMetal.java | 22 +++- src/java/mmm/materials/MOre.java | 22 ++-- src/java/mmm/materials/Materials.java | 15 +-- src/java/mmm/materials/ore/MOCopper.java | 36 ++++++ src/java/mmm/proxy/PCommon.java | 2 + .../mmm/utils/I_UOreGenerationRegistrar.java | 15 +++ src/java/mmm/utils/URegistry.java | 21 +++- src/java/mmm/world/I_WLocationCheck.java | 58 ++++++++++ src/java/mmm/world/WLocation.java | 32 ++++++ src/java/mmm/world/WLocationInBiome.java | 31 +++++ src/java/mmm/world/WLocationInDimension.java | 29 +++++ .../mmm/world/WOreGenerationCondition.java | 17 +++ .../mmm/world/WOreGenerationParameters.java | 108 ++++++++++++++++++ src/java/mmm/world/WOreGenerator.java | 52 +++++++++ 14 files changed, 436 insertions(+), 24 deletions(-) create mode 100644 src/java/mmm/materials/ore/MOCopper.java create mode 100644 src/java/mmm/utils/I_UOreGenerationRegistrar.java create mode 100644 src/java/mmm/world/I_WLocationCheck.java create mode 100644 src/java/mmm/world/WLocation.java create mode 100644 src/java/mmm/world/WLocationInBiome.java create mode 100644 src/java/mmm/world/WLocationInDimension.java create mode 100644 src/java/mmm/world/WOreGenerationCondition.java create mode 100644 src/java/mmm/world/WOreGenerationParameters.java create mode 100644 src/java/mmm/world/WOreGenerator.java diff --git a/src/java/mmm/materials/MMetal.java b/src/java/mmm/materials/MMetal.java index ab960df..c342b9f 100644 --- a/src/java/mmm/materials/MMetal.java +++ b/src/java/mmm/materials/MMetal.java @@ -13,25 +13,35 @@ public class MMetal implements I_URecipeRegistrar { + public final float SMELTING_XP; public final Item INGOT; public final Item NUGGET; - public MMetal( final String name ) + public MMetal( final String name , float baseSmeltingXP ) { - this.INGOT = new MMetalItem( E_MMetalItemType.INGOT , name ); - this.NUGGET = new MMetalItem( E_MMetalItemType.NUGGET , name ); + this( baseSmeltingXP , // + new MMetalItem( E_MMetalItemType.INGOT , name ) , // + new MMetalItem( E_MMetalItemType.NUGGET , name ) ); } public MMetal( final Item ingot , final Item nugget ) { - this.INGOT = ingot; - this.NUGGET = nugget; + this( 0 , ingot , nugget ); } - public MMetal register( ) + protected MMetal( float baseSmeltingXP , Item ingot , Item nugget ) + { + SMELTING_XP = baseSmeltingXP; + INGOT = ingot; + NUGGET = nugget; + this.register( ); + } + + + protected MMetal register( ) { if ( this.INGOT instanceof MMetalItem ) { URegistry.addItem( this.INGOT ); diff --git a/src/java/mmm/materials/MOre.java b/src/java/mmm/materials/MOre.java index 45b3a0d..7520cd6 100644 --- a/src/java/mmm/materials/MOre.java +++ b/src/java/mmm/materials/MOre.java @@ -34,7 +34,7 @@ public class MOre private int expMin , expMax; private MMetal metal; - private float smeltingXP; + private int genIngots; public MOre( final String name , final int harvestLevel ) @@ -55,7 +55,7 @@ public class MOre this.dropMin = this.dropMax = 1; this.expMin = this.expMax = 0; this.metal = null; - this.smeltingXP = 0; + this.genIngots = 0; } @@ -105,10 +105,17 @@ public class MOre } - public MOre setMetal( final MMetal metal , final float smeltingXP ) + public MOre setMetal( final MMetal metal ) { + return this.setMetal( metal , 1 ); + } + + + public MOre setMetal( final MMetal metal , final int ingots ) + { + assert metal != null && ingots > 0; this.metal = metal; - this.smeltingXP = smeltingXP; + this.genIngots = ingots; return this; } @@ -174,12 +181,13 @@ public class MOre public void registerRecipes( ) { if ( this.metal != null ) { + ItemStack output = new ItemStack( this.metal.INGOT , 0 , this.genIngots ); + float xp = this.metal.SMELTING_XP * this.genIngots; if ( this.dropItems == null ) { - GameRegistry.addSmelting( this , new ItemStack( this.metal.INGOT ) , this.smeltingXP ); + GameRegistry.addSmelting( this , output , xp ); } else { - GameRegistry.addSmelting( this.dropItems , new ItemStack( this.metal.INGOT ) , this.smeltingXP ); + GameRegistry.addSmelting( this.dropItems , output , xp ); } - this.metal = null; } } diff --git a/src/java/mmm/materials/Materials.java b/src/java/mmm/materials/Materials.java index 3f98463..117c4ba 100644 --- a/src/java/mmm/materials/Materials.java +++ b/src/java/mmm/materials/Materials.java @@ -1,6 +1,7 @@ package mmm.materials; +import mmm.materials.ore.MOCopper; import mmm.utils.URegistry; import net.minecraft.init.Items; @@ -15,11 +16,11 @@ public class Materials public static final MOre ORE_COPPER; static { - GOLD = new MMetal( Items.GOLD_INGOT , Items.GOLD_NUGGET ).register( ); - IRON = new MMetal( Items.IRON_INGOT , new MMetalItem( E_MMetalItemType.NUGGET , "iron" ) ).register( ); - COPPER = new MMetal( "copper" ).register( ); + GOLD = new MMetal( Items.GOLD_INGOT , Items.GOLD_NUGGET ); + IRON = new MMetal( Items.IRON_INGOT , new MMetalItem( E_MMetalItemType.NUGGET , "iron" ) ); + COPPER = new MMetal( "copper" , 0.4f ); - URegistry.addBlock( ORE_COPPER = new MOre( "copper" , 1 ).setMetal( COPPER , 0.4f ) ); + URegistry.addBlock( ORE_COPPER = new MOCopper( ) ); } @@ -28,10 +29,4 @@ public class Materials // EMPTY } - - private Materials( ) - { - // EMPTY - } - } diff --git a/src/java/mmm/materials/ore/MOCopper.java b/src/java/mmm/materials/ore/MOCopper.java new file mode 100644 index 0000000..fbca57c --- /dev/null +++ b/src/java/mmm/materials/ore/MOCopper.java @@ -0,0 +1,36 @@ +package mmm.materials.ore; + + +import java.util.List; + +import mmm.materials.MOre; +import mmm.materials.Materials; +import mmm.utils.I_UOreGenerationRegistrar; +import mmm.world.WLocation; +import mmm.world.WOreGenerationCondition; +import mmm.world.WOreGenerationParameters; + + + +public class MOCopper + extends MOre + implements I_UOreGenerationRegistrar +{ + + public MOCopper( ) + { + super( "copper" , 1 ); + this.setMetal( Materials.COPPER ); + } + + + @Override + public void addConditions( List< WOreGenerationCondition > conditions ) + { + conditions.add( new WOreGenerationCondition( WLocation.inOverworld( ) , + new WOreGenerationParameters( this.getDefaultState( ) , 20 , 9 , 0 , 128 ) ) ); + conditions.add( new WOreGenerationCondition( WLocation.inOverworld( ) , + new WOreGenerationParameters( this.getDefaultState( ) , 10 , 17 , 40 , 60 ) ) ); + } + +} diff --git a/src/java/mmm/proxy/PCommon.java b/src/java/mmm/proxy/PCommon.java index d745e78..284f8cd 100644 --- a/src/java/mmm/proxy/PCommon.java +++ b/src/java/mmm/proxy/PCommon.java @@ -7,6 +7,7 @@ import mmm.materials.Materials; import mmm.utils.UAccessors; import mmm.utils.URegistry; import mmm.utils.USeat; +import mmm.world.WOreGenerator; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; @@ -29,5 +30,6 @@ public abstract class PCommon public void init( final FMLInitializationEvent event ) { USeat.register( Mmm.get( ) ); + WOreGenerator.init( ); } } \ No newline at end of file diff --git a/src/java/mmm/utils/I_UOreGenerationRegistrar.java b/src/java/mmm/utils/I_UOreGenerationRegistrar.java new file mode 100644 index 0000000..c7b737a --- /dev/null +++ b/src/java/mmm/utils/I_UOreGenerationRegistrar.java @@ -0,0 +1,15 @@ +package mmm.utils; + + +import java.util.List; + +import mmm.world.WOreGenerationCondition; + + + +public interface I_UOreGenerationRegistrar +{ + + public void addConditions( List< WOreGenerationCondition > conditions ); + +} diff --git a/src/java/mmm/utils/URegistry.java b/src/java/mmm/utils/URegistry.java index a6dd2f3..d1f8db3 100644 --- a/src/java/mmm/utils/URegistry.java +++ b/src/java/mmm/utils/URegistry.java @@ -1,6 +1,8 @@ package mmm.utils; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -20,7 +22,8 @@ import net.minecraftforge.fml.common.registry.IForgeRegistryEntry; public class URegistry { - private static final HashSet< I_URecipeRegistrar > RECIPE_REGISTRARS = new HashSet< I_URecipeRegistrar >( ); + private static final HashSet< I_URecipeRegistrar > RECIPE_REGISTRARS = new HashSet<>( ); + private static final HashSet< I_UOreGenerationRegistrar > ORE_GEN_REGISTRARS = new HashSet<>( ); private static final HashMap< Item , Boolean > ITEMS = new HashMap< Item , Boolean >( ); private static final HashSet< Block > BLOCKS = new HashSet< Block >( ); @@ -94,6 +97,8 @@ public class URegistry GameRegistry.register( block ); URegistry.BLOCKS.add( block ); URegistry.addRecipeRegistrar( block ); + URegistry.addOreGenerationRegistrar( block ); + if ( blockItem != null ) { URegistry.addItem( blockItem , registerItemModel ); } @@ -108,6 +113,20 @@ public class URegistry } + public static void addOreGenerationRegistrar( final Object object ) + { + if ( object instanceof I_UOreGenerationRegistrar ) { + URegistry.ORE_GEN_REGISTRARS.add( (I_UOreGenerationRegistrar) object ); + } + } + + + public static Collection< I_UOreGenerationRegistrar > getOreGenerationRegistrars( ) + { + return Collections.unmodifiableCollection( URegistry.ORE_GEN_REGISTRARS ); + } + + public static void registerRecipes( ) { for ( final I_URecipeRegistrar registrar : URegistry.RECIPE_REGISTRARS ) { diff --git a/src/java/mmm/world/I_WLocationCheck.java b/src/java/mmm/world/I_WLocationCheck.java new file mode 100644 index 0000000..ef375dd --- /dev/null +++ b/src/java/mmm/world/I_WLocationCheck.java @@ -0,0 +1,58 @@ +package mmm.world; + + +import net.minecraft.world.World; +import net.minecraft.world.chunk.IChunkProvider; + + + +public interface I_WLocationCheck +{ + + public boolean checkLocation( World world , int chunkX , int chunkZ , IChunkProvider provider ); + + + default I_WLocationCheck and( final I_WLocationCheck other ) + { + final I_WLocationCheck self = this; + return new I_WLocationCheck( ) { + @Override + public boolean checkLocation( final World world , final int chunkX , final int chunkZ , + final IChunkProvider provider ) + { + return self.checkLocation( world , chunkX , chunkZ , provider ) + && other.checkLocation( world , chunkX , chunkZ , provider ); + } + }; + } + + + default I_WLocationCheck or( final I_WLocationCheck other ) + { + final I_WLocationCheck self = this; + return new I_WLocationCheck( ) { + @Override + public boolean checkLocation( final World world , final int chunkX , final int chunkZ , + final IChunkProvider provider ) + { + return self.checkLocation( world , chunkX , chunkZ , provider ) + || other.checkLocation( world , chunkX , chunkZ , provider ); + } + }; + } + + + default I_WLocationCheck invert( ) + { + final I_WLocationCheck self = this; + return new I_WLocationCheck( ) { + @Override + public boolean checkLocation( final World world , final int chunkX , final int chunkZ , + final IChunkProvider provider ) + { + return !self.checkLocation( world , chunkX , chunkZ , provider ); + } + }; + } + +} diff --git a/src/java/mmm/world/WLocation.java b/src/java/mmm/world/WLocation.java new file mode 100644 index 0000000..e945562 --- /dev/null +++ b/src/java/mmm/world/WLocation.java @@ -0,0 +1,32 @@ +package mmm.world; + + +import net.minecraft.world.biome.Biome; + + + +public class WLocation +{ + private static I_WLocationCheck inOverworld; + + + public static I_WLocationCheck inDimension( final int dimension ) + { + return new WLocationInDimension( dimension ); + } + + + public static I_WLocationCheck inOverworld( ) + { + if ( WLocation.inOverworld == null ) { + WLocation.inOverworld = WLocation.inDimension( 0 ); + } + return WLocation.inOverworld; + } + + + public static < T extends Biome > WLocationInBiome< T > inBiome( final Class< T > biomeType ) + { + return new WLocationInBiome<>( biomeType ); + } +} diff --git a/src/java/mmm/world/WLocationInBiome.java b/src/java/mmm/world/WLocationInBiome.java new file mode 100644 index 0000000..65f9400 --- /dev/null +++ b/src/java/mmm/world/WLocationInBiome.java @@ -0,0 +1,31 @@ +package mmm.world; + + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.chunk.IChunkProvider; + + + +public class WLocationInBiome< T extends Biome > + implements I_WLocationCheck +{ + public final Class< T > biomeType; + + + public WLocationInBiome( final Class< T > biomeType ) + { + this.biomeType = biomeType; + } + + + @Override + public boolean checkLocation( final World world , final int chunkX , final int chunkZ , + final IChunkProvider provider ) + { + final Biome biome = world.getBiomeGenForCoords( new BlockPos( chunkX , 0 , chunkZ ) ); + return this.biomeType.isAssignableFrom( biome.getClass( ) ); + } + +} diff --git a/src/java/mmm/world/WLocationInDimension.java b/src/java/mmm/world/WLocationInDimension.java new file mode 100644 index 0000000..098ac23 --- /dev/null +++ b/src/java/mmm/world/WLocationInDimension.java @@ -0,0 +1,29 @@ +package mmm.world; + + +import net.minecraft.world.World; +import net.minecraft.world.chunk.IChunkProvider; + + + +public class WLocationInDimension + implements I_WLocationCheck +{ + + public final int dimension; + + + public WLocationInDimension( final int dimension ) + { + this.dimension = dimension; + } + + + @Override + public boolean checkLocation( final World world , final int chunkX , final int chunkZ , + final IChunkProvider provider ) + { + return world.provider.getDimension( ) == this.dimension; + } + +} diff --git a/src/java/mmm/world/WOreGenerationCondition.java b/src/java/mmm/world/WOreGenerationCondition.java new file mode 100644 index 0000000..889ea1c --- /dev/null +++ b/src/java/mmm/world/WOreGenerationCondition.java @@ -0,0 +1,17 @@ +package mmm.world; + + +public class WOreGenerationCondition +{ + + public final I_WLocationCheck conditions; + public final WOreGenerationParameters parameters; + + + public WOreGenerationCondition( final I_WLocationCheck conditions , final WOreGenerationParameters parameters ) + { + this.conditions = conditions; + this.parameters = parameters; + } + +} diff --git a/src/java/mmm/world/WOreGenerationParameters.java b/src/java/mmm/world/WOreGenerationParameters.java new file mode 100644 index 0000000..5c698a9 --- /dev/null +++ b/src/java/mmm/world/WOreGenerationParameters.java @@ -0,0 +1,108 @@ +package mmm.world; + + +import java.util.Random; + +import com.google.common.base.Predicate; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.block.state.pattern.BlockMatcher; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenMinable; + + + +public class WOreGenerationParameters +{ + + public final IBlockState ore; + public final int clusters; + public final int clusterSize; + public final int minHeight; + public final int maxHeight; + public Predicate< IBlockState > matcher; + + private WorldGenMinable generator; + + + public WOreGenerationParameters( final IBlockState ore , final int clusters , final int clusterSize ) + { + this( ore , clusters , clusterSize , Integer.MIN_VALUE , Integer.MIN_VALUE , + BlockMatcher.forBlock( Blocks.STONE ) ); + } + + + public WOreGenerationParameters( final IBlockState ore , final int clusters , final int clusterSize , + final int minHeight , final int maxHeight ) + { + this( ore , clusters , clusterSize , minHeight , maxHeight , BlockMatcher.forBlock( Blocks.STONE ) ); + } + + + public WOreGenerationParameters( final IBlockState ore , final int clusters , final int clusterSize , + final Predicate< IBlockState > matcher ) + { + this( ore , clusters , clusterSize , Integer.MIN_VALUE , Integer.MIN_VALUE , matcher ); + } + + + public WOreGenerationParameters( final IBlockState ore , final int clusters , final int clusterSize , + int minHeight , int maxHeight , final Predicate< IBlockState > matcher ) + { + if ( clusters < 1 ) { + throw new IllegalArgumentException( "cluster count should be at least 1" ); + } + if ( clusterSize < 1 ) { + throw new IllegalArgumentException( "cluster size should be at least 1" ); + } + + if ( minHeight != Integer.MIN_VALUE || maxHeight != Integer.MIN_VALUE ) { + if ( minHeight > maxHeight ) { + throw new IllegalArgumentException( "min height should be <= max height" ); + } + if ( minHeight < 0 ) { + throw new IllegalArgumentException( "min height should be at least 0" ); + } + if ( maxHeight > 255 ) { + throw new IllegalArgumentException( "max height should be at most 255" ); + } + if ( maxHeight == minHeight ) { + if ( minHeight < 255 ) { + ++maxHeight; + } else { + --minHeight; + } + } + } else { + minHeight = 0; + maxHeight = 255; + } + + this.ore = ore; + this.clusters = clusters; + this.clusterSize = clusterSize; + this.minHeight = minHeight; + this.maxHeight = maxHeight; + this.matcher = matcher; + } + + + public void generate( final World worldIn , final Random random , final int chunkX , final int chunkZ ) + { + if ( this.generator == null ) { + this.generator = new WorldGenMinable( this.ore , this.clusterSize , this.matcher ); + } + + for ( int j = 0 ; j < this.clusters ; ++j ) { + final BlockPos blockpos = new BlockPos( // + chunkX * 16 + random.nextInt( 16 ) , // + MathHelper.getRandomIntegerInRange( random , this.minHeight , this.maxHeight ) , // + chunkZ * 16 + random.nextInt( 16 ) ); + this.generator.generate( worldIn , random , blockpos ); + } + } + +} diff --git a/src/java/mmm/world/WOreGenerator.java b/src/java/mmm/world/WOreGenerator.java new file mode 100644 index 0000000..e9fe92a --- /dev/null +++ b/src/java/mmm/world/WOreGenerator.java @@ -0,0 +1,52 @@ +package mmm.world; + + +import java.util.ArrayList; +import java.util.Random; + +import mmm.utils.I_UOreGenerationRegistrar; +import mmm.utils.URegistry; +import net.minecraft.world.World; +import net.minecraft.world.chunk.IChunkGenerator; +import net.minecraft.world.chunk.IChunkProvider; +import net.minecraftforge.fml.common.IWorldGenerator; +import net.minecraftforge.fml.common.registry.GameRegistry; + + + +public class WOreGenerator + implements IWorldGenerator +{ + + public static void init( ) + { + final ArrayList< WOreGenerationCondition > conditions = new ArrayList<>( ); + for ( final I_UOreGenerationRegistrar registrar : URegistry.getOreGenerationRegistrars( ) ) { + registrar.addConditions( conditions ); + } + GameRegistry.registerWorldGenerator( new WOreGenerator( conditions ) , 0 ); + } + + private final ArrayList< WOreGenerationCondition > conditions; + + + private WOreGenerator( final ArrayList< WOreGenerationCondition > conditions ) + { + this.conditions = conditions; + } + + + @Override + public void generate( final Random random , final int chunkX , final int chunkZ , final World world , + final IChunkGenerator chunkGenerator , final IChunkProvider chunkProvider ) + { + final int n = this.conditions.size( ); + for ( int i = 0 ; i < n ; i++ ) { + final WOreGenerationCondition cond = this.conditions.get( i ); + if ( cond.conditions.checkLocation( world , chunkX , chunkZ , chunkProvider ) ) { + cond.parameters.generate( world , random , chunkX , chunkZ ); + } + } + } + +}