package com.arkcraft.module.core.common.gen.ore; import net.minecraft.block.Block; import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; import net.minecraft.world.World; import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.gen.feature.WorldGenMinable; import net.minecraftforge.fml.common.IWorldGenerator; import net.minecraftforge.fml.common.registry.GameRegistry; import java.util.HashMap; import java.util.Map; import java.util.Random; public class WrappedOreGenerator implements IWorldGenerator { public static class Instruction { private Block blockType; private int maxHeight = 64; private int blocksPerVein = 7; private int veinsPerChunk = 10; private int[] dimensions = new int[] {}; private boolean overworld = true; private boolean nether = false; private boolean end = false; private boolean enabled = true; /** * Create a new generation instructions for the generator. * * @param par1 the block type to use when generating. * @param par2 the maximum height the blocks will appear on (64 is surface). * @param par3 the maximum amount of blocks that can be generated in a vein. * @param par4 the amount of veins to generate in each chunk. */ public Instruction(Block par1, int par2, int par3, int par4) { this.blockType = par1; this.maxHeight = par2; this.blocksPerVein = par3; this.veinsPerChunk = par4; } /** * Set whether this instruction should be ran when the world generation starts.<br> * Set to false if you want the instruction to be ignored by the wrapper. * * @param par1 the value. */ public final void setEnabled(boolean par1) { this.enabled = par1; } /** * Returns the dimensions to run this instruction on. Just set to <b>null</b>.<br> * if you don't have any additional dimension to generate on. * * @return the dimensions. */ public final int[] getDimensions() { return this.dimensions; } /** * Set the dimensions to run this instruction on. * * @param par1 an {@link #Integer} array representing the dimension id's to run. * @return the Instruction for construction conveniences. */ public final Instruction setDimensions(int[] par1) { this.dimensions = par1; return this; } /** * Allow the block to generate in the overworld (0). * * @param par1 true/false. * @return the Instruction for structuring convenience. */ public final Instruction setOverworld(boolean par1) { this.overworld = par1; return this; } /** * Allow the block to generate in the nether (-1). * * @param par1 true/false. * @return the Instruction for structuring convenience. */ public final Instruction setNether(boolean par1) { this.nether = par1; return this; } /** * Allow the block to generate in the nether (1). * * @param par1 true/false. * @return the Instruction for structuring convenience. */ public final Instruction setEnd(boolean par1) { this.end = par1; return this; } /** * Whether this generator instruction is enabled. * * @return if the instruction is enabled. */ public final boolean isEnabled() { return this.enabled; } /** * Returns the block type to use when generating. * * @return the block type. */ public final Block getBlockType() { return this.blockType; } /** * The maximum height that the block can be generated on. * * @return the max height. */ public final int getMaxHeight() { return this.maxHeight; } /** * The maximum amount of blocks that can be generated in every vein. * * @return the amount of blocks per vein. */ public final int getBlocksPerVein() { return this.blocksPerVein; } /** * The amount of veins to generate in each chunk. * * @return the amount of veins per chunk. */ public final int getVeinsPerChunk() { return this.veinsPerChunk; } } private Map<String, Instruction> generations = new HashMap<String, Instruction>(); public WrappedOreGenerator(int par1, Instruction... par2) { GameRegistry.registerWorldGenerator(this, par1); for (Instruction var : par2) { if (var.getBlocksPerVein() > 0 && var.getVeinsPerChunk() > 0 && var.getMaxHeight() > 0) { generations.put(var.getBlockType().getUnlocalizedName(), var); } } } protected Block[] getValidSpawnBlocks() { Block[] validSpawnBlocks = { Blocks.grass, Blocks.gravel, Blocks.sand, Blocks.stone }; return validSpawnBlocks; } public boolean isValidSpawn(World world, int x, int y, int z) { int distanceToAir = 0; BlockPos pos = new BlockPos(x, y, z); Block check = world.getBlockState(pos).getBlock(); while (check != Blocks.air) { if (distanceToAir > 3) { return false; } distanceToAir++; check = world.getBlockState(new BlockPos(x, y - distanceToAir, z)).getBlock(); } y += distanceToAir - 1; Block block = world.getBlockState(pos).getBlock(); Block above = world.getBlockState(new BlockPos(x, y + 1, z)).getBlock(); Block below = world.getBlockState(new BlockPos(x, y - 1, z)).getBlock(); for (Block b : getValidSpawnBlocks()) { if (above != Blocks.air) { return false; } if (block == b) { return true; } else if (block == Blocks.snow && below == b) { return true; } } return false; } @Override public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) { for (Instruction var : this.generations.values()) { int var1 = world.provider.getDimensionId(); if (var1 == -1) { if (var.nether) { generateInNether(var, world, random, chunkX * 16, chunkZ * 16); } } else if (var1 == 0) { if (var.overworld) { generateInOverworld(var, world, random, chunkX * 16, chunkZ * 16); } } else if (var1 == 1) { if (var.end) { generateInEnd(var, world, random, chunkX * 16, chunkZ * 16); } } else { for (int v : var.getDimensions()) { if (var1 == v) { this.generateInDimension(var, world, random, chunkX * 16, chunkZ * 16); } } } } } private void generateInDimension(Instruction par1, World world, Random random, int x, int z) { for (int k = 0; k < par1.getVeinsPerChunk(); k++) { int chunkX = x + random.nextInt(16); int chunkY = random.nextInt(par1.getMaxHeight()); int chunkZ = z + random.nextInt(16); new WorldGenMinable(par1.getBlockType().getDefaultState(), par1.getBlocksPerVein()).generate(world, random, new BlockPos(chunkX, chunkY, chunkZ)); } } private void generateInEnd(Instruction par1, World world, Random random, int x, int z) { for (int k = 0; k < par1.getVeinsPerChunk(); k++) { int chunkX = x + random.nextInt(16); int chunkY = random.nextInt(par1.getMaxHeight()); int chunkZ = z + random.nextInt(16); new WorldGenMinable(par1.getBlockType().getDefaultState(), par1.getBlocksPerVein()).generate(world, random, new BlockPos(chunkX, chunkY, chunkZ)); } } private void generateInOverworld(Instruction par1, World world, Random random, int x, int z) { for (int k = 0; k < par1.getVeinsPerChunk(); k++) { int chunkX = x + random.nextInt(16); int chunkY = random.nextInt(par1.getMaxHeight()); int chunkZ = z + random.nextInt(16); //TODO Implement the below if() statement //if(world.getBlockState(instruction.getBlockType() == GlobalAdditions.surfaceCrystals)) { if (!isValidSpawn(world, chunkX, chunkY, chunkZ)) { return; } //} new WorldGenMinable(par1.getBlockType().getDefaultState(), par1.getBlocksPerVein()).generate(world, random, new BlockPos(chunkX, chunkY, chunkZ)); } } private void generateInNether(Instruction par1, World world, Random random, int x, int z) { for (int k = 0; k < par1.getVeinsPerChunk(); k++) { int chunkX = x + random.nextInt(16); int chunkY = random.nextInt(par1.getMaxHeight()); int chunkZ = z + random.nextInt(16); new WorldGenMinable(par1.getBlockType().getDefaultState(), par1.getBlocksPerVein()).generate(world, random, new BlockPos(chunkX, chunkY, chunkZ)); } } }