From 1f8fd77a46941259d81c17c9a9cc0f6d239e2b93 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Mon, 6 Dec 2021 08:13:50 +0300 Subject: [PATCH] Biome surface provider --- .../java/ru/bclib/api/biomes/BiomeAPI.java | 15 ++++ .../ru/bclib/interfaces/SurfaceProvider.java | 10 +++ .../common/NoiseBasedChunkGeneratorMixin.java | 74 +++++++++++++++++++ .../ru/bclib/world/features/BCLFeature.java | 1 - src/main/resources/bclib.mixins.common.json | 1 + 5 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 src/main/java/ru/bclib/interfaces/SurfaceProvider.java create mode 100644 src/main/java/ru/bclib/mixin/common/NoiseBasedChunkGeneratorMixin.java diff --git a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java index c8c77909..5b188007 100644 --- a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java @@ -12,6 +12,7 @@ import net.fabricmc.api.Environment; import net.fabricmc.fabric.impl.biome.NetherBiomeData; import net.fabricmc.fabric.impl.biome.TheEndBiomeData; import net.minecraft.client.Minecraft; +import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; import net.minecraft.data.BuiltinRegistries; import net.minecraft.resources.ResourceKey; @@ -27,8 +28,12 @@ import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.biome.Biomes; import net.minecraft.world.level.biome.Climate; import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData; +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.GenerationStep.Carving; import net.minecraft.world.level.levelgen.GenerationStep.Decoration; +import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; import net.minecraft.world.level.levelgen.SurfaceRules; import net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver; @@ -39,6 +44,7 @@ import net.minecraft.world.level.levelgen.placement.PlacedFeature; import org.jetbrains.annotations.Nullable; import ru.bclib.BCLib; import ru.bclib.config.Configs; +import ru.bclib.interfaces.SurfaceProvider; import ru.bclib.interfaces.SurfaceRuleProvider; import ru.bclib.mixin.common.BiomeGenerationSettingsAccessor; import ru.bclib.mixin.common.MobSpawnSettingsAccessor; @@ -666,6 +672,15 @@ public class BiomeAPI { accessor.bcl_setSpawners(spawners); } + public static BlockState getBiomeSurfaceBlock(BlockPos pos, Biome biome, ServerLevel level) { + ChunkGenerator generator = level.getChunkSource().getGenerator(); + if (generator instanceof NoiseBasedChunkGenerator) { + SurfaceProvider provider = SurfaceProvider.class.cast(generator); + return provider.getSurface(pos, biome, level); + } + return Blocks.AIR.defaultBlockState(); + } + private static void configureBiome(BCLBiome biome, float chance, float fog) { String group = biome.getID().getNamespace() + "." + biome.getID().getPath(); chance = Configs.BIOMES_CONFIG.getFloat(group, "generation_chance", chance); diff --git a/src/main/java/ru/bclib/interfaces/SurfaceProvider.java b/src/main/java/ru/bclib/interfaces/SurfaceProvider.java new file mode 100644 index 00000000..23dbc3cd --- /dev/null +++ b/src/main/java/ru/bclib/interfaces/SurfaceProvider.java @@ -0,0 +1,10 @@ +package ru.bclib.interfaces; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.state.BlockState; + +public interface SurfaceProvider { + public BlockState getSurface(BlockPos pos, Biome biome, ServerLevel level); +} diff --git a/src/main/java/ru/bclib/mixin/common/NoiseBasedChunkGeneratorMixin.java b/src/main/java/ru/bclib/mixin/common/NoiseBasedChunkGeneratorMixin.java new file mode 100644 index 00000000..f09bce4f --- /dev/null +++ b/src/main/java/ru/bclib/mixin/common/NoiseBasedChunkGeneratorMixin.java @@ -0,0 +1,74 @@ +package ru.bclib.mixin.common; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.StructureFeatureManager; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.levelgen.Aquifer; +import net.minecraft.world.level.levelgen.Beardifier; +import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; +import net.minecraft.world.level.levelgen.NoiseChunk; +import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; +import net.minecraft.world.level.levelgen.NoiseSampler; +import net.minecraft.world.level.levelgen.blending.Blender; +import net.minecraft.world.level.levelgen.carver.CarvingContext; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import ru.bclib.BCLib; +import ru.bclib.interfaces.SurfaceProvider; + +import java.lang.reflect.Constructor; +import java.util.Optional; +import java.util.function.Supplier; + +@Mixin(NoiseBasedChunkGenerator.class) +public abstract class NoiseBasedChunkGeneratorMixin implements SurfaceProvider { + @Final + @Shadow + private NoiseSampler sampler; + + @Final + @Shadow + protected Supplier settings; + + @Final + @Shadow + private Aquifer.FluidPicker globalFluidPicker; + + private static BlockState bclib_air = Blocks.AIR.defaultBlockState(); + private static Constructor bclib_constructor; + + @Override + @SuppressWarnings("deprecation") + public BlockState getSurface(BlockPos pos, Biome biome, ServerLevel level) { + ChunkAccess chunkAccess = level.getChunk(pos.getX() >> 4, pos.getZ() >> 4); + StructureFeatureManager structureFeatureManager = level.structureFeatureManager(); + NoiseBasedChunkGenerator generator = NoiseBasedChunkGenerator.class.cast(this); + if (bclib_constructor == null) { + bclib_constructor = Beardifier.class.getConstructors()[0]; + bclib_constructor.setAccessible(true); + } + + Beardifier beardifier = null; + try { + beardifier = (Beardifier) bclib_constructor.newInstance(structureFeatureManager, chunkAccess); + } + catch (Exception e) { + BCLib.LOGGER.error(e.getLocalizedMessage()); + } + + if (beardifier == null) { + return bclib_air; + } + + Beardifier finalBeardifier = beardifier; + NoiseChunk noiseChunk = chunkAccess.getOrCreateNoiseChunk(this.sampler, () -> finalBeardifier, this.settings.get(), this.globalFluidPicker, Blender.empty()); + CarvingContext carvingContext = new CarvingContext(generator, level.registryAccess(), chunkAccess.getHeightAccessorForGeneration(), noiseChunk); + Optional optional = carvingContext.topMaterial(bpos -> biome, chunkAccess, pos, false); + return optional.isPresent() ? optional.get() : bclib_air; + } +} diff --git a/src/main/java/ru/bclib/world/features/BCLFeature.java b/src/main/java/ru/bclib/world/features/BCLFeature.java index 00c54632..6468be84 100644 --- a/src/main/java/ru/bclib/world/features/BCLFeature.java +++ b/src/main/java/ru/bclib/world/features/BCLFeature.java @@ -12,7 +12,6 @@ import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration; -import net.minecraft.world.level.levelgen.heightproviders.UniformHeight; import net.minecraft.world.level.levelgen.placement.BiomeFilter; import net.minecraft.world.level.levelgen.placement.CountPlacement; import net.minecraft.world.level.levelgen.placement.HeightRangePlacement; diff --git a/src/main/resources/bclib.mixins.common.json b/src/main/resources/bclib.mixins.common.json index c489e915..b387bdb9 100644 --- a/src/main/resources/bclib.mixins.common.json +++ b/src/main/resources/bclib.mixins.common.json @@ -8,6 +8,7 @@ "BiomeGenerationSettingsAccessor", "shears.DiggingEnchantmentMixin", "LayerLightSectionStorageMixin", + "NoiseBasedChunkGeneratorMixin", "NoiseGeneratorSettingsMixin", "shears.TripWireBlockMixin", "StructureSettingsAccessor",