diff --git a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java index ee104548..937036f4 100644 --- a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java @@ -1,5 +1,19 @@ package ru.bclib.api.biomes; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Random; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import org.jetbrains.annotations.Nullable; + import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMultimap; @@ -7,6 +21,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; + import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.impl.biome.NetherBiomeData; @@ -23,6 +38,7 @@ import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.MobCategory; import net.minecraft.world.level.Level; +import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeGenerationSettings; import net.minecraft.world.level.biome.BiomeSource; @@ -43,9 +59,9 @@ import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; import net.minecraft.world.level.levelgen.feature.StructureFeature; import net.minecraft.world.level.levelgen.placement.PlacedFeature; import org.apache.commons.lang3.mutable.MutableInt; -import org.jetbrains.annotations.Nullable; import ru.bclib.BCLib; import ru.bclib.config.Configs; +import ru.bclib.interfaces.SurfaceMaterialProvider; import ru.bclib.interfaces.SurfaceProvider; import ru.bclib.interfaces.SurfaceRuleProvider; import ru.bclib.mixin.common.BiomeGenerationSettingsAccessor; @@ -59,17 +75,6 @@ import ru.bclib.world.features.BCLFeature; import ru.bclib.world.generator.BiomePicker; import ru.bclib.world.structures.BCLStructureFeature; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.stream.Collectors; - public class BiomeAPI { /** * Empty biome used as default value if requested biome doesn't exist or linked. Shouldn't be registered anywhere to prevent bugs. @@ -727,6 +732,36 @@ public class BiomeAPI { } return Blocks.AIR.defaultBlockState(); } + + public static Optional findTopMaterial(WorldGenLevel world, BlockPos pos){ + return findTopMaterial(getBiome(world.getBiome(pos))); + } + + public static Optional findTopMaterial(Biome biome){ + return findTopMaterial(getBiome(biome)); + } + + public static Optional findTopMaterial(BCLBiome biome){ + if (biome instanceof SurfaceMaterialProvider smp){ + return Optional.of(smp.getTopMaterial()); + } + return Optional.empty(); + } + + public static Optional findUnderMaterial(WorldGenLevel world, BlockPos pos){ + return findUnderMaterial(getBiome(world.getBiome(pos))); + } + + public static Optional findUnderMaterial(Biome biome){ + return findUnderMaterial(getBiome(biome)); + } + + public static Optional findUnderMaterial(BCLBiome biome){ + if (biome instanceof SurfaceMaterialProvider smp){ + return Optional.of(smp.getUnderMaterial()); + } + return Optional.empty(); + } private static void changeStructureStarts(Consumer, Multimap, ResourceKey>>> modifier) { Registry chunkGenSettingsRegistry = BuiltinRegistries.NOISE_GENERATOR_SETTINGS; diff --git a/src/main/java/ru/bclib/util/StructureHelper.java b/src/main/java/ru/bclib/util/StructureHelper.java index 0b0f3df2..f4c89261 100644 --- a/src/main/java/ru/bclib/util/StructureHelper.java +++ b/src/main/java/ru/bclib/util/StructureHelper.java @@ -1,6 +1,16 @@ package ru.bclib.util; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.Random; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + import com.google.common.collect.Sets; + import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos.MutableBlockPos; import net.minecraft.core.Direction; @@ -20,15 +30,7 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp import net.minecraft.world.level.material.Material; import net.minecraft.world.phys.Vec3; import ru.bclib.api.TagAPI; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.Enumeration; -import java.util.Random; -import java.util.Set; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; +import ru.bclib.api.biomes.BiomeAPI; public class StructureHelper { private static final Direction[] DIR = BlocksHelper.makeHorizontal(); @@ -372,15 +374,13 @@ public class StructureHelper { .isInvulnerable(state, world, pos); } - public static void cover(WorldGenLevel world, BoundingBox bounds, Random random) { + public static void cover(WorldGenLevel world, BoundingBox bounds, Random random, BlockState defaultBlock) { MutableBlockPos mut = new MutableBlockPos(); for (int x = bounds.minX(); x <= bounds.maxX(); x++) { mut.setX(x); for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) { mut.setZ(z); - BlockState top = Blocks.PURPLE_CONCRETE.defaultBlockState(); - //TODO: 1.18 find another way to get the Top Materiel - //world.getBiome(mut).getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); + BlockState top = BiomeAPI.findTopMaterial(world.getBiome(mut)).orElse(defaultBlock); for (int y = bounds.maxY(); y >= bounds.minY(); y--) { mut.setY(y); BlockState state = world.getBlockState(mut); diff --git a/src/main/java/ru/bclib/world/features/ListFeature.java b/src/main/java/ru/bclib/world/features/ListFeature.java index a6990896..6357c86b 100644 --- a/src/main/java/ru/bclib/world/features/ListFeature.java +++ b/src/main/java/ru/bclib/world/features/ListFeature.java @@ -1,21 +1,23 @@ package ru.bclib.world.features; +import java.util.List; +import java.util.Random; + import net.minecraft.core.BlockPos; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; import ru.bclib.util.StructureHelper; -import java.util.List; -import java.util.Random; - public class ListFeature extends NBTStructureFeature { private final List list; private StructureInfo selected; - public ListFeature(List list) { + public ListFeature(List list, BlockState defaultBlock) { + super(defaultBlock); this.list = list; } diff --git a/src/main/java/ru/bclib/world/features/NBTStructureFeature.java b/src/main/java/ru/bclib/world/features/NBTStructureFeature.java index e0b44884..190eb86a 100644 --- a/src/main/java/ru/bclib/world/features/NBTStructureFeature.java +++ b/src/main/java/ru/bclib/world/features/NBTStructureFeature.java @@ -1,5 +1,9 @@ package ru.bclib.world.features; +import java.io.IOException; +import java.io.InputStream; +import java.util.Random; + import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos.MutableBlockPos; import net.minecraft.core.Direction; @@ -10,7 +14,6 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.state.BlockState; @@ -24,11 +27,12 @@ import ru.bclib.api.biomes.BiomeAPI; import ru.bclib.util.BlocksHelper; import ru.bclib.world.processors.DestructionStructureProcessor; -import java.io.IOException; -import java.io.InputStream; -import java.util.Random; - public abstract class NBTStructureFeature extends DefaultFeature { + private final BlockState defaultBlock; + public NBTStructureFeature(BlockState defaultBlock){ + this.defaultBlock = defaultBlock; + } + protected static final DestructionStructureProcessor DESTRUCTION = new DestructionStructureProcessor(); protected abstract StructureTemplate getStructure(WorldGenLevel world, BlockPos pos, Random random); @@ -142,14 +146,9 @@ public abstract class NBTStructureFeature extends DefaultFeature { BlockState stateSt = world.getBlockState(mut); if (!stateSt.is(TagAPI.BLOCK_GEN_TERRAIN)) { if (merge == TerrainMerge.SURFACE) { -// SurfaceBuilderConfiguration config = world.getBiome(mut) -// .getGenerationSettings() -// .getSurfaceBuilderConfig(); boolean isTop = mut.getY() == surfMax && state.getMaterial().isSolidBlocking(); - BlockState top = - Blocks.PURPLE_CONCRETE.defaultBlockState(); - //TODO: 1.18 find another way to get the Top/Bottom Materiel - //isTop ? config.getTopMaterial() : config.getUnderMaterial(); + Biome b = world.getBiome(mut); + BlockState top = (isTop ? BiomeAPI.findTopMaterial(b) : BiomeAPI.findUnderMaterial(b)).orElse(defaultBlock); BlocksHelper.setWithoutUpdate(world, mut, top); } else { @@ -159,12 +158,8 @@ public abstract class NBTStructureFeature extends DefaultFeature { else { if (stateSt.is(TagAPI.BLOCK_END_GROUND) && state.getMaterial().isSolidBlocking()) { if (merge == TerrainMerge.SURFACE) { -// SurfaceBuilderConfiguration config = world.getBiome(mut) -// .getGenerationSettings() -// .getSurfaceBuilderConfig(); - BlockState bottom = Blocks.PURPLE_CONCRETE.defaultBlockState(); - //TODO: 1.18 find another way to get the Top Material - //config.getUnderMaterial() + Biome b = world.getBiome(mut); + BlockState bottom = BiomeAPI.findUnderMaterial(b).orElse(defaultBlock); BlocksHelper.setWithoutUpdate(world, mut, bottom); } else { diff --git a/src/main/java/ru/bclib/world/processors/TerrainStructureProcessor.java b/src/main/java/ru/bclib/world/processors/TerrainStructureProcessor.java index bcb70630..5753b07f 100644 --- a/src/main/java/ru/bclib/world/processors/TerrainStructureProcessor.java +++ b/src/main/java/ru/bclib/world/processors/TerrainStructureProcessor.java @@ -2,24 +2,25 @@ package ru.bclib.world.processors; import net.minecraft.core.BlockPos; import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessor; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorType; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo; +import ru.bclib.api.biomes.BiomeAPI; public class TerrainStructureProcessor extends StructureProcessor { + private final Block defaultBlock; + public TerrainStructureProcessor(Block defaultBlock){ + this.defaultBlock = defaultBlock; + } + @Override public StructureBlockInfo processBlock(LevelReader worldView, BlockPos pos, BlockPos blockPos, StructureBlockInfo structureBlockInfo, StructureBlockInfo structureBlockInfo2, StructurePlaceSettings structurePlacementData) { BlockPos bpos = structureBlockInfo2.pos; - if (structureBlockInfo2.state.is(Blocks.END_STONE) && worldView.isEmptyBlock(bpos.above())) { - BlockState top = Blocks.PURPLE_CONCRETE.defaultBlockState(); - //TODO: 1.18 find another way to get the Top Materiel -// worldView.getBiome(structureBlockInfo2.pos) -// .getGenerationSettings() -// .getSurfaceBuilderConfig() -// .getTopMaterial(); + if (structureBlockInfo2.state.is(defaultBlock) && worldView.isEmptyBlock(bpos.above())) { + final BlockState top = BiomeAPI.findTopMaterial(worldView.getBiome(pos)).orElse(defaultBlock.defaultBlockState()); return new StructureBlockInfo(bpos, top, structureBlockInfo2.nbt); } return structureBlockInfo2;