diff --git a/common/src/main/java/com/khorn/terraincontrol/customobjects/bo3/BO3.java b/common/src/main/java/com/khorn/terraincontrol/customobjects/bo3/BO3.java index a65c0e761..35ae62ec6 100644 --- a/common/src/main/java/com/khorn/terraincontrol/customobjects/bo3/BO3.java +++ b/common/src/main/java/com/khorn/terraincontrol/customobjects/bo3/BO3.java @@ -78,7 +78,7 @@ public int getOffsetAndVariance(Random random, int offset, int variance) { variance = random.nextInt(variance + 1); } - return MathHelper.clamp(offset + variance, TerrainControl.WORLD_DEPTH, TerrainControl.WORLD_HEIGHT); + return offset + variance; } @Override @@ -194,7 +194,7 @@ public boolean spawnForced(LocalWorld world, Random random, Rotation rotation, i return true; } - protected boolean spawn(LocalWorld world, Random random, int x, int z) + public boolean spawn(LocalWorld world, Random random, int x, int z) { Rotation rotation = settings.rotateRandomly ? Rotation.getRandomRotation(random) : Rotation.NORTH; int y = 0; @@ -214,12 +214,17 @@ protected boolean spawn(LocalWorld world, Random random, int x, int z) { y = world.getSolidHeight(x, z); } - // Offset by static and random settings values - y += this.getOffsetAndVariance(random, settings.spawnHeightOffset, settings.spawnHeightVariance); + + // Check spawn point before getting offset and variance if (!canSpawnAt(world, rotation, x, y, z)) { return false; } + + // Offset by static and random settings values + y += this.getOffsetAndVariance(random, settings.spawnHeightOffset, settings.spawnHeightVariance); + y = MathHelper.clamp(y, TerrainControl.WORLD_DEPTH, TerrainControl.WORLD_HEIGHT); + return spawnForced(world, random, rotation, x, y, z); } diff --git a/common/src/main/java/com/khorn/terraincontrol/generator/resource/SaplingGen.java b/common/src/main/java/com/khorn/terraincontrol/generator/resource/SaplingGen.java index 0b7a0d970..f930a4815 100644 --- a/common/src/main/java/com/khorn/terraincontrol/generator/resource/SaplingGen.java +++ b/common/src/main/java/com/khorn/terraincontrol/generator/resource/SaplingGen.java @@ -4,6 +4,7 @@ import com.khorn.terraincontrol.configuration.BiomeConfig; import com.khorn.terraincontrol.configuration.ConfigFunction; import com.khorn.terraincontrol.customobjects.CustomObject; +import com.khorn.terraincontrol.customobjects.bo3.BO3; import com.khorn.terraincontrol.exception.InvalidConfigException; import com.khorn.terraincontrol.util.Rotation; @@ -147,12 +148,23 @@ public boolean growSapling(LocalWorld world, Random random, boolean isWideTree, spawnZ += offset[1]; } - if (tree.spawnForced(world, random, rotation, spawnX, y, spawnZ)) + if(tree instanceof BO3) { - // Success! - return true; + if(((BO3) tree).spawn(world, random, spawnX, spawnZ)) + { + // Success! + return true; + } } - } + else + { + if (tree.spawnForced(world, random, rotation, spawnX, y, spawnZ)) + { + // Success! + return true; + } + } + } } return false; } diff --git a/common/src/main/java/com/khorn/terraincontrol/generator/resource/TreeGen.java b/common/src/main/java/com/khorn/terraincontrol/generator/resource/TreeGen.java index 09a2772a0..c81b775ef 100644 --- a/common/src/main/java/com/khorn/terraincontrol/generator/resource/TreeGen.java +++ b/common/src/main/java/com/khorn/terraincontrol/generator/resource/TreeGen.java @@ -5,6 +5,7 @@ import com.khorn.terraincontrol.configuration.BiomeConfig; import com.khorn.terraincontrol.configuration.ConfigFunction; import com.khorn.terraincontrol.customobjects.CustomObject; +import com.khorn.terraincontrol.customobjects.bo3.BO3; import com.khorn.terraincontrol.exception.InvalidConfigException; import com.khorn.terraincontrol.logging.LogMarker; import com.khorn.terraincontrol.util.ChunkCoordinate; @@ -143,20 +144,32 @@ private void spawnTree(LocalWorld world, Random random, ChunkCoordinate chunkCoo int x = chunkCoord.getBlockXCenter() + random.nextInt(ChunkCoordinate.CHUNK_X_SIZE); int z = chunkCoord.getBlockZCenter() + random.nextInt(ChunkCoordinate.CHUNK_Z_SIZE); - int y = world.getHighestBlockYAt(x, z); CustomObject tree = trees.get(treeKind); - Rotation rotation = Rotation.getRandomRotation(random); - if (!tree.canSpawnAt(world, rotation, x, y, z)) + if(tree instanceof BO3) { - // Try another tree - continue; + if(((BO3) tree).spawn(world, random, x, z)) + { + // Success! + return; + } } - - if (tree.spawnForced(world, random, rotation, x, y, z)) + else { - // Success! - return; + int y = world.getHighestBlockYAt(x, z); + Rotation rotation = Rotation.getRandomRotation(random); + + if (!tree.canSpawnAt(world, rotation, x, y, z)) + { + // Try another tree + continue; + } + + if (tree.spawnForced(world, random, rotation, x, y, z)) + { + // Success! + return; + } } } } diff --git a/platforms/bukkit/src/main/java/com/khorn/terraincontrol/bukkit/events/SaplingListener.java b/platforms/bukkit/src/main/java/com/khorn/terraincontrol/bukkit/events/SaplingListener.java index acca7b177..d4df6775a 100644 --- a/platforms/bukkit/src/main/java/com/khorn/terraincontrol/bukkit/events/SaplingListener.java +++ b/platforms/bukkit/src/main/java/com/khorn/terraincontrol/bukkit/events/SaplingListener.java @@ -1,12 +1,16 @@ package com.khorn.terraincontrol.bukkit.events; import com.khorn.terraincontrol.LocalBiome; +import com.khorn.terraincontrol.LocalMaterialData; import com.khorn.terraincontrol.LocalWorld; +import com.khorn.terraincontrol.bukkit.BukkitMaterialData; import com.khorn.terraincontrol.bukkit.util.WorldHelper; import com.khorn.terraincontrol.configuration.BiomeConfig; import com.khorn.terraincontrol.exception.BiomeNotFoundException; import com.khorn.terraincontrol.generator.resource.SaplingGen; import com.khorn.terraincontrol.generator.resource.SaplingType; +import net.minecraft.server.v1_12_R1.Blocks; +import net.minecraft.server.v1_12_R1.IBlockState; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.TreeType; @@ -46,6 +50,9 @@ void onStructureGrow(StructureGrowEvent event) return; } + // Get sapling material + LocalMaterialData sapling = world.getMaterial(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + // Adjust position for bigger saplings boolean wideTrunk = saplingType.requiresFourSaplings(); if (wideTrunk) @@ -59,25 +66,56 @@ void onStructureGrow(StructureGrowEvent event) } // Get generator - SaplingGen sapling = biomeConfig.getSaplingGen(saplingType); - if (sapling == null) + SaplingGen saplingGen = biomeConfig.getSaplingGen(saplingType); + if (saplingGen == null) { return; } + // Remove saplings + BukkitMaterialData air = BukkitMaterialData.ofMinecraftBlock(Blocks.AIR); + int saplingX = location.getBlockX(); + int saplingY = location.getBlockY(); + int saplingZ = location.getBlockZ(); + if (wideTrunk) + { + world.setBlock(saplingX, saplingY, saplingZ, air); + world.setBlock(saplingX + 1, saplingY, saplingZ, air); + world.setBlock(saplingX, saplingY, saplingZ + 1, air); + world.setBlock(saplingX + 1, saplingY, saplingZ + 1, air); + } else + { + world.setBlock(saplingX, saplingY, saplingZ, air); + } + // Try 10 times to spawn tree - boolean success = false; + boolean saplingGrown = false; Random random = new Random(); for (int i = 0; i < 10; i++) { - if (sapling.growSapling(world, random, wideTrunk, location.getBlockX(), location.getBlockY(), location.getBlockZ())) + if (saplingGen.growSapling(world, random, wideTrunk, location.getBlockX(), location.getBlockY(), location.getBlockZ())) { - success = true; + saplingGrown = true; break; } } - if (success) + if (!saplingGrown) + { + // Restore sapling + if (wideTrunk) + { + world.setBlock(saplingX, saplingY, saplingZ, sapling); + world.setBlock(saplingX + 1, saplingY, saplingZ, sapling); + world.setBlock(saplingX, saplingY, saplingZ + 1, sapling); + world.setBlock(saplingX + 1, saplingY, saplingZ + 1, sapling); + } else + { + world.setBlock(saplingX, saplingY, saplingZ, sapling); + } + } + + if (saplingGrown) { // Just spawned the tree, clear the blocks list to prevent // Bukkit spawning another tree