Ore generation framework (ish)

+ copper ore generation, obviously
This commit is contained in:
Emmanuel BENOîT 2016-06-16 11:34:13 +02:00
parent a43b2730d3
commit 595d622c17
14 changed files with 436 additions and 24 deletions

View file

@ -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 );

View file

@ -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;
}
}

View file

@ -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
}
}

View file

@ -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 ) ) );
}
}

View file

@ -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( );
}
}

View file

@ -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 );
}

View file

@ -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 ) {

View file

@ -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 );
}
};
}
}

View file

@ -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 );
}
}

View file

@ -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( ) );
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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 );
}
}
}

View file

@ -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 );
}
}
}
}