diff --git a/src/main/java/biomesoplenty/common/world/gen/feature/FleshTendonFeature.java b/src/main/java/biomesoplenty/common/world/gen/feature/FleshTendonFeature.java index 1fea2ef18..448b7ba3c 100644 --- a/src/main/java/biomesoplenty/common/world/gen/feature/FleshTendonFeature.java +++ b/src/main/java/biomesoplenty/common/world/gen/feature/FleshTendonFeature.java @@ -10,6 +10,8 @@ import net.minecraft.state.properties.AttachFace; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.MutableBoundingBox; +import net.minecraft.util.math.vector.Vector3d; import net.minecraft.world.ISeedReader; import net.minecraft.world.IWorld; import net.minecraft.world.gen.ChunkGenerator; @@ -21,61 +23,55 @@ import java.util.Random; public class FleshTendonFeature extends Feature { - protected IBlockPosQuery placeOn = (world, pos) -> world.getBlockState(pos).getBlock() == BOPBlocks.flesh; - protected IBlockPosQuery replace = (world, pos) -> world.getBlockState(pos).canBeReplacedByLeaves(world, pos) || world.getBlockState(pos).getBlock() == BOPBlocks.nether_crystal; + private static final int MIN_DISTANCE = 8; + private static final int MAX_DISTANCE = 16; + private static final float MID_POS_MULTIPLIER = 0.1F; + private static final float TENDON_STEP = 0.005f; public FleshTendonFeature(Codec deserializer) { super(deserializer); } - @Override - public boolean place(ISeedReader world, StructureManager p_230362_2_, ChunkGenerator p_230362_3_, Random rand, BlockPos pos, NoFeatureConfig p_230362_6_) + private static BlockPos quadratic(float t, BlockPos v0, BlockPos v1, BlockPos v2) { - if (!world.isEmptyBlock(pos)) + float dt = 1f - t; + Vector3d v = new Vector3d(v0.getX(), v0.getY(), v0.getZ()).scale(dt * dt).add(new Vector3d(v1.getX(), v1.getY(), v1.getZ()).scale(2 * dt * t)).add(new Vector3d(v2.getX(), v2.getY(), v2.getZ()).scale(t * t)); + return new BlockPos(v.x, v.y, v.z); + } + + @Override + public boolean place(ISeedReader world, StructureManager structureManager, ChunkGenerator generator, Random rand, BlockPos pos, NoFeatureConfig config) + { + BlockState below = world.getBlockState(pos.below()); + if (!below.is(BOPBlocks.flesh)) { return false; } - else + + int minX = rand.nextBoolean() ? MIN_DISTANCE : -MIN_DISTANCE; + int minZ = rand.nextBoolean() ? MIN_DISTANCE : -MIN_DISTANCE; + BlockPos endPos = pos.offset(rand.nextInt(MAX_DISTANCE * 2) - MAX_DISTANCE + minX, pos.getY(), rand.nextInt(MAX_DISTANCE * 2) - MAX_DISTANCE + minZ); + + while (world.isEmptyBlock(endPos) && endPos.getY() < 120) { - BlockState blockstate = world.getBlockState(pos.below()); - if (!blockstate.is(BOPBlocks.flesh)) - { - return false; - } - else - { - int height = 120; - double baseSlant = rand.nextInt(35) / 100D; - double slantOffset = baseSlant; - double slantMultiplier = 1.3D; - Direction direction = Direction.Plane.HORIZONTAL.getRandomDirection(rand); - - for(int step = 0; step <= height; step++) - { - BlockPos offsetPos = pos.above(step).relative(direction, (int)Math.floor(slantOffset)); - - if (offsetPos.getY() < 127) - { - this.setBlock(world, offsetPos, BOPBlocks.flesh.defaultBlockState()); - } - - //As the height increases, slant more drastically - slantOffset *= slantMultiplier; - } - - return true; - } + endPos = endPos.above(); } - } - public boolean setBlock(IWorld world, BlockPos pos, BlockState state) - { - if (this.replace.matches(world, pos)) + // No room for the tendon + if (endPos.getY() == pos.getY()) { - super.setBlock(world, pos, state); - return true; + return false; } - return false; + + BlockPos midPos = endPos.offset(0, -(endPos.getY() - pos.getY()) * MID_POS_MULTIPLIER, 0); + + for (float d = 0.0f; d < 1.0f; d += TENDON_STEP) + { + BlockPos curPos = quadratic(d, pos, midPos, endPos); + this.setBlock(world, curPos, BOPBlocks.flesh.defaultBlockState()); + } + + return true; } } \ No newline at end of file