Skip to content

Instantly share code, notes, and snippets.

@CorgiTaco
Last active November 25, 2020 04:16
Show Gist options
  • Save CorgiTaco/d9c04e5361c8df6c6801af05d5dc57ac to your computer and use it in GitHub Desktop.
Save CorgiTaco/d9c04e5361c8df6c6801af05d5dc57ac to your computer and use it in GitHub Desktop.
package corgiaoc.byg.common.world.feature.overworld;
import com.mojang.serialization.Codec;
import corgiaoc.byg.core.world.BYGBiomes;
import corgiaoc.byg.util.noise.fastnoise.FastNoise;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.data.BuiltinRegistries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
import net.minecraft.world.level.material.Material;
import java.util.Random;
public class OverhangFeature extends Feature<NoneFeatureConfiguration> {
protected static FastNoise fastNoise;
protected long seed;
public OverhangFeature(Codec<NoneFeatureConfiguration> codec) {
super(codec);
}
@Override
public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, NoneFeatureConfiguration config) {
setSeed(world.getSeed());
if (!(chunkGenerator instanceof NoiseBasedChunkGenerator))
return false;
BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos();
BlockPos.MutableBlockPos storedStartPos = new BlockPos.MutableBlockPos();
boolean foundEdge = false;
for (int x = 0; x < 16; x++) {
if (foundEdge)
break;
for (int z = 0; z < 16; z++) {
if (foundEdge)
break;
mutable.set(pos.getX() + x, 0, pos.getZ() + z);
int oceanFloorHeight = world.getHeight(Heightmap.Types.OCEAN_FLOOR_WG, mutable.getX(), mutable.getZ());
mutable.setY(oceanFloorHeight - 4);
if (!(world.getBiomeName(mutable).get() == ResourceKey.create(Registry.BIOME_REGISTRY, BuiltinRegistries.BIOME.getKey(BYGBiomes.GUIANA_SHIELD)) || world.getBiomeName(mutable).get() == ResourceKey.create(Registry.BIOME_REGISTRY, BuiltinRegistries.BIOME.getKey(BYGBiomes.GUIANA_CLEARING))))
foundEdge = true;
storedStartPos = mutable;
}
}
if (!foundEdge)
return false;
storedStartPos.setY(140);
int radius = 25;
BlockPos.MutableBlockPos mutable2 = new BlockPos.MutableBlockPos().set(storedStartPos);
int carveDepth = 2;
for (int boulderIDX = 0; boulderIDX <= carveDepth; boulderIDX++) {
for (int x = -radius; x <= radius; x++) {
int lowestPoint = (int) -(radius * 3);
for (int y = lowestPoint; y <= radius; y++) {
for (int z = -radius; z <= radius; z++) {
int squaredDistance = x * x + y * y + z * z;
if (squaredDistance <= radius * radius) {
mutable2.set(storedStartPos).move(x, y, z);
double boulderRoughnessNoise = fastNoise.GetNoise(mutable2.getX() * 0.04F, mutable2.getY() * 0.01F, mutable2.getZ() * 0.04F);
if (squaredDistance > radius * radius * 0.8f && boulderRoughnessNoise > -0.7D && boulderRoughnessNoise < 0.3D)
continue;
if (!avoidTrees(world.getBlockState(mutable2)))
world.setBlock(mutable2, Blocks.AIR.defaultBlockState(), 2);
}
}
}
}
storedStartPos.move(random.nextInt(5), -(int) (random.nextInt(Math.abs(radius) + 1) * 0.2f + radius * 0.8f) - random.nextInt(7), random.nextInt(5));
}
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
int y = world.getHeight(Heightmap.Types.OCEAN_FLOOR, pos.getX() + x, pos.getZ() + z) - 1;
mutable.set(pos.getX() + x, y, pos.getZ() + z);
if (world.getBlockState(mutable).is(BlockTags.BASE_STONE_OVERWORLD))
world.setBlock(mutable, world.getBiome(mutable).getGenerationSettings().getSurfaceBuilder().get().config().getTopMaterial(), 2);
}
}
return true;
}
public void setSeed(long seed) {
if (this.seed != seed || fastNoise == null) {
fastNoise = new FastNoise((int) seed);
fastNoise.SetNoiseType(FastNoise.NoiseType.Simplex);
fastNoise.SetFrequency(1.9F);
this.seed = seed;
}
}
private boolean avoidTrees(BlockState state) {
return state.getMaterial() == Material.LEAVES || state.getMaterial() == Material.WOOD;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment