diff --git a/magicbees_src/magicbees/block/types/HiveType.java b/magicbees_src/magicbees/block/types/HiveType.java index 8cc9481..1a0bed6 100644 --- a/magicbees_src/magicbees/block/types/HiveType.java +++ b/magicbees_src/magicbees/block/types/HiveType.java @@ -40,6 +40,7 @@ public enum HiveType private int lightLevel; private ArrayList drops; private ArrayList validBiomes; + private float[] spawnChance; @SideOnly(Side.CLIENT) private Icon[] icons; @@ -60,44 +61,44 @@ public enum HiveType ItemStack[] combs = new ItemStack[] {Config.combs.getStackForType(CombType.MUNDANE)}; HiveDrop valiantDrop = new HiveDrop(BeeGenomeManager.addRainResist(ForestryHelper.getTemplateForestryForSpecies("Valiant")), combs, 5); - CURIOUS.validBiomes.add(Type.FOREST); - CURIOUS.validBiomes.add(Type.JUNGLE); - CURIOUS.validBiomes.add(Type.HILLS); + CURIOUS.addSpawnBiome(Type.FOREST, 0.015F); + CURIOUS.addSpawnBiome(Type.JUNGLE, 0.01F); + CURIOUS.addSpawnBiome(Type.HILLS, 0.07F); CURIOUS.drops.add(new HiveDrop(BeeSpecies.MYSTICAL.getGenome(), combs, 80).setIgnoblePercentage(0.7f)); CURIOUS.drops.add(new HiveDrop(BeeGenomeManager.addRainResist(BeeSpecies.MYSTICAL.getGenome()), combs, 15)); CURIOUS.drops.add(valiantDrop); - UNUSUAL.validBiomes.add(Type.PLAINS); - UNUSUAL.validBiomes.add(Type.MOUNTAIN); - UNUSUAL.validBiomes.add(Type.HILLS); + UNUSUAL.addSpawnBiome(Type.PLAINS, 0.01F); + UNUSUAL.addSpawnBiome(Type.MOUNTAIN, 0.02F); + UNUSUAL.addSpawnBiome(Type.HILLS, 0.02F); UNUSUAL.drops.add(new HiveDrop(BeeSpecies.UNUSUAL.getGenome(), combs, 80).setIgnoblePercentage(0.7f)); UNUSUAL.drops.add(new HiveDrop(BeeGenomeManager.addRainResist(BeeSpecies.UNUSUAL.getGenome()), combs, 15)); UNUSUAL.drops.add(valiantDrop); - RESONANT.validBiomes.add(Type.DESERT); - RESONANT.validBiomes.add(Type.MAGICAL); + RESONANT.addSpawnBiome(Type.DESERT, 0.01F); + RESONANT.addSpawnBiome(Type.MAGICAL, 0.02F); RESONANT.drops.add(new HiveDrop(BeeSpecies.SORCEROUS.getGenome(), combs, 80).setIgnoblePercentage(0.7f)); RESONANT.drops.add(new HiveDrop(BeeGenomeManager.addRainResist(BeeSpecies.SORCEROUS.getGenome()), combs, 20)); RESONANT.drops.add(valiantDrop); - DEEP.validBiomes.add(Type.HILLS); - DEEP.validBiomes.add(Type.MOUNTAIN); - DEEP.validBiomes.add(Type.MAGICAL); + DEEP.addSpawnBiome(Type.HILLS, 0.01F); + DEEP.addSpawnBiome(Type.MOUNTAIN, 0.01F); + DEEP.addSpawnBiome(Type.MAGICAL, 0.02F); DEEP.drops.add(new HiveDrop(BeeSpecies.ATTUNED.getGenome(), combs, 80).setIgnoblePercentage(0.65f)); DEEP.drops.add(new HiveDrop(BeeGenomeManager.addRainResist(BeeSpecies.ATTUNED.getGenome()), combs, 20)); DEEP.drops.add(valiantDrop); combs = new ItemStack[] {Config.combs.getStackForType(CombType.MOLTEN), new ItemStack(Item.glowstone, 6)}; - INFERNAL.validBiomes.add(Type.NETHER); - INFERNAL.validBiomes.add(Type.MAGICAL); + INFERNAL.addSpawnBiome(Type.NETHER, 0.04F); + INFERNAL.addSpawnBiome(Type.MAGICAL, 0.007F); INFERNAL.drops.add(new HiveDrop(BeeSpecies.INFERNAL.getGenome(), combs, 80).setIgnoblePercentage(0.5f)); INFERNAL.drops.add(new HiveDrop(ForestryHelper.getTemplateForestryForSpecies("Steadfast"), combs, 3)); combs = new ItemStack[] {Config.combs.getStackForType(CombType.FORGOTTEN), new ItemStack(Item.enderPearl, 1)}; - OBLIVION.validBiomes.add(Type.END); - OBLIVION.validBiomes.add(Type.MAGICAL); + OBLIVION.addSpawnBiome(Type.END, 0.05F); + OBLIVION.addSpawnBiome(Type.MAGICAL, 0.005F); OBLIVION.drops.add(new HiveDrop(BeeSpecies.OBLIVION.getGenome(), combs, 80)); OBLIVION.drops.add(new HiveDrop(ForestryHelper.getTemplateForestryForSpecies("Steadfast"), combs, 9)); } @@ -211,98 +212,59 @@ public enum HiveType return names; } - public void generateHive(World world, Random random, int chunkX, int chunkZ, boolean initialGen) + private void addSpawnBiome(Type biome, float chance) { - if (spawnsInBiome(world.getBiomeGenForCoordsBody(chunkX * 16, chunkZ * 16))) - { - switch (this) - { - case CURIOUS: - for (int i = 0; i < 3; ++i) - { - int coordX = chunkX * 16 + random.nextInt(16); - int coordZ = chunkZ * 16 + random.nextInt(16); - if (FeatureHive.generateHiveCurious(world, random, coordX, coordZ, initialGen)) - { - break; - } - } - break; - case UNUSUAL: - for (int i = 0; i < 3; ++i) - { - int coordX = chunkX * 16 + random.nextInt(16); - int coordZ = chunkZ * 16 + random.nextInt(16); - if (FeatureHive.generateHiveUnusual(world, random, coordX, coordZ, initialGen)) - { - break; - } - } - break; - case RESONANT: - for (int i = 0; i < 2; ++i) - { - int coordX = chunkX * 16 + random.nextInt(16); - int coordZ = chunkZ * 16 + random.nextInt(16); - if (FeatureHive.generateHiveResonant(world, random, coordX, coordZ, initialGen)) - { - break; - } - } - break; - case DEEP: - if (chunkX % 2 == 0 && chunkZ % 2 == 0) - { - for (int i = 0; i < 1; ++i) - { - int coordX = chunkX * 16 + random.nextInt(16); - int coordZ = chunkZ * 16 + random.nextInt(16); - if (FeatureHive.generateHiveDeep(world, random, coordX, coordZ, initialGen)) - { - break; - } - } - } - break; - case INFERNAL: - for (int i = 0; i < 2; ++i) - { - int coordX = chunkX * 16 + random.nextInt(16); - int coordZ = chunkZ * 16 + random.nextInt(16); - if (FeatureHive.generateHiveInfernal(world, random, coordX, coordZ, initialGen)) - { - break; - } - } - break; - case OBLIVION: - for (int i = 0; i < 3; ++i) - { - int coordX = chunkX * 16 + random.nextInt(16); - int coordZ = chunkZ * 16 + random.nextInt(16); - if (FeatureHive.generateHiveOblivion(world, random, coordX, coordZ, initialGen)) - { - break; - } - } - break; - } - } + validBiomes.add(biome); + spawnChance[biome.ordinal()] = chance; } - public boolean spawnsInBiome(BiomeGenBase biomeGen) + public boolean generateHive(World world, Random random, int coordX, int coordZ, boolean initialGen) { - boolean found = false; + switch (this) + { + case CURIOUS: + return FeatureHive.generateHiveCurious(world, random, coordX, coordZ, initialGen); + + case UNUSUAL: + return FeatureHive.generateHiveUnusual(world, random, coordX, coordZ, initialGen); + + case RESONANT: + return FeatureHive.generateHiveResonant(world, random, coordX, coordZ, initialGen); + + case DEEP: + return FeatureHive.generateHiveDeep(world, random, coordX, coordZ, initialGen); + + case INFERNAL: + return FeatureHive.generateHiveInfernal(world, random, coordX, coordZ, initialGen); + + case OBLIVION: + return FeatureHive.generateHiveOblivion(world, random, coordX, coordZ, initialGen); + } + return true; + } + + public float getBiomeSpawnChance(BiomeGenBase biomeGen) + { + float chanceSum = 0; + int validTypes = 0; + BiomeDictionary.Type[] types = BiomeDictionary.getTypesForBiome(biomeGen); for (int i = 0; i < types.length; ++i) { - if (this.validBiomes.contains(types[i])) + if (validBiomes.contains(types[i])) { - found = true; - break; + chanceSum += spawnChance[types[i].ordinal()]; + validTypes++; } } - return found; + if(validTypes > 0) + { + return chanceSum / (float)validTypes; + } + else + { + return 0; + } } } diff --git a/magicbees_src/magicbees/main/utils/compat/ThaumcraftHelper.java b/magicbees_src/magicbees/main/utils/compat/ThaumcraftHelper.java index 6ce30d2..efa0131 100644 --- a/magicbees_src/magicbees/main/utils/compat/ThaumcraftHelper.java +++ b/magicbees_src/magicbees/main/utils/compat/ThaumcraftHelper.java @@ -147,7 +147,12 @@ public class ThaumcraftHelper public static void init() { - //if (isActive()) { } + if (isActive()) + { + + aspectTime = new Aspect("tempus", 0xB68CFF, new Aspect[] { Aspect.VOID, Aspect.ORDER }, + new ResourceLocation(CommonProxy.DOMAIN, CommonProxy.TEXTURE + "aspects/tempus.png"), 1); + } } public static void postInit() @@ -158,8 +163,6 @@ public class ThaumcraftHelper getBlocks(); getItems(); - aspectTime = new Aspect("tempus", 0xB68CFF, new Aspect[] { Aspect.VOID, Aspect.ORDER }, - new ResourceLocation(CommonProxy.DOMAIN, CommonProxy.TEXTURE + "aspects/tempus.png"), 1); //addItemsToBackpack(); setupItemAspects(); diff --git a/magicbees_src/magicbees/world/feature/FeatureHive.java b/magicbees_src/magicbees/world/feature/FeatureHive.java index 6b4a456..29b886e 100644 --- a/magicbees_src/magicbees/world/feature/FeatureHive.java +++ b/magicbees_src/magicbees/world/feature/FeatureHive.java @@ -1,11 +1,14 @@ package magicbees.world.feature; import java.util.Random; +import java.lang.Math; import magicbees.block.types.HiveType; import magicbees.main.Config; import magicbees.main.MagicBees; import net.minecraft.block.Block; +import net.minecraft.block.BlockLeavesBase; +import net.minecraft.block.material.Material; import net.minecraft.world.World; import net.minecraft.world.biome.BiomeGenBase; import net.minecraftforge.common.BiomeDictionary; @@ -33,66 +36,100 @@ public class FeatureHive { for (HiveType type : HiveType.values()) { - type.generateHive(world, random, chunkX, chunkZ, initialGen); + if(random.nextFloat() < type.getBiomeSpawnChance(world.getBiomeGenForCoordsBody(chunkX * 16, chunkZ * 16))) + { + for (int i = 0; i < 5; ++i) + { + int coordX = chunkX * 16 + random.nextInt(16); + int coordZ = chunkZ * 16 + random.nextInt(16); + if (type.generateHive(world, random, coordX, coordZ, initialGen)) + { + break; + } + } + } } } public static boolean generateHiveCurious(World world, Random random, int coordX, int coordZ, boolean initialGen) { - int coordY = getHeight(world, random, coordX, coordZ); - boolean doSpawn = false; + int heightMapY = getHeightMapY(world, coordX, coordZ); - Block b = Block.blocksList[world.getBlockId(coordX, coordY + 1, coordZ)]; - if (world.isAirBlock(coordX, coordY - 1, coordZ) && world.isAirBlock(coordX, coordY, coordZ) && - b != null && b.isLeaves(world, coordX, coordY + 1, coordZ)) + if(!isLeaves(world, coordX, heightMapY - 1, coordZ)) { - world.setBlock(coordX, coordY, coordZ, Config.hive.blockID, HiveType.CURIOUS.ordinal(), 3); - if (logSpawns) FMLLog.info("Spawning %s hive at: X %d, Z %d, Y %d", "Curious", coordX, coordZ, coordY); - doSpawn = true; + return false; } - return doSpawn; + int undersideY = seekGround(world, coordX, heightMapY, coordZ); + + // Find lowest branch + while(!isLeaves(world, coordX, undersideY + 1, coordZ) && (undersideY < heightMapY)) + { + undersideY++; + } + + int coordY = 0; + for(int i = 5; i > 0; i--) + { + // Attempt to spawn the hive on a random tree branch height + if((i > 1) && ((heightMapY - undersideY) > 0)) + { + coordY = random.nextInt(heightMapY - undersideY) + undersideY; + while(!isLeaves(world, coordX, coordY + 1, coordZ) && (coordY < heightMapY)) + { + coordY++; + } + } + + // Default to lowest branch + else + { + coordY = undersideY; + } + + if( isSoft(world, coordX, coordY - 1, coordZ) && + isSoft(world, coordX, coordY, coordZ) && + isLeaves(world, coordX, coordY + 1, coordZ) ) + { + world.setBlock(coordX, coordY, coordZ, Config.hive.blockID, HiveType.CURIOUS.ordinal(), 3); + if (logSpawns) FMLLog.info("Spawning %s hive at: X %d, Z %d, Y %d", "Curious", coordX, coordZ, coordY); + return true; + } + } + + return false; } public static boolean generateHiveUnusual(World world, Random random, int coordX, int coordZ, boolean initialGen) { - int coordY = getHeight(world, random, coordX, coordZ); + int coordY = findSurface(world, coordX, coordZ); - boolean doSpawn = false; - if (world.isAirBlock(coordX, coordY + 1, coordZ) && world.isAirBlock(coordX, coordY, coordZ) && - GlobalManager.dirtBlockIds.contains(world.getBlockId(coordX, coordY - 1, coordZ)) ) - { - doSpawn = true; - } - - if (doSpawn) + if( world.isAirBlock(coordX, coordY + 1, coordZ) && + isSoft(world, coordX, coordY, coordZ) && + GlobalManager.dirtBlockIds.contains(world.getBlockId(coordX, coordY - 1, coordZ)) ) { world.setBlock(coordX, coordY, coordZ, Config.hive.blockID, HiveType.UNUSUAL.ordinal(), 3); if (logSpawns) FMLLog.info("Spawning %s hive at: X %d, Z %d, Y %d", "Unusual", coordX, coordZ, coordY); + return true; } - return doSpawn; + return false; } public static boolean generateHiveResonant(World world, Random random, int coordX, int coordZ, boolean initialGen) { - int coordY = getHeight(world, random, coordX, coordZ); - boolean doSpawn = false; - if (world.isAirBlock(coordX, coordY + 1, coordZ) && - (world.isAirBlock(coordX, coordY, coordZ) || world.getBlockId(coordX, coordY, coordZ) == Block.tallGrass.blockID) && - (GlobalManager.dirtBlockIds.contains(world.getBlockId(coordX, coordY - 1, coordZ)) || - GlobalManager.sandBlockIds.contains(world.getBlockId(coordX, coordY - 1, coordZ))) ) - { - doSpawn = true; - } + int coordY = findSurface(world, coordX, coordZ); - if (doSpawn) + if( world.isAirBlock(coordX, coordY + 1, coordZ) && + isSoft(world, coordX, coordY, coordZ) && + (GlobalManager.dirtBlockIds.contains(world.getBlockId(coordX, coordY - 1, coordZ)) || GlobalManager.sandBlockIds.contains(world.getBlockId(coordX, coordY - 1, coordZ))) ) { world.setBlock(coordX, coordY, coordZ, Config.hive.blockID, HiveType.RESONANT.ordinal(), 3); if (logSpawns) FMLLog.info("Spawning %s hive at: X %d, Z %d, Y %d", "Resonant", coordX, coordZ, coordY); + return true; } - return doSpawn; + return false; } public static boolean generateHiveDeep(World world, Random random, int coordX, int coordZ, boolean initialGen) @@ -100,47 +137,37 @@ public class FeatureHive BiomeGenBase biome = world.getBiomeGenForCoords(coordX, coordZ); int coordY = 10 + random.nextInt(10); - - boolean doSpawn = false; - if (random.nextInt(100) < 40 && - !world.isAirBlock(coordX, coordY, coordZ) && - world.getBlockId(coordX, coordY, coordZ) == Block.stone.blockID) - { - doSpawn = getSurroundCount(world, coordX, coordY, coordZ, Block.stone) >= 6; - } - - if (doSpawn) + if( world.getBlockId(coordX, coordY, coordZ) == Block.stone.blockID && + (getSurroundCount(world, coordX, coordY, coordZ, Block.stone) >= 6) ) { world.setBlock(coordX, coordY, coordZ, Config.hive.blockID, HiveType.DEEP.ordinal(), 3); if (logSpawns) FMLLog.info("Spawning %s hive at: X %d, Z %d, Y %d", "Deep", coordX, coordZ, coordY); - redstoneGen.generateVein(world, random, coordX + 1, coordY, coordZ, 2); redstoneGen.generateVein(world, random, coordX - 1, coordY, coordZ, 2); redstoneGen.generateVein(world, random, coordX, coordY + 1, coordZ, 2); redstoneGen.generateVein(world, random, coordX, coordY - 1, coordZ, 2); redstoneGen.generateVein(world, random, coordX, coordY, coordZ + 1, 2); redstoneGen.generateVein(world, random, coordX, coordY, coordZ - 1, 2); + + return true; } - return doSpawn; + return false; } public static boolean generateHiveInfernal(World world, Random random, int coordX, int coordZ, boolean initialGen) { - boolean doSpawn = false; if (!world.provider.isSurfaceWorld()) { - int chop = random.nextInt(2) + 1; - int coordY = random.nextInt(60 / chop) + random.nextInt(chop) * (120 / chop) - 5; + /*int chop = random.nextInt(2) + 1; + int coordY = random.nextInt(60 / chop) + random.nextInt(chop) * (120 / chop) - 5;*/ - if (!world.isAirBlock(coordX, coordY, coordZ) && world.getBlockId(coordX, coordY, coordZ) == Block.netherrack.blockID) - { - doSpawn = getSurroundCount(world, coordX, coordY, coordZ, Block.netherrack) >= 5; - } + int coordY = random.nextInt(64) + (int)Math.round(Math.pow(((random.nextDouble() * 2) - 1), 3) * 32 + 32); - if (doSpawn) + if( world.getBlockId(coordX, coordY, coordZ) == Block.netherrack.blockID && + (getSurroundCount(world, coordX, coordY, coordZ, Block.netherrack) >= 5) ) { world.setBlock(coordX, coordY, coordZ, Config.hive.blockID, HiveType.INFERNAL.ordinal(), 3); if (logSpawns) FMLLog.info("Spawning %s hive at: X %d, Z %d, Y %d", "Infernal", coordX, coordZ, coordY); @@ -151,90 +178,77 @@ public class FeatureHive netherQuartzGen.generateVein(world, random, coordX, coordY - 1, coordZ, 4); netherQuartzGen.generateVein(world, random, coordX, coordY, coordZ + 1, 4); netherQuartzGen.generateVein(world, random, coordX, coordY, coordZ - 1, 4); + + return true; } } else if (MagicBees.getConfig().DoSpecialHiveGen) { int coordY = random.nextInt(13) + 5; - if (!world.isAirBlock(coordX, coordY, coordZ) && world.getBlockId(coordX, coordY, coordZ) == Block.stone.blockID) - { - - doSpawn = getSurroundCount(world, coordX, coordY, coordZ, Block.stone) >= 6; - } - - if (doSpawn) + if( world.getBlockId(coordX, coordY, coordZ) == Block.stone.blockID && + (getSurroundCount(world, coordX, coordY, coordZ, Block.stone) >= 6) ) { world.setBlock(coordX, coordY, coordZ, Config.hive.blockID, HiveType.INFERNAL.ordinal(), 3); if (logSpawns) FMLLog.info("Spawning %s hive at: X %d, Z %d, Y %d", "Infernal", coordX, coordZ, coordY); glowstoneGen.generateVein(world, random, coordX + 1, coordY, coordZ, 2); glowstoneGen.generateVein(world, random, coordX - 1, coordY, coordZ, 2); - if (world.getBlockId(coordX, coordY + 1, coordZ) == Block.stone.blockID || - world.getBlockId(coordX, coordY + 1, coordZ) == Block.netherrack.blockID) - { - world.setBlock(coordX, coordY + 1, coordZ, Block.glowStone.blockID, 0, 3); - } - if (world.getBlockId(coordX, coordY - 1, coordZ) == Block.stone.blockID || - world.getBlockId(coordX, coordY + 1, coordZ) == Block.netherrack.blockID) - { - world.setBlock(coordX, coordY - 1, coordZ, Block.glowStone.blockID, 0, 3); - } + glowstoneGen.generateVein(world, random, coordX, coordY + 1, coordZ, 1); + glowstoneGen.generateVein(world, random, coordX, coordY - 1, coordZ, 1); glowstoneGen.generateVein(world, random, coordX, coordY, coordZ + 1, 2); glowstoneGen.generateVein(world, random, coordX, coordY, coordZ - 1, 2); + + return true; } } - return doSpawn; + return false; } public static boolean generateHiveOblivion(World world, Random random, int coordX, int coordZ, boolean initialGen) { - boolean doSpawn = false; if (!world.provider.isSurfaceWorld()) { - // 1 per gen - int coordY = 10 + random.nextInt(25); + int heightMapY = getHeightMapY(world, coordX, coordZ); - if (world.isAirBlock(coordX, coordY - 2, coordZ) && - world.getBlockId(coordX, coordY - 1, coordZ) == Block.whiteStone.blockID && - world.getBlockId(coordX, coordY, coordZ) == Block.whiteStone.blockID) + if(heightMapY == 0) { - doSpawn = true; + return false; } - if (doSpawn) + int coordY = 0; + + while((world.getBlockId(coordX, coordY + 1, coordZ) != Block.whiteStone.blockID) && (coordY < heightMapY)) + { + coordY++; + } + + coordY += 2; + + if( world.isAirBlock(coordX, coordY - 2, coordZ) && + world.getBlockId(coordX, coordY - 1, coordZ) == Block.whiteStone.blockID && + world.getBlockId(coordX, coordY, coordZ) == Block.whiteStone.blockID ) { world.setBlock(coordX, coordY, coordZ, Config.hive.blockID, HiveType.OBLIVION.ordinal(), 3); if (logSpawns) FMLLog.info("Spawning %s hive at: X %d, Z %d, Y %d", "Oblivion", coordX, coordZ, coordY); int obsidianSpikeHeight = random.nextInt(8) + 2; - for (int i = 1; i < obsidianSpikeHeight && coordY - i > 0; ++i) + for (int i = 1; i <= obsidianSpikeHeight && coordY - i > 0; ++i) { world.setBlock(coordX, coordY - i, coordZ, Block.obsidian.blockID, 0, 2); } + + return true; } } else if (MagicBees.getConfig().DoSpecialHiveGen) { - // 1 per gen int coordY = random.nextInt(5) + 5; - do - { - --coordY; - - if (!world.isAirBlock(coordX, coordY, coordZ) && world.getBlockId(coordX, coordY, coordZ) == Block.stone.blockID || - world.getBlockId(coordX, coordY + 1, coordZ) == Block.whiteStone.blockID) - { - doSpawn = getSurroundCount(world, coordX, coordY, coordZ, Block.whiteStone) >= 5 || - getSurroundCount(world, coordX, coordY, coordZ, Block.stone) >= 5; - } - } - while (!doSpawn && coordY > 5); - - if (doSpawn) + if( world.getBlockId(coordX, coordY, coordZ) == Block.stone.blockID && + (getSurroundCount(world, coordX, coordY, coordZ, Block.stone) >= 6) ) { world.setBlock(coordX, coordY, coordZ, Config.hive.blockID, HiveType.OBLIVION.ordinal(), 3); if (logSpawns) FMLLog.info("Spawning %s hive at: X %d, Z %d, Y %d", "Oblivion", coordX, coordZ, coordY); @@ -245,20 +259,52 @@ public class FeatureHive endStoneGen.generateVein(world, random, coordX, coordY - 1, coordZ, 2); endStoneGen.generateVein(world, random, coordX, coordY, coordZ + 1, 3); endStoneGen.generateVein(world, random, coordX, coordY, coordZ - 1, 3); + + return true; } } - return doSpawn; + + return false; } - private static int getHeight(World world, Random random, int coordX, int coordZ) + // Get surface y from chunk height map (derived from canBlockSeeTheSky) + public static int getHeightMapY(World world, int x, int z) { - BiomeGenBase biome = world.getBiomeGenForCoords(coordX, coordZ); - int min = (int)(biome.minHeight * 64 + 62); - int max = (int)(biome.maxHeight * 64); - // sanity - min = (min > 1) ? min : 1; - max = (max > 10) ? max : 10; - return min + random.nextInt(max); + return world.getChunkFromChunkCoords(x >> 4, z >> 4).heightMap[(z & 15) << 4 | (x & 15)]; + } + + // Seek down through transparent blocks + public static int seekGround(World world, int x, int y, int z) + { + while((isSoft(world, x, y - 1, z) || isLeaves(world, x, y - 1, z)) && (y > 0)) //(!Block.opaqueCubeLookup[world.getBlockId(x, y - 1, z)] || GlobalManager.leafBlockIds.contains(world.getBlockId(x, y - 1, z))) + { + y--; + } + return y; + } + + public static int findSurface(World world, int x, int z) + { + return seekGround(world, x, getHeightMapY(world, x, z), z); + } + + public static boolean isLeaves(World world, int x, int y, int z) + { + Block block = Block.blocksList[world.getBlockId(x, y, z)]; + if(block == null) + { + return false; + } + + // Apparently Thaumcraft and MF:R leaves don't play nice + return ( GlobalManager.leafBlockIds.contains(block.blockID) || + BlockLeavesBase.class.isAssignableFrom(block.getClass()) || + block.blockMaterial == Material.leaves ); + } + + public static boolean isSoft(World world, int x, int y, int z) + { + return (!world.getBlockMaterial(x, y, z).isSolid() && !world.getBlockMaterial(x, y, z).isLiquid()); } private static int getSurroundCount(World world, int x, int y, int z, Block blockType)