From 0e0b7a5f51c9b311075a72c328c75dd017ab6c7a Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 1 Jul 2022 01:41:51 +0200 Subject: [PATCH 01/50] [Feature] Ability to erode Template Structures --- .../v2/levelgen/structures/TemplatePiece.java | 68 ++++- .../structures/TemplateStructure.java | 16 +- .../betterx/bclib/util/StructureErode.java | 276 ++++++++++++++++++ 3 files changed, 355 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/betterx/bclib/util/StructureErode.java diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplatePiece.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplatePiece.java index a8245d00..e7204457 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplatePiece.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplatePiece.java @@ -1,15 +1,23 @@ package org.betterx.bclib.api.v2.levelgen.structures; import org.betterx.bclib.BCLib; +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.StructureErode; import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; +import net.minecraft.core.Vec3i; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.RandomSource; +import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.level.StructureManager; +import net.minecraft.world.level.WorldGenLevel; +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.chunk.ChunkGenerator; import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.level.levelgen.structure.TemplateStructurePiece; import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext; @@ -20,6 +28,8 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; public class TemplatePiece extends TemplateStructurePiece { + private final int erosion; + private final boolean cover; public static final StructurePieceType INSTANCE = setTemplatePieceId( TemplatePiece::new, "template_piece" @@ -41,7 +51,6 @@ public class TemplatePiece extends TemplateStructurePiece { public static void ensureStaticInitialization() { } - public TemplatePiece( StructureTemplateManager structureTemplateManager, ResourceLocation resourceLocation, @@ -49,6 +58,19 @@ public class TemplatePiece extends TemplateStructurePiece { Rotation rotation, Mirror mirror, BlockPos halfSize + ) { + this(structureTemplateManager, resourceLocation, centerPos, rotation, mirror, halfSize, 0, false); + } + + public TemplatePiece( + StructureTemplateManager structureTemplateManager, + ResourceLocation resourceLocation, + BlockPos centerPos, + Rotation rotation, + Mirror mirror, + BlockPos halfSize, + int erosion, + boolean cover ) { super( INSTANCE, @@ -59,6 +81,8 @@ public class TemplatePiece extends TemplateStructurePiece { makeSettings(rotation, mirror, halfSize), shiftPos(rotation, mirror, halfSize, centerPos) ); + this.erosion = erosion; + this.cover = cover; } public TemplatePiece(StructureTemplateManager structureTemplateManager, CompoundTag compoundTag) { @@ -68,6 +92,15 @@ public class TemplatePiece extends TemplateStructurePiece { structureTemplateManager, (ResourceLocation resourceLocation) -> makeSettings(compoundTag) ); + if (compoundTag.contains("E")) + this.erosion = compoundTag.getInt("E"); + else + this.erosion = 0; + + if (compoundTag.contains("C")) + this.cover = compoundTag.getBoolean("C"); + else + this.cover = true; } private static BlockPos shiftPos( @@ -107,6 +140,8 @@ public class TemplatePiece extends TemplateStructurePiece { tag.putInt("RX", this.placeSettings.getRotationPivot().getX()); tag.putInt("RY", this.placeSettings.getRotationPivot().getY()); tag.putInt("RZ", this.placeSettings.getRotationPivot().getZ()); + tag.putInt("E", this.erosion); + tag.putBoolean("C", this.cover); } @Override @@ -119,4 +154,35 @@ public class TemplatePiece extends TemplateStructurePiece { ) { } + + @Override + public void postProcess( + WorldGenLevel world, + StructureManager structureManager, + ChunkGenerator chunkGenerator, + RandomSource random, + BoundingBox boundingBox, + ChunkPos chunkPos, + BlockPos blockPos + ) { + super.postProcess(world, structureManager, chunkGenerator, random, boundingBox, chunkPos, blockPos); + BoundingBox bounds = BoundingBox.fromCorners(new Vec3i( + this.boundingBox.minX(), + this.boundingBox.minY(), + this.boundingBox.minZ() + ), new Vec3i(this.boundingBox.maxX(), this.boundingBox.maxX(), this.boundingBox.maxZ())); + + if (erosion > 0) { + int x1 = MHelper.min(bounds.maxX(), this.boundingBox.maxX()); + int x0 = MHelper.max(bounds.minX(), this.boundingBox.minX()); + int z1 = MHelper.min(bounds.maxZ(), this.boundingBox.maxZ()); + int z0 = MHelper.max(bounds.minZ(), this.boundingBox.minZ()); + bounds = BoundingBox.fromCorners(new Vec3i(x0, bounds.minY(), z0), new Vec3i(x1, bounds.maxY(), z1)); + StructureErode.erode(world, bounds, erosion, random); + } + + if (cover) { + StructureErode.cover(world, bounds, random, Blocks.END_STONE.defaultBlockState()); + } + } } diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplateStructure.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplateStructure.java index 5cf3a4d4..cfac7fe6 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplateStructure.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplateStructure.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Optional; import java.util.function.BiFunction; import java.util.function.BiPredicate; -import java.util.stream.Collectors; public abstract class TemplateStructure extends Structure { protected final List configs; @@ -83,6 +82,14 @@ public abstract class TemplateStructure extends Structure { return (state == null || state.is(Blocks.AIR)) && before.getMaterial().isSolid(); } + protected int erosion(RandomSource rnd) { + return 0; + } + + protected boolean cover(RandomSource rnd) { + return false; + } + @Override public Optional findGenerationPoint(GenerationContext ctx) { WorldGenerationContext worldGenerationContext = new WorldGenerationContext( @@ -152,8 +159,7 @@ public abstract class TemplateStructure extends Structure { blockPos.getZ(), ctx.heightAccessor(), ctx.randomState() - )) - .collect(Collectors.toList()); + )).toList(); int y = noiseColumns .stream() @@ -199,7 +205,9 @@ public abstract class TemplateStructure extends Structure { ), rotation, mirror, - halfSize + halfSize, + erosion(ctx.random()), + cover(ctx.random()) )) )); diff --git a/src/main/java/org/betterx/bclib/util/StructureErode.java b/src/main/java/org/betterx/bclib/util/StructureErode.java new file mode 100644 index 00000000..adbb5a01 --- /dev/null +++ b/src/main/java/org/betterx/bclib/util/StructureErode.java @@ -0,0 +1,276 @@ +package org.betterx.bclib.util; + +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.RandomSource; +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.levelgen.structure.BoundingBox; +import net.minecraft.world.level.material.Material; + +import com.google.common.collect.Sets; + +import java.util.Set; + +public class StructureErode { + private static final Direction[] DIR = BlocksHelper.makeHorizontal(); + + public static void erode(WorldGenLevel world, BoundingBox bounds, int iterations, RandomSource random) { + MutableBlockPos mut = new MutableBlockPos(); + boolean canDestruct = true; + for (int i = 0; i < iterations; i++) { + for (int x = bounds.minX(); x <= bounds.maxX(); x++) { + mut.setX(x); + for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) { + mut.setZ(z); + for (int y = bounds.maxY(); y >= bounds.minY(); y--) { + mut.setY(y); + BlockState state = world.getBlockState(mut); + boolean ignore = ignore(state, world, mut); + if (canDestruct && BlocksHelper.isInvulnerable( + state, + world, + mut + ) && random.nextInt(8) == 0 && world.isEmptyBlock( + mut.below(2))) { + int r = MHelper.randRange(1, 4, random); + int cx = mut.getX(); + int cy = mut.getY(); + int cz = mut.getZ(); + int x1 = cx - r; + int y1 = cy - r; + int z1 = cz - r; + int x2 = cx + r; + int y2 = cy + r; + int z2 = cz + r; + for (int px = x1; px <= x2; px++) { + int dx = px - cx; + dx *= dx; + mut.setX(px); + for (int py = y1; py <= y2; py++) { + int dy = py - cy; + dy *= dy; + mut.setY(py); + for (int pz = z1; pz <= z2; pz++) { + int dz = pz - cz; + dz *= dz; + mut.setZ(pz); + if (dx + dy + dz <= r && BlocksHelper.isInvulnerable( + world.getBlockState(mut), + world, + mut + )) { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR); + } + } + } + } + mut.setX(cx); + mut.setY(cy); + mut.setZ(cz); + canDestruct = false; + continue; + } else if (ignore) { + continue; + } + if (!state.isAir() && random.nextBoolean()) { + MHelper.shuffle(DIR, random); + for (Direction dir : DIR) { + if (world.isEmptyBlock(mut.relative(dir)) && world.isEmptyBlock(mut.below() + .relative(dir))) { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR); + mut.move(dir).move(Direction.DOWN); + for (int py = mut.getY(); y >= bounds.minY() - 10; y--) { + mut.setY(py - 1); + if (!world.isEmptyBlock(mut)) { + mut.setY(py); + BlocksHelper.setWithoutUpdate(world, mut, state); + break; + } + } + } + } + break; + } else if (random.nextInt(8) == 0 && !BlocksHelper.isInvulnerable( + world.getBlockState(mut.above()), + world, + mut + )) { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR); + } + } + } + } + } + for (int x = bounds.minX(); x <= bounds.maxX(); x++) { + mut.setX(x); + for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) { + mut.setZ(z); + for (int y = bounds.maxY(); y >= bounds.minY(); y--) { + mut.setY(y); + BlockState state = world.getBlockState(mut); + if (!ignore(state, world, mut) && world.isEmptyBlock(mut.below())) { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR); + for (int py = mut.getY(); py >= bounds.minY() - 10; py--) { + mut.setY(py - 1); + if (!world.isEmptyBlock(mut)) { + mut.setY(py); + BlocksHelper.setWithoutUpdate(world, mut, state); + break; + } + } + } + } + } + } + } + + public static void erodeIntense(WorldGenLevel world, BoundingBox bounds, RandomSource random) { + MutableBlockPos mut = new MutableBlockPos(); + MutableBlockPos mut2 = new MutableBlockPos(); + int minY = bounds.minY() - 10; + for (int x = bounds.minX(); x <= bounds.maxX(); x++) { + mut.setX(x); + for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) { + mut.setZ(z); + for (int y = bounds.maxY(); y >= bounds.minY(); y--) { + mut.setY(y); + BlockState state = world.getBlockState(mut); + if (!ignore(state, world, mut)) { + if (random.nextInt(6) == 0) { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR); + if (random.nextBoolean()) { + int px = MHelper.floor(random.nextGaussian() * 2 + x + 0.5); + int pz = MHelper.floor(random.nextGaussian() * 2 + z + 0.5); + mut2.set(px, y, pz); + while (world.getBlockState(mut2).getMaterial().isReplaceable() && mut2.getY() > minY) { + mut2.setY(mut2.getY() - 1); + } + if (!world.getBlockState(mut2).isAir() && state.canSurvive(world, mut2)) { + mut2.setY(mut2.getY() + 1); + BlocksHelper.setWithoutUpdate(world, mut2, state); + } + } + } else if (random.nextInt(8) == 0) { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR); + } + } + } + } + } + + drop(world, bounds); + } + + private static void drop(WorldGenLevel world, BoundingBox bounds) { + MutableBlockPos mut = new MutableBlockPos(); + + Set blocks = Sets.newHashSet(); + Set edge = Sets.newHashSet(); + Set add = Sets.newHashSet(); + + for (int x = bounds.minX(); x <= bounds.maxX(); x++) { + mut.setX(x); + for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) { + mut.setZ(z); + for (int y = bounds.minY(); y <= bounds.maxY(); y++) { + mut.setY(y); + BlockState state = world.getBlockState(mut); + if (!ignore(state, world, mut) && isTerrainNear(world, mut)) { + edge.add(mut.immutable()); + } + } + } + } + + if (edge.isEmpty()) { + return; + } + + while (!edge.isEmpty()) { + for (BlockPos center : edge) { + for (Direction dir : BlocksHelper.DIRECTIONS) { + BlockState state = world.getBlockState(center); + if (state.isCollisionShapeFullBlock(world, center)) { + mut.set(center).move(dir); + if (bounds.isInside(mut)) { + state = world.getBlockState(mut); + if (!ignore(state, world, mut) && !blocks.contains(mut)) { + add.add(mut.immutable()); + } + } + } + } + } + + blocks.addAll(edge); + edge.clear(); + edge.addAll(add); + add.clear(); + } + + int minY = bounds.minY() - 10; + for (int x = bounds.minX(); x <= bounds.maxX(); x++) { + mut.setX(x); + for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) { + mut.setZ(z); + for (int y = bounds.minY(); y <= bounds.maxY(); y++) { + mut.setY(y); + BlockState state = world.getBlockState(mut); + if (!ignore(state, world, mut) && !blocks.contains(mut)) { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR); + while (world.getBlockState(mut).getMaterial().isReplaceable() && mut.getY() > minY) { + mut.setY(mut.getY() - 1); + } + if (mut.getY() > minY) { + mut.setY(mut.getY() + 1); + BlocksHelper.setWithoutUpdate(world, mut, state); + } + } + } + } + } + } + + private static boolean ignore(BlockState state, WorldGenLevel world, BlockPos pos) { + if (state.is(CommonBlockTags.GEN_END_STONES) || state.is(BlockTags.NYLIUM)) { + return true; + } + return !state.getMaterial().equals(Material.STONE) || BlocksHelper.isInvulnerable(state, world, pos); + } + + private static boolean isTerrainNear(WorldGenLevel world, BlockPos pos) { + for (Direction dir : BlocksHelper.DIRECTIONS) { + if (world.getBlockState(pos.relative(dir)).is(CommonBlockTags.GEN_END_STONES)) { + return true; + } + } + return false; + } + + public static void cover(WorldGenLevel world, BoundingBox bounds, RandomSource 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 = BiomeAPI.findTopMaterial(world.getBiome(mut)).orElse(defaultBlock); + for (int y = bounds.maxY(); y >= bounds.minY(); y--) { + mut.setY(y); + BlockState state = world.getBlockState(mut); + if (state.is(CommonBlockTags.TERRAIN) && !world.getBlockState(mut.above()) + .getMaterial() + .isSolidBlocking()) { + BlocksHelper.setWithoutUpdate(world, mut, top); + } + } + } + } + } +} From 598d8f790b34158636200e010e7d1def5e635522 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 1 Jul 2022 02:20:22 +0200 Subject: [PATCH 02/50] Find actual cover block state --- .../v2/levelgen/structures/TemplatePiece.java | 32 ++++++++++++++++--- .../structures/TemplateStructure.java | 6 ++-- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplatePiece.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplatePiece.java index e7204457..7c928e84 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplatePiece.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplatePiece.java @@ -1,10 +1,13 @@ package org.betterx.bclib.api.v2.levelgen.structures; import org.betterx.bclib.BCLib; +import org.betterx.bclib.util.BlocksHelper; import org.betterx.bclib.util.MHelper; import org.betterx.bclib.util.StructureErode; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.core.Registry; import net.minecraft.core.Vec3i; import net.minecraft.nbt.CompoundTag; @@ -14,9 +17,9 @@ import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.level.StructureManager; import net.minecraft.world.level.WorldGenLevel; -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; import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.level.levelgen.structure.TemplateStructurePiece; @@ -165,12 +168,30 @@ public class TemplatePiece extends TemplateStructurePiece { ChunkPos chunkPos, BlockPos blockPos ) { + BlockState coverState = null; + if (cover) { + BlockPos.MutableBlockPos mPos = new BlockPos( + this.boundingBox.minX() - 1, + blockPos.getY(), + this.boundingBox.minZ() - 1 + ).mutable(); + if (BlocksHelper.findOnSurroundingSurface( + world, + mPos, + Direction.DOWN, + 8, + s -> s.is(CommonBlockTags.TERRAIN) + )) { + mPos.move(Direction.DOWN); + coverState = world.getBlockState(mPos); + } + } super.postProcess(world, structureManager, chunkGenerator, random, boundingBox, chunkPos, blockPos); BoundingBox bounds = BoundingBox.fromCorners(new Vec3i( - this.boundingBox.minX(), + boundingBox.minX(), this.boundingBox.minY(), - this.boundingBox.minZ() - ), new Vec3i(this.boundingBox.maxX(), this.boundingBox.maxX(), this.boundingBox.maxZ())); + boundingBox.minZ() + ), new Vec3i(boundingBox.maxX(), this.boundingBox.maxY(), boundingBox.maxZ())); if (erosion > 0) { int x1 = MHelper.min(bounds.maxX(), this.boundingBox.maxX()); @@ -182,7 +203,8 @@ public class TemplatePiece extends TemplateStructurePiece { } if (cover) { - StructureErode.cover(world, bounds, random, Blocks.END_STONE.defaultBlockState()); + System.out.println("CoverState:" + coverState + ", " + blockPos + " " + boundingBox.getCenter()); + StructureErode.cover(world, bounds, random, coverState); } } } diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplateStructure.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplateStructure.java index cfac7fe6..bf8ab098 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplateStructure.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplateStructure.java @@ -190,6 +190,8 @@ public abstract class TemplateStructure extends Structure { centerPos.setY(y - (searchStep == 1 ? 0 : (structureTemplate.getSize(Rotation.NONE).getY()))); + int erosion = erosion(ctx.random()); + boolean cover = cover(ctx.random()); // if (!structure.canGenerate(ctx.chunkGenerator()., centerPos)) return Optional.of(new GenerationStub( centerPos, @@ -206,8 +208,8 @@ public abstract class TemplateStructure extends Structure { rotation, mirror, halfSize, - erosion(ctx.random()), - cover(ctx.random()) + erosion, + cover )) )); From b0456270303eb9c354fb7623997fee4d8e27f38a Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 1 Jul 2022 02:23:30 +0200 Subject: [PATCH 03/50] Disabled loging --- .../betterx/bclib/api/v2/levelgen/structures/TemplatePiece.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplatePiece.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplatePiece.java index 7c928e84..4b2ca88b 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplatePiece.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplatePiece.java @@ -203,7 +203,7 @@ public class TemplatePiece extends TemplateStructurePiece { } if (cover) { - System.out.println("CoverState:" + coverState + ", " + blockPos + " " + boundingBox.getCenter()); + //System.out.println("CoverState:" + coverState + ", " + blockPos + " " + boundingBox.getCenter()); StructureErode.cover(world, bounds, random, coverState); } } From 9e3dbbec76bcecd43e6903de93423619745fedd0 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 1 Jul 2022 12:49:22 +0200 Subject: [PATCH 04/50] Some Cleanup --- .../features/features/TemplateFeature.java | 40 ------------------- 1 file changed, 40 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v3/levelgen/features/features/TemplateFeature.java b/src/main/java/org/betterx/bclib/api/v3/levelgen/features/features/TemplateFeature.java index 8fe8798b..d70948ec 100644 --- a/src/main/java/org/betterx/bclib/api/v3/levelgen/features/features/TemplateFeature.java +++ b/src/main/java/org/betterx/bclib/api/v3/levelgen/features/features/TemplateFeature.java @@ -14,51 +14,11 @@ import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; public class TemplateFeature extends Feature { - - public static BCLFeature createAndRegisterRare( - ResourceLocation location, - TemplateFeatureConfig configuration, - int onceEveryChunk - ) { - - - return BCLFeatureBuilder - .start(location, org.betterx.bclib.api.v3.levelgen.features.BCLFeature.TEMPLATE) - .decoration(GenerationStep.Decoration.SURFACE_STRUCTURES) - .onceEvery(onceEveryChunk) //discard neighboring chunks - .count(16) //try 16 placements in chunk - .squarePlacement() //randomize x/z in chunk - .randomHeight10FromFloorCeil() //randomize height 10 above and 10 below max vertical - .findSolidFloor(12) //cast downward ray to find solid surface - .isEmptyAbove4() //make sure we have 4 free blocks above - .onlyInBiome() //ensure that we still are in the correct biome - - .buildAndRegister(configuration); - } - - public static BCLFeature createAndRegister( - ResourceLocation location, - TemplateFeatureConfig configuration, - int count - ) { - return BCLFeatureBuilder - .start(location, org.betterx.bclib.api.v3.levelgen.features.BCLFeature.TEMPLATE) - .decoration(GenerationStep.Decoration.SURFACE_STRUCTURES) - .count(count) - .squarePlacement() - .randomHeight10FromFloorCeil() - .findSolidFloor(12) //cast downward ray to find solid surface - .isEmptyAbove4() - .onlyInBiome() - .buildAndRegister(configuration); - } - public TemplateFeature(Codec codec) { super(codec); } protected StructureWorldNBT randomStructure(TemplateFeatureConfig cfg, RandomSource random) { - if (cfg.structures.size() > 1) { final float chanceSum = cfg.structures.parallelStream().map(c -> c.chance).reduce(0.0f, (p, c) -> p + c); float rnd = random.nextFloat() * chanceSum; From b1e21b097ba16ffe2dfa2e504dbff95db0a24ff1 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 1 Jul 2022 12:49:35 +0200 Subject: [PATCH 05/50] Some Cleanup --- .../api/v3/levelgen/features/features/TemplateFeature.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v3/levelgen/features/features/TemplateFeature.java b/src/main/java/org/betterx/bclib/api/v3/levelgen/features/features/TemplateFeature.java index d70948ec..91e28907 100644 --- a/src/main/java/org/betterx/bclib/api/v3/levelgen/features/features/TemplateFeature.java +++ b/src/main/java/org/betterx/bclib/api/v3/levelgen/features/features/TemplateFeature.java @@ -1,15 +1,11 @@ package org.betterx.bclib.api.v3.levelgen.features.features; -import org.betterx.bclib.api.v2.levelgen.features.BCLFeature; -import org.betterx.bclib.api.v2.levelgen.features.BCLFeatureBuilder; import org.betterx.bclib.api.v2.levelgen.structures.StructureNBT; import org.betterx.bclib.api.v2.levelgen.structures.StructureWorldNBT; import org.betterx.bclib.api.v3.levelgen.features.config.TemplateFeatureConfig; import com.mojang.serialization.Codec; -import net.minecraft.resources.ResourceLocation; import net.minecraft.util.RandomSource; -import net.minecraft.world.level.levelgen.GenerationStep; import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; From aaba0cec250e40d4ea0bc60c0290af8599108a99 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 1 Jul 2022 16:54:02 +0200 Subject: [PATCH 06/50] Changed visibility --- .../api/v2/levelgen/features/features/DefaultFeature.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/features/features/DefaultFeature.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/features/features/DefaultFeature.java index 2f5195ff..89cec529 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/features/features/DefaultFeature.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/features/features/DefaultFeature.java @@ -11,8 +11,8 @@ import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; public abstract class DefaultFeature extends Feature { - protected static final BlockState AIR = Blocks.AIR.defaultBlockState(); - protected static final BlockState WATER = Blocks.WATER.defaultBlockState(); + public static final BlockState AIR = Blocks.AIR.defaultBlockState(); + public static final BlockState WATER = Blocks.WATER.defaultBlockState(); public DefaultFeature() { super(NoneFeatureConfiguration.CODEC); From c5c61a11fd3ff26ba8d166b7ade189509ff4ec02 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 1 Jul 2022 20:00:46 +0200 Subject: [PATCH 07/50] [Fix] Handling of vanilla/fabric End Biomes --- .../api/v2/generator/BCLibEndBiomeSource.java | 17 ++++++++++------- .../api/v2/generator/TheEndBiomesHelper.java | 5 +++-- .../config/BCLEndBiomeSourceConfig.java | 2 +- .../bclib/api/v2/levelgen/biomes/BiomeAPI.java | 16 ++++++++-------- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java index ef0cb6ca..51fd7155 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java @@ -125,7 +125,10 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi if (bclBiome != BiomeAPI.EMPTY_BIOME) { if (bclBiome.getParentBiome() == null) { if (config.withVoidBiomes) { - if (BiomeAPI.wasRegisteredAsEndVoidBiome(biomeID) + if (biomeID.equals(Biomes.THE_END.location())) { + //we discard those Biomes + } else if (BiomeAPI.wasRegisteredAsEndVoidBiome(biomeID) + || biomeID.equals(Biomes.SMALL_END_ISLANDS.location()) || TheEndBiomesHelper.isIntendedForEndBarrens(key) || includeVoid.contains(biomeID.toString()) ) { @@ -137,16 +140,17 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi endLandBiomePicker.addBiome(bclBiome); } } else { - if (BiomeAPI.wasRegisteredAsEndLandBiome(biomeID) + if (biomeID.equals(Biomes.SMALL_END_ISLANDS.location()) + || biomeID.equals(Biomes.THE_END.location()) + ) { + //we discard those Biomes + } else if (BiomeAPI.wasRegisteredAsEndLandBiome(biomeID) || TheEndBiomesHelper.isIntendedForEndLand(key) || includeLand.contains(biomeID.toString()) ) { endLandBiomePicker.addBiome(bclBiome); endVoidBiomePicker.addBiome(bclBiome); - } - if (!biomeID.equals(Biomes.SMALL_END_ISLANDS.location()) && !biomeID.equals(Biomes.THE_END.location()) - && (BiomeAPI.wasRegisteredAsEndVoidBiome(biomeID) || includeVoid.contains(biomeID.toString())) - ) { + } else if (BiomeAPI.wasRegisteredAsEndVoidBiome(biomeID) || includeVoid.contains(biomeID.toString())) { endVoidBiomePicker.addBiome(bclBiome); } @@ -272,7 +276,6 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi mapLand.clearCache(); mapVoid.clearCache(); } - if (config.generatorVersion == BCLEndBiomeSourceConfig.EndBiomeGeneratorType.VANILLA || endLandFunction == null) { if (dist <= (long) config.innerVoidRadiusSquared) { return this.centerBiome; diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/TheEndBiomesHelper.java b/src/main/java/org/betterx/bclib/api/v2/generator/TheEndBiomesHelper.java index 7720a0c5..f3337abd 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/TheEndBiomesHelper.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/TheEndBiomesHelper.java @@ -75,7 +75,7 @@ public class TheEndBiomesHelper { * and any biomes added to the End as midland biome by mods. */ public static boolean isIntendedForEndMidlands(ResourceKey biome) { - return get().bcl_canGenerateAsEndMidlandBiome(biome); + return get().bcl_canGenerateAsEndMidlandBiome(biome) && !get().bcl_canGenerateAsEndBiome(biome); } /** @@ -83,7 +83,8 @@ public class TheEndBiomesHelper { * and any biomes added to the End as barrens biome by mods. */ public static boolean isIntendedForEndBarrens(ResourceKey biome) { - return get().bcl_canGenerateAsEndBarrensBiome(biome); + return get().bcl_canGenerateAsEndBarrensBiome(biome) && !get().bcl_canGenerateAsEndBiome(biome) && !get().bcl_canGenerateAsEndMidlandBiome( + biome); } public static boolean isIntendedForEndLand(ResourceKey biome) { diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java b/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java index bbfaa7b4..af8ab01b 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java @@ -31,7 +31,7 @@ public class BCLEndBiomeSourceConfig implements BiomeSourceConfig biome) { BCLBiome bclBiome = new BCLBiome(biome.value(), null); - registerBiome(bclBiome, BiomeType.END_VOID); + registerBiome(bclBiome, BiomeType.OTHER_END_VOID); return bclBiome; } @@ -334,7 +334,7 @@ public class BiomeAPI { VanillaBiomeSettings.createVanilla().setGenChance(genChance).build() ); - registerBiome(bclBiome, BiomeType.END_VOID); + registerBiome(bclBiome, BiomeType.OTHER_END_VOID); return bclBiome; } From 90d0c191f59de17000e5fc18c30f3d7e7a4505cf Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 1 Jul 2022 22:29:21 +0200 Subject: [PATCH 08/50] Version update --- gradle.properties | 2 +- src/main/resources/fabric.mod.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 3382f01f..5deee94f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ minecraft_version=1.19 loader_version=0.14.8 fabric_version=0.57.0+1.19 # Mod Properties -mod_version=2.0.8 +mod_version=2.0.9 maven_group=org.betterx.bclib archives_base_name=bclib # Dependencies diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 3172816b..c0a24182 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "id": "bclib", - "version": "2.0.8", + "version": "2.0.9", "name": "BCLib", "description": "A library for BetterX team mods", "authors": [ From e411dc10d972c9c8b2270d182e4c959d12c7b4fc Mon Sep 17 00:00:00 2001 From: Frank Date: Sat, 2 Jul 2022 14:33:00 +0200 Subject: [PATCH 09/50] [Fix] Edge Biomes are never selected when only a single biome is available --- .../bclib/api/v2/generator/BiomePicker.java | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java b/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java index 68da8291..1371b0e7 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java @@ -59,13 +59,25 @@ public class BiomePicker { public void rebuild() { WeightedList list = new WeightedList<>(); - if (biomes.isEmpty()) { + + biomes.forEach(biome -> { + if (biome.isValid) + list.add(biome, biome.bclBiome.getGenChance()); + }); + //only a single biome, we need to add the edges as well + if (list.size() == 1) { + ActualBiome biome = list.get(0); + + if (biome.getEdge() != null) { + float defaultBiomeSize = 128; + float edgeSize = (biome.bclBiome.getEdgeSize() * list.getWeight(0)) / defaultBiomeSize; + list.add(biome.getEdge(), edgeSize); + } + } + + //no Biome, make sure we add at least one, otherwise bad things will happen + if (list.isEmpty()) { list.add(create(BiomeAPI.EMPTY_BIOME), 1); - } else { - biomes.forEach(biome -> { - if (biome.isValid) - list.add(biome, biome.bclBiome.getGenChance()); - }); } @@ -131,5 +143,16 @@ public class BiomePicker { public boolean isSame(ActualBiome e) { return bclBiome.isSame(e.bclBiome); } + + @Override + public String toString() { + return "ActualBiome{" + + "key=" + key.location() + + ", subbiomes=" + subbiomes.size() + + ", edge=" + (edge != null ? edge.key.location() : "null") + + ", parent=" + (parent != null ? parent.key.location() : "null") + + ", isValid=" + isValid + + '}'; + } } } From e35fe997c1852421b3df28a1f6c9c233337bc762 Mon Sep 17 00:00:00 2001 From: Frank Date: Sat, 2 Jul 2022 14:33:52 +0200 Subject: [PATCH 10/50] [Change] Change handling of End Biomes once more. (EndSource will consider Barrens and MainIsland biomes as well now) --- .../api/v2/generator/BCLibEndBiomeSource.java | 198 ++++++------ .../api/v2/generator/GeneratorOptions.java | 10 +- .../api/v2/generator/TheEndBiomesHelper.java | 121 ++++--- .../config/BCLEndBiomeSourceConfig.java | 73 ++++- .../bclib/api/v2/levelgen/LevelGenEvents.java | 6 +- .../api/v2/levelgen/biomes/BCLBiome.java | 16 + .../api/v2/levelgen/biomes/BiomeAPI.java | 296 +++++++++++------- .../v2/levelgen/biomes/InternalBiomeAPI.java | 110 +++++++ .../client/gui/screens/WorldSetupScreen.java | 6 +- .../betterx/bclib/config/BiomesConfig.java | 101 ++++++ .../org/betterx/bclib/config/Configs.java | 3 +- ...ccessor.java => TheEndBiomesAccessor.java} | 2 +- .../mixin/common/TheEndBiomeDataMixin.java | 40 --- .../bclib/mixin/common/TheEndBiomesMixin.java | 64 ++++ src/main/resources/bclib.mixins.common.json | 2 +- 15 files changed, 714 insertions(+), 334 deletions(-) create mode 100644 src/main/java/org/betterx/bclib/config/BiomesConfig.java rename src/main/java/org/betterx/bclib/interfaces/{TheEndBiomeDataAccessor.java => TheEndBiomesAccessor.java} (94%) delete mode 100644 src/main/java/org/betterx/bclib/mixin/common/TheEndBiomeDataMixin.java create mode 100644 src/main/java/org/betterx/bclib/mixin/common/TheEndBiomesMixin.java diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java index 51fd7155..8680c39d 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java @@ -4,7 +4,6 @@ import org.betterx.bclib.BCLib; import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; -import org.betterx.bclib.config.ConfigKeeper.StringArrayEntry; import org.betterx.bclib.config.Configs; import org.betterx.bclib.interfaces.BiomeMap; import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig; @@ -26,9 +25,8 @@ import net.minecraft.world.level.biome.Climate; import net.minecraft.world.level.levelgen.DensityFunction; import java.awt.*; -import java.util.ArrayList; import java.util.List; -import java.util.Set; +import java.util.*; import java.util.function.BiFunction; import org.jetbrains.annotations.NotNull; @@ -54,15 +52,17 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi instance.stable(BCLibEndBiomeSource::new) ) ); - private final Holder centerBiome; - private final Holder barrens; private final Point pos; private final BiFunction endLandFunction; private BiomeMap mapLand; private BiomeMap mapVoid; + private BiomeMap mapCenter; + private BiomeMap mapBarrens; private final BiomePicker endLandBiomePicker; private final BiomePicker endVoidBiomePicker; + private final BiomePicker endCenterBiomePicker; + private final BiomePicker endBarrensBiomePicker; private BCLEndBiomeSourceConfig config; @@ -92,81 +92,79 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi ) { super(biomeRegistry, list, seed); this.config = config; + var includeMap = Configs.BIOMES_CONFIG.getBiomeIncludeMap(); + var excludeList = Configs.BIOMES_CONFIG.getBiomeExcludeMap().get(BiomeAPI.BiomeType.END); endLandBiomePicker = new BiomePicker(biomeRegistry); endVoidBiomePicker = new BiomePicker(biomeRegistry); + endCenterBiomePicker = new BiomePicker(biomeRegistry); + endBarrensBiomePicker = new BiomePicker(biomeRegistry); + Map pickerMap = new HashMap<>(); + pickerMap.put(BiomeAPI.BiomeType.END_LAND, endLandBiomePicker); + pickerMap.put(BiomeAPI.BiomeType.END_VOID, endVoidBiomePicker); + pickerMap.put(BiomeAPI.BiomeType.END_CENTER, endCenterBiomePicker); + pickerMap.put(BiomeAPI.BiomeType.END_BARRENS, endBarrensBiomePicker); - List includeVoid = Configs.BIOMES_CONFIG.getEntry( - "force_include", - "end_void_biomes", - StringArrayEntry.class - ).getValue(); - List includeLand = Configs.BIOMES_CONFIG.getEntry( - "force_include", - "end_land_biomes", - StringArrayEntry.class - ).getValue(); this.possibleBiomes().forEach(biome -> { ResourceKey key = biome.unwrapKey().orElseThrow(); ResourceLocation biomeID = key.location(); + String biomeStr = biomeID.toString(); + //exclude everything that was listed + if (excludeList != null && excludeList.contains(biomeStr)) return; - + final BCLBiome bclBiome; if (!BiomeAPI.hasBiome(biomeID)) { - BCLBiome bclBiome = new BCLBiome(biomeID, biome.value()); - - if (includeVoid.contains(biomeID.toString())) { - endVoidBiomePicker.addBiome(bclBiome); - } else { - endLandBiomePicker.addBiome(bclBiome); - } + bclBiome = new BCLBiome(biomeID, biome.value()); } else { - BCLBiome bclBiome = BiomeAPI.getBiome(biomeID); - if (bclBiome != BiomeAPI.EMPTY_BIOME) { - if (bclBiome.getParentBiome() == null) { - if (config.withVoidBiomes) { - if (biomeID.equals(Biomes.THE_END.location())) { - //we discard those Biomes - } else if (BiomeAPI.wasRegisteredAsEndVoidBiome(biomeID) - || biomeID.equals(Biomes.SMALL_END_ISLANDS.location()) - || TheEndBiomesHelper.isIntendedForEndBarrens(key) - || includeVoid.contains(biomeID.toString()) - ) { - endVoidBiomePicker.addBiome(bclBiome); - } else if (BiomeAPI.wasRegisteredAsEndLandBiome(biomeID) - || TheEndBiomesHelper.isIntendedForEndLand(key) - || includeLand.contains(biomeID.toString()) - ) { - endLandBiomePicker.addBiome(bclBiome); - } - } else { - if (biomeID.equals(Biomes.SMALL_END_ISLANDS.location()) - || biomeID.equals(Biomes.THE_END.location()) - ) { - //we discard those Biomes - } else if (BiomeAPI.wasRegisteredAsEndLandBiome(biomeID) - || TheEndBiomesHelper.isIntendedForEndLand(key) - || includeLand.contains(biomeID.toString()) - ) { - endLandBiomePicker.addBiome(bclBiome); - endVoidBiomePicker.addBiome(bclBiome); - } else if (BiomeAPI.wasRegisteredAsEndVoidBiome(biomeID) || includeVoid.contains(biomeID.toString())) { - endVoidBiomePicker.addBiome(bclBiome); - } + bclBiome = BiomeAPI.getBiome(biomeID); + } + + if (bclBiome != null || bclBiome != BiomeAPI.EMPTY_BIOME) { + if (bclBiome.getParentBiome() == null) { + //ignore small islands when void biomes are disabled + if (!config.withVoidBiomes) { + if (biomeID.equals(Biomes.SMALL_END_ISLANDS.location())) { + return; + } + } + + //force include biomes + boolean didForceAdd = false; + for (var entry : pickerMap.entrySet()) { + var includeList = includeMap == null ? null : includeMap.get(entry.getKey()); + if (includeList != null && includeList.contains(biomeStr)) { + entry.getValue().addBiome(bclBiome); + didForceAdd = true; + } + } + + if (!didForceAdd) { + if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_CENTER) + || TheEndBiomesHelper.canGenerateAsMainIslandBiome(key)) { + endCenterBiomePicker.addBiome(bclBiome); + } else if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_LAND) + || TheEndBiomesHelper.canGenerateAsHighlandsBiome(key)) { + if (!config.withVoidBiomes) endVoidBiomePicker.addBiome(bclBiome); + endLandBiomePicker.addBiome(bclBiome); + } else if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_BARRENS) + || TheEndBiomesHelper.canGenerateAsEndBarrens(key)) { + endBarrensBiomePicker.addBiome(bclBiome); + } else if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_VOID) + || TheEndBiomesHelper.canGenerateAsSmallIslandsBiome(key)) { + endVoidBiomePicker.addBiome(bclBiome); } } } } - }); + }); endLandBiomePicker.rebuild(); endVoidBiomePicker.rebuild(); - - - this.centerBiome = biomeRegistry.getOrCreateHolderOrThrow(Biomes.THE_END); - this.barrens = biomeRegistry.getOrCreateHolderOrThrow(Biomes.END_BARRENS); + endBarrensBiomePicker.rebuild(); + endCenterBiomePicker.rebuild(); this.endLandFunction = GeneratorOptions.getEndLandFunction(); this.pos = new Point(); @@ -188,51 +186,37 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi } private static List> getBclBiomes(Registry biomeRegistry) { - List include = Configs.BIOMES_CONFIG.getEntry( - "force_include", - "end_land_biomes", - StringArrayEntry.class - ).getValue(); - include.addAll(Configs.BIOMES_CONFIG.getEntry( - "force_include", - "end_void_biomes", - StringArrayEntry.class - ).getValue()); return getBiomes( biomeRegistry, new ArrayList<>(0), - include, + Configs.BIOMES_CONFIG.getIncludeMatching(BiomeAPI.BiomeType.END), BCLibEndBiomeSource::isValidNonVanillaEndBiome ); } private static List> getBiomes(Registry biomeRegistry) { - List include = Configs.BIOMES_CONFIG.getEntry( - "force_include", - "end_land_biomes", - StringArrayEntry.class - ).getValue(); - include.addAll(Configs.BIOMES_CONFIG.getEntry( - "force_include", - "end_void_biomes", - StringArrayEntry.class - ).getValue()); - - return getBiomes(biomeRegistry, new ArrayList<>(0), include, BCLibEndBiomeSource::isValidEndBiome); + return getBiomes( + biomeRegistry, + new ArrayList<>(0), + Configs.BIOMES_CONFIG.getIncludeMatching(BiomeAPI.BiomeType.END), + BCLibEndBiomeSource::isValidEndBiome + ); } private static boolean isValidEndBiome(Holder biome, ResourceLocation location) { return biome.is(BiomeTags.IS_END) || BiomeAPI.wasRegisteredAsEndBiome(location) || - TheEndBiomesHelper.isIntendedForAny(biome.unwrapKey().orElse(null)); + TheEndBiomesHelper.canGenerateInEnd(biome.unwrapKey().orElse(null)); } private static boolean isValidNonVanillaEndBiome(Holder biome, ResourceLocation location) { return biome.is(BiomeTags.IS_END) || BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.BCL_END_LAND) || BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.BCL_END_VOID) || - TheEndBiomesHelper.isIntendedForAny(biome.unwrapKey().orElse(null)); + BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.BCL_END_CENTER) || + BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.BCL_END_BARRENS) || + TheEndBiomesHelper.canGenerateInEnd(biome.unwrapKey().orElse(null)); } public static void register() { @@ -243,15 +227,27 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi protected void onInitMap(long seed) { this.mapLand = config.mapVersion.mapBuilder.apply( seed, - GeneratorOptions.getBiomeSizeEndLand(), + config.landBiomesSize, endLandBiomePicker ); this.mapVoid = config.mapVersion.mapBuilder.apply( seed, - GeneratorOptions.getBiomeSizeEndVoid(), + config.voidBiomesSize, endVoidBiomePicker ); + + this.mapCenter = config.mapVersion.mapBuilder.apply( + seed, + config.centerBiomesSize, + endCenterBiomePicker + ); + + this.mapBarrens = config.mapVersion.mapBuilder.apply( + seed, + config.barrensBiomesSize, + endBarrensBiomePicker + ); } @Override @@ -261,7 +257,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi @Override public Holder getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.@NotNull Sampler sampler) { - if (mapLand == null || mapVoid == null) + if (mapLand == null || mapVoid == null || mapCenter == null || mapBarrens == null) return this.possibleBiomes().stream().findFirst().orElseThrow(); int posX = QuartPos.toBlock(biomeX); @@ -275,32 +271,38 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi if ((biomeX & 63) == 0 && (biomeZ & 63) == 0) { mapLand.clearCache(); mapVoid.clearCache(); + mapCenter.clearCache(); + mapVoid.clearCache(); } + if (config.generatorVersion == BCLEndBiomeSourceConfig.EndBiomeGeneratorType.VANILLA || endLandFunction == null) { if (dist <= (long) config.innerVoidRadiusSquared) { - return this.centerBiome; + return mapCenter.getBiome(posX, biomeY << 2, posZ).biome; } int x = (SectionPos.blockToSectionCoord(posX) * 2 + 1) * 8; int z = (SectionPos.blockToSectionCoord(posZ) * 2 + 1) * 8; double d = sampler.erosion().compute(new DensityFunction.SinglePointContext(x, posY, z)); if (d > 0.25) { - return mapLand.getBiome(posX, biomeY << 2, posZ).biome; + return mapLand.getBiome(posX, biomeY << 2, posZ).biome; //highlands } else if (d >= -0.0625) { - return mapLand.getBiome(posX, biomeY << 2, posZ).biome; + return mapLand.getBiome(posX, biomeY << 2, posZ).biome; //midlands } else { return d < -0.21875 - ? mapVoid.getBiome(posX, biomeY << 2, posZ).biome - : config.withVoidBiomes ? this.barrens : mapVoid.getBiome(posX, biomeY << 2, posZ).biome; + ? mapVoid.getBiome(posX, biomeY << 2, posZ).biome //small islands + : (config.withVoidBiomes ? mapBarrens : mapLand).getBiome( + posX, + biomeY << 2, + posZ + ).biome; //barrens } } else { pos.setLocation(biomeX, biomeZ); if (endLandFunction.apply(pos, maxHeight)) { - return dist <= (long) config.innerVoidRadiusSquared - ? centerBiome : mapLand.getBiome(posX, biomeY << 2, posZ).biome; + return (dist <= (long) config.innerVoidRadiusSquared ? mapCenter : mapLand) + .getBiome(posX, biomeY << 2, posZ).biome; } else { - return dist <= (long) config.innerVoidRadiusSquared - ? barrens - : mapVoid.getBiome(posX, biomeY << 2, posZ).biome; + return (dist <= (long) config.innerVoidRadiusSquared ? mapBarrens : mapVoid) + .getBiome(posX, biomeY << 2, posZ).biome; } } diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/GeneratorOptions.java b/src/main/java/org/betterx/bclib/api/v2/generator/GeneratorOptions.java index d7dac883..fc1ba549 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/GeneratorOptions.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/GeneratorOptions.java @@ -11,8 +11,6 @@ import java.util.function.Function; public class GeneratorOptions { private static int biomeSizeNether; private static int biomeVSizeNether; - private static int biomeSizeEndLand; - private static int biomeSizeEndVoid; private static BiFunction endLandFunction; private static boolean customNetherBiomeSource = true; private static boolean customEndBiomeSource = true; @@ -28,8 +26,6 @@ public class GeneratorOptions { "biomeVerticalSize(onlyInTallNether)", 86 ); - biomeSizeEndLand = Configs.GENERATOR_CONFIG.getInt("end.biomeMap", "biomeSizeLand", 256); - biomeSizeEndVoid = Configs.GENERATOR_CONFIG.getInt("end.biomeMap", "biomeSizeVoid", 256); customNetherBiomeSource = Configs.GENERATOR_CONFIG.getBoolean("options", "customNetherBiomeSource", true); customEndBiomeSource = Configs.GENERATOR_CONFIG.getBoolean("options", "customEndBiomeSource", true); verticalBiomes = Configs.GENERATOR_CONFIG.getBoolean("options", "verticalBiomesInTallNether", true); @@ -45,12 +41,14 @@ public class GeneratorOptions { return Mth.clamp(biomeVSizeNether, 1, 8192); } + @Deprecated(forRemoval = true) public static int getBiomeSizeEndLand() { - return Mth.clamp(biomeSizeEndLand, 1, 8192); + return 256; } + @Deprecated(forRemoval = true) public static int getBiomeSizeEndVoid() { - return Mth.clamp(biomeSizeEndVoid, 1, 8192); + return 256; } /** diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/TheEndBiomesHelper.java b/src/main/java/org/betterx/bclib/api/v2/generator/TheEndBiomesHelper.java index f3337abd..07dffc7a 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/TheEndBiomesHelper.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/TheEndBiomesHelper.java @@ -1,97 +1,92 @@ package org.betterx.bclib.api.v2.generator; -import org.betterx.bclib.BCLib; -import org.betterx.bclib.interfaces.TheEndBiomeDataAccessor; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.biome.Biome; -import net.fabricmc.fabric.impl.biome.TheEndBiomeData; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.jetbrains.annotations.ApiStatus; /** - * Helper class until FAPI integrates https://github.com/FabricMC/fabric/pull/2369 + * Helper class until FAPI integrates this PR */ public class TheEndBiomesHelper { - public static TheEndBiomeDataAccessor INSTANCE; + @ApiStatus.Internal + public static Map>> END_BIOMES = new HashMap<>(); - private static TheEndBiomeDataAccessor get() { - if (INSTANCE == null) { - try { - Class cl = TheEndBiomeData.class; - Constructor constr = Arrays.stream(cl.getDeclaredConstructors()) - .filter(c -> c.getParameterCount() == 0) - .findFirst() - .orElseThrow(); - constr.setAccessible(true); - INSTANCE = (TheEndBiomeDataAccessor) constr.newInstance(); - } catch (NoClassDefFoundError cnf) { - - } catch (InstantiationException e) { - - } catch (IllegalAccessException e) { - - } catch (InvocationTargetException e) { - - } - if (INSTANCE == null) { - BCLib.LOGGER.warning("Unable to access internal End-Biome API from Fabric. Using Fallback behaviour."); - INSTANCE = new TheEndBiomeDataAccessor() { - @Override - public boolean bcl_canGenerateAsEndBiome(ResourceKey key) { - return true; - } - - @Override - public boolean bcl_canGenerateAsEndMidlandBiome(ResourceKey key) { - return false; - } - - @Override - public boolean bcl_canGenerateAsEndBarrensBiome(ResourceKey key) { - return false; - } - }; - } - } - return INSTANCE; + @ApiStatus.Internal + public static void add(BiomeAPI.BiomeType type, ResourceKey biome) { + if (biome == null) return; + END_BIOMES.computeIfAbsent(type, t -> new HashSet<>()).add(biome); } + private static boolean has(BiomeAPI.BiomeType type, ResourceKey biome) { + if (biome == null) return false; + Set> set = END_BIOMES.get(type); + if (set == null) return false; + return set.contains(biome); + } /** - * Returns true if the given biome was added in the end, considering the Vanilla end biomes, + * Returns true if the given biome was added as a main end Biome in the end, considering the Vanilla end biomes, * and any biomes added to the End by mods. + * + * @param biome The biome to search for */ - public static boolean isIntendedForEndBiome(ResourceKey biome) { - return get().bcl_canGenerateAsEndBiome(biome); + public static boolean canGenerateAsMainIslandBiome(ResourceKey biome) { + return has(BiomeAPI.BiomeType.END_CENTER, biome); + } + + /** + * Returns true if the given biome was added as a small end islands Biome in the end, considering the Vanilla end biomes, + * and any biomes added to the End by mods. + * + * @param biome The biome to search for + */ + public static boolean canGenerateAsSmallIslandsBiome(ResourceKey biome) { + return has(BiomeAPI.BiomeType.END_VOID, biome); + } + + /** + * Returns true if the given biome was added as a Highland Biome in the end, considering the Vanilla end biomes, + * and any biomes added to the End by mods. + * + * @param biome The biome to search for + */ + public static boolean canGenerateAsHighlandsBiome(ResourceKey biome) { + return has(BiomeAPI.BiomeType.END_LAND, biome); } /** * Returns true if the given biome was added as midland biome in the end, considering the Vanilla end biomes, * and any biomes added to the End as midland biome by mods. + * + * @param biome The biome to search for */ - public static boolean isIntendedForEndMidlands(ResourceKey biome) { - return get().bcl_canGenerateAsEndMidlandBiome(biome) && !get().bcl_canGenerateAsEndBiome(biome); + public static boolean canGenerateAsEndMidlands(ResourceKey biome) { + return false; } /** * Returns true if the given biome was added as barrens biome in the end, considering the Vanilla end biomes, * and any biomes added to the End as barrens biome by mods. + * + * @param biome The biome to search for */ - public static boolean isIntendedForEndBarrens(ResourceKey biome) { - return get().bcl_canGenerateAsEndBarrensBiome(biome) && !get().bcl_canGenerateAsEndBiome(biome) && !get().bcl_canGenerateAsEndMidlandBiome( - biome); + public static boolean canGenerateAsEndBarrens(ResourceKey biome) { + return has(BiomeAPI.BiomeType.END_BARRENS, biome); } - public static boolean isIntendedForEndLand(ResourceKey biome) { - return isIntendedForEndBiome(biome) || isIntendedForEndMidlands(biome); - } - - public static boolean isIntendedForAny(ResourceKey biome) { - return isIntendedForEndBiome(biome) || isIntendedForEndMidlands(biome) || isIntendedForEndBarrens(biome); + public static boolean canGenerateInEnd(ResourceKey biome) { + return canGenerateAsHighlandsBiome(biome) + || canGenerateAsEndBarrens(biome) + || canGenerateAsEndMidlands(biome) + || canGenerateAsSmallIslandsBiome(biome) + || canGenerateAsMainIslandBiome(biome); } } diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java b/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java index af8ab01b..8ab7a7db 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java @@ -10,6 +10,7 @@ import org.betterx.worlds.together.biomesource.config.BiomeSourceConfig; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.util.Mth; import net.minecraft.util.StringRepresentable; import java.util.Objects; @@ -20,19 +21,31 @@ public class BCLEndBiomeSourceConfig implements BiomeSourceConfig o.innerVoidRadiusSquared) + .forGetter(o -> o.innerVoidRadiusSquared), + Codec.INT + .fieldOf("center_biomes_size") + .orElse(DEFAULT.innerVoidRadiusSquared) + .forGetter(o -> o.centerBiomesSize), + Codec.INT + .fieldOf("void_biomes_size") + .orElse(DEFAULT.innerVoidRadiusSquared) + .forGetter(o -> o.voidBiomesSize), + Codec.INT + .fieldOf("land_biomes_size") + .orElse(DEFAULT.innerVoidRadiusSquared) + .forGetter(o -> o.landBiomesSize), + Codec.INT + .fieldOf("barrens_biomes_size") + .orElse(DEFAULT.innerVoidRadiusSquared) + .forGetter(o -> o.barrensBiomesSize) ) .apply(instance, BCLEndBiomeSourceConfig::new)); @@ -61,12 +90,20 @@ public class BCLEndBiomeSourceConfig implements BiomeSourceConfig BIOME_TYPE_MAP = Maps.newHashMap(); public final BiomeType parentOrNull; - private final String debugName; + private final String name; - public BiomeType(String debugName) { - this(debugName, null); + public BiomeType(String name) { + this(name, null); } - public BiomeType(String debugName, BiomeType parentOrNull) { + public BiomeType(String name, BiomeType parentOrNull) { this.parentOrNull = parentOrNull; - this.debugName = debugName; + this.name = name; } public boolean is(BiomeType d) { @@ -93,9 +93,13 @@ public class BiomeAPI { return false; } + public String getName() { + return name; + } + @Override public String toString() { - String str = debugName; + String str = name; if (parentOrNull != null) str += " -> " + parentOrNull; return str; } @@ -109,28 +113,58 @@ public class BiomeAPI { private static final Map ID_MAP = Maps.newHashMap(); - public static final BCLBiome NETHER_WASTES_BIOME = registerNetherBiome(getFromRegistry(Biomes.NETHER_WASTES).value()); - public static final BCLBiome CRIMSON_FOREST_BIOME = registerNetherBiome(getFromRegistry(Biomes.CRIMSON_FOREST).value()); - public static final BCLBiome WARPED_FOREST_BIOME = registerNetherBiome(getFromRegistry(Biomes.WARPED_FOREST).value()); - public static final BCLBiome SOUL_SAND_VALLEY_BIOME = registerNetherBiome(getFromRegistry(Biomes.SOUL_SAND_VALLEY).value()); - public static final BCLBiome BASALT_DELTAS_BIOME = registerNetherBiome(getFromRegistry(Biomes.BASALT_DELTAS).value()); - - - public static final BCLBiome THE_END = registerCenterBiome(getFromRegistry(Biomes.THE_END)); - - public static final BCLBiome END_HIGHLANDS = registerEndLandBiome( - getFromRegistry(Biomes.END_HIGHLANDS), - 0.5F + public static final BCLBiome NETHER_WASTES_BIOME = InternalBiomeAPI.wrapNativeBiome( + Biomes.NETHER_WASTES, + InternalBiomeAPI.OTHER_NETHER ); - public static final BCLBiome END_MIDLANDS = registerSubBiome( - END_HIGHLANDS, - getFromRegistry(Biomes.END_MIDLANDS).value(), - 0.5F + public static final BCLBiome CRIMSON_FOREST_BIOME = InternalBiomeAPI.wrapNativeBiome( + Biomes.CRIMSON_FOREST, + InternalBiomeAPI.OTHER_NETHER + ); + public static final BCLBiome WARPED_FOREST_BIOME = InternalBiomeAPI.wrapNativeBiome( + Biomes.WARPED_FOREST, + InternalBiomeAPI.OTHER_NETHER + ); + public static final BCLBiome SOUL_SAND_VALLEY_BIOME = InternalBiomeAPI.wrapNativeBiome( + Biomes.SOUL_SAND_VALLEY, + InternalBiomeAPI.OTHER_NETHER + ); + public static final BCLBiome BASALT_DELTAS_BIOME = InternalBiomeAPI.wrapNativeBiome( + Biomes.BASALT_DELTAS, + InternalBiomeAPI.OTHER_NETHER ); - public static final BCLBiome END_BARRENS = registerEndBiome(getFromRegistry(new ResourceLocation("end_barrens"))); - public static final BCLBiome SMALL_END_ISLANDS = registerEndVoidBiome(getFromRegistry(new ResourceLocation( - "small_end_islands"))); + + public static final BCLBiome THE_END = InternalBiomeAPI.wrapNativeBiome( + Biomes.THE_END, + 0.5F, + InternalBiomeAPI.OTHER_END_CENTER + ); + + public static final BCLBiome END_MIDLANDS = InternalBiomeAPI.wrapNativeBiome( + Biomes.END_MIDLANDS, + 0.5F, + InternalBiomeAPI.OTHER_END_LAND + ); + + public static final BCLBiome END_HIGHLANDS = InternalBiomeAPI.wrapNativeBiome( + Biomes.END_HIGHLANDS, + END_MIDLANDS, + 8, + 0.5F, + InternalBiomeAPI.OTHER_END_LAND + ); + + + public static final BCLBiome END_BARRENS = InternalBiomeAPI.wrapNativeBiome( + Biomes.END_BARRENS, + InternalBiomeAPI.OTHER_END_BARRENS + ); + + public static final BCLBiome SMALL_END_ISLANDS = InternalBiomeAPI.wrapNativeBiome( + Biomes.SMALL_END_ISLANDS, + InternalBiomeAPI.OTHER_END_VOID + ); /** * Register {@link BCLBiome} instance and its {@link Biome} if necessary. @@ -189,36 +223,6 @@ public class BiomeAPI { return registerSubBiome(parent, subBiome, dim); } - /** - * Register {@link BCLBiome} instance and its {@link Biome} if necessary. - * After that biome will be added to BCLib Nether Biome Generator and into Fabric Biome API. - * - * @param bclBiome {@link BCLBiome} - * @return {@link BCLBiome} - */ - public static BCLBiome registerNetherBiome(BCLBiome bclBiome) { - registerBiome(bclBiome, BiomeType.BCL_NETHER); - - ResourceKey key = getBiomeKey(bclBiome.getBiome()); - if (bclBiome.allowFabricRegistration()) { - bclBiome.forEachClimateParameter(p -> NetherBiomes.addNetherBiome(key, p)); - } - return bclBiome; - } - - /** - * Register {@link BCLBiome} instance and its {@link Biome} if necessary. - * After that biome will be added to BCLib Nether Biome Generator and into Fabric Biome API. - * - * @param biome {@link BCLBiome} - * @return {@link BCLBiome} - */ - public static BCLBiome registerNetherBiome(Biome biome) { - BCLBiome bclBiome = new BCLBiome(biome, null); - registerBiome(bclBiome, BiomeType.OTHER_NETHER); - return bclBiome; - } - /** * Register {@link BCLBiome} instance and its {@link Biome} if necessary. * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). @@ -232,47 +236,16 @@ public class BiomeAPI { float weight = biome.getGenChance(); ResourceKey key = getBiomeKey(biome.getBiome()); if (biome.allowFabricRegistration()) { - TheEndBiomes.addHighlandsBiome(key, weight); - TheEndBiomes.addMidlandsBiome(key, key, weight); if (biome.isEdgeBiome()) { ResourceKey parentKey = getBiomeKey(biome.getParentBiome().getBiome()); TheEndBiomes.addMidlandsBiome(parentKey, key, weight); + } else { + TheEndBiomes.addHighlandsBiome(key, weight); } } return biome; } - /** - * Register {@link BCLBiome} wrapper for {@link Biome}. - * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). - * - * @param biome {@link BCLBiome} - * @return {@link BCLBiome} - */ - public static BCLBiome registerEndLandBiome(Holder biome) { - BCLBiome bclBiome = new BCLBiome(biome.value(), null); - - registerBiome(bclBiome, BiomeType.OTHER_END_LAND); - return bclBiome; - } - - /** - * Register {@link BCLBiome} wrapper for {@link Biome}. - * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). - * - * @param biome {@link BCLBiome}; - * @param genChance float generation chance. - * @return {@link BCLBiome} - */ - public static BCLBiome registerEndLandBiome(Holder biome, float genChance) { - BCLBiome bclBiome = new BCLBiome( - biome.value(), - VanillaBiomeSettings.createVanilla().setGenChance(genChance).build() - ); - - registerBiome(bclBiome, BiomeType.OTHER_END_LAND); - return bclBiome; - } /** * Register {@link BCLBiome} instance and its {@link Biome} if necessary. @@ -294,18 +267,44 @@ public class BiomeAPI { /** * Register {@link BCLBiome} instance and its {@link Biome} if necessary. - * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a void biome (will generate only in the End void - between islands). + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a center island + * biome (will generate only on the center island). * * @param biome {@link BCLBiome} * @return {@link BCLBiome} */ - public static BCLBiome registerEndVoidBiome(Holder biome) { - BCLBiome bclBiome = new BCLBiome(biome.value(), null); + public static BCLBiome registerEndCenterBiome(BCLBiome biome) { + registerBiome(biome, BiomeType.BCL_END_CENTER); - registerBiome(bclBiome, BiomeType.OTHER_END_VOID); - return bclBiome; + float weight = biome.getGenChance(); + ResourceKey key = getBiomeKey(biome.getBiome()); + if (biome.allowFabricRegistration()) { + TheEndBiomes.addMainIslandBiome(key, weight); + } + return biome; } + /** + * Register {@link BCLBiome} instance and its {@link Biome} if necessary. + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a barrens island + * biome (will generate on the edge of midland biomes on the larger islands). + * + * @param biome {@link BCLBiome} + * @return {@link BCLBiome} + */ + public static BCLBiome registerEndBarrensBiome(BCLBiome highlandBiome, BCLBiome biome) { + registerBiome(biome, BiomeType.BCL_END_BARRENS); + + float weight = biome.getGenChance(); + ResourceKey key = getBiomeKey(biome.getBiome()); + if (biome.allowFabricRegistration()) { + ResourceKey parentKey = getBiomeKey(highlandBiome.getBiome()); + TheEndBiomes.addBarrensBiome(parentKey, key, weight); + } + return biome; + } + + public static BCLBiome registerEndBiome(Holder biome) { BCLBiome bclBiome = new BCLBiome(biome.value(), null); @@ -320,23 +319,6 @@ public class BiomeAPI { return bclBiome; } - /** - * Register {@link BCLBiome} instance and its {@link Biome} if necessary. - * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a void biome (will generate only in the End void - between islands). - * - * @param biome {@link BCLBiome}. - * @param genChance float generation chance. - * @return {@link BCLBiome} - */ - public static BCLBiome registerEndVoidBiome(Holder biome, float genChance) { - BCLBiome bclBiome = new BCLBiome( - biome.value(), - VanillaBiomeSettings.createVanilla().setGenChance(genChance).build() - ); - - registerBiome(bclBiome, BiomeType.OTHER_END_VOID); - return bclBiome; - } /** * Get {@link BCLBiome} from {@link Biome} instance on server. Used to convert world biomes to BCLBiomes. @@ -532,6 +514,14 @@ public class BiomeAPI { return wasRegisteredAs(biomeID, BiomeType.END_VOID); } + public static boolean wasRegisteredAsEndCenterBiome(ResourceLocation biomeID) { + return wasRegisteredAs(biomeID, BiomeType.END_CENTER); + } + + public static boolean wasRegisteredAsEndBarrensBiome(ResourceLocation biomeID) { + return wasRegisteredAs(biomeID, BiomeType.END_BARRENS); + } + /** * Registers new biome modification for specified dimension. Will work both for mod and datapack biomes. * @@ -845,4 +835,84 @@ public class BiomeAPI { } return features.get(index).stream().collect(Collectors.toList()); } + + /** + * Register {@link BCLBiome} instance and its {@link Biome} if necessary. + * After that biome will be added to BCLib Nether Biome Generator and into Fabric Biome API. + * + * @param bclBiome {@link BCLBiome} + * @return {@link BCLBiome} + */ + public static BCLBiome registerNetherBiome(BCLBiome bclBiome) { + registerBiome(bclBiome, BiomeType.BCL_NETHER); + + ResourceKey key = getBiomeKey(bclBiome.getBiome()); + if (bclBiome.allowFabricRegistration()) { + bclBiome.forEachClimateParameter(p -> NetherBiomes.addNetherBiome(key, p)); + } + return bclBiome; + } + + /** + * Register {@link BCLBiome} instance and its {@link Biome} if necessary. + * After that biome will be added to BCLib Nether Biome Generator and into Fabric Biome API. + * + * @param biome {@link BCLBiome} + * @return {@link BCLBiome} + */ + @Deprecated(forRemoval = true) + public static BCLBiome registerNetherBiome(Biome biome) { + return InternalBiomeAPI.wrapNativeBiome(biome, -1, InternalBiomeAPI.OTHER_NETHER); + } + + @Deprecated(forRemoval = true) + public static BCLBiome registerEndLandBiome(Holder biome) { + return InternalBiomeAPI.wrapNativeBiome(biome.unwrapKey().orElseThrow(), InternalBiomeAPI.OTHER_END_LAND); + } + + /** + * Register {@link BCLBiome} instance and its {@link Biome} if necessary. + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a void biome (will generate only in the End void - between islands). + * + * @param biome {@link BCLBiome} + * @return {@link BCLBiome} + */ + @Deprecated(forRemoval = true) + public static BCLBiome registerEndVoidBiome(Holder biome) { + return InternalBiomeAPI.wrapNativeBiome(biome.unwrapKey().orElseThrow(), InternalBiomeAPI.OTHER_END_VOID); + } + + /** + * Register {@link BCLBiome} wrapper for {@link Biome}. + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). + * + * @param biome {@link BCLBiome}; + * @param genChance float generation chance. + * @return {@link BCLBiome} + */ + @Deprecated(forRemoval = true) + public static BCLBiome registerEndLandBiome(Holder biome, float genChance) { + return InternalBiomeAPI.wrapNativeBiome( + biome.unwrapKey().orElseThrow(), + genChance, + InternalBiomeAPI.OTHER_END_LAND + ); + } + + /** + * Register {@link BCLBiome} instance and its {@link Biome} if necessary. + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a void biome (will generate only in the End void - between islands). + * + * @param biome {@link BCLBiome}. + * @param genChance float generation chance. + * @return {@link BCLBiome} + */ + @Deprecated(forRemoval = true) + public static BCLBiome registerEndVoidBiome(Holder biome, float genChance) { + return InternalBiomeAPI.wrapNativeBiome( + biome.unwrapKey().orElseThrow(), + genChance, + InternalBiomeAPI.OTHER_END_VOID + ); + } } diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java index a1b273e4..2f0cffcd 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java @@ -34,8 +34,30 @@ import java.util.Optional; import java.util.Set; import java.util.function.BiConsumer; import java.util.stream.Stream; +import org.jetbrains.annotations.ApiStatus; +@ApiStatus.Internal public class InternalBiomeAPI { + public static final BiomeAPI.BiomeType OTHER_NETHER = new BiomeAPI.BiomeType( + "OTHER_NETHER", + BiomeAPI.BiomeType.NETHER + ); + public static final BiomeAPI.BiomeType OTHER_END_LAND = new BiomeAPI.BiomeType( + "OTHER_END_LAND", + BiomeAPI.BiomeType.END_LAND + ); + public static final BiomeAPI.BiomeType OTHER_END_VOID = new BiomeAPI.BiomeType( + "OTHER_END_VOID", + BiomeAPI.BiomeType.END_VOID + ); + public static final BiomeAPI.BiomeType OTHER_END_CENTER = new BiomeAPI.BiomeType( + "OTHER_END_CENTER", + BiomeAPI.BiomeType.END_CENTER + ); + public static final BiomeAPI.BiomeType OTHER_END_BARRENS = new BiomeAPI.BiomeType( + "OTHER_END_BARRENS", + BiomeAPI.BiomeType.END_BARRENS + ); static final Map CLIENT = Maps.newHashMap(); static final Map, Integer> FEATURE_ORDER = Maps.newHashMap(); static final MutableInt FEATURE_ORDER_ID = new MutableInt(0); @@ -246,6 +268,94 @@ public class InternalBiomeAPI { private static final Set BIOMES_TO_SORT = Sets.newHashSet(); + + /** + * Register {@link BCLBiome} wrapper for {@link Biome}. + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). + * + * @param biome The source biome to wrap + * @return {@link BCLBiome} + */ + public static BCLBiome wrapNativeBiome(ResourceKey biome, BiomeAPI.BiomeType type) { + return wrapNativeBiome(biome, -1, type); + } + + /** + * Register {@link BCLBiome} wrapper for {@link Biome}. + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). + * + * @param biome The source biome to wrap + * @param genChance generation chance. If <0 the default genChance is used + * @return {@link BCLBiome} + */ + public static BCLBiome wrapNativeBiome(ResourceKey biome, float genChance, BiomeAPI.BiomeType type) { + return wrapNativeBiome( + biome, + genChance < 0 ? null : VanillaBiomeSettings.createVanilla().setGenChance(genChance).build(), + type + ); + } + + public static BCLBiome wrapNativeBiome( + ResourceKey biome, + BCLBiome edgeBiome, + int edgeBiomeSize, + float genChance, + BiomeAPI.BiomeType type + ) { + VanillaBiomeSettings.Builder settings = VanillaBiomeSettings.createVanilla(); + if (genChance >= 0) settings.setGenChance(genChance); + settings.setEdge(edgeBiome); + settings.setEdgeSize(edgeBiomeSize); + return wrapNativeBiome(biome, settings.build(), type); + } + + /** + * Register {@link BCLBiome} wrapper for {@link Biome}. + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). + * + * @param biome The source biome to wrap + * @param setings the {@link VanillaBiomeSettings} to use + * @return {@link BCLBiome} + */ + private static BCLBiome wrapNativeBiome( + ResourceKey biome, + VanillaBiomeSettings setings, + BiomeAPI.BiomeType type + ) { + BCLBiome bclBiome = BiomeAPI.getBiome(biome.location()); + if (bclBiome == BiomeAPI.EMPTY_BIOME) { + bclBiome = new BCLBiome( + BiomeAPI.getFromRegistry(biome).value(), + setings + ); + } + + BiomeAPI.registerBiome(bclBiome, type); + return bclBiome; + } + + /** + * Register {@link BCLBiome} wrapper for {@link Biome}. + * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). + * + * @param biome The source biome to wrap + * @param genChance generation chance. + * @return {@link BCLBiome} + */ + static BCLBiome wrapNativeBiome(Biome biome, float genChance, BiomeAPI.BiomeType type) { + BCLBiome bclBiome = BiomeAPI.getBiome(biome); + if (bclBiome == BiomeAPI.EMPTY_BIOME) { + bclBiome = new BCLBiome( + biome, + genChance < 0 ? null : VanillaBiomeSettings.createVanilla().setGenChance(genChance).build() + ); + } + + BiomeAPI.registerBiome(bclBiome, type); + return bclBiome; + } + static { DynamicRegistrySetupCallback.EVENT.register(registryManager -> { Optional> oBiomeRegistry = registryManager.registry(Registry.BIOME_REGISTRY); diff --git a/src/main/java/org/betterx/bclib/client/gui/screens/WorldSetupScreen.java b/src/main/java/org/betterx/bclib/client/gui/screens/WorldSetupScreen.java index 29a988f2..65916b23 100644 --- a/src/main/java/org/betterx/bclib/client/gui/screens/WorldSetupScreen.java +++ b/src/main/java/org/betterx/bclib/client/gui/screens/WorldSetupScreen.java @@ -187,7 +187,11 @@ public class WorldSetupScreen extends BCLibScreen { ? BCLEndBiomeSourceConfig.EndBiomeGeneratorType.PAULEVS : BCLEndBiomeSourceConfig.EndBiomeGeneratorType.VANILLA, generateEndVoid.isChecked(), - BCLEndBiomeSourceConfig.DEFAULT.innerVoidRadiusSquared + BCLEndBiomeSourceConfig.DEFAULT.innerVoidRadiusSquared, + BCLEndBiomeSourceConfig.DEFAULT.centerBiomesSize, + BCLEndBiomeSourceConfig.DEFAULT.voidBiomesSize, + BCLEndBiomeSourceConfig.DEFAULT.landBiomesSize, + BCLEndBiomeSourceConfig.DEFAULT.barrensBiomesSize ); ChunkGenerator endGenerator = betterxDimensions.get(LevelStem.END); diff --git a/src/main/java/org/betterx/bclib/config/BiomesConfig.java b/src/main/java/org/betterx/bclib/config/BiomesConfig.java new file mode 100644 index 00000000..c096b86e --- /dev/null +++ b/src/main/java/org/betterx/bclib/config/BiomesConfig.java @@ -0,0 +1,101 @@ +package org.betterx.bclib.config; + +import org.betterx.bclib.BCLib; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; + +import java.util.*; + +public class BiomesConfig extends PathConfig { + + private Map> BIOME_INCLUDE_LIST = null; + private Map> BIOME_EXCLUDE_LIST = null; + + + public static final BiomeAPI.BiomeType[] endTypes = { + BiomeAPI.BiomeType.END_LAND, + BiomeAPI.BiomeType.END_VOID, + BiomeAPI.BiomeType.END_CENTER, + BiomeAPI.BiomeType.END_BARRENS + }; + + public static final BiomeAPI.BiomeType[] netherTypes = { + BiomeAPI.BiomeType.NETHER + }; + + private static final BiomeAPI.BiomeType[] includeTypes = all(); + private static final BiomeAPI.BiomeType[] excludeTypes = {BiomeAPI.BiomeType.NETHER, BiomeAPI.BiomeType.END}; + + public BiomesConfig() { + super(BCLib.MOD_ID, "biomes", false); + for (var type : includeTypes) { + keeper.registerEntry( + new ConfigKey(type.getName(), "force_include"), + new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST) + ); + } + for (var type : excludeTypes) { + keeper.registerEntry( + new ConfigKey(type.getName(), "force_exclude"), + new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST) + ); + } + } + + private static BiomeAPI.BiomeType[] all() { + BiomeAPI.BiomeType[] res = new BiomeAPI.BiomeType[endTypes.length + netherTypes.length]; + System.arraycopy(netherTypes, 0, res, 0, netherTypes.length); + System.arraycopy(endTypes, 0, res, netherTypes.length, endTypes.length); + return res; + } + + private List getBiomeIncludeList(BiomeAPI.BiomeType type) { + var entry = getEntry( + "force_include", + type.getName(), + ConfigKeeper.StringArrayEntry.class + ); + if (entry == null) + return List.of(); + return entry.getValue(); + } + + private List getBiomeExcludeList(BiomeAPI.BiomeType type) { + var entry = getEntry( + "force_exclude", + type.getName(), + ConfigKeeper.StringArrayEntry.class + ); + if (entry == null) + return List.of(); + return entry.getValue(); + } + + public List getIncludeMatching(BiomeAPI.BiomeType type) { + return getBiomeIncludeMap().entrySet() + .stream() + .filter(e -> e.getKey().is(type)) + .map(e -> e.getValue()) + .flatMap(Collection::stream) + .toList(); + } + + public Map> getBiomeIncludeMap() { + if (BIOME_INCLUDE_LIST == null) { + BIOME_INCLUDE_LIST = new HashMap<>(); + for (BiomeAPI.BiomeType type : includeTypes) { + BIOME_INCLUDE_LIST.put(type, getBiomeIncludeList(type)); + } + } + return BIOME_INCLUDE_LIST; + } + + public Map> getBiomeExcludeMap() { + if (BIOME_EXCLUDE_LIST == null) { + BIOME_EXCLUDE_LIST = new HashMap<>(); + for (BiomeAPI.BiomeType type : excludeTypes) { + BIOME_EXCLUDE_LIST.put(type, getBiomeExcludeList(type)); + } + } + return BIOME_EXCLUDE_LIST; + } +} diff --git a/src/main/java/org/betterx/bclib/config/Configs.java b/src/main/java/org/betterx/bclib/config/Configs.java index ac54aa55..cb099f8a 100644 --- a/src/main/java/org/betterx/bclib/config/Configs.java +++ b/src/main/java/org/betterx/bclib/config/Configs.java @@ -18,7 +18,7 @@ public class Configs { public static final MainConfig MAIN_CONFIG = new MainConfig(); public static final PathConfig RECIPE_CONFIG = new PathConfig(BCLib.MOD_ID, "recipes"); - public static final PathConfig BIOMES_CONFIG = new PathConfig(BCLib.MOD_ID, "biomes", false); + public static final BiomesConfig BIOMES_CONFIG = new BiomesConfig(); public static final String MAIN_PATCH_CATEGORY = "patches"; @@ -29,6 +29,7 @@ public class Configs { BIOMES_CONFIG.saveChanges(); } + static { BIOMES_CONFIG.keeper.registerEntry( new ConfigKey("end_land_biomes", "force_include"), diff --git a/src/main/java/org/betterx/bclib/interfaces/TheEndBiomeDataAccessor.java b/src/main/java/org/betterx/bclib/interfaces/TheEndBiomesAccessor.java similarity index 94% rename from src/main/java/org/betterx/bclib/interfaces/TheEndBiomeDataAccessor.java rename to src/main/java/org/betterx/bclib/interfaces/TheEndBiomesAccessor.java index c18ae9cd..aa39ebb6 100644 --- a/src/main/java/org/betterx/bclib/interfaces/TheEndBiomeDataAccessor.java +++ b/src/main/java/org/betterx/bclib/interfaces/TheEndBiomesAccessor.java @@ -3,7 +3,7 @@ package org.betterx.bclib.interfaces; import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.biome.Biome; -public interface TheEndBiomeDataAccessor { +public interface TheEndBiomesAccessor { boolean bcl_canGenerateAsEndBiome(ResourceKey key); boolean bcl_canGenerateAsEndMidlandBiome(ResourceKey key); diff --git a/src/main/java/org/betterx/bclib/mixin/common/TheEndBiomeDataMixin.java b/src/main/java/org/betterx/bclib/mixin/common/TheEndBiomeDataMixin.java deleted file mode 100644 index 1fc7b9c8..00000000 --- a/src/main/java/org/betterx/bclib/mixin/common/TheEndBiomeDataMixin.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.betterx.bclib.mixin.common; - -import org.betterx.bclib.interfaces.TheEndBiomeDataAccessor; - -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.level.biome.Biome; - -import net.fabricmc.fabric.impl.biome.TheEndBiomeData; -import net.fabricmc.fabric.impl.biome.WeightedPicker; - -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import java.util.Map; - -@Mixin(value = TheEndBiomeData.class, remap = false) -public class TheEndBiomeDataMixin implements TheEndBiomeDataAccessor { - @Shadow - @Final - private static Map, WeightedPicker>> END_BIOMES_MAP; - @Shadow - @Final - private static Map, WeightedPicker>> END_MIDLANDS_MAP; - @Shadow - @Final - private static Map, WeightedPicker>> END_BARRENS_MAP; - - public boolean bcl_canGenerateAsEndBiome(ResourceKey key) { - return END_BIOMES_MAP != null && END_BIOMES_MAP.containsKey(key); - } - - public boolean bcl_canGenerateAsEndMidlandBiome(ResourceKey key) { - return END_MIDLANDS_MAP != null && END_MIDLANDS_MAP.containsKey(key); - } - - public boolean bcl_canGenerateAsEndBarrensBiome(ResourceKey key) { - return END_BARRENS_MAP != null && END_BARRENS_MAP.containsKey(key); - } -} diff --git a/src/main/java/org/betterx/bclib/mixin/common/TheEndBiomesMixin.java b/src/main/java/org/betterx/bclib/mixin/common/TheEndBiomesMixin.java new file mode 100644 index 00000000..7a3aa38b --- /dev/null +++ b/src/main/java/org/betterx/bclib/mixin/common/TheEndBiomesMixin.java @@ -0,0 +1,64 @@ +package org.betterx.bclib.mixin.common; + +import org.betterx.bclib.api.v2.generator.TheEndBiomesHelper; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI; + +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.biome.Biome; + +import net.fabricmc.fabric.api.biome.v1.TheEndBiomes; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(value = TheEndBiomes.class, remap = false) +public class TheEndBiomesMixin { + @Inject(method = "addBarrensBiome", at = @At("HEAD")) + private static void bcl_registerBarrens( + ResourceKey highlands, + ResourceKey barrens, + double weight, + CallbackInfo ci + ) { + TheEndBiomesHelper.add(InternalBiomeAPI.OTHER_END_BARRENS, barrens); + } + + @Inject(method = "addMidlandsBiome", at = @At("HEAD")) + private static void bcl_registerMidlands( + ResourceKey highlands, + ResourceKey midlands, + double weight, + CallbackInfo ci + ) { + BCLBiome highland = InternalBiomeAPI.wrapNativeBiome(highlands, InternalBiomeAPI.OTHER_END_LAND); + BCLBiome midland = InternalBiomeAPI.wrapNativeBiome(midlands, InternalBiomeAPI.OTHER_END_LAND); + if (highland != null) { + highland.addEdge(midland); + } + TheEndBiomesHelper.add(InternalBiomeAPI.OTHER_END_LAND, midlands); + } + + @Inject(method = "addSmallIslandsBiome", at = @At("HEAD")) + private static void bcl_registerSmallIslands( + ResourceKey biome, double weight, CallbackInfo ci + ) { + TheEndBiomesHelper.add(InternalBiomeAPI.OTHER_END_VOID, biome); + } + + @Inject(method = "addHighlandsBiome", at = @At("HEAD")) + private static void bcl_registerHighlands( + ResourceKey biome, double weight, CallbackInfo ci + ) { + TheEndBiomesHelper.add(InternalBiomeAPI.OTHER_END_LAND, biome); + } + + @Inject(method = "addMainIslandBiome", at = @At("HEAD")) + private static void bcl_registerMainIsnalnd( + ResourceKey biome, double weight, CallbackInfo ci + ) { + TheEndBiomesHelper.add(InternalBiomeAPI.OTHER_END_CENTER, biome); + } +} diff --git a/src/main/resources/bclib.mixins.common.json b/src/main/resources/bclib.mixins.common.json index 29267b7d..7e1f5ebb 100644 --- a/src/main/resources/bclib.mixins.common.json +++ b/src/main/resources/bclib.mixins.common.json @@ -33,7 +33,7 @@ "ShovelItemAccessor", "StructuresAccessor", "SurfaceRulesContextAccessor", - "TheEndBiomeDataMixin", + "TheEndBiomesMixin", "WorldGenRegionMixin", "elytra.LivingEntityMixin", "shears.BeehiveBlockMixin", From 600bb6f9ac01eecbc5c2fbbeb77fd45a73961af0 Mon Sep 17 00:00:00 2001 From: Frank Date: Sat, 2 Jul 2022 19:38:45 +0200 Subject: [PATCH 11/50] [Fix] Crash when erroding --- src/main/java/org/betterx/bclib/util/StructureErode.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/betterx/bclib/util/StructureErode.java b/src/main/java/org/betterx/bclib/util/StructureErode.java index adbb5a01..0a451a22 100644 --- a/src/main/java/org/betterx/bclib/util/StructureErode.java +++ b/src/main/java/org/betterx/bclib/util/StructureErode.java @@ -261,6 +261,7 @@ public class StructureErode { for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) { mut.setZ(z); BlockState top = BiomeAPI.findTopMaterial(world.getBiome(mut)).orElse(defaultBlock); + if (top == null) continue; for (int y = bounds.maxY(); y >= bounds.minY(); y--) { mut.setY(y); BlockState state = world.getBlockState(mut); From a3aae4c01646e3313d8b7b75c3f9068f259ec51a Mon Sep 17 00:00:00 2001 From: Frank Date: Sat, 2 Jul 2022 19:39:25 +0200 Subject: [PATCH 12/50] Corrected defult values --- .../v2/generator/config/BCLEndBiomeSourceConfig.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java b/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java index 8ab7a7db..d43d1005 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java @@ -31,7 +31,7 @@ public class BCLEndBiomeSourceConfig implements BiomeSourceConfig o.innerVoidRadiusSquared), Codec.INT .fieldOf("center_biomes_size") - .orElse(DEFAULT.innerVoidRadiusSquared) + .orElse(DEFAULT.centerBiomesSize) .forGetter(o -> o.centerBiomesSize), Codec.INT .fieldOf("void_biomes_size") - .orElse(DEFAULT.innerVoidRadiusSquared) + .orElse(DEFAULT.voidBiomesSize) .forGetter(o -> o.voidBiomesSize), Codec.INT .fieldOf("land_biomes_size") - .orElse(DEFAULT.innerVoidRadiusSquared) + .orElse(DEFAULT.landBiomesSize) .forGetter(o -> o.landBiomesSize), Codec.INT .fieldOf("barrens_biomes_size") - .orElse(DEFAULT.innerVoidRadiusSquared) + .orElse(DEFAULT.barrensBiomesSize) .forGetter(o -> o.barrensBiomesSize) ) .apply(instance, BCLEndBiomeSourceConfig::new)); From d6cf5a6cd9ed65abf34fbb6bd2cf5da08862ea10 Mon Sep 17 00:00:00 2001 From: Frank Date: Sat, 2 Jul 2022 19:40:09 +0200 Subject: [PATCH 13/50] More frequent cash dumps --- .../betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java index 8680c39d..9c657e6f 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java @@ -268,7 +268,8 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi ? ((long) config.innerVoidRadiusSquared + 1) : (long) posX * (long) posX + (long) posZ * (long) posZ; - if ((biomeX & 63) == 0 && (biomeZ & 63) == 0) { + + if ((biomeX & 63) == 0 || (biomeZ & 63) == 0) { mapLand.clearCache(); mapVoid.clearCache(); mapCenter.clearCache(); From 85f1d7b1e48b296bc612f6e574f3aef4aa65ede7 Mon Sep 17 00:00:00 2001 From: Frank Date: Sat, 2 Jul 2022 20:04:31 +0200 Subject: [PATCH 14/50] [Change] Moved Nether Config Settings to BiomeSource-Config --- .../api/v2/generator/BCLibEndBiomeSource.java | 2 +- .../v2/generator/BCLibNetherBiomeSource.java | 21 ++++------ .../api/v2/generator/GeneratorOptions.java | 40 +++++++------------ .../config/BCLNetherBiomeSourceConfig.java | 39 +++++++++++++++--- .../client/gui/screens/WorldSetupScreen.java | 5 ++- .../betterx/bclib/config/BiomesConfig.java | 7 ++++ 6 files changed, 69 insertions(+), 45 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java index 9c657e6f..e3fe68c8 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java @@ -93,7 +93,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi super(biomeRegistry, list, seed); this.config = config; var includeMap = Configs.BIOMES_CONFIG.getBiomeIncludeMap(); - var excludeList = Configs.BIOMES_CONFIG.getBiomeExcludeMap().get(BiomeAPI.BiomeType.END); + var excludeList = Configs.BIOMES_CONFIG.getExcludeMatching(BiomeAPI.BiomeType.END); endLandBiomePicker = new BiomePicker(biomeRegistry); endVoidBiomePicker = new BiomePicker(biomeRegistry); diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibNetherBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibNetherBiomeSource.java index e61257f5..834d1706 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibNetherBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibNetherBiomeSource.java @@ -5,7 +5,6 @@ import org.betterx.bclib.api.v2.generator.config.BCLNetherBiomeSourceConfig; import org.betterx.bclib.api.v2.generator.map.MapStack; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; -import org.betterx.bclib.config.ConfigKeeper.StringArrayEntry; import org.betterx.bclib.config.Configs; import org.betterx.bclib.interfaces.BiomeMap; import org.betterx.bclib.util.TriFunction; @@ -116,20 +115,16 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc } private static List> getBclBiomes(Registry biomeRegistry) { - List include = Configs.BIOMES_CONFIG.getEntry("force_include", "nether_biomes", StringArrayEntry.class) - .getValue(); - List exclude = Configs.BIOMES_CONFIG.getEntry("force_exclude", "nether_biomes", StringArrayEntry.class) - .getValue(); + List include = Configs.BIOMES_CONFIG.getIncludeMatching(BiomeAPI.BiomeType.NETHER); + List exclude = Configs.BIOMES_CONFIG.getExcludeMatching(BiomeAPI.BiomeType.NETHER); return getBiomes(biomeRegistry, exclude, include, BCLibNetherBiomeSource::isValidNonVanillaNetherBiome); } private static List> getBiomes(Registry biomeRegistry) { - List include = Configs.BIOMES_CONFIG.getEntry("force_include", "nether_biomes", StringArrayEntry.class) - .getValue(); - List exclude = Configs.BIOMES_CONFIG.getEntry("force_exclude", "nether_biomes", StringArrayEntry.class) - .getValue(); + List include = Configs.BIOMES_CONFIG.getIncludeMatching(BiomeAPI.BiomeType.NETHER); + List exclude = Configs.BIOMES_CONFIG.getExcludeMatching(BiomeAPI.BiomeType.NETHER); return getBiomes(biomeRegistry, exclude, include, BCLibNetherBiomeSource::isValidNetherBiome); } @@ -177,19 +172,19 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc @Override protected void onInitMap(long seed) { TriFunction mapConstructor = config.mapVersion.mapBuilder; - if (maxHeight > 128 && GeneratorOptions.useVerticalBiomes()) { + if (maxHeight > config.biomeSizeVertical * 1.5 && config.useVerticalBiomes) { this.biomeMap = new MapStack( seed, - GeneratorOptions.getBiomeSizeNether(), + config.biomeSize, biomePicker, - GeneratorOptions.getVerticalBiomeSizeNether(), + config.biomeSizeVertical, maxHeight, mapConstructor ); } else { this.biomeMap = mapConstructor.apply( seed, - GeneratorOptions.getBiomeSizeNether(), + config.biomeSize, biomePicker ); } diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/GeneratorOptions.java b/src/main/java/org/betterx/bclib/api/v2/generator/GeneratorOptions.java index fc1ba549..a15eef3e 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/GeneratorOptions.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/GeneratorOptions.java @@ -2,43 +2,28 @@ package org.betterx.bclib.api.v2.generator; import org.betterx.bclib.config.Configs; -import net.minecraft.util.Mth; - import java.awt.*; import java.util.function.BiFunction; import java.util.function.Function; public class GeneratorOptions { - private static int biomeSizeNether; - private static int biomeVSizeNether; private static BiFunction endLandFunction; - private static boolean customNetherBiomeSource = true; - private static boolean customEndBiomeSource = true; - private static boolean verticalBiomes = true; - private static long farEndBiomesSqr = 1000000; private static boolean fixEndBiomeSource = true; private static boolean fixNetherBiomeSource = true; public static void init() { - biomeSizeNether = Configs.GENERATOR_CONFIG.getInt("nether.biomeMap", "biomeSize", 256); - biomeVSizeNether = Configs.GENERATOR_CONFIG.getInt( - "nether.biomeMap", - "biomeVerticalSize(onlyInTallNether)", - 86 - ); - customNetherBiomeSource = Configs.GENERATOR_CONFIG.getBoolean("options", "customNetherBiomeSource", true); - customEndBiomeSource = Configs.GENERATOR_CONFIG.getBoolean("options", "customEndBiomeSource", true); - verticalBiomes = Configs.GENERATOR_CONFIG.getBoolean("options", "verticalBiomesInTallNether", true); fixEndBiomeSource = Configs.GENERATOR_CONFIG.getBoolean("options.biomeSource", "fixEndBiomeSource", true); fixNetherBiomeSource = Configs.GENERATOR_CONFIG.getBoolean("options.biomeSource", "fixNetherBiomeSource", true); } + @Deprecated(forRemoval = true) public static int getBiomeSizeNether() { - return Mth.clamp(biomeSizeNether, 1, 8192); + return 256; } + @Deprecated(forRemoval = true) public static int getVerticalBiomeSizeNether() { - return Mth.clamp(biomeVSizeNether, 1, 8192); + return 86; } @Deprecated(forRemoval = true) @@ -68,8 +53,9 @@ public class GeneratorOptions { return endLandFunction; } + @Deprecated(forRemoval = true) public static long getFarEndBiomes() { - return farEndBiomesSqr; + return 1000000; } /** @@ -77,8 +63,8 @@ public class GeneratorOptions { * * @param distance */ + @Deprecated(forRemoval = true) public static void setFarEndBiomes(int distance) { - GeneratorOptions.farEndBiomesSqr = (long) distance * (long) distance; } /** @@ -86,21 +72,25 @@ public class GeneratorOptions { * * @param distanceSqr the distance squared */ + @Deprecated(forRemoval = true) public static void setFarEndBiomesSqr(long distanceSqr) { - GeneratorOptions.farEndBiomesSqr = distanceSqr; + } + @Deprecated(forRemoval = true) public static boolean customNetherBiomeSource() { - return customNetherBiomeSource; + return true; } + @Deprecated(forRemoval = true) public static boolean customEndBiomeSource() { - return customEndBiomeSource; + return true; } + @Deprecated(forRemoval = true) public static boolean useVerticalBiomes() { - return verticalBiomes; + return true; } public static boolean fixEndBiomeSource() { diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLNetherBiomeSourceConfig.java b/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLNetherBiomeSourceConfig.java index 7a95c9da..d50e7313 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLNetherBiomeSourceConfig.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLNetherBiomeSourceConfig.java @@ -10,6 +10,7 @@ import org.betterx.worlds.together.biomesource.config.BiomeSourceConfig; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.util.Mth; import net.minecraft.util.StringRepresentable; import java.util.Objects; @@ -17,13 +18,22 @@ import org.jetbrains.annotations.NotNull; public class BCLNetherBiomeSourceConfig implements BiomeSourceConfig { public static final BCLNetherBiomeSourceConfig VANILLA = new BCLNetherBiomeSourceConfig( - NetherBiomeMapType.VANILLA + NetherBiomeMapType.VANILLA, + 256, + 86, + false ); public static final BCLNetherBiomeSourceConfig MINECRAFT_17 = new BCLNetherBiomeSourceConfig( - NetherBiomeMapType.SQUARE + NetherBiomeMapType.SQUARE, + 256, + 86, + true ); public static final BCLNetherBiomeSourceConfig MINECRAFT_18 = new BCLNetherBiomeSourceConfig( - NetherBiomeMapType.HEX + NetherBiomeMapType.HEX, + MINECRAFT_17.biomeSize, + MINECRAFT_17.biomeSizeVertical, + MINECRAFT_17.useVerticalBiomes ); public static final BCLNetherBiomeSourceConfig DEFAULT = MINECRAFT_18; @@ -32,13 +42,32 @@ public class BCLNetherBiomeSourceConfig implements BiomeSourceConfig o.mapVersion) + .forGetter(o -> o.mapVersion), + Codec.INT.fieldOf("biome_size").orElse(DEFAULT.biomeSize).forGetter(o -> o.biomeSize), + Codec.INT.fieldOf("biome_size_vertical") + .orElse(DEFAULT.biomeSizeVertical) + .forGetter(o -> o.biomeSizeVertical), + Codec.BOOL.fieldOf("use_vertical_biomes") + .orElse(DEFAULT.useVerticalBiomes) + .forGetter(o -> o.useVerticalBiomes) ) .apply(instance, BCLNetherBiomeSourceConfig::new)); public final @NotNull NetherBiomeMapType mapVersion; + public final int biomeSize; + public final int biomeSizeVertical; - public BCLNetherBiomeSourceConfig(@NotNull NetherBiomeMapType mapVersion) { + public final boolean useVerticalBiomes; + + public BCLNetherBiomeSourceConfig( + @NotNull NetherBiomeMapType mapVersion, + int biomeSize, + int biomeSizeVertical, + boolean useVerticalBiomes + ) { this.mapVersion = mapVersion; + this.biomeSize = Mth.clamp(biomeSize, 1, 8192); + this.biomeSizeVertical = Mth.clamp(biomeSizeVertical, 1, 8192); + this.useVerticalBiomes = useVerticalBiomes; } @Override diff --git a/src/main/java/org/betterx/bclib/client/gui/screens/WorldSetupScreen.java b/src/main/java/org/betterx/bclib/client/gui/screens/WorldSetupScreen.java index 65916b23..160d9139 100644 --- a/src/main/java/org/betterx/bclib/client/gui/screens/WorldSetupScreen.java +++ b/src/main/java/org/betterx/bclib/client/gui/screens/WorldSetupScreen.java @@ -207,7 +207,10 @@ public class WorldSetupScreen extends BCLibScreen { BCLNetherBiomeSourceConfig netherConfig = new BCLNetherBiomeSourceConfig( netherLegacy.isChecked() ? BCLNetherBiomeSourceConfig.NetherBiomeMapType.SQUARE - : BCLNetherBiomeSourceConfig.NetherBiomeMapType.HEX + : BCLNetherBiomeSourceConfig.NetherBiomeMapType.HEX, + BCLNetherBiomeSourceConfig.DEFAULT.biomeSize, + BCLNetherBiomeSourceConfig.DEFAULT.biomeSizeVertical, + BCLNetherBiomeSourceConfig.DEFAULT.useVerticalBiomes ); ChunkGenerator netherGenerator = betterxDimensions.get(LevelStem.NETHER); diff --git a/src/main/java/org/betterx/bclib/config/BiomesConfig.java b/src/main/java/org/betterx/bclib/config/BiomesConfig.java index c096b86e..9091cb62 100644 --- a/src/main/java/org/betterx/bclib/config/BiomesConfig.java +++ b/src/main/java/org/betterx/bclib/config/BiomesConfig.java @@ -79,6 +79,13 @@ public class BiomesConfig extends PathConfig { .toList(); } + public List getExcludeMatching(BiomeAPI.BiomeType type) { + var list = getBiomeExcludeMap().get(type); + if (list == null) return List.of(); + return list; + } + + public Map> getBiomeIncludeMap() { if (BIOME_INCLUDE_LIST == null) { BIOME_INCLUDE_LIST = new HashMap<>(); From c9baae0724f8d00ef6fb5f3b54de999bc56be1e5 Mon Sep 17 00:00:00 2001 From: Frank Date: Sat, 2 Jul 2022 20:06:10 +0200 Subject: [PATCH 15/50] Fixed JavaDoc --- .../betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java index 2f0cffcd..61bf9d75 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java @@ -285,7 +285,7 @@ public class InternalBiomeAPI { * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). * * @param biome The source biome to wrap - * @param genChance generation chance. If <0 the default genChance is used + * @param genChance generation chance. If <0 the default genChance is used * @return {@link BCLBiome} */ public static BCLBiome wrapNativeBiome(ResourceKey biome, float genChance, BiomeAPI.BiomeType type) { From 204f60174bc59a79fdec2a8d18876b0e4895352a Mon Sep 17 00:00:00 2001 From: Frank Date: Sat, 2 Jul 2022 20:07:05 +0200 Subject: [PATCH 16/50] Version Update --- gradle.properties | 2 +- src/main/resources/fabric.mod.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 5deee94f..774e809a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ minecraft_version=1.19 loader_version=0.14.8 fabric_version=0.57.0+1.19 # Mod Properties -mod_version=2.0.9 +mod_version=2.0.10 maven_group=org.betterx.bclib archives_base_name=bclib # Dependencies diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index c0a24182..bef018ed 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "id": "bclib", - "version": "2.0.9", + "version": "2.0.10", "name": "BCLib", "description": "A library for BetterX team mods", "authors": [ From 2bfb7a068780d063a8228db11d2bd9e28111db94 Mon Sep 17 00:00:00 2001 From: Frank Date: Sat, 2 Jul 2022 20:16:17 +0200 Subject: [PATCH 17/50] [Fix] `getExcludeMatching` just returns Biomes that have the exact type --- src/main/java/org/betterx/bclib/config/BiomesConfig.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/betterx/bclib/config/BiomesConfig.java b/src/main/java/org/betterx/bclib/config/BiomesConfig.java index 9091cb62..30c185da 100644 --- a/src/main/java/org/betterx/bclib/config/BiomesConfig.java +++ b/src/main/java/org/betterx/bclib/config/BiomesConfig.java @@ -80,9 +80,12 @@ public class BiomesConfig extends PathConfig { } public List getExcludeMatching(BiomeAPI.BiomeType type) { - var list = getBiomeExcludeMap().get(type); - if (list == null) return List.of(); - return list; + return getBiomeExcludeMap().entrySet() + .stream() + .filter(e -> e.getKey().is(type)) + .map(e -> e.getValue()) + .flatMap(Collection::stream) + .toList(); } From 89737d5f6c54f39742ce8d153674ea4cd02a131d Mon Sep 17 00:00:00 2001 From: Frank Date: Sat, 2 Jul 2022 20:16:48 +0200 Subject: [PATCH 18/50] [Fix] End BiomeSource would contain exlcuded biomes in the `possibleBiomes` list --- .../bclib/api/v2/generator/BCLibEndBiomeSource.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java index e3fe68c8..5d00d744 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java @@ -25,8 +25,10 @@ import net.minecraft.world.level.biome.Climate; import net.minecraft.world.level.levelgen.DensityFunction; import java.awt.*; +import java.util.HashMap; import java.util.List; -import java.util.*; +import java.util.Map; +import java.util.Set; import java.util.function.BiFunction; import org.jetbrains.annotations.NotNull; @@ -188,7 +190,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi private static List> getBclBiomes(Registry biomeRegistry) { return getBiomes( biomeRegistry, - new ArrayList<>(0), + Configs.BIOMES_CONFIG.getExcludeMatching(BiomeAPI.BiomeType.END), Configs.BIOMES_CONFIG.getIncludeMatching(BiomeAPI.BiomeType.END), BCLibEndBiomeSource::isValidNonVanillaEndBiome ); @@ -197,7 +199,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi private static List> getBiomes(Registry biomeRegistry) { return getBiomes( biomeRegistry, - new ArrayList<>(0), + Configs.BIOMES_CONFIG.getExcludeMatching(BiomeAPI.BiomeType.END), Configs.BIOMES_CONFIG.getIncludeMatching(BiomeAPI.BiomeType.END), BCLibEndBiomeSource::isValidEndBiome ); From 3e81071b96053d4935ed93ec6e1fe3f12b2ea8ff Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 12:42:30 +0200 Subject: [PATCH 19/50] [Change] BCLBiome is no longer a wrapper around a Biome-Instance but references the Biome by ResourceKey [Fix] Crash with Promenade (#15) --- .../api/v2/generator/BCLibEndBiomeSource.java | 5 +- .../v2/generator/BCLibNetherBiomeSource.java | 13 +- .../api/v2/generator/TheEndBiomesHelper.java | 2 +- .../api/v2/levelgen/biomes/BCLBiome.java | 83 ++++++++--- .../v2/levelgen/biomes/BCLBiomeBuilder.java | 134 ++++++++++-------- .../api/v2/levelgen/biomes/BiomeAPI.java | 116 ++++++++++----- .../v2/levelgen/biomes/InternalBiomeAPI.java | 42 +++--- .../worlds/together/tag/v3/TagRegistry.java | 18 +++ 8 files changed, 274 insertions(+), 139 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java index 5d00d744..6520216e 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java @@ -114,7 +114,10 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi String biomeStr = biomeID.toString(); //exclude everything that was listed if (excludeList != null && excludeList.contains(biomeStr)) return; - + if (!biome.isBound()) { + BCLib.LOGGER.warning("Biome " + biomeStr + " is requested but not yet bound."); + return; + } final BCLBiome bclBiome; if (!BiomeAPI.hasBiome(biomeID)) { bclBiome = new BCLBiome(biomeID, biome.value()); diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibNetherBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibNetherBiomeSource.java index 834d1706..bdf504b4 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibNetherBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibNetherBiomeSource.java @@ -81,13 +81,16 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc biomePicker = new BiomePicker(biomeRegistry); this.possibleBiomes().forEach(biome -> { - ResourceLocation key = biome.unwrapKey().orElseThrow().location(); - - if (!BiomeAPI.hasBiome(key)) { - BCLBiome bclBiome = new BCLBiome(key, biome.value()); + ResourceLocation biomeID = biome.unwrapKey().orElseThrow().location(); + if (!biome.isBound()) { + BCLib.LOGGER.warning("Biome " + biomeID.toString() + " is requested but not yet bound."); + return; + } + if (!BiomeAPI.hasBiome(biomeID)) { + BCLBiome bclBiome = new BCLBiome(biomeID, biome.value()); biomePicker.addBiome(bclBiome); } else { - BCLBiome bclBiome = BiomeAPI.getBiome(key); + BCLBiome bclBiome = BiomeAPI.getBiome(biomeID); if (bclBiome != BiomeAPI.EMPTY_BIOME) { if (bclBiome.getParentBiome() == null) { diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/TheEndBiomesHelper.java b/src/main/java/org/betterx/bclib/api/v2/generator/TheEndBiomesHelper.java index 07dffc7a..93fe1d91 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/TheEndBiomesHelper.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/TheEndBiomesHelper.java @@ -17,7 +17,7 @@ import org.jetbrains.annotations.ApiStatus; */ public class TheEndBiomesHelper { @ApiStatus.Internal - public static Map>> END_BIOMES = new HashMap<>(); + private static Map>> END_BIOMES = new HashMap<>(); @ApiStatus.Internal public static void add(BiomeAPI.BiomeType type, ResourceKey biome) { diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java index ddaabf10..6d99d2a6 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java @@ -3,6 +3,7 @@ package org.betterx.bclib.api.v2.levelgen.biomes; import org.betterx.bclib.util.WeightedList; import org.betterx.worlds.together.tag.v3.TagManager; +import net.minecraft.core.Registry; import net.minecraft.data.BuiltinRegistries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -28,7 +29,8 @@ public class BCLBiome extends BCLBiomeSettings { private final WeightedList subbiomes = new WeightedList<>(); private final Map customData = Maps.newHashMap(); private final ResourceLocation biomeID; - private final Biome biome; + private final ResourceKey biomeKey; + final Biome biomeToRegister; private final List parameterPoints = Lists.newArrayList(); @@ -49,43 +51,74 @@ public class BCLBiome extends BCLBiomeSettings { * @param biomeID {@link ResourceLocation} biome ID. */ protected BCLBiome(ResourceLocation biomeID) { - this(biomeID, BuiltinRegistries.BIOME.get(biomeID), null); + this(ResourceKey.create(Registry.BIOME_REGISTRY, biomeID), null); } /** * Create wrapper for existing biome using biome instance from {@link BuiltinRegistries}. * - * @param biome {@link Biome} to wrap. + * @param biomeToRegister {@link Biome} to wrap. */ - protected BCLBiome(Biome biome) { - this(biome, null); + @Deprecated(forRemoval = true) + protected BCLBiome(Biome biomeToRegister) { + this(biomeToRegister, null); } /** * Create wrapper for existing biome using biome instance from {@link BuiltinRegistries}. * - * @param biome {@link Biome} to wrap. - * @param settings The Settings for this Biome or {@code null} if you want to apply default settings + * @param biomeToRegister {@link Biome} to wrap. + * @param settings The Settings for this Biome or {@code null} if you want to apply default settings */ - protected BCLBiome(Biome biome, VanillaBiomeSettings settings) { - this(BiomeAPI.getBiomeID(biome), biome, settings); + @Deprecated(forRemoval = true) + protected BCLBiome(Biome biomeToRegister, VanillaBiomeSettings settings) { + this(BiomeAPI.getBiomeID(biomeToRegister), biomeToRegister, settings); } - public BCLBiome(ResourceLocation biomeID, Biome biome) { - this(biomeID, biome, null); + /** + * Create wrapper for existing biome using biome instance from {@link BuiltinRegistries}. + * + * @param biomeToRegister {@link Biome} to wrap. + * @param biomeID Teh ResoureLocation for this Biome + */ + @Deprecated(forRemoval = true) + public BCLBiome(ResourceLocation biomeID, Biome biomeToRegister) { + this(biomeID, biomeToRegister, null); } /** * Create a new Biome * - * @param biomeID {@link ResourceLocation} biome ID. - * @param biome {@link Biome} to wrap. + * @param biomeID {@link ResourceLocation} biome ID. + * @param biomeToRegister {@link Biome} to wrap. + * @param defaults The Settings for this Biome or null if you want to apply the defaults + */ + protected BCLBiome(ResourceLocation biomeID, Biome biomeToRegister, BCLBiomeSettings defaults) { + this(ResourceKey.create(Registry.BIOME_REGISTRY, biomeID), biomeToRegister, defaults); + } + + /** + * Create a new Biome + * + * @param biomeKey {@link ResourceKey} of the wrapped Biome * @param defaults The Settings for this Biome or null if you want to apply the defaults */ - protected BCLBiome(ResourceLocation biomeID, Biome biome, BCLBiomeSettings defaults) { + protected BCLBiome(ResourceKey biomeKey, BCLBiomeSettings defaults) { + this(biomeKey, null, defaults); + } + + /** + * Create a new Biome + * + * @param biomeKey {@link ResourceKey} of the wrapped Biome + * @param biomeToRegister The biome you want to use when this instance gets registered through the {@link BiomeAPI} + * @param defaults The Settings for this Biome or null if you want to apply the defaults + */ + protected BCLBiome(ResourceKey biomeKey, Biome biomeToRegister, BCLBiomeSettings defaults) { + this.biomeToRegister = biomeToRegister; this.subbiomes.add(this, 1.0F); - this.biomeID = biomeID; - this.biome = biome; + this.biomeID = biomeKey.location(); + this.biomeKey = biomeKey; if (defaults != null) { defaults.applyWithDefaults(this); @@ -203,16 +236,26 @@ public class BCLBiome extends BCLBiomeSettings { * * @return {@link Biome}. */ - public Biome getBiome() { - return biome; + @Deprecated(forRemoval = true) + public Biome getBiomeOld() { + if (biomeToRegister != null) return biomeToRegister; + return BiomeAPI.getFromBuiltinRegistry(biomeKey).value(); + } + + /** + * Getter for biomeKey + * + * @return {@link ResourceKey}. + */ + public ResourceKey getBiomeKey() { + return biomeKey; } /** * For internal use from BiomeAPI only */ void afterRegistration() { - ResourceKey key = BuiltinRegistries.BIOME.getResourceKey(getBiome()).orElseThrow(); - this.biomeTags.forEach(tagKey -> TagManager.BIOMES.add(tagKey, biome)); + this.biomeTags.forEach(tagKey -> TagManager.BIOMES.add(tagKey, this)); } diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeBuilder.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeBuilder.java index 8de19f94..ba395cfb 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeBuilder.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeBuilder.java @@ -10,6 +10,7 @@ import org.betterx.bclib.util.ColorUtil; import org.betterx.bclib.util.Pair; import org.betterx.bclib.util.TriFunction; import org.betterx.worlds.together.surfaceRules.SurfaceRuleRegistry; +import org.betterx.worlds.together.tag.v3.TagManager; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; @@ -72,7 +73,6 @@ public class BCLBiomeBuilder { private final List parameters = Lists.newArrayList(); - //BiomeTags.IS_NETHER private float temperature; private float fogDensity; private float genChance; @@ -82,6 +82,8 @@ public class BCLBiomeBuilder { private BCLBiome edge; private boolean vertical; + private BiomeAPI.BiomeType biomeType; + /** * Starts new biome building process. @@ -106,6 +108,7 @@ public class BCLBiomeBuilder { INSTANCE.carvers.clear(); INSTANCE.parameters.clear(); INSTANCE.tags.clear(); + INSTANCE.biomeType = null; return INSTANCE; } @@ -114,6 +117,17 @@ public class BCLBiomeBuilder { return this; } + /** + * Set the type for this Biome. If the type was set, the Biome can be registered. + * + * @param type selected Type + * @return same {@link BCLBiomeBuilder} instance. + */ + public BCLBiomeBuilder type(BiomeAPI.BiomeType type) { + this.biomeType = type; + return this; + } + /** * Set biome {@link Precipitation}. Affect biome visual effects (rain, snow, none). * @@ -724,26 +738,6 @@ public class BCLBiomeBuilder { return this; } - /** - * Finalize biome creation. - * - * @return created {@link BCLBiome} instance. - */ - public BCLBiome build() { - return build((BiomeSupplier) BCLBiome::new); - } - - /** - * Finalize biome creation. - * - * @param biomeConstructor {@link BiFunction} biome constructor. - * @return created {@link BCLBiome} instance. - * @deprecated Replaced with {@link #build(BiomeSupplier)} - */ - @Deprecated(forRemoval = true) - public T build(BiFunction biomeConstructor) { - return build((id, biome, settings) -> biomeConstructor.apply(id, biome)); - } private static BiomeGenerationSettings fixGenerationSettings(BiomeGenerationSettings settings) { //Fabric Biome Modification API can not handle an empty carver map, thus we will create one with @@ -760,43 +754,6 @@ public class BCLBiomeBuilder { return settings; } - /** - * Finalize biome creation. - * - * @param biomeConstructor {@link BiomeSupplier} biome constructor. - * @return created {@link BCLBiome} instance. - */ - public T build(BiomeSupplier biomeConstructor) { - BiomeBuilder builder = new BiomeBuilder() - .precipitation(precipitation) - .temperature(temperature) - .downfall(downfall); - - builder.mobSpawnSettings(getSpawns().build()); - builder.specialEffects(getEffects().build()); - - builder.generationSettings(fixGenerationSettings(getGeneration().build())); - - BCLBiomeSettings settings = BCLBiomeSettings.createBCL() - .setTerrainHeight(height) - .setFogDensity(fogDensity) - .setGenChance(genChance) - .setEdgeSize(edgeSize) - .setEdge(edge) - .setVertical(vertical) - .build(); - - final Biome biome = builder.build(); - final T res = biomeConstructor.apply(biomeID, biome, settings); - res.addBiomeTags(tags); - //res.setSurface(surfaceRule); - SurfaceRuleRegistry.registerRule(biomeID, surfaceRule, biomeID); - res.addClimateParameters(parameters); - - - //carvers.forEach(cfg -> BiomeAPI.addBiomeCarver(biome, cfg.second, cfg.first)); - return res; - } /** * Get or create {@link BiomeSpecialEffects.Builder} for biome visual effects. @@ -837,4 +794,65 @@ public class BCLBiomeBuilder { } return generationSettings; } + + /** + * Finalize biome creation. + * + * @return created {@link BCLBiome} instance. + */ + public BCLBiome build() { + return build((BiomeSupplier) BCLBiome::new); + } + + /** + * Finalize biome creation. + * + * @param biomeConstructor {@link BiFunction} biome constructor. + * @return created {@link BCLBiome} instance. + * @deprecated Replaced with {@link #build(BiomeSupplier)} + */ + @Deprecated(forRemoval = true) + public T build(BiFunction biomeConstructor) { + return build((id, biome, settings) -> biomeConstructor.apply(id, biome)); + } + + /** + * Finalize biome creation. + * + * @param biomeConstructor {@link BiomeSupplier} biome constructor. + * @return created {@link BCLBiome} instance. + */ + public T build(BiomeSupplier biomeConstructor) { + BiomeBuilder builder = new BiomeBuilder() + .precipitation(precipitation) + .temperature(temperature) + .downfall(downfall); + + builder.mobSpawnSettings(getSpawns().build()); + builder.specialEffects(getEffects().build()); + + builder.generationSettings(fixGenerationSettings(getGeneration().build())); + + BCLBiomeSettings settings = BCLBiomeSettings.createBCL() + .setTerrainHeight(height) + .setFogDensity(fogDensity) + .setGenChance(genChance) + .setEdgeSize(edgeSize) + .setEdge(edge) + .setVertical(vertical) + .build(); + + final Biome biome = builder.build(); + final T res = biomeConstructor.apply(biomeID, biome, settings); + tags.forEach(tagKey -> TagManager.BIOMES.add(tagKey, res)); + + //res.addBiomeTags(tags); + //res.setSurface(surfaceRule); + SurfaceRuleRegistry.registerRule(biomeID, surfaceRule, biomeID); + res.addClimateParameters(parameters); + + + //carvers.forEach(cfg -> BiomeAPI.addBiomeCarver(biome, cfg.second, cfg.first)); + return res; + } } diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java index 543be1d3..4f072fc8 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java @@ -26,7 +26,6 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; 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.Biomes; import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData; import net.minecraft.world.level.block.state.BlockState; @@ -174,19 +173,29 @@ public class BiomeAPI { * @return {@link BCLBiome} */ public static BCLBiome registerBiome(BCLBiome bclbiome, BiomeType dim) { - if (BuiltinRegistries.BIOME.get(bclbiome.getID()) == null) { - final Biome biome = bclbiome.getBiome(); - ResourceLocation loc = bclbiome.getID(); - Registry.register(BuiltinRegistries.BIOME, loc, biome); + return registerBiome(bclbiome, dim, BuiltinRegistries.BIOME); + } + + /** + * Register {@link BCLBiome} instance and its {@link Biome} if necessary. + * + * @param bclbiome {@link BCLBiome} + * @param dim The Dimension fo rthis Biome + * @return {@link BCLBiome} + */ + static BCLBiome registerBiome(BCLBiome bclbiome, BiomeType dim, Registry registryOrNull) { + if (registryOrNull != null && bclbiome.biomeToRegister != null && registryOrNull.get(bclbiome.getID()) == null) { + Registry.register(registryOrNull, bclbiome.getBiomeKey(), bclbiome.biomeToRegister); } + ID_MAP.put(bclbiome.getID(), bclbiome); BiomeType.BIOME_TYPE_MAP.put(bclbiome.getID(), dim); if (dim != null && dim.is(BiomeType.NETHER)) { - TagManager.BIOMES.add(BiomeTags.IS_NETHER, bclbiome.getBiome()); - TagManager.BIOMES.add(CommonBiomeTags.IN_NETHER, bclbiome.getBiome()); + TagManager.BIOMES.add(BiomeTags.IS_NETHER, bclbiome); + TagManager.BIOMES.add(CommonBiomeTags.IN_NETHER, bclbiome); } else if (dim != null && dim.is(BiomeType.END)) { - TagManager.BIOMES.add(BiomeTags.IS_END, bclbiome.getBiome()); + TagManager.BIOMES.add(BiomeTags.IS_END, bclbiome); } bclbiome.afterRegistration(); @@ -234,10 +243,10 @@ public class BiomeAPI { registerBiome(biome, BiomeType.BCL_END_LAND); float weight = biome.getGenChance(); - ResourceKey key = getBiomeKey(biome.getBiome()); + ResourceKey key = biome.getBiomeKey(); if (biome.allowFabricRegistration()) { if (biome.isEdgeBiome()) { - ResourceKey parentKey = getBiomeKey(biome.getParentBiome().getBiome()); + ResourceKey parentKey = biome.getParentBiome().getBiomeKey(); TheEndBiomes.addMidlandsBiome(parentKey, key, weight); } else { TheEndBiomes.addHighlandsBiome(key, weight); @@ -258,7 +267,7 @@ public class BiomeAPI { registerBiome(biome, BiomeType.BCL_END_VOID); float weight = biome.getGenChance(); - ResourceKey key = getBiomeKey(biome.getBiome()); + ResourceKey key = biome.getBiomeKey(); if (biome.allowFabricRegistration()) { TheEndBiomes.addSmallIslandsBiome(key, weight); } @@ -277,7 +286,7 @@ public class BiomeAPI { registerBiome(biome, BiomeType.BCL_END_CENTER); float weight = biome.getGenChance(); - ResourceKey key = getBiomeKey(biome.getBiome()); + ResourceKey key = biome.getBiomeKey(); if (biome.allowFabricRegistration()) { TheEndBiomes.addMainIslandBiome(key, weight); } @@ -296,9 +305,9 @@ public class BiomeAPI { registerBiome(biome, BiomeType.BCL_END_BARRENS); float weight = biome.getGenChance(); - ResourceKey key = getBiomeKey(biome.getBiome()); + ResourceKey key = biome.getBiomeKey(); if (biome.allowFabricRegistration()) { - ResourceKey parentKey = getBiomeKey(highlandBiome.getBiome()); + ResourceKey parentKey = highlandBiome.getBiomeKey(); TheEndBiomes.addBarrensBiome(parentKey, key, weight); } return biome; @@ -416,23 +425,29 @@ public class BiomeAPI { } public static Holder getBiomeHolder(BCLBiome biome) { - return getBiomeHolder(biome.getBiome()); + return getBiomeHolder(biome.getBiomeKey()); } public static Holder getBiomeHolder(Biome biome) { + Optional> key = Optional.empty(); if (InternalBiomeAPI.biomeRegistry != null) { - Optional> key = InternalBiomeAPI.biomeRegistry.getResourceKey(biome); - if (key.isPresent()) return InternalBiomeAPI.biomeRegistry.getOrCreateHolderOrThrow(key.get()); + key = InternalBiomeAPI.biomeRegistry.getResourceKey(biome); + } else { + key = BuiltinRegistries.BIOME.getResourceKey(biome); } - return BuiltinRegistries.BIOME.getOrCreateHolderOrThrow(BiomeAPI.getBiomeKey(biome)); + return getBiomeHolder(key.orElseThrow()); + } + + public static Holder getBiomeHolder(ResourceKey biomeKey) { + if (InternalBiomeAPI.biomeRegistry != null) { + return InternalBiomeAPI.biomeRegistry.getOrCreateHolderOrThrow(biomeKey); + } + return BuiltinRegistries.BIOME.getOrCreateHolderOrThrow(biomeKey); } public static Holder getBiomeHolder(ResourceLocation biome) { - if (InternalBiomeAPI.biomeRegistry != null) { - return getBiomeHolder(InternalBiomeAPI.biomeRegistry.get(biome)); - } - return getBiomeHolder(BuiltinRegistries.BIOME.get(biome)); + return getBiomeHolder(ResourceKey.create(Registry.BIOME_REGISTRY, biome)); } /** @@ -475,18 +490,45 @@ public class BiomeAPI { return ID_MAP.containsKey(biomeID); } - @Nullable - public static Holder getFromRegistry(ResourceLocation key) { - return BuiltinRegistries.BIOME.getHolder(ResourceKey.create(Registry.BIOME_REGISTRY, key)).orElseThrow(); + public static Holder getFromRegistry(ResourceLocation biomeID) { + if (InternalBiomeAPI.biomeRegistry != null) + return InternalBiomeAPI.biomeRegistry.getHolder(ResourceKey.create(Registry.BIOME_REGISTRY, biomeID)) + .orElseThrow(); + return getFromBuiltinRegistry(biomeID); } @Nullable public static Holder getFromRegistry(ResourceKey key) { + if (InternalBiomeAPI.biomeRegistry != null) + return InternalBiomeAPI.biomeRegistry.getHolder(key).orElseThrow(); + return getFromBuiltinRegistry(key); + } + + @Nullable + public static Holder getFromBuiltinRegistry(ResourceLocation biomeID) { + return BuiltinRegistries.BIOME.getHolder(ResourceKey.create(Registry.BIOME_REGISTRY, biomeID)).orElseThrow(); + } + + @Nullable + public static Holder getFromBuiltinRegistry(ResourceKey key) { return BuiltinRegistries.BIOME.getOrCreateHolderOrThrow(key); } + @Deprecated(forRemoval = true) + public static boolean registryContains(ResourceKey key) { + if (InternalBiomeAPI.biomeRegistry != null) + return InternalBiomeAPI.biomeRegistry.containsKey(key); + return builtinRegistryContains(key); + } + + @Nullable + @Deprecated(forRemoval = true) + public static boolean builtinRegistryContains(ResourceKey key) { + return BuiltinRegistries.BIOME.containsKey(key); + } + public static boolean isDatapackBiome(ResourceLocation biomeID) { - return getFromRegistry(biomeID) == null; + return getFromBuiltinRegistry(biomeID) == null; } public static boolean wasRegisteredAs(ResourceLocation biomeID, BiomeType dim) { @@ -619,16 +661,16 @@ public class BiomeAPI { } static void sortBiomeFeatures(Biome biome) { - BiomeGenerationSettings settings = biome.getGenerationSettings(); - BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) settings; - List> featureList = CollectionsUtil.getMutable(accessor.bclib_getFeatures()); - final int size = featureList.size(); - for (int i = 0; i < size; i++) { - List> features = getFeaturesListCopy(featureList, i); - sortFeatures(features); - featureList.set(i, HolderSet.direct(features)); - } - accessor.bclib_setFeatures(featureList); +// BiomeGenerationSettings settings = biome.getGenerationSettings(); +// BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) settings; +// List> featureList = CollectionsUtil.getMutable(accessor.bclib_getFeatures()); +// final int size = featureList.size(); +// for (int i = 0; i < size; i++) { +// List> features = getFeaturesListCopy(featureList, i); +// sortFeatures(features); +// featureList.set(i, HolderSet.direct(features)); +// } +// accessor.bclib_setFeatures(featureList); } /** @@ -846,7 +888,7 @@ public class BiomeAPI { public static BCLBiome registerNetherBiome(BCLBiome bclBiome) { registerBiome(bclBiome, BiomeType.BCL_NETHER); - ResourceKey key = getBiomeKey(bclBiome.getBiome()); + ResourceKey key = bclBiome.getBiomeKey(); if (bclBiome.allowFabricRegistration()) { bclBiome.forEachClimateParameter(p -> NetherBiomes.addNetherBiome(key, p)); } diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java index 61bf9d75..f381955c 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java @@ -273,31 +273,31 @@ public class InternalBiomeAPI { * Register {@link BCLBiome} wrapper for {@link Biome}. * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). * - * @param biome The source biome to wrap + * @param biomeKey The source biome to wrap * @return {@link BCLBiome} */ - public static BCLBiome wrapNativeBiome(ResourceKey biome, BiomeAPI.BiomeType type) { - return wrapNativeBiome(biome, -1, type); + public static BCLBiome wrapNativeBiome(ResourceKey biomeKey, BiomeAPI.BiomeType type) { + return wrapNativeBiome(biomeKey, -1, type); } /** * Register {@link BCLBiome} wrapper for {@link Biome}. * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). * - * @param biome The source biome to wrap + * @param biomeKey The source biome to wrap * @param genChance generation chance. If <0 the default genChance is used * @return {@link BCLBiome} */ - public static BCLBiome wrapNativeBiome(ResourceKey biome, float genChance, BiomeAPI.BiomeType type) { + public static BCLBiome wrapNativeBiome(ResourceKey biomeKey, float genChance, BiomeAPI.BiomeType type) { return wrapNativeBiome( - biome, + biomeKey, genChance < 0 ? null : VanillaBiomeSettings.createVanilla().setGenChance(genChance).build(), type ); } public static BCLBiome wrapNativeBiome( - ResourceKey biome, + ResourceKey biomeKey, BCLBiome edgeBiome, int edgeBiomeSize, float genChance, @@ -307,28 +307,25 @@ public class InternalBiomeAPI { if (genChance >= 0) settings.setGenChance(genChance); settings.setEdge(edgeBiome); settings.setEdgeSize(edgeBiomeSize); - return wrapNativeBiome(biome, settings.build(), type); + return wrapNativeBiome(biomeKey, settings.build(), type); } /** * Register {@link BCLBiome} wrapper for {@link Biome}. * After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands). * - * @param biome The source biome to wrap - * @param setings the {@link VanillaBiomeSettings} to use + * @param biomeKey The source biome to wrap + * @param setings the {@link VanillaBiomeSettings} to use * @return {@link BCLBiome} */ private static BCLBiome wrapNativeBiome( - ResourceKey biome, + ResourceKey biomeKey, VanillaBiomeSettings setings, BiomeAPI.BiomeType type ) { - BCLBiome bclBiome = BiomeAPI.getBiome(biome.location()); + BCLBiome bclBiome = BiomeAPI.getBiome(biomeKey.location()); if (bclBiome == BiomeAPI.EMPTY_BIOME) { - bclBiome = new BCLBiome( - BiomeAPI.getFromRegistry(biome).value(), - setings - ); + bclBiome = new BCLBiome(biomeKey, setings); } BiomeAPI.registerBiome(bclBiome, type); @@ -343,6 +340,7 @@ public class InternalBiomeAPI { * @param genChance generation chance. * @return {@link BCLBiome} */ + @Deprecated(forRemoval = true) static BCLBiome wrapNativeBiome(Biome biome, float genChance, BiomeAPI.BiomeType type) { BCLBiome bclBiome = BiomeAPI.getBiome(biome); if (bclBiome == BiomeAPI.EMPTY_BIOME) { @@ -352,7 +350,7 @@ public class InternalBiomeAPI { ); } - BiomeAPI.registerBiome(bclBiome, type); + BiomeAPI.registerBiome(bclBiome, type, null); return bclBiome; } @@ -370,4 +368,14 @@ public class InternalBiomeAPI { }); }); } + + public static boolean registryContainsBound(ResourceKey key) { + Registry reg = biomeRegistry; + if (reg == null) reg = BuiltinRegistries.BIOME; + + if (reg.containsKey(key)) { + return reg.getOrCreateHolderOrThrow(key).isBound(); + } + return false; + } } diff --git a/src/main/java/org/betterx/worlds/together/tag/v3/TagRegistry.java b/src/main/java/org/betterx/worlds/together/tag/v3/TagRegistry.java index 54472d83..1c5bb2da 100644 --- a/src/main/java/org/betterx/worlds/together/tag/v3/TagRegistry.java +++ b/src/main/java/org/betterx/worlds/together/tag/v3/TagRegistry.java @@ -1,6 +1,7 @@ package org.betterx.worlds.together.tag.v3; import org.betterx.bclib.BCLib; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI; import net.minecraft.core.DefaultedRegistry; @@ -83,6 +84,23 @@ public class TagRegistry { super(Registry.BIOME_REGISTRY, directory, locationProvider); } + /** + * Adds one Tag to multiple Elements. + * + * @param tagID {@link TagKey< Biome >} tag ID. + * @param elements array of Elements to add into tag. + */ + public void add(TagKey tagID, BCLBiome... elements) { + if (isFrozen) BCLib.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); + Set set = getSetForTag(tagID); + for (BCLBiome element : elements) { + ResourceLocation id = element.getID(); + if (id != null) { + set.add(TagEntry.element(id)); + } + } + } + public TagKey makeStructureTag(String modID, String name) { return makeTag(modID, "has_structure/" + name); } From 102db44595e0c6d545cd22c1296ea938178a8678 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 12:54:42 +0200 Subject: [PATCH 20/50] [Change] Added old End Biome-tag --- .../betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java | 10 +--------- .../betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java | 2 ++ .../worlds/together/tag/v3/CommonBiomeTags.java | 1 + 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java index 6d99d2a6..de552400 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java @@ -1,7 +1,6 @@ package org.betterx.bclib.api.v2.levelgen.biomes; import org.betterx.bclib.util.WeightedList; -import org.betterx.worlds.together.tag.v3.TagManager; import net.minecraft.core.Registry; import net.minecraft.data.BuiltinRegistries; @@ -255,7 +254,7 @@ public class BCLBiome extends BCLBiomeSettings { * For internal use from BiomeAPI only */ void afterRegistration() { - this.biomeTags.forEach(tagKey -> TagManager.BIOMES.add(tagKey, this)); + } @@ -327,13 +326,6 @@ public class BCLBiome extends BCLBiomeSettings { return biomeID.toString(); } - /** - * Adds structures to this biome. For internal use only. - * Used inside {@link BCLBiomeBuilder}. - */ - void addBiomeTags(Set> tags) { - biomeTags.addAll(tags); - } /** * Adds structures to this biome. For internal use only. diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java index 4f072fc8..4cb43b0a 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java @@ -196,6 +196,7 @@ public class BiomeAPI { TagManager.BIOMES.add(CommonBiomeTags.IN_NETHER, bclbiome); } else if (dim != null && dim.is(BiomeType.END)) { TagManager.BIOMES.add(BiomeTags.IS_END, bclbiome); + TagManager.BIOMES.add(CommonBiomeTags.IN_END, bclbiome); } bclbiome.afterRegistration(); @@ -335,6 +336,7 @@ public class BiomeAPI { * @param biome - {@link Holder} from world. * @return {@link BCLBiome} or {@code BiomeAPI.EMPTY_BIOME}. */ + @Deprecated(forRemoval = true) public static BCLBiome getFromBiome(Holder biome) { if (InternalBiomeAPI.biomeRegistry == null) { return EMPTY_BIOME; diff --git a/src/main/java/org/betterx/worlds/together/tag/v3/CommonBiomeTags.java b/src/main/java/org/betterx/worlds/together/tag/v3/CommonBiomeTags.java index 5db5278f..8976ddfe 100644 --- a/src/main/java/org/betterx/worlds/together/tag/v3/CommonBiomeTags.java +++ b/src/main/java/org/betterx/worlds/together/tag/v3/CommonBiomeTags.java @@ -5,6 +5,7 @@ import net.minecraft.world.level.biome.Biome; public class CommonBiomeTags { public static final TagKey IN_NETHER = TagManager.BIOMES.makeCommonTag("in_nether"); + public static final TagKey IN_END = TagManager.BIOMES.makeCommonTag("in_end"); static void prepareTags() { } From 0eb857e293775945d5e8532cd0604720b43f7d7e Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 12:55:27 +0200 Subject: [PATCH 21/50] Reformated --- .../org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java index 4cb43b0a..c28370a5 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java @@ -184,7 +184,9 @@ public class BiomeAPI { * @return {@link BCLBiome} */ static BCLBiome registerBiome(BCLBiome bclbiome, BiomeType dim, Registry registryOrNull) { - if (registryOrNull != null && bclbiome.biomeToRegister != null && registryOrNull.get(bclbiome.getID()) == null) { + if (registryOrNull != null + && bclbiome.biomeToRegister != null + && registryOrNull.get(bclbiome.getID()) == null) { Registry.register(registryOrNull, bclbiome.getBiomeKey(), bclbiome.biomeToRegister); } From b3c58b42e991dbd70e40d9f5a3f58f33821ceb78 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 13:35:12 +0200 Subject: [PATCH 22/50] [Fix] Dimension height is not updated for repaired BiomeSources (quiqueck/BetterEnd#28) --- .../bclib/api/v2/generator/BCLBiomeSource.java | 9 ++++++++- .../bclib/api/v2/generator/BCLChunkGenerator.java | 5 +++-- .../betterx/bclib/mixin/common/ServerLevelMixin.java | 11 +++++++++-- .../worlds/together/levelgen/WorldGenUtil.java | 7 +++++++ .../world/BiomeSourceWithNoiseRelatedSettings.java | 7 +++++++ 5 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/betterx/worlds/together/world/BiomeSourceWithNoiseRelatedSettings.java diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLBiomeSource.java index b495ed67..6e01ee27 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLBiomeSource.java @@ -2,6 +2,7 @@ package org.betterx.bclib.api.v2.generator; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.worlds.together.biomesource.MergeableBiomeSource; +import org.betterx.worlds.together.world.BiomeSourceWithNoiseRelatedSettings; import org.betterx.worlds.together.world.BiomeSourceWithSeed; import net.minecraft.core.Holder; @@ -9,6 +10,7 @@ import net.minecraft.core.Registry; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeSource; +import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; import com.google.common.collect.Sets; @@ -16,7 +18,7 @@ import java.util.Comparator; import java.util.List; import java.util.Set; -public abstract class BCLBiomeSource extends BiomeSource implements BiomeSourceWithSeed, MergeableBiomeSource { +public abstract class BCLBiomeSource extends BiomeSource implements BiomeSourceWithSeed, MergeableBiomeSource, BiomeSourceWithNoiseRelatedSettings { protected final Registry biomeRegistry; protected long currentSeed; protected int maxHeight; @@ -110,4 +112,9 @@ public abstract class BCLBiomeSource extends BiomeSource implements BiomeSourceW final Set> datapackBiomes = inputBiomeSource.possibleBiomes(); return this.createCopyForDatapack(datapackBiomes); } + + public void onLoadGeneratorSettings(NoiseGeneratorSettings generator) { + this.setMaxHeight(generator.noiseSettings().height()); + } + } diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLChunkGenerator.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLChunkGenerator.java index d18958f8..160614ba 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLChunkGenerator.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLChunkGenerator.java @@ -9,6 +9,7 @@ import org.betterx.worlds.together.biomesource.MergeableBiomeSource; import org.betterx.worlds.together.chunkgenerator.EnforceableChunkGenerator; import org.betterx.worlds.together.chunkgenerator.InjectableSurfaceRules; import org.betterx.worlds.together.chunkgenerator.RestorableBiomeSource; +import org.betterx.worlds.together.world.BiomeSourceWithNoiseRelatedSettings; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -71,8 +72,8 @@ public class BCLChunkGenerator extends NoiseBasedChunkGenerator implements Resto ) { super(registry, registry2, biomeSource, holder); initialBiomeSource = biomeSource; - if (biomeSource instanceof BCLBiomeSource bcl) { - bcl.setMaxHeight(holder.value().noiseSettings().height()); + if (biomeSource instanceof BiomeSourceWithNoiseRelatedSettings bcl) { + bcl.onLoadGeneratorSettings(holder.value()); } if (WorldsTogether.RUNS_TERRABLENDER) { diff --git a/src/main/java/org/betterx/bclib/mixin/common/ServerLevelMixin.java b/src/main/java/org/betterx/bclib/mixin/common/ServerLevelMixin.java index 61d1922d..b85859e9 100644 --- a/src/main/java/org/betterx/bclib/mixin/common/ServerLevelMixin.java +++ b/src/main/java/org/betterx/bclib/mixin/common/ServerLevelMixin.java @@ -1,7 +1,8 @@ package org.betterx.bclib.mixin.common; import org.betterx.bclib.api.v2.LifeCycleAPI; -import org.betterx.bclib.api.v2.generator.BCLBiomeSource; +import org.betterx.worlds.together.world.BiomeSourceWithNoiseRelatedSettings; +import org.betterx.worlds.together.world.BiomeSourceWithSeed; import net.minecraft.core.Holder; import net.minecraft.resources.ResourceKey; @@ -12,6 +13,7 @@ import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.world.level.Level; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; import net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess; import net.minecraft.world.level.storage.ServerLevelData; import net.minecraft.world.level.storage.WritableLevelData; @@ -73,10 +75,15 @@ public abstract class ServerLevelMixin extends Level { bl2 ); - if (levelStem.generator().getBiomeSource() instanceof BCLBiomeSource source) { + if (levelStem.generator().getBiomeSource() instanceof BiomeSourceWithSeed source) { source.setSeed(level.getSeed()); } + if (levelStem.generator().getBiomeSource() instanceof BiomeSourceWithNoiseRelatedSettings bcl + && levelStem.generator() instanceof NoiseBasedChunkGenerator noiseGenerator) { + bcl.onLoadGeneratorSettings(noiseGenerator.generatorSettings().value()); + } + if (bclib_lastWorld != null && bclib_lastWorld.equals(levelStorageAccess.getLevelId())) { return; } diff --git a/src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java b/src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java index f4f2c514..0d58fe79 100644 --- a/src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java +++ b/src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java @@ -3,6 +3,7 @@ package org.betterx.worlds.together.levelgen; import org.betterx.worlds.together.WorldsTogether; import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig; import org.betterx.worlds.together.chunkgenerator.EnforceableChunkGenerator; +import org.betterx.worlds.together.world.BiomeSourceWithNoiseRelatedSettings; import org.betterx.worlds.together.world.BiomeSourceWithSeed; import org.betterx.worlds.together.world.WorldConfig; import org.betterx.worlds.together.worldPreset.TogetherWorldPreset; @@ -19,6 +20,7 @@ import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; import net.minecraft.world.level.levelgen.WorldGenSettings; import net.minecraft.world.level.levelgen.presets.WorldPreset; @@ -46,6 +48,11 @@ public class WorldGenUtil { if (stem.generator().getBiomeSource() instanceof BiomeSourceWithSeed bcl) { bcl.setSeed(seed); } + + if (stem.generator().getBiomeSource() instanceof BiomeSourceWithNoiseRelatedSettings bcl + && stem.generator() instanceof NoiseBasedChunkGenerator noiseGenerator) { + bcl.onLoadGeneratorSettings(noiseGenerator.generatorSettings().value()); + } } return settings; diff --git a/src/main/java/org/betterx/worlds/together/world/BiomeSourceWithNoiseRelatedSettings.java b/src/main/java/org/betterx/worlds/together/world/BiomeSourceWithNoiseRelatedSettings.java new file mode 100644 index 00000000..558172e7 --- /dev/null +++ b/src/main/java/org/betterx/worlds/together/world/BiomeSourceWithNoiseRelatedSettings.java @@ -0,0 +1,7 @@ +package org.betterx.worlds.together.world; + +import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; + +public interface BiomeSourceWithNoiseRelatedSettings { + void onLoadGeneratorSettings(NoiseGeneratorSettings generator); +} From 25948c7c6b1961d369d5ab7ab4f32613a2d15099 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 13:42:15 +0200 Subject: [PATCH 23/50] restored `getBiome()` name for backward compatibility --- .../java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java index de552400..1275e5db 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java @@ -236,7 +236,7 @@ public class BCLBiome extends BCLBiomeSettings { * @return {@link Biome}. */ @Deprecated(forRemoval = true) - public Biome getBiomeOld() { + public Biome getBiome() { if (biomeToRegister != null) return biomeToRegister; return BiomeAPI.getFromBuiltinRegistry(biomeKey).value(); } From e0f8cb24b6ab2616ffe4ae83230c2468a4b54710 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 14:52:20 +0200 Subject: [PATCH 24/50] [Fix] Endless chung generation if picker is empty --- .../org/betterx/bclib/api/v2/generator/BiomePicker.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java b/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java index 1371b0e7..134ab6a4 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java @@ -1,5 +1,6 @@ package org.betterx.bclib.api.v2.generator; +import org.betterx.bclib.BCLib; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.util.WeighTree; @@ -23,6 +24,7 @@ public class BiomePicker { public final Registry biomeRegistry; private final List biomes = Lists.newArrayList(); private final List allowedBiomes; + public final ActualBiome fallbackBiome; private WeighTree tree; public BiomePicker(Registry biomeRegistry) { @@ -36,6 +38,7 @@ public class BiomePicker { .map(h -> h.unwrapKey()) .filter(o -> o.isPresent()) .map(o -> o.get().location().toString()).toList() : null; + this.fallbackBiome = create(BiomeAPI.EMPTY_BIOME); } private boolean isAllowed(BCLBiome b) { @@ -50,11 +53,13 @@ public class BiomePicker { } public void addBiome(BCLBiome biome) { - biomes.add(create(biome)); + ActualBiome a = create(biome); + BCLib.LOGGER.info("Adding Biome " + a + " from " + biome); + biomes.add(a); } public ActualBiome getBiome(WorldgenRandom random) { - return biomes.isEmpty() ? null : tree.get(random); + return biomes.isEmpty() ? fallbackBiome : tree.get(random); } public void rebuild() { From c042d00c23ba329fc88a1a7315bbdc236285a4a7 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 14:57:19 +0200 Subject: [PATCH 25/50] [Features] End Source has fallbacks if barrens/voids or center Biomes are missing --- .../api/v2/generator/BCLibEndBiomeSource.java | 20 ++++++++++++++++--- .../bclib/api/v2/generator/BiomePicker.java | 4 ++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java index 6520216e..be97e203 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java @@ -62,9 +62,9 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi private BiomeMap mapBarrens; private final BiomePicker endLandBiomePicker; - private final BiomePicker endVoidBiomePicker; - private final BiomePicker endCenterBiomePicker; - private final BiomePicker endBarrensBiomePicker; + private BiomePicker endVoidBiomePicker; + private BiomePicker endCenterBiomePicker; + private BiomePicker endBarrensBiomePicker; private BCLEndBiomeSourceConfig config; @@ -171,6 +171,20 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi endBarrensBiomePicker.rebuild(); endCenterBiomePicker.rebuild(); + if (endVoidBiomePicker.isEmpty()) { + BCLib.LOGGER.info("No Void Biomes found. Disabling by using barrens"); + endVoidBiomePicker = endBarrensBiomePicker; + } + if (endBarrensBiomePicker.isEmpty()) { + BCLib.LOGGER.info("No Barrens Biomes found. Disabling by using land Biomes"); + endBarrensBiomePicker = endLandBiomePicker; + endVoidBiomePicker = endLandBiomePicker; + } + if (endCenterBiomePicker.isEmpty()) { + BCLib.LOGGER.warning("No Center Island Biomes found. Forcing use of vanilla center."); + endCenterBiomePicker.addBiome(BiomeAPI.THE_END); + } + this.endLandFunction = GeneratorOptions.getEndLandFunction(); this.pos = new Point(); diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java b/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java index 134ab6a4..7721a3be 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java @@ -62,6 +62,10 @@ public class BiomePicker { return biomes.isEmpty() ? fallbackBiome : tree.get(random); } + public boolean isEmpty() { + return biomes.isEmpty(); + } + public void rebuild() { WeightedList list = new WeightedList<>(); From 82023316c68c6a5102cba10370c01d1cff6f038e Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 15:01:29 +0200 Subject: [PATCH 26/50] Added forgotten rebuild --- .../betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java index be97e203..9927070c 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java @@ -183,6 +183,11 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi if (endCenterBiomePicker.isEmpty()) { BCLib.LOGGER.warning("No Center Island Biomes found. Forcing use of vanilla center."); endCenterBiomePicker.addBiome(BiomeAPI.THE_END); + endCenterBiomePicker.rebuild(); + if (endCenterBiomePicker.isEmpty()) { + BCLib.LOGGER.error("Unable to force vanilla central Island. Falling back to land Biomes..."); + endCenterBiomePicker = endLandBiomePicker; + } } this.endLandFunction = GeneratorOptions.getEndLandFunction(); From f0fdcdba05777878639aa109eda10adaaad67bba Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 15:08:43 +0200 Subject: [PATCH 27/50] Removed debug logging --- .../java/org/betterx/bclib/api/v2/generator/BiomePicker.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java b/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java index 7721a3be..7c2e21c2 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java @@ -1,6 +1,5 @@ package org.betterx.bclib.api.v2.generator; -import org.betterx.bclib.BCLib; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.util.WeighTree; @@ -54,7 +53,6 @@ public class BiomePicker { public void addBiome(BCLBiome biome) { ActualBiome a = create(biome); - BCLib.LOGGER.info("Adding Biome " + a + " from " + biome); biomes.add(a); } From 3be3fdd2eae937d7fc3d01ef77d563835e74aeac Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 19:49:22 +0200 Subject: [PATCH 28/50] No local var --- .../java/org/betterx/bclib/api/v2/generator/BiomePicker.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java b/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java index 7c2e21c2..9f59eaab 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java @@ -52,8 +52,7 @@ public class BiomePicker { } public void addBiome(BCLBiome biome) { - ActualBiome a = create(biome); - biomes.add(a); + biomes.add(create(biome)); } public ActualBiome getBiome(WorldgenRandom random) { From f80c12f796d226715e141f80e9ace8f598af3cce Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 19:50:05 +0200 Subject: [PATCH 29/50] Removed deprecated config values --- .../org/betterx/bclib/config/Configs.java | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/src/main/java/org/betterx/bclib/config/Configs.java b/src/main/java/org/betterx/bclib/config/Configs.java index cb099f8a..5670759c 100644 --- a/src/main/java/org/betterx/bclib/config/Configs.java +++ b/src/main/java/org/betterx/bclib/config/Configs.java @@ -5,8 +5,6 @@ import org.betterx.bclib.BCLib; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import java.util.Collections; - public class Configs { // Client and Server-Config must be the first entries. They are not part of the Auto-Sync process // But will be needed by other Auto-Sync Config-Files @@ -28,24 +26,4 @@ public class Configs { GENERATOR_CONFIG.saveChanges(); BIOMES_CONFIG.saveChanges(); } - - - static { - BIOMES_CONFIG.keeper.registerEntry( - new ConfigKey("end_land_biomes", "force_include"), - new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST) - ); - BIOMES_CONFIG.keeper.registerEntry( - new ConfigKey("end_void_biomes", "force_include"), - new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST) - ); - BIOMES_CONFIG.keeper.registerEntry( - new ConfigKey("nether_biomes", "force_include"), - new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST) - ); - BIOMES_CONFIG.keeper.registerEntry( - new ConfigKey("nether_biomes", "force_exclude"), - new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST) - ); - } } From 910314a1e8fe13ec5723affb243154298b542c54 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 19:50:24 +0200 Subject: [PATCH 30/50] Make sure MainMixin is called early --- .../org/betterx/worlds/together/mixin/common/MainMixin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/betterx/worlds/together/mixin/common/MainMixin.java b/src/main/java/org/betterx/worlds/together/mixin/common/MainMixin.java index e8b18f9d..1e9087f5 100644 --- a/src/main/java/org/betterx/worlds/together/mixin/common/MainMixin.java +++ b/src/main/java/org/betterx/worlds/together/mixin/common/MainMixin.java @@ -14,7 +14,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.ModifyVariable; -@Mixin(Main.class) +@Mixin(value = Main.class, priority = 200) abstract public class MainMixin { @ModifyVariable(method = "main", ordinal = 0, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess;getSummary()Lnet/minecraft/world/level/storage/LevelSummary;")) private static LevelStorageSource.LevelStorageAccess bc_createAccess(LevelStorageSource.LevelStorageAccess levelStorageAccess) { From e670fea21aebbd5a9fdacdadbb95c54b61d5f696 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 19:51:18 +0200 Subject: [PATCH 31/50] Allow server to disable the forced preset override --- src/main/java/org/betterx/bclib/BCLib.java | 2 ++ .../java/org/betterx/bclib/config/ServerConfig.java | 9 +++++++++ .../org/betterx/worlds/together/WorldsTogether.java | 1 + .../common/DedicatedServerPropertiesMixin.java | 13 +++++++++---- src/main/resources/bclib.mixins.common.json | 1 - src/main/resources/together.mixins.common.json | 1 + 6 files changed, 22 insertions(+), 5 deletions(-) rename src/main/java/org/betterx/{bclib => worlds/together}/mixin/common/DedicatedServerPropertiesMixin.java (64%) diff --git a/src/main/java/org/betterx/bclib/BCLib.java b/src/main/java/org/betterx/bclib/BCLib.java index dbf56276..7cabae04 100644 --- a/src/main/java/org/betterx/bclib/BCLib.java +++ b/src/main/java/org/betterx/bclib/BCLib.java @@ -70,6 +70,8 @@ public class BCLib implements ModInitializer { PlacementModifiers.ensureStaticInitialization(); Configs.save(); + WorldsTogether.FORCE_SERVER_TO_BETTERX_PRESET = Configs.SERVER_CONFIG.forceBetterXPreset(); + if (false && isDevEnvironment()) { BCLBiome theYellow = BCLBiomeBuilder .start(makeID("the_yellow")) diff --git a/src/main/java/org/betterx/bclib/config/ServerConfig.java b/src/main/java/org/betterx/bclib/config/ServerConfig.java index aaa6758c..92ae389d 100644 --- a/src/main/java/org/betterx/bclib/config/ServerConfig.java +++ b/src/main/java/org/betterx/bclib/config/ServerConfig.java @@ -55,6 +55,11 @@ public class ServerConfig extends NamedPathConfig { "excludeMods", AutoSync.SYNC_CATEGORY ); + public static final ConfigToken FORCE_BETTERX_PRESET = ConfigToken.Boolean( + true, + "forceBetterXPreset", + AutoSync.SYNC_CATEGORY + ); public ServerConfig() { @@ -85,4 +90,8 @@ public class ServerConfig extends NamedPathConfig { return get(SEND_ALL_MOD_INFO) /*&& isAllowingAutoSync()*/; } + public boolean forceBetterXPreset() { + return get(FORCE_BETTERX_PRESET); + } + } diff --git a/src/main/java/org/betterx/worlds/together/WorldsTogether.java b/src/main/java/org/betterx/worlds/together/WorldsTogether.java index 28f4a65f..a74adba5 100644 --- a/src/main/java/org/betterx/worlds/together/WorldsTogether.java +++ b/src/main/java/org/betterx/worlds/together/WorldsTogether.java @@ -12,6 +12,7 @@ import net.fabricmc.loader.api.FabricLoader; public class WorldsTogether { public static boolean SURPRESS_EXPERIMENTAL_DIALOG = false; + public static boolean FORCE_SERVER_TO_BETTERX_PRESET = false; public static final String MOD_ID = "worlds_together"; public static final Logger LOGGER = new Logger(MOD_ID); public static final boolean RUNS_TERRABLENDER = FabricLoader.getInstance() diff --git a/src/main/java/org/betterx/bclib/mixin/common/DedicatedServerPropertiesMixin.java b/src/main/java/org/betterx/worlds/together/mixin/common/DedicatedServerPropertiesMixin.java similarity index 64% rename from src/main/java/org/betterx/bclib/mixin/common/DedicatedServerPropertiesMixin.java rename to src/main/java/org/betterx/worlds/together/mixin/common/DedicatedServerPropertiesMixin.java index 8642a0c0..a7dee9c1 100644 --- a/src/main/java/org/betterx/bclib/mixin/common/DedicatedServerPropertiesMixin.java +++ b/src/main/java/org/betterx/worlds/together/mixin/common/DedicatedServerPropertiesMixin.java @@ -1,5 +1,6 @@ -package org.betterx.bclib.mixin.common; +package org.betterx.worlds.together.mixin.common; +import org.betterx.worlds.together.WorldsTogether; import org.betterx.worlds.together.worldPreset.WorldPresets; import net.minecraft.server.dedicated.DedicatedServerProperties; @@ -10,9 +11,13 @@ import org.spongepowered.asm.mixin.injection.ModifyArg; @Mixin(DedicatedServerProperties.class) public class DedicatedServerPropertiesMixin { - //Make sure the default server properties use our Default World Preset + //Make sure the default server properties use our Default World Preset by default (read from "level-type") @ModifyArg(method = "", index = 3, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/dedicated/DedicatedServerProperties$WorldGenProperties;(Ljava/lang/String;Lcom/google/gson/JsonObject;ZLjava/lang/String;)V")) - private String bcl_init(String levelType) { - return WorldPresets.getDEFAULT().location().toString(); + protected String wt_defaultPreset(String string) { + if (WorldsTogether.FORCE_SERVER_TO_BETTERX_PRESET) { + return WorldPresets.getDEFAULT().location().toString(); + } + + return string; } } diff --git a/src/main/resources/bclib.mixins.common.json b/src/main/resources/bclib.mixins.common.json index 7e1f5ebb..8b7bf1aa 100644 --- a/src/main/resources/bclib.mixins.common.json +++ b/src/main/resources/bclib.mixins.common.json @@ -15,7 +15,6 @@ "ChunkGeneratorsMixin", "ComposterBlockAccessor", "CraftingMenuMixin", - "DedicatedServerPropertiesMixin", "DiggerItemMixin", "EnchantingTableBlockMixin", "ItemStackMixin", diff --git a/src/main/resources/together.mixins.common.json b/src/main/resources/together.mixins.common.json index 01a9360e..75e009db 100644 --- a/src/main/resources/together.mixins.common.json +++ b/src/main/resources/together.mixins.common.json @@ -5,6 +5,7 @@ "compatibilityLevel": "JAVA_17", "mixins": [ "BuiltinRegistriesMixin", + "DedicatedServerPropertiesMixin", "DiggerItemAccessor", "MainMixin", "MinecraftServerMixin", From 7d3ef6c7563181810127f891884cef47578c0655 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 19:52:00 +0200 Subject: [PATCH 32/50] Make sure default `level-type` in `server-properties` is betterx --- .../mixin/common/DedicatedServerPropertiesMixin.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/org/betterx/worlds/together/mixin/common/DedicatedServerPropertiesMixin.java b/src/main/java/org/betterx/worlds/together/mixin/common/DedicatedServerPropertiesMixin.java index a7dee9c1..a26d5be1 100644 --- a/src/main/java/org/betterx/worlds/together/mixin/common/DedicatedServerPropertiesMixin.java +++ b/src/main/java/org/betterx/worlds/together/mixin/common/DedicatedServerPropertiesMixin.java @@ -9,6 +9,8 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; +import java.util.Properties; + @Mixin(DedicatedServerProperties.class) public class DedicatedServerPropertiesMixin { //Make sure the default server properties use our Default World Preset by default (read from "level-type") @@ -20,4 +22,14 @@ public class DedicatedServerPropertiesMixin { return string; } + + @ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/dedicated/Settings;(Ljava/util/Properties;)V")) + private static Properties wt_defaultPreset(Properties property) { + //init default value level preset in server.properties + property.setProperty( + "level-type", + property.getProperty("level-type", WorldPresets.getDEFAULT().location().toString()) + ); + return property; + } } From 1186e962f697e6d193eaceeb3724443ed1a5ca58 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 21:56:54 +0200 Subject: [PATCH 33/50] [Fix] End Biomes without type are ignored (quiqueck/BetterEnd#29) --- .../betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java index 9927070c..96e14a9c 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java @@ -159,6 +159,9 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi } else if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_VOID) || TheEndBiomesHelper.canGenerateAsSmallIslandsBiome(key)) { endVoidBiomePicker.addBiome(bclBiome); + } else { + BCLib.LOGGER.info("Found End Biome " + biomeStr + " that was not registers with fabric or bclib. Assuming end-land Biome..."); + endLandBiomePicker.addBiome(bclBiome); } } } From 5bf8c4d6691686cb0e0275709c0959a0704abc72 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 22:14:54 +0200 Subject: [PATCH 34/50] [Fix] unbound biomes are valid --- .../java/org/betterx/bclib/api/v2/generator/BiomePicker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java b/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java index 9f59eaab..6763ce9d 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java @@ -106,7 +106,7 @@ public class BiomePicker { this.key = biomeRegistry.getResourceKey(biomeRegistry.get(bclBiome.getID())).orElse(null); this.biome = key != null ? biomeRegistry.getOrCreateHolderOrThrow(key) : null; - this.isValid = key != null; + this.isValid = key != null && biome != null && biome.isBound(); bclBiome.forEachSubBiome((b, w) -> { if (isAllowed(b)) subbiomes.add(create(b), w); From 9b537683ea35e502e1ed957a46904662d78f3c9b Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 22:15:12 +0200 Subject: [PATCH 35/50] Changed wording --- .../betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java index f381955c..e21cf626 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java @@ -108,7 +108,7 @@ public class InternalBiomeAPI { BIOMES_TO_SORT.forEach(id -> { Biome b = biomeRegistry.get(id); if (b != null) { - BCLib.LOGGER.info("Sorting Features in Biome: " + id + "(" + b + ")"); + BCLib.LOGGER.info("Found non fabric/bclib Biome: " + id + "(" + b + ")"); BiomeAPI.sortBiomeFeatures(b); } else { BCLib.LOGGER.info("Unknown Biome: " + id); From 44a008bcf0ff5aa31d338ed1d16adaca0140e7c1 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 22:15:54 +0200 Subject: [PATCH 36/50] Some renaming --- .../together/mixin/client/CreateWorldScreenMixin.java | 8 ++++---- .../together/mixin/client/WorldOpenFlowsMixin.java | 6 +++--- .../together/mixin/common/WorldGenPropertiesMixin.java | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/betterx/worlds/together/mixin/client/CreateWorldScreenMixin.java b/src/main/java/org/betterx/worlds/together/mixin/client/CreateWorldScreenMixin.java index 1d3f9c22..bf97ed5a 100644 --- a/src/main/java/org/betterx/worlds/together/mixin/client/CreateWorldScreenMixin.java +++ b/src/main/java/org/betterx/worlds/together/mixin/client/CreateWorldScreenMixin.java @@ -34,7 +34,7 @@ public class CreateWorldScreenMixin { public WorldGenSettingsComponent worldGenSettingsComponent; @Inject(method = "", at = @At("TAIL")) - private void bcl_init( + private void wt_init( Screen screen, DataPackConfig dataPackConfig, WorldGenSettingsComponent worldGenSettingsComponent, @@ -45,13 +45,13 @@ public class CreateWorldScreenMixin { //Change the WorldPreset that is selected by default on the Create World Screen @ModifyArg(method = "openFresh", index = 1, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/worldselection/WorldGenSettingsComponent;(Lnet/minecraft/client/gui/screens/worldselection/WorldCreationContext;Ljava/util/Optional;Ljava/util/OptionalLong;)V")) - private static Optional> bcl_NewDefault(Optional> preset) { + private static Optional> wt_NewDefault(Optional> preset) { return Optional.of(WorldPresets.getDEFAULT()); } //Make sure the WorldGenSettings used to populate the create screen match the default WorldPreset @ModifyArg(method = "openFresh", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/WorldLoader;load(Lnet/minecraft/server/WorldLoader$InitConfig;Lnet/minecraft/server/WorldLoader$WorldDataSupplier;Lnet/minecraft/server/WorldLoader$ResultFactory;Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;")) - private static WorldLoader.WorldDataSupplier bcl_NewDefaultSettings(WorldLoader.WorldDataSupplier worldDataSupplier) { + private static WorldLoader.WorldDataSupplier wt_NewDefaultSettings(WorldLoader.WorldDataSupplier worldDataSupplier) { return (resourceManager, dataPackConfig) -> { Pair res = worldDataSupplier.get(resourceManager, dataPackConfig); return WorldGenUtil.defaultWorldDataSupplier(res.getSecond()); @@ -60,7 +60,7 @@ public class CreateWorldScreenMixin { //this is called when a new world is first created @Inject(method = "createNewWorldDirectory", at = @At("RETURN")) - void bcl_createNewWorld(CallbackInfoReturnable> cir) { + void wt_createNewWorld(CallbackInfoReturnable> cir) { WorldBootstrap.InGUI.registryReadyOnNewWorld(this.worldGenSettingsComponent); WorldBootstrap.InGUI.setupNewWorld(cir.getReturnValue(), this.worldGenSettingsComponent); } diff --git a/src/main/java/org/betterx/worlds/together/mixin/client/WorldOpenFlowsMixin.java b/src/main/java/org/betterx/worlds/together/mixin/client/WorldOpenFlowsMixin.java index 6da1e173..8319df0c 100644 --- a/src/main/java/org/betterx/worlds/together/mixin/client/WorldOpenFlowsMixin.java +++ b/src/main/java/org/betterx/worlds/together/mixin/client/WorldOpenFlowsMixin.java @@ -32,7 +32,7 @@ public abstract class WorldOpenFlowsMixin { protected abstract void doLoadLevel(Screen screen, String levelID, boolean safeMode, boolean canAskForBackup); @Inject(method = "loadLevel", cancellable = true, at = @At("HEAD")) - private void bcl_callFixerOnLoad(Screen screen, String levelID, CallbackInfo ci) { + private void wt_callFixerOnLoad(Screen screen, String levelID, CallbackInfo ci) { WorldBootstrap.InGUI.setupLoadedWorld(levelID, this.levelSource); //if (DataFixerAPI.fixData(this.levelSource, levelID, true, (appliedFixes) -> { @@ -53,7 +53,7 @@ public abstract class WorldOpenFlowsMixin { } @Inject(method = "createFreshLevel", at = @At("HEAD")) - public void bcl_createFreshLevel( + public void wt_createFreshLevel( String levelID, LevelSettings levelSettings, RegistryAccess registryAccess, @@ -64,7 +64,7 @@ public abstract class WorldOpenFlowsMixin { } @Inject(method = "createLevelFromExistingSettings", at = @At("HEAD")) - public void bcl_createLevelFromExistingSettings( + public void wt_createLevelFromExistingSettings( LevelStorageSource.LevelStorageAccess levelStorageAccess, ReloadableServerResources reloadableServerResources, RegistryAccess.Frozen frozen, diff --git a/src/main/java/org/betterx/worlds/together/mixin/common/WorldGenPropertiesMixin.java b/src/main/java/org/betterx/worlds/together/mixin/common/WorldGenPropertiesMixin.java index dfd9a13f..99ae7a09 100644 --- a/src/main/java/org/betterx/worlds/together/mixin/common/WorldGenPropertiesMixin.java +++ b/src/main/java/org/betterx/worlds/together/mixin/common/WorldGenPropertiesMixin.java @@ -12,14 +12,14 @@ import org.spongepowered.asm.mixin.injection.ModifyArg; @Mixin(DedicatedServerProperties.WorldGenProperties.class) public class WorldGenPropertiesMixin { - @ModifyArg(method = "create", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/presets/WorldPreset;createWorldGenSettings(JZZ)Lnet/minecraft/world/level/levelgen/WorldGenSettings;")) - public long bcl_create(long seed) { - return seed; - } +// @ModifyArg(method = "create", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/presets/WorldPreset;createWorldGenSettings(JZZ)Lnet/minecraft/world/level/levelgen/WorldGenSettings;")) +// public long wt_getSeed(long seed) { +// return seed; +// } //Make sure Servers use our Default World Preset @ModifyArg(method = "create", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/core/Registry;getHolder(Lnet/minecraft/resources/ResourceKey;)Ljava/util/Optional;")) - private ResourceKey bcl_foo(ResourceKey resourceKey) { + private ResourceKey wt_returnDefault(ResourceKey resourceKey) { return WorldPresets.getDEFAULT(); } } \ No newline at end of file From bb928d5feb22a80eb02554bb3e07658699105fad Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 22:18:57 +0200 Subject: [PATCH 37/50] [Fix] RandomSource was not Thread-Safe (quiqueck/BetterEnd#29) --- .../java/org/betterx/bclib/util/MHelper.java | 61 ++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/betterx/bclib/util/MHelper.java b/src/main/java/org/betterx/bclib/util/MHelper.java index 960c4d54..32c83104 100644 --- a/src/main/java/org/betterx/bclib/util/MHelper.java +++ b/src/main/java/org/betterx/bclib/util/MHelper.java @@ -3,17 +3,74 @@ package org.betterx.bclib.util; import com.mojang.math.Vector3f; import net.minecraft.core.Vec3i; import net.minecraft.util.RandomSource; -import net.minecraft.world.level.levelgen.LegacyRandomSource; +import net.minecraft.world.level.levelgen.PositionalRandomFactory; import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; public class MHelper { + static class ThreadLocalRandomSource implements RandomSource { + ThreadLocalRandomSource(long seed) { + this.setSeed(seed); + } + + @Override + public RandomSource fork() { + return this; + } + + @Override + public PositionalRandomFactory forkPositional() { + return null; + } + + @Override + public void setSeed(long l) { + ThreadLocalRandom.current().setSeed(l); + } + + @Override + public int nextInt() { + return ThreadLocalRandom.current().nextInt(); + } + + @Override + public int nextInt(int i) { + return ThreadLocalRandom.current().nextInt(i); + } + + @Override + public long nextLong() { + return ThreadLocalRandom.current().nextLong(); + } + + @Override + public boolean nextBoolean() { + return ThreadLocalRandom.current().nextBoolean(); + } + + @Override + public float nextFloat() { + return ThreadLocalRandom.current().nextFloat(); + } + + @Override + public double nextDouble() { + return ThreadLocalRandom.current().nextDouble(); + } + + @Override + public double nextGaussian() { + return ThreadLocalRandom.current().nextGaussian(); + } + } + private static final Vec3i[] RANDOM_OFFSETS = new Vec3i[3 * 3 * 3 - 1]; private static final float RAD_TO_DEG = 57.295779513082320876798154814105F; public static final float PHI = (float) (Math.PI * (3 - Math.sqrt(5))); public static final float PI2 = (float) (Math.PI * 2); public static final Random RANDOM = new Random(); - public static final RandomSource RANDOM_SOURCE = new LegacyRandomSource(RANDOM.nextLong()); + public static final RandomSource RANDOM_SOURCE = new ThreadLocalRandomSource(RANDOM.nextLong()); public static int randRange(int min, int max, RandomSource random) { return min + random.nextInt(max - min + 1); From faa347c5bb6e1be0332353816aa3d36c8b4b3d10 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 22:25:55 +0200 Subject: [PATCH 38/50] Seed changes are not supported --- src/main/java/org/betterx/bclib/util/MHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/betterx/bclib/util/MHelper.java b/src/main/java/org/betterx/bclib/util/MHelper.java index 32c83104..16b3555a 100644 --- a/src/main/java/org/betterx/bclib/util/MHelper.java +++ b/src/main/java/org/betterx/bclib/util/MHelper.java @@ -11,7 +11,7 @@ import java.util.concurrent.ThreadLocalRandom; public class MHelper { static class ThreadLocalRandomSource implements RandomSource { ThreadLocalRandomSource(long seed) { - this.setSeed(seed); + } @Override From de94a808d0508528185c04058473d45cff00fa07 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 23:29:31 +0200 Subject: [PATCH 39/50] [Feature] Flag End Biomes as ignored for picking --- .../betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java | 4 +++- .../org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java index 96e14a9c..56e9cc77 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java @@ -146,7 +146,9 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi } if (!didForceAdd) { - if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_CENTER) + if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_IGNORE)) { + //we should not add this biome anywhere, so just ignore it + } else if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_CENTER) || TheEndBiomesHelper.canGenerateAsMainIslandBiome(key)) { endCenterBiomePicker.addBiome(bclBiome); } else if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_LAND) diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java index c28370a5..4251c54b 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java @@ -64,6 +64,7 @@ public class BiomeAPI { public static final BiomeType NETHER = new BiomeType("NETHER"); public static final BiomeType BCL_NETHER = new BiomeType("BCL_NETHER", NETHER); public static final BiomeType END = new BiomeType("END"); + public static final BiomeType END_IGNORE = new BiomeType("END_IGNORE", END); public static final BiomeType END_LAND = new BiomeType("END_LAND", END); public static final BiomeType END_VOID = new BiomeType("END_VOID", END); public static final BiomeType END_CENTER = new BiomeType("END_CENTER", END); From 3b0f609776cc66d8c5c7465ced91628b995267ad Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 3 Jul 2022 23:36:42 +0200 Subject: [PATCH 40/50] [Fix] Do not implicitly add keys to Biome registry (#16) --- .../org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java | 4 ++-- .../bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java index 4251c54b..342a7faa 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java @@ -511,12 +511,12 @@ public class BiomeAPI { @Nullable public static Holder getFromBuiltinRegistry(ResourceLocation biomeID) { - return BuiltinRegistries.BIOME.getHolder(ResourceKey.create(Registry.BIOME_REGISTRY, biomeID)).orElseThrow(); + return BuiltinRegistries.BIOME.getHolder(ResourceKey.create(Registry.BIOME_REGISTRY, biomeID)).orElse(null); } @Nullable public static Holder getFromBuiltinRegistry(ResourceKey key) { - return BuiltinRegistries.BIOME.getOrCreateHolderOrThrow(key); + return BuiltinRegistries.BIOME.getHolder(key).orElse(null); } @Deprecated(forRemoval = true) diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java index e21cf626..ba14625f 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java @@ -177,9 +177,11 @@ public class InternalBiomeAPI { .map(e -> e.getKey()); if (s != null) { s.forEach(id -> { - Holder biomeHolder = BiomeAPI.getBiomeHolder(id); - if (biomeHolder.isBound()) { + Holder biomeHolder = BiomeAPI.getFromRegistry(id); + if (biomeHolder != null && biomeHolder.isBound()) { mod.getValue().forEach(c -> c.accept(id, biomeHolder)); + } else { + BCLib.LOGGER.info("No Holder for " + id); } }); } From a73bd23ddf04e8933196e33a904f00fafb4696e9 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 4 Jul 2022 00:54:41 +0200 Subject: [PATCH 41/50] [Fix] DataPack Biomes from other mods are loaded after the WorldStem was first built. Our Biomes-Sources would not recognize that change (#16) --- .../api/v2/generator/BCLBiomeSource.java | 6 ++++- .../biomesource/BiomeSourceFromRegistry.java | 26 +++++++++++++++++++ .../EnforceableChunkGenerator.java | 9 ++++++- 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/betterx/worlds/together/biomesource/BiomeSourceFromRegistry.java diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLBiomeSource.java index 6e01ee27..8c406bb8 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLBiomeSource.java @@ -1,6 +1,7 @@ package org.betterx.bclib.api.v2.generator; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.worlds.together.biomesource.BiomeSourceFromRegistry; import org.betterx.worlds.together.biomesource.MergeableBiomeSource; import org.betterx.worlds.together.world.BiomeSourceWithNoiseRelatedSettings; import org.betterx.worlds.together.world.BiomeSourceWithSeed; @@ -18,7 +19,7 @@ import java.util.Comparator; import java.util.List; import java.util.Set; -public abstract class BCLBiomeSource extends BiomeSource implements BiomeSourceWithSeed, MergeableBiomeSource, BiomeSourceWithNoiseRelatedSettings { +public abstract class BCLBiomeSource extends BiomeSource implements BiomeSourceWithSeed, MergeableBiomeSource, BiomeSourceWithNoiseRelatedSettings, BiomeSourceFromRegistry { protected final Registry biomeRegistry; protected long currentSeed; protected int maxHeight; @@ -117,4 +118,7 @@ public abstract class BCLBiomeSource extends BiomeSource implements BiomeSourceW this.setMaxHeight(generator.noiseSettings().height()); } + public Registry getBiomeRegistry() { + return biomeRegistry; + } } diff --git a/src/main/java/org/betterx/worlds/together/biomesource/BiomeSourceFromRegistry.java b/src/main/java/org/betterx/worlds/together/biomesource/BiomeSourceFromRegistry.java new file mode 100644 index 00000000..dd908026 --- /dev/null +++ b/src/main/java/org/betterx/worlds/together/biomesource/BiomeSourceFromRegistry.java @@ -0,0 +1,26 @@ +package org.betterx.worlds.together.biomesource; + +import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.world.level.biome.Biome; + +import java.util.Set; + +public interface BiomeSourceFromRegistry { + Registry getBiomeRegistry(); + Set> possibleBiomes(); + + default boolean sameRegistryButDifferentBiomes(BiomeSourceFromRegistry other) { + if (other.getBiomeRegistry() == getBiomeRegistry()) { + Set> mySet = this.possibleBiomes(); + Set> otherSet = other.possibleBiomes(); + if (otherSet.size() != mySet.size()) return true; + for (Holder b : mySet) { + if (!otherSet.contains(b)) + return true; + } + } + + return false; + } +} diff --git a/src/main/java/org/betterx/worlds/together/chunkgenerator/EnforceableChunkGenerator.java b/src/main/java/org/betterx/worlds/together/chunkgenerator/EnforceableChunkGenerator.java index f43e5ed5..505b3bbb 100644 --- a/src/main/java/org/betterx/worlds/together/chunkgenerator/EnforceableChunkGenerator.java +++ b/src/main/java/org/betterx/worlds/together/chunkgenerator/EnforceableChunkGenerator.java @@ -1,5 +1,6 @@ package org.betterx.worlds.together.chunkgenerator; +import org.betterx.worlds.together.biomesource.BiomeSourceFromRegistry; import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig; import net.minecraft.core.RegistryAccess; @@ -28,8 +29,14 @@ public interface EnforceableChunkGenerator { if (one == two) return false; if (one instanceof BiomeSourceWithConfig ba && two instanceof BiomeSourceWithConfig bb) { - return !ba.getTogetherConfig().couldSetWithoutRepair(bb.getTogetherConfig()); + if (!ba.getTogetherConfig().couldSetWithoutRepair(bb.getTogetherConfig())) + return true; } + if (one instanceof BiomeSourceFromRegistry ba && two instanceof BiomeSourceFromRegistry bb) { + if (ba.sameRegistryButDifferentBiomes(bb)) + return true; + } + return !one.getClass().isAssignableFrom(two.getClass()) && !two.getClass().isAssignableFrom(one.getClass()); } } From 85e1d35496d989d28d21e923117943b7a5eeab14 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 5 Jul 2022 17:42:56 +0200 Subject: [PATCH 42/50] Strict separation of worldpreset code from rest of bclib --- src/main/java/org/betterx/bclib/BCLib.java | 3 +- .../bclib/api/v2/datafixer/DataFixerAPI.java | 2 +- .../bclib/api/v2/levelgen/LevelGenEvents.java | 23 +++++++ .../v2/levelgen/biomes/BCLBiomeBuilder.java | 2 +- .../api/v2/levelgen/biomes/BiomeAPI.java | 8 +-- .../config/TemplateFeatureConfig.java | 1 + .../org/betterx/bclib/client/BCLibClient.java | 4 +- .../bclib/registry/PresetsRegistry.java | 5 +- .../java/org/betterx/bclib/util/Logger.java | 10 +++ .../worlds/together/WorldsTogether.java | 7 ++- .../together/client/WorldsTogetherClient.java | 6 +- .../together/entrypoints/EntrypointUtil.java | 29 +++++++++ .../entrypoints/WorldPresetBootstrap.java | 5 ++ .../entrypoints/WorldsTogetherEntrypoint.java | 4 ++ .../together/levelgen/WorldGenUtil.java | 15 +++++ .../worlds/together/tag/v3/TagManager.java | 8 +-- .../worlds/together/tag/v3/TagRegistry.java | 34 +++++++--- .../betterx/worlds/together/util/Logger.java | 62 +++++++++++++++++++ .../betterx/worlds/together/util/ModUtil.java | 3 - .../world/event/BeforeAddingTags.java | 14 +++++ .../together/world/event/EventImpl.java | 2 +- .../together/world/event/WorldBootstrap.java | 17 ++--- .../together/world/event/WorldEvents.java | 2 + .../together/world/event/WorldEventsImpl.java | 7 ++- .../together/worldPreset/WorldPresets.java | 6 +- .../client/WorldPresetsClient.java | 3 - src/main/resources/fabric.mod.json | 3 + 27 files changed, 234 insertions(+), 51 deletions(-) create mode 100644 src/main/java/org/betterx/worlds/together/entrypoints/EntrypointUtil.java create mode 100644 src/main/java/org/betterx/worlds/together/entrypoints/WorldPresetBootstrap.java create mode 100644 src/main/java/org/betterx/worlds/together/entrypoints/WorldsTogetherEntrypoint.java create mode 100644 src/main/java/org/betterx/worlds/together/util/Logger.java create mode 100644 src/main/java/org/betterx/worlds/together/world/event/BeforeAddingTags.java diff --git a/src/main/java/org/betterx/bclib/BCLib.java b/src/main/java/org/betterx/bclib/BCLib.java index 7cabae04..602da7e2 100644 --- a/src/main/java/org/betterx/bclib/BCLib.java +++ b/src/main/java/org/betterx/bclib/BCLib.java @@ -19,9 +19,9 @@ import org.betterx.bclib.recipes.AnvilRecipe; import org.betterx.bclib.recipes.CraftingRecipes; import org.betterx.bclib.registry.BaseBlockEntities; import org.betterx.bclib.registry.BaseRegistry; -import org.betterx.bclib.util.Logger; import org.betterx.worlds.together.WorldsTogether; import org.betterx.worlds.together.tag.v3.TagManager; +import org.betterx.worlds.together.util.Logger; import org.betterx.worlds.together.world.WorldConfig; import net.minecraft.resources.ResourceLocation; @@ -41,7 +41,6 @@ public class BCLib implements ModInitializer { @Override public void onInitialize() { LevelGenEvents.register(); - WorldsTogether.onInitialize(); BlockPredicates.ensureStaticInitialization(); BaseRegistry.register(); GeneratorOptions.init(); diff --git a/src/main/java/org/betterx/bclib/api/v2/datafixer/DataFixerAPI.java b/src/main/java/org/betterx/bclib/api/v2/datafixer/DataFixerAPI.java index 54277511..07a9cf20 100644 --- a/src/main/java/org/betterx/bclib/api/v2/datafixer/DataFixerAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/datafixer/DataFixerAPI.java @@ -7,7 +7,7 @@ import org.betterx.bclib.client.gui.screens.LevelFixErrorScreen; import org.betterx.bclib.client.gui.screens.LevelFixErrorScreen.Listener; import org.betterx.bclib.client.gui.screens.ProgressScreen; import org.betterx.bclib.config.Configs; -import org.betterx.bclib.util.Logger; +import org.betterx.worlds.together.util.Logger; import org.betterx.worlds.together.world.WorldConfig; import net.minecraft.Util; diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/LevelGenEvents.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/LevelGenEvents.java index 9a2142ad..79393780 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/LevelGenEvents.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/LevelGenEvents.java @@ -7,19 +7,25 @@ import org.betterx.bclib.api.v2.datafixer.DataFixerAPI; import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource; import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig; import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI; +import org.betterx.bclib.api.v2.tag.TagAPI; import org.betterx.bclib.registry.PresetsRegistry; +import org.betterx.worlds.together.tag.v3.TagManager; +import org.betterx.worlds.together.world.WorldConfig; import org.betterx.worlds.together.world.event.WorldEvents; import org.betterx.worlds.together.worldPreset.TogetherWorldPreset; import net.minecraft.core.Holder; import net.minecraft.core.RegistryAccess; import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagLoader; import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.levelgen.WorldGenSettings; import net.minecraft.world.level.levelgen.presets.WorldPreset; import net.minecraft.world.level.storage.LevelStorageSource; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Consumer; @@ -40,6 +46,21 @@ public class LevelGenEvents { WorldEvents.PATCH_WORLD.on(LevelGenEvents::patchExistingWorld); WorldEvents.ADAPT_WORLD_PRESET.on(LevelGenEvents::adaptWorldPresetSettings); + + WorldEvents.BEFORE_ADDING_TAGS.on(LevelGenEvents::appplyTags); + } + + private static void appplyTags( + String directory, + Map> tagsMap + ) { + //make sure we include Tags registered by the deprecated API + TagAPI.apply(directory, tagsMap); + + + if (directory.equals(TagManager.BIOMES.directory)) { + InternalBiomeAPI._runBiomeTagAdders(); + } } @@ -103,6 +124,7 @@ public class LevelGenEvents { ) { setupWorld(); if (isNewWorld) { + WorldConfig.saveFile(BCLib.MOD_ID); DataFixerAPI.initializePatchData(); } else { LevelGenUtil.migrateGeneratorSettings(); @@ -117,6 +139,7 @@ public class LevelGenEvents { setupWorld(); if (isNewWorld) { + WorldConfig.saveFile(BCLib.MOD_ID); DataFixerAPI.initializePatchData(); } else { LevelGenUtil.migrateGeneratorSettings(); diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeBuilder.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeBuilder.java index ba395cfb..bd11dab7 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeBuilder.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeBuilder.java @@ -844,7 +844,7 @@ public class BCLBiomeBuilder { final Biome biome = builder.build(); final T res = biomeConstructor.apply(biomeID, biome, settings); - tags.forEach(tagKey -> TagManager.BIOMES.add(tagKey, res)); + tags.forEach(tagKey -> TagManager.BIOMES.add(tagKey, res.getBiomeKey())); //res.addBiomeTags(tags); //res.setSurface(surfaceRule); diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java index 342a7faa..a7169b94 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java @@ -195,11 +195,11 @@ public class BiomeAPI { BiomeType.BIOME_TYPE_MAP.put(bclbiome.getID(), dim); if (dim != null && dim.is(BiomeType.NETHER)) { - TagManager.BIOMES.add(BiomeTags.IS_NETHER, bclbiome); - TagManager.BIOMES.add(CommonBiomeTags.IN_NETHER, bclbiome); + TagManager.BIOMES.add(BiomeTags.IS_NETHER, bclbiome.getBiomeKey()); + TagManager.BIOMES.add(CommonBiomeTags.IN_NETHER, bclbiome.getBiomeKey()); } else if (dim != null && dim.is(BiomeType.END)) { - TagManager.BIOMES.add(BiomeTags.IS_END, bclbiome); - TagManager.BIOMES.add(CommonBiomeTags.IN_END, bclbiome); + TagManager.BIOMES.add(BiomeTags.IS_END, bclbiome.getBiomeKey()); + TagManager.BIOMES.add(CommonBiomeTags.IN_END, bclbiome.getBiomeKey()); } bclbiome.afterRegistration(); diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/features/config/TemplateFeatureConfig.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/features/config/TemplateFeatureConfig.java index 2a434388..e414a37c 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/features/config/TemplateFeatureConfig.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/features/config/TemplateFeatureConfig.java @@ -10,6 +10,7 @@ import java.util.List; /** * @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.config.TemplateFeatureConfig} instead */ +@Deprecated(forRemoval = true) public class TemplateFeatureConfig extends org.betterx.bclib.api.v3.levelgen.features.config.TemplateFeatureConfig { public TemplateFeatureConfig(ResourceLocation location, int offsetY, StructurePlacementType type) { diff --git a/src/main/java/org/betterx/bclib/client/BCLibClient.java b/src/main/java/org/betterx/bclib/client/BCLibClient.java index 02417552..6a6d632b 100644 --- a/src/main/java/org/betterx/bclib/client/BCLibClient.java +++ b/src/main/java/org/betterx/bclib/client/BCLibClient.java @@ -6,8 +6,8 @@ import org.betterx.bclib.api.v2.dataexchange.DataExchangeAPI; import org.betterx.bclib.client.models.CustomModelBakery; import org.betterx.bclib.config.Configs; import org.betterx.bclib.registry.BaseBlockEntityRenders; +import org.betterx.bclib.registry.PresetsRegistryClient; import org.betterx.worlds.together.WorldsTogether; -import org.betterx.worlds.together.client.WorldsTogetherClient; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.client.resources.model.UnbakedModel; @@ -31,7 +31,7 @@ public class BCLibClient implements ClientModInitializer, ModelResourceProvider, ModelLoadingRegistry.INSTANCE.registerResourceProvider(rm -> this); ModelLoadingRegistry.INSTANCE.registerVariantProvider(rm -> this); - WorldsTogetherClient.onInitializeClient(); + PresetsRegistryClient.onLoad(); WorldsTogether.SURPRESS_EXPERIMENTAL_DIALOG = Configs.CLIENT_CONFIG.suppressExperimentalDialog(); //dumpDatapack(); } diff --git a/src/main/java/org/betterx/bclib/registry/PresetsRegistry.java b/src/main/java/org/betterx/bclib/registry/PresetsRegistry.java index 5fb40084..bcee77d5 100644 --- a/src/main/java/org/betterx/bclib/registry/PresetsRegistry.java +++ b/src/main/java/org/betterx/bclib/registry/PresetsRegistry.java @@ -4,6 +4,7 @@ import org.betterx.bclib.BCLib; import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig; import org.betterx.bclib.api.v2.generator.config.BCLNetherBiomeSourceConfig; import org.betterx.bclib.api.v2.levelgen.LevelGenUtil; +import org.betterx.worlds.together.entrypoints.WorldPresetBootstrap; import org.betterx.worlds.together.levelgen.WorldGenUtil; import org.betterx.worlds.together.worldPreset.TogetherWorldPreset; import org.betterx.worlds.together.worldPreset.WorldPresets; @@ -14,11 +15,11 @@ import net.minecraft.world.level.levelgen.presets.WorldPreset; import java.util.Map; -public class PresetsRegistry { +public class PresetsRegistry implements WorldPresetBootstrap { public static ResourceKey BCL_WORLD; public static ResourceKey BCL_WORLD_17; - public static void onLoad() { + public void bootstrapWorldPresets() { BCL_WORLD = WorldPresets.register( BCLib.makeID("normal"), diff --git a/src/main/java/org/betterx/bclib/util/Logger.java b/src/main/java/org/betterx/bclib/util/Logger.java index 373bf2a6..d7115089 100644 --- a/src/main/java/org/betterx/bclib/util/Logger.java +++ b/src/main/java/org/betterx/bclib/util/Logger.java @@ -3,10 +3,20 @@ package org.betterx.bclib.util; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; + +/** + * @deprecated Please use {@link org.betterx.worlds.together.util.Logger} instead + */ +@Deprecated(forRemoval = true) public final class Logger { private static final org.apache.logging.log4j.Logger LOGGER = LogManager.getLogger(); private final String modPref; + + /** + * @deprecated Please use {@link org.betterx.worlds.together.util.Logger#Logger(String)} instead + */ + @Deprecated(forRemoval = true) public Logger(String modID) { this.modPref = "[" + modID + "] "; } diff --git a/src/main/java/org/betterx/worlds/together/WorldsTogether.java b/src/main/java/org/betterx/worlds/together/WorldsTogether.java index a74adba5..24ae4bef 100644 --- a/src/main/java/org/betterx/worlds/together/WorldsTogether.java +++ b/src/main/java/org/betterx/worlds/together/WorldsTogether.java @@ -1,16 +1,17 @@ package org.betterx.worlds.together; -import org.betterx.bclib.util.Logger; import org.betterx.worlds.together.surfaceRules.SurfaceRuleRegistry; import org.betterx.worlds.together.tag.v3.TagManager; +import org.betterx.worlds.together.util.Logger; import org.betterx.worlds.together.world.WorldConfig; import org.betterx.worlds.together.worldPreset.WorldPresets; import net.minecraft.resources.ResourceLocation; +import net.fabricmc.api.ModInitializer; import net.fabricmc.loader.api.FabricLoader; -public class WorldsTogether { +public class WorldsTogether implements ModInitializer { public static boolean SURPRESS_EXPERIMENTAL_DIALOG = false; public static boolean FORCE_SERVER_TO_BETTERX_PRESET = false; public static final String MOD_ID = "worlds_together"; @@ -23,7 +24,7 @@ public class WorldsTogether { return FabricLoader.getInstance().isDevelopmentEnvironment(); } - public static void onInitialize() { + public void onInitialize() { TagManager.ensureStaticallyLoaded(); SurfaceRuleRegistry.ensureStaticallyLoaded(); diff --git a/src/main/java/org/betterx/worlds/together/client/WorldsTogetherClient.java b/src/main/java/org/betterx/worlds/together/client/WorldsTogetherClient.java index 1aa64f4e..2a646f80 100644 --- a/src/main/java/org/betterx/worlds/together/client/WorldsTogetherClient.java +++ b/src/main/java/org/betterx/worlds/together/client/WorldsTogetherClient.java @@ -2,8 +2,10 @@ package org.betterx.worlds.together.client; import org.betterx.worlds.together.worldPreset.client.WorldPresetsClient; -public class WorldsTogetherClient { - public static void onInitializeClient() { +import net.fabricmc.api.ClientModInitializer; + +public class WorldsTogetherClient implements ClientModInitializer { + public void onInitializeClient() { WorldPresetsClient.setupClientside(); } } diff --git a/src/main/java/org/betterx/worlds/together/entrypoints/EntrypointUtil.java b/src/main/java/org/betterx/worlds/together/entrypoints/EntrypointUtil.java new file mode 100644 index 00000000..0476a601 --- /dev/null +++ b/src/main/java/org/betterx/worlds/together/entrypoints/EntrypointUtil.java @@ -0,0 +1,29 @@ +package org.betterx.worlds.together.entrypoints; + +import net.fabricmc.loader.api.FabricLoader; + +import java.util.List; +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +public class EntrypointUtil { + private static List getEntryPoints(boolean client, Class select) { + return FabricLoader.getInstance() + .getEntrypoints( + client ? "worlds_together_client" : "worlds_together", + WorldsTogetherEntrypoint.class + ) + .stream() + .filter(o -> select.isAssignableFrom(o.getClass())) + .map(e -> (T) e) + .toList(); + } + + public static List getCommon(Class select) { + return getEntryPoints(false, select); + } + + public static List getClient(Class select) { + return getEntryPoints(true, select); + } +} diff --git a/src/main/java/org/betterx/worlds/together/entrypoints/WorldPresetBootstrap.java b/src/main/java/org/betterx/worlds/together/entrypoints/WorldPresetBootstrap.java new file mode 100644 index 00000000..238fec8e --- /dev/null +++ b/src/main/java/org/betterx/worlds/together/entrypoints/WorldPresetBootstrap.java @@ -0,0 +1,5 @@ +package org.betterx.worlds.together.entrypoints; + +public interface WorldPresetBootstrap extends WorldsTogetherEntrypoint { + void bootstrapWorldPresets(); +} diff --git a/src/main/java/org/betterx/worlds/together/entrypoints/WorldsTogetherEntrypoint.java b/src/main/java/org/betterx/worlds/together/entrypoints/WorldsTogetherEntrypoint.java new file mode 100644 index 00000000..b41b8601 --- /dev/null +++ b/src/main/java/org/betterx/worlds/together/entrypoints/WorldsTogetherEntrypoint.java @@ -0,0 +1,4 @@ +package org.betterx.worlds.together.entrypoints; + +public interface WorldsTogetherEntrypoint { +} diff --git a/src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java b/src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java index 0d58fe79..4a82f11f 100644 --- a/src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java +++ b/src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java @@ -6,6 +6,7 @@ import org.betterx.worlds.together.chunkgenerator.EnforceableChunkGenerator; import org.betterx.worlds.together.world.BiomeSourceWithNoiseRelatedSettings; import org.betterx.worlds.together.world.BiomeSourceWithSeed; import org.betterx.worlds.together.world.WorldConfig; +import org.betterx.worlds.together.world.event.WorldBootstrap; import org.betterx.worlds.together.worldPreset.TogetherWorldPreset; import org.betterx.worlds.together.worldPreset.WorldPresets; @@ -15,6 +16,7 @@ import net.minecraft.core.Registry; import net.minecraft.core.RegistryAccess; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; import net.minecraft.util.RandomSource; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.chunk.ChunkGenerator; @@ -165,4 +167,17 @@ public class WorldGenUtil { } return settings; } + + public static ResourceLocation getBiomeID(Biome biome) { + ResourceLocation id = null; + RegistryAccess access = WorldBootstrap.getLastRegistryAccessOrElseBuiltin(); + + id = access.registryOrThrow(Registry.BIOME_REGISTRY).getKey(biome); + + if (id == null) { + WorldsTogether.LOGGER.error("Unable to get ID for " + biome + "."); + } + + return id; + } } diff --git a/src/main/java/org/betterx/worlds/together/tag/v3/TagManager.java b/src/main/java/org/betterx/worlds/together/tag/v3/TagManager.java index fbfc4a70..e547d9cb 100644 --- a/src/main/java/org/betterx/worlds/together/tag/v3/TagManager.java +++ b/src/main/java/org/betterx/worlds/together/tag/v3/TagManager.java @@ -1,8 +1,8 @@ package org.betterx.worlds.together.tag.v3; -import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; -import org.betterx.bclib.api.v2.tag.TagAPI; +import org.betterx.worlds.together.levelgen.WorldGenUtil; import org.betterx.worlds.together.mixin.common.DiggerItemAccessor; +import org.betterx.worlds.together.world.event.WorldEventsImpl; import net.minecraft.core.DefaultedRegistry; import net.minecraft.core.Registry; @@ -62,7 +62,7 @@ public class TagManager { "tags/worldgen/biome", (dir) -> new TagRegistry.Biomes( dir, - b -> BiomeAPI.getBiomeID(b) + b -> WorldGenUtil.getBiomeID(b) ) ); } @@ -105,7 +105,7 @@ public class TagManager { String directory, Map> tagsMap ) { - tagsMap = TagAPI.apply(directory, tagsMap); + WorldEventsImpl.BEFORE_ADDING_TAGS.emit(e -> e.apply(directory, tagsMap)); TagRegistry type = TYPES.get(directory); if (type != null) { diff --git a/src/main/java/org/betterx/worlds/together/tag/v3/TagRegistry.java b/src/main/java/org/betterx/worlds/together/tag/v3/TagRegistry.java index 1c5bb2da..27bc6153 100644 --- a/src/main/java/org/betterx/worlds/together/tag/v3/TagRegistry.java +++ b/src/main/java/org/betterx/worlds/together/tag/v3/TagRegistry.java @@ -1,8 +1,7 @@ package org.betterx.worlds.together.tag.v3; -import org.betterx.bclib.BCLib; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; -import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI; +import org.betterx.worlds.together.WorldsTogether; import net.minecraft.core.DefaultedRegistry; import net.minecraft.core.Registry; @@ -90,8 +89,26 @@ public class TagRegistry { * @param tagID {@link TagKey< Biome >} tag ID. * @param elements array of Elements to add into tag. */ + public void add(TagKey tagID, ResourceKey... elements) { + if (isFrozen) WorldsTogether.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); + Set set = getSetForTag(tagID); + for (ResourceKey element : elements) { + ResourceLocation id = element.location(); + if (id != null) { + set.add(TagEntry.element(id)); + } + } + } + + /** + * Adds one Tag to multiple Elements. + * + * @param tagID {@link TagKey< Biome >} tag ID. + * @param elements array of Elements to add into tag. + */ + @Deprecated(forRemoval = true) public void add(TagKey tagID, BCLBiome... elements) { - if (isFrozen) BCLib.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); + if (isFrozen) WorldsTogether.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); Set set = getSetForTag(tagID); for (BCLBiome element : elements) { ResourceLocation id = element.getID(); @@ -106,7 +123,6 @@ public class TagRegistry { } public void apply(Map> tagsMap) { - InternalBiomeAPI._runBiomeTagAdders(); super.apply(tagsMap); } } @@ -209,7 +225,7 @@ public class TagRegistry { } public void addUntyped(TagKey tagID, ResourceLocation... elements) { - if (isFrozen) BCLib.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); + if (isFrozen) WorldsTogether.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); Set set = getSetForTag(tagID); for (ResourceLocation id : elements) { if (id != null) { @@ -225,7 +241,7 @@ public class TagRegistry { } public void addOtherTags(TagKey tagID, TagKey... tags) { - if (isFrozen) BCLib.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); + if (isFrozen) WorldsTogether.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); Set set = getSetForTag(tagID); for (TagKey tag : tags) { ResourceLocation id = tag.location(); @@ -242,7 +258,7 @@ public class TagRegistry { * @param elements array of Elements to add into tag. */ protected void add(TagKey tagID, T... elements) { - if (isFrozen) BCLib.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); + if (isFrozen) WorldsTogether.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); Set set = getSetForTag(tagID); for (T element : elements) { ResourceLocation id = locationProvider.apply(element); @@ -260,7 +276,7 @@ public class TagRegistry { @Deprecated(forRemoval = true) protected void add(ResourceLocation tagID, T... elements) { - if (isFrozen) BCLib.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); + if (isFrozen) WorldsTogether.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); Set set = getSetForTag(tagID); for (T element : elements) { ResourceLocation id = locationProvider.apply(element); @@ -292,7 +308,7 @@ public class TagRegistry { List builder, Set ids ) { - ids.forEach(value -> builder.add(new TagLoader.EntryWithSource(value, BCLib.MOD_ID))); + ids.forEach(value -> builder.add(new TagLoader.EntryWithSource(value, WorldsTogether.MOD_ID))); return builder; } } diff --git a/src/main/java/org/betterx/worlds/together/util/Logger.java b/src/main/java/org/betterx/worlds/together/util/Logger.java new file mode 100644 index 00000000..8600e677 --- /dev/null +++ b/src/main/java/org/betterx/worlds/together/util/Logger.java @@ -0,0 +1,62 @@ +package org.betterx.worlds.together.util; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; + +public final class Logger { + private static final org.apache.logging.log4j.Logger LOGGER = LogManager.getLogger(); + private final String modPref; + + public Logger(String modID) { + this.modPref = "[" + modID + "] "; + } + + public void log(Level level, String message) { + LOGGER.log(level, modPref + message); + } + + public void log(Level level, String message, Object... params) { + LOGGER.log(level, modPref + message, params); + } + + public void debug(Object message) { + this.log(Level.DEBUG, message.toString()); + } + + public void debug(Object message, Object... params) { + this.log(Level.DEBUG, message.toString(), params); + } + + public void catching(Throwable ex) { + this.error(ex.getLocalizedMessage()); + LOGGER.catching(ex); + } + + public void info(String message) { + this.log(Level.INFO, message); + } + + public void info(String message, Object... params) { + this.log(Level.INFO, message, params); + } + + public void warning(String message, Object... params) { + this.log(Level.WARN, message, params); + } + + public void warning(String message, Object obj, Exception ex) { + LOGGER.warn(modPref + message, obj, ex); + } + + public void error(String message) { + this.log(Level.ERROR, message); + } + + public void error(String message, Object obj, Exception ex) { + LOGGER.error(modPref + message, obj, ex); + } + + public void error(String message, Exception ex) { + LOGGER.error(modPref + message, ex); + } +} diff --git a/src/main/java/org/betterx/worlds/together/util/ModUtil.java b/src/main/java/org/betterx/worlds/together/util/ModUtil.java index 99085a38..54dd38e1 100644 --- a/src/main/java/org/betterx/worlds/together/util/ModUtil.java +++ b/src/main/java/org/betterx/worlds/together/util/ModUtil.java @@ -1,6 +1,5 @@ package org.betterx.worlds.together.util; -import org.betterx.bclib.BCLib; import org.betterx.worlds.together.WorldsTogether; import net.fabricmc.loader.api.*; @@ -261,8 +260,6 @@ public class ModUtil { * @return The version of the locally installed Mod */ public static String getModVersion(String modID) { - if (modID == WorldsTogether.MOD_ID) modID = BCLib.MOD_ID; - Optional optional = FabricLoader.getInstance() .getModContainer(modID); if (optional.isPresent()) { diff --git a/src/main/java/org/betterx/worlds/together/world/event/BeforeAddingTags.java b/src/main/java/org/betterx/worlds/together/world/event/BeforeAddingTags.java new file mode 100644 index 00000000..1908161d --- /dev/null +++ b/src/main/java/org/betterx/worlds/together/world/event/BeforeAddingTags.java @@ -0,0 +1,14 @@ +package org.betterx.worlds.together.world.event; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagLoader; + +import java.util.List; +import java.util.Map; + +public interface BeforeAddingTags { + void apply( + String directory, + Map> tagsMap + ); +} diff --git a/src/main/java/org/betterx/worlds/together/world/event/EventImpl.java b/src/main/java/org/betterx/worlds/together/world/event/EventImpl.java index 01419060..5fcb9b5a 100644 --- a/src/main/java/org/betterx/worlds/together/world/event/EventImpl.java +++ b/src/main/java/org/betterx/worlds/together/world/event/EventImpl.java @@ -4,7 +4,7 @@ import java.util.LinkedList; import java.util.List; import java.util.function.Consumer; -class EventImpl implements Event { +public class EventImpl implements Event { final List handlers = new LinkedList<>(); public final boolean on(T handler) { diff --git a/src/main/java/org/betterx/worlds/together/world/event/WorldBootstrap.java b/src/main/java/org/betterx/worlds/together/world/event/WorldBootstrap.java index 11fbe943..fd64e9b9 100644 --- a/src/main/java/org/betterx/worlds/together/world/event/WorldBootstrap.java +++ b/src/main/java/org/betterx/worlds/together/world/event/WorldBootstrap.java @@ -1,6 +1,5 @@ package org.betterx.worlds.together.world.event; -import org.betterx.bclib.BCLib; import org.betterx.worlds.together.WorldsTogether; import org.betterx.worlds.together.levelgen.WorldGenUtil; import org.betterx.worlds.together.mixin.common.RegistryOpsAccessor; @@ -56,10 +55,6 @@ public class WorldBootstrap { private static void initializeWorldConfig(File levelBaseDir, boolean newWorld) { WorldConfig.load(new File(levelBaseDir, "data")); - - if (newWorld) { - WorldConfig.saveFile(BCLib.MOD_ID); - } } private static void onRegistryReady(RegistryAccess a) { @@ -115,7 +110,7 @@ public class WorldBootstrap { public static void setupWorld(LevelStorageSource.LevelStorageAccess levelStorageAccess) { File levelDat = levelStorageAccess.getLevelPath(LevelResource.LEVEL_DATA_FILE).toFile(); if (!levelDat.exists()) { - BCLib.LOGGER.info("Creating a new World, no fixes needed"); + WorldsTogether.LOGGER.info("Creating a new World, no fixes needed"); final Map, ChunkGenerator> settings = Helpers.defaultServerDimensions(); Helpers.initializeWorldConfig(levelStorageAccess, true); @@ -241,11 +236,11 @@ public class WorldBootstrap { false )); } catch (Exception e) { - BCLib.LOGGER.error("Failed to initialize data in world", e); + WorldsTogether.LOGGER.error("Failed to initialize data in world", e); } levelStorageAccess.close(); } catch (Exception e) { - BCLib.LOGGER.error("Failed to acquire storage access", e); + WorldsTogether.LOGGER.error("Failed to acquire storage access", e); } } @@ -260,7 +255,7 @@ public class WorldBootstrap { result = WorldEventsImpl.PATCH_WORLD.applyPatches(levelStorageAccess, onResume); levelStorageAccess.close(); } catch (Exception e) { - BCLib.LOGGER.error("Failed to initialize data in world", e); + WorldsTogether.LOGGER.error("Failed to initialize data in world", e); } return result; @@ -287,7 +282,7 @@ public class WorldBootstrap { InGUI.setupNewWorldCommon(levelStorageAccess, worldPreset, worldGenSettings); levelStorageAccess.close(); } catch (Exception e) { - BCLib.LOGGER.error("Failed to initialize data in world", e); + WorldsTogether.LOGGER.error("Failed to initialize data in world", e); } } } @@ -315,7 +310,7 @@ public class WorldBootstrap { return WorldGenUtil.repairBiomeSourceInAllDimensions(acc.bcl_getRegistryAccess(), worldGenSettings); //.repairSettingsOnLoad(LAST_REGISTRY_ACCESS, worldGenSettings); } else { - BCLib.LOGGER.error("Unable to obtain registryAccess when enforcing generators."); + WorldsTogether.LOGGER.error("Unable to obtain registryAccess when enforcing generators."); } return worldGenSettings; } diff --git a/src/main/java/org/betterx/worlds/together/world/event/WorldEvents.java b/src/main/java/org/betterx/worlds/together/world/event/WorldEvents.java index 16d9f6a8..fa0ff83a 100644 --- a/src/main/java/org/betterx/worlds/together/world/event/WorldEvents.java +++ b/src/main/java/org/betterx/worlds/together/world/event/WorldEvents.java @@ -8,4 +8,6 @@ public class WorldEvents { public static final Event ON_FINALIZE_LEVEL_STEM = WorldEventsImpl.ON_FINALIZE_LEVEL_STEM; public static final Event PATCH_WORLD = WorldEventsImpl.PATCH_WORLD; public static final Event ADAPT_WORLD_PRESET = WorldEventsImpl.ADAPT_WORLD_PRESET; + + public static final Event BEFORE_ADDING_TAGS = WorldEventsImpl.BEFORE_ADDING_TAGS; } diff --git a/src/main/java/org/betterx/worlds/together/world/event/WorldEventsImpl.java b/src/main/java/org/betterx/worlds/together/world/event/WorldEventsImpl.java index cf37f48c..cc1e93ab 100644 --- a/src/main/java/org/betterx/worlds/together/world/event/WorldEventsImpl.java +++ b/src/main/java/org/betterx/worlds/together/world/event/WorldEventsImpl.java @@ -1,6 +1,9 @@ package org.betterx.worlds.together.world.event; -class WorldEventsImpl { +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +public class WorldEventsImpl { public static final EventImpl WORLD_REGISTRY_READY = new EventImpl<>(); public static final EventImpl BEFORE_WORLD_LOAD = new EventImpl<>(); public static final EventImpl BEFORE_SERVER_WORLD_LOAD = new EventImpl<>(); @@ -10,4 +13,6 @@ class WorldEventsImpl { public static final PatchWorldEvent PATCH_WORLD = new PatchWorldEvent(); public static final AdaptWorldPresetSettingEvent ADAPT_WORLD_PRESET = new AdaptWorldPresetSettingEvent(); + + public static final EventImpl BEFORE_ADDING_TAGS = new EventImpl<>(); } diff --git a/src/main/java/org/betterx/worlds/together/worldPreset/WorldPresets.java b/src/main/java/org/betterx/worlds/together/worldPreset/WorldPresets.java index 32fd264e..a77273f7 100644 --- a/src/main/java/org/betterx/worlds/together/worldPreset/WorldPresets.java +++ b/src/main/java/org/betterx/worlds/together/worldPreset/WorldPresets.java @@ -1,7 +1,8 @@ package org.betterx.worlds.together.worldPreset; -import org.betterx.bclib.registry.PresetsRegistry; import org.betterx.worlds.together.WorldsTogether; +import org.betterx.worlds.together.entrypoints.EntrypointUtil; +import org.betterx.worlds.together.entrypoints.WorldPresetBootstrap; import org.betterx.worlds.together.levelgen.WorldGenUtil; import org.betterx.worlds.together.tag.v3.TagManager; import org.betterx.worlds.together.tag.v3.TagRegistry; @@ -83,7 +84,8 @@ public class WorldPresets { WorldGenUtil.Context netherContext, WorldGenUtil.Context endContext ) { - PresetsRegistry.onLoad(); + EntrypointUtil.getCommon(WorldPresetBootstrap.class) + .forEach(e -> e.bootstrapWorldPresets()); for (Map.Entry, PresetBuilder> e : BUILDERS.entrySet()) { TogetherWorldPreset preset = e.getValue().create(overworldStem, netherContext, endContext); diff --git a/src/main/java/org/betterx/worlds/together/worldPreset/client/WorldPresetsClient.java b/src/main/java/org/betterx/worlds/together/worldPreset/client/WorldPresetsClient.java index ff0768db..e65a8803 100644 --- a/src/main/java/org/betterx/worlds/together/worldPreset/client/WorldPresetsClient.java +++ b/src/main/java/org/betterx/worlds/together/worldPreset/client/WorldPresetsClient.java @@ -1,7 +1,5 @@ package org.betterx.worlds.together.worldPreset.client; -import org.betterx.bclib.registry.PresetsRegistryClient; - import net.minecraft.client.gui.screens.worldselection.PresetEditor; import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.levelgen.presets.WorldPreset; @@ -20,6 +18,5 @@ public class WorldPresetsClient { } public static void setupClientside() { - PresetsRegistryClient.onLoad(); } } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index bef018ed..ea76eab7 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -29,6 +29,9 @@ ], "modmenu": [ "org.betterx.bclib.integration.modmenu.ModMenuEntryPoint" + ], + "worlds_together": [ + "org.betterx.bclib.registry.PresetsRegistry" ] }, "accessWidener": "bclib.accesswidener", From 94c08e79b2b80a966c02b7c07c82c24ccc51c6f7 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 5 Jul 2022 19:14:56 +0200 Subject: [PATCH 43/50] [Fix] Make sure biomes marked for ignore are not added to the end biome source --- .../betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java index 56e9cc77..ccc94786 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java @@ -234,12 +234,16 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi private static boolean isValidEndBiome(Holder biome, ResourceLocation location) { + if (BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.END_IGNORE)) return false; + return biome.is(BiomeTags.IS_END) || BiomeAPI.wasRegisteredAsEndBiome(location) || TheEndBiomesHelper.canGenerateInEnd(biome.unwrapKey().orElse(null)); } private static boolean isValidNonVanillaEndBiome(Holder biome, ResourceLocation location) { + if (BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.END_IGNORE)) return false; + return biome.is(BiomeTags.IS_END) || BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.BCL_END_LAND) || BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.BCL_END_VOID) || From 32e7ffec693cd066fb97b0e89d9f0042f37d9ec9 Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 7 Jul 2022 18:53:08 +0200 Subject: [PATCH 44/50] [Change] BCLBiome Data is managed in a Datapack-Aware registry now --- gradle.properties | 2 +- src/main/java/org/betterx/bclib/BCLib.java | 2 + .../api/v2/generator/BCLChunkGenerator.java | 3 + .../api/v2/generator/BCLibEndBiomeSource.java | 48 +-- .../v2/generator/BCLibNetherBiomeSource.java | 25 +- .../bclib/api/v2/generator/BiomePicker.java | 15 +- .../api/v2/levelgen/biomes/BCLBiome.java | 180 ++++++++++- .../v2/levelgen/biomes/BCLBiomeBuilder.java | 61 ++++ .../v2/levelgen/biomes/BCLBiomeRegistry.java | 145 +++++++++ .../v2/levelgen/biomes/BCLBiomeSettings.java | 16 + .../api/v2/levelgen/biomes/BiomeAPI.java | 280 +++++++++++++----- .../api/v2/levelgen/biomes/BiomeData.java | 15 + .../v2/levelgen/biomes/InternalBiomeAPI.java | 23 +- .../client/render/CustomFogRenderer.java | 3 +- .../betterx/bclib/commands/DumpDatapack.java | 30 +- .../mixin/common/BuiltinRegistriesMixin.java | 40 +++ .../mixin/common/RegistryAccessMixin.java | 48 +++ .../java/org/betterx/bclib/util/Pair.java | 12 + .../org/betterx/bclib/util/WeightedList.java | 54 ++++ .../biomesource/ReloadableBiomeSource.java | 5 + .../chunkgenerator/RestorableBiomeSource.java | 2 +- .../together/levelgen/WorldGenUtil.java | 9 + .../mixin/common/WorldLoaderMixin.java | 22 ++ .../surfaceRules/SurfaceRuleRegistry.java | 2 +- .../together/world/event/WorldBootstrap.java | 4 + src/main/resources/bclib.accesswidener | 4 +- src/main/resources/bclib.mixins.common.json | 2 + src/main/resources/fabric.mod.json | 2 +- .../resources/together.mixins.common.json | 1 + 29 files changed, 910 insertions(+), 145 deletions(-) create mode 100644 src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeRegistry.java create mode 100644 src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeData.java create mode 100644 src/main/java/org/betterx/bclib/mixin/common/BuiltinRegistriesMixin.java create mode 100644 src/main/java/org/betterx/bclib/mixin/common/RegistryAccessMixin.java create mode 100644 src/main/java/org/betterx/worlds/together/biomesource/ReloadableBiomeSource.java create mode 100644 src/main/java/org/betterx/worlds/together/mixin/common/WorldLoaderMixin.java diff --git a/gradle.properties b/gradle.properties index 774e809a..bb807776 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ minecraft_version=1.19 loader_version=0.14.8 fabric_version=0.57.0+1.19 # Mod Properties -mod_version=2.0.10 +mod_version=2.0.11 maven_group=org.betterx.bclib archives_base_name=bclib # Dependencies diff --git a/src/main/java/org/betterx/bclib/BCLib.java b/src/main/java/org/betterx/bclib/BCLib.java index 602da7e2..e839214c 100644 --- a/src/main/java/org/betterx/bclib/BCLib.java +++ b/src/main/java/org/betterx/bclib/BCLib.java @@ -8,6 +8,7 @@ import org.betterx.bclib.api.v2.generator.GeneratorOptions; import org.betterx.bclib.api.v2.levelgen.LevelGenEvents; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.api.v2.levelgen.structures.TemplatePiece; import org.betterx.bclib.api.v2.levelgen.surface.rules.Conditions; @@ -42,6 +43,7 @@ public class BCLib implements ModInitializer { public void onInitialize() { LevelGenEvents.register(); BlockPredicates.ensureStaticInitialization(); + BCLBiomeRegistry.ensureStaticallyLoaded(); BaseRegistry.register(); GeneratorOptions.init(); BaseBlockEntities.register(); diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLChunkGenerator.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLChunkGenerator.java index 160614ba..cbbd853f 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLChunkGenerator.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLChunkGenerator.java @@ -6,6 +6,7 @@ import org.betterx.bclib.interfaces.NoiseGeneratorSettingsProvider; import org.betterx.bclib.mixin.common.ChunkGeneratorAccessor; import org.betterx.worlds.together.WorldsTogether; import org.betterx.worlds.together.biomesource.MergeableBiomeSource; +import org.betterx.worlds.together.biomesource.ReloadableBiomeSource; import org.betterx.worlds.together.chunkgenerator.EnforceableChunkGenerator; import org.betterx.worlds.together.chunkgenerator.InjectableSurfaceRules; import org.betterx.worlds.together.chunkgenerator.RestorableBiomeSource; @@ -110,6 +111,8 @@ public class BCLChunkGenerator extends NoiseBasedChunkGenerator implements Resto if (this instanceof ChunkGeneratorAccessor acc) { if (initialBiomeSource instanceof MergeableBiomeSource bs) { acc.bcl_setBiomeSource(bs.mergeWithBiomeSource(getBiomeSource())); + } else if (initialBiomeSource instanceof ReloadableBiomeSource bs) { + bs.reloadBiomes(); } rebuildFeaturesPerStep(getBiomeSource()); diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java index ccc94786..bd4ef2e1 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java @@ -3,10 +3,12 @@ package org.betterx.bclib.api.v2.generator; import org.betterx.bclib.BCLib; import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.config.Configs; import org.betterx.bclib.interfaces.BiomeMap; import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig; +import org.betterx.worlds.together.biomesource.ReloadableBiomeSource; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -32,7 +34,7 @@ import java.util.Set; import java.util.function.BiFunction; import org.jetbrains.annotations.NotNull; -public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWithConfig { +public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWithConfig, ReloadableBiomeSource { public static Codec CODEC = RecordCodecBuilder.create((instance) -> instance.group( RegistryOps @@ -61,7 +63,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi private BiomeMap mapCenter; private BiomeMap mapBarrens; - private final BiomePicker endLandBiomePicker; + private BiomePicker endLandBiomePicker; private BiomePicker endVoidBiomePicker; private BiomePicker endCenterBiomePicker; private BiomePicker endBarrensBiomePicker; @@ -94,13 +96,25 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi ) { super(biomeRegistry, list, seed); this.config = config; + rebuildBiomePickers(); + + this.endLandFunction = GeneratorOptions.getEndLandFunction(); + this.pos = new Point(); + + if (initMaps) { + initMap(seed); + } + } + + @NotNull + private void rebuildBiomePickers() { var includeMap = Configs.BIOMES_CONFIG.getBiomeIncludeMap(); var excludeList = Configs.BIOMES_CONFIG.getExcludeMatching(BiomeAPI.BiomeType.END); - endLandBiomePicker = new BiomePicker(biomeRegistry); - endVoidBiomePicker = new BiomePicker(biomeRegistry); - endCenterBiomePicker = new BiomePicker(biomeRegistry); - endBarrensBiomePicker = new BiomePicker(biomeRegistry); + this.endLandBiomePicker = new BiomePicker(biomeRegistry); + this.endVoidBiomePicker = new BiomePicker(biomeRegistry); + this.endCenterBiomePicker = new BiomePicker(biomeRegistry); + this.endBarrensBiomePicker = new BiomePicker(biomeRegistry); Map pickerMap = new HashMap<>(); pickerMap.put(BiomeAPI.BiomeType.END_LAND, endLandBiomePicker); pickerMap.put(BiomeAPI.BiomeType.END_VOID, endVoidBiomePicker); @@ -126,7 +140,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi } - if (bclBiome != null || bclBiome != BiomeAPI.EMPTY_BIOME) { + if (bclBiome != null || bclBiome != BCLBiomeRegistry.EMPTY_BIOME) { if (bclBiome.getParentBiome() == null) { //ignore small islands when void biomes are disabled if (!config.withVoidBiomes) { @@ -168,7 +182,6 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi } } } - }); endLandBiomePicker.rebuild(); @@ -194,20 +207,15 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi endCenterBiomePicker = endLandBiomePicker; } } - - this.endLandFunction = GeneratorOptions.getEndLandFunction(); - this.pos = new Point(); - - if (initMaps) { - initMap(seed); - } } protected BCLBiomeSource cloneForDatapack(Set> datapackBiomes) { datapackBiomes.addAll(getBclBiomes(this.biomeRegistry)); return new BCLibEndBiomeSource( this.biomeRegistry, - datapackBiomes.stream().toList(), + datapackBiomes.stream() + .filter(b -> b.unwrapKey().orElse(null) != BCLBiomeRegistry.EMPTY_BIOME.getBiomeKey()) + .toList(), this.currentSeed, this.config, true @@ -235,7 +243,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi private static boolean isValidEndBiome(Holder biome, ResourceLocation location) { if (BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.END_IGNORE)) return false; - + return biome.is(BiomeTags.IS_END) || BiomeAPI.wasRegisteredAsEndBiome(location) || TheEndBiomesHelper.canGenerateInEnd(biome.unwrapKey().orElse(null)); @@ -363,4 +371,10 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi this.config = newConfig; this.initMap(currentSeed); } + + @Override + public void reloadBiomes() { + rebuildBiomePickers(); + this.initMap(currentSeed); + } } diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibNetherBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibNetherBiomeSource.java index bdf504b4..dc614b86 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibNetherBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibNetherBiomeSource.java @@ -4,11 +4,13 @@ import org.betterx.bclib.BCLib; import org.betterx.bclib.api.v2.generator.config.BCLNetherBiomeSourceConfig; import org.betterx.bclib.api.v2.generator.map.MapStack; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.config.Configs; import org.betterx.bclib.interfaces.BiomeMap; import org.betterx.bclib.util.TriFunction; import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig; +import org.betterx.worlds.together.biomesource.ReloadableBiomeSource; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -26,7 +28,7 @@ import net.fabricmc.fabric.api.biome.v1.NetherBiomes; import java.util.List; import java.util.Set; -public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourceWithConfig { +public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourceWithConfig, ReloadableBiomeSource { public static final Codec CODEC = RecordCodecBuilder .create(instance -> instance .group( @@ -49,7 +51,7 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc .apply(instance, instance.stable(BCLibNetherBiomeSource::new)) ); private BiomeMap biomeMap; - private final BiomePicker biomePicker; + private BiomePicker biomePicker; private BCLNetherBiomeSourceConfig config; public BCLibNetherBiomeSource(Registry biomeRegistry, BCLNetherBiomeSourceConfig config) { @@ -78,6 +80,13 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc ) { super(biomeRegistry, list, seed); this.config = config; + rebuildBiomePicker(); + if (initMaps) { + initMap(seed); + } + } + + private void rebuildBiomePicker() { biomePicker = new BiomePicker(biomeRegistry); this.possibleBiomes().forEach(biome -> { @@ -87,12 +96,13 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc return; } if (!BiomeAPI.hasBiome(biomeID)) { + BCLBiome bclBiome = new BCLBiome(biomeID, biome.value()); biomePicker.addBiome(bclBiome); } else { BCLBiome bclBiome = BiomeAPI.getBiome(biomeID); - if (bclBiome != BiomeAPI.EMPTY_BIOME) { + if (bclBiome != BCLBiomeRegistry.EMPTY_BIOME) { if (bclBiome.getParentBiome() == null) { biomePicker.addBiome(bclBiome); } @@ -101,9 +111,6 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc }); biomePicker.rebuild(); - if (initMaps) { - initMap(seed); - } } protected BCLBiomeSource cloneForDatapack(Set> datapackBiomes) { @@ -213,4 +220,10 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc this.config = newConfig; initMap(currentSeed); } + + @Override + public void reloadBiomes() { + rebuildBiomePicker(); + initMap(currentSeed); + } } diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java b/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java index 6763ce9d..550d467e 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BiomePicker.java @@ -1,7 +1,7 @@ package org.betterx.bclib.api.v2.generator; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; -import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; import org.betterx.bclib.util.WeighTree; import org.betterx.bclib.util.WeightedList; @@ -37,7 +37,7 @@ public class BiomePicker { .map(h -> h.unwrapKey()) .filter(o -> o.isPresent()) .map(o -> o.get().location().toString()).toList() : null; - this.fallbackBiome = create(BiomeAPI.EMPTY_BIOME); + this.fallbackBiome = create(BCLBiomeRegistry.EMPTY_BIOME); } private boolean isAllowed(BCLBiome b) { @@ -83,7 +83,7 @@ public class BiomePicker { //no Biome, make sure we add at least one, otherwise bad things will happen if (list.isEmpty()) { - list.add(create(BiomeAPI.EMPTY_BIOME), 1); + list.add(create(BCLBiomeRegistry.EMPTY_BIOME), 1); } @@ -161,4 +161,13 @@ public class BiomePicker { '}'; } } + + @Override + public String toString() { + return "BiomePicker{" + + "biomes=" + biomes.size() + " (" + all.size() + ")" + + ", biomeRegistry=" + biomeRegistry + + ", type=" + super.toString() + + '}'; + } } diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java index 1275e5db..70bdd5f9 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java @@ -2,39 +2,179 @@ package org.betterx.bclib.api.v2.levelgen.biomes; import org.betterx.bclib.util.WeightedList; +import com.mojang.datafixers.Products; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.Registry; import net.minecraft.data.BuiltinRegistries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.TagKey; +import net.minecraft.util.KeyDispatchDataCodec; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Climate; import net.minecraft.world.level.levelgen.WorldgenRandom; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.common.collect.Sets; 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 org.jetbrains.annotations.Nullable; -public class BCLBiome extends BCLBiomeSettings { - private final Set> biomeTags = Sets.newHashSet(); - private final WeightedList subbiomes = new WeightedList<>(); + +public class BCLBiome extends BCLBiomeSettings implements BiomeData { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> codecWithSettings(instance).apply( + instance, + BCLBiome::new + )); + public static final KeyDispatchDataCodec KEY_CODEC = KeyDispatchDataCodec.of(CODEC); + + public KeyDispatchDataCodec codec() { + return KEY_CODEC; + } + + private static class CodecAttributes { + public RecordCodecBuilder t0 = Codec.FLOAT.fieldOf("terrainHeight") + .orElse(0.1f) + .forGetter((T o1) -> o1.terrainHeight); + + public RecordCodecBuilder t1 = Codec.FLOAT.fieldOf("fogDensity") + .orElse(1.0f) + .forGetter((T o1) -> o1.fogDensity); + public RecordCodecBuilder t2 = Codec.FLOAT.fieldOf("genChance") + .orElse(1.0f) + .forGetter((T o1) -> o1.genChance); + public RecordCodecBuilder t3 = Codec.INT.fieldOf("edgeSize") + .orElse(0) + .forGetter((T o1) -> o1.edgeSize); + public RecordCodecBuilder t4 = Codec.BOOL.fieldOf("vertical") + .orElse(false) + .forGetter((T o1) -> o1.vertical); + public RecordCodecBuilder> t5 = + ResourceLocation.CODEC + .optionalFieldOf("edge") + .orElse(Optional.empty()) + .forGetter((T o1) -> o1.edge == null + ? Optional.empty() + : Optional.of(o1.edge.biomeID)); + public RecordCodecBuilder t6 = + ResourceLocation.CODEC.fieldOf("biome") + .forGetter((T o) -> ((BCLBiome) o).biomeID); + public RecordCodecBuilder>> t7 = + Climate.ParameterPoint.CODEC.listOf() + .optionalFieldOf("parameter_points") + .orElse(Optional.of(List.of())) + .forGetter((T o) -> + o.parameterPoints == null || o.parameterPoints.isEmpty() + ? Optional.empty() + : Optional.of(o.parameterPoints)); + + public RecordCodecBuilder> t8 = + ResourceLocation.CODEC.optionalFieldOf("parent") + .orElse(Optional.empty()) + .forGetter( + (T o1) -> + ((BCLBiome) o1).biomeParent == null + ? Optional.empty() + : Optional.of( + ((BCLBiome) o1).biomeParent.biomeID)); + public RecordCodecBuilder>> t9 = + WeightedList.listCodec( + ResourceLocation.CODEC, + "biomes", + "biome" + ) + .optionalFieldOf("sub_biomes") + .forGetter( + (T o) -> { + if (o.subbiomes == null + || o.subbiomes.isEmpty() + || (o.subbiomes.size() == 1 && o.subbiomes.contains( + o))) { + return Optional.empty(); + } + return Optional.of( + o.subbiomes.map( + b -> b.biomeID)); + }); + public RecordCodecBuilder> t10 = + Codec.STRING.optionalFieldOf("intended_for") + .orElse(Optional.of(BiomeAPI.BiomeType.NONE.getName())) + .forGetter((T o) -> + ((BCLBiome) o).intendedType == null + ? Optional.empty() + : Optional.of(((BCLBiome) o).intendedType.getName())); + } + + public static Products.P12, Float, Float, Float, Integer, Boolean, Optional, ResourceLocation, Optional>, Optional, Optional>, Optional, P12> codecWithSettings( + RecordCodecBuilder.Instance instance, + final RecordCodecBuilder p12 + ) { + CodecAttributes a = new CodecAttributes<>(); + return instance.group(a.t0, a.t1, a.t2, a.t3, a.t4, a.t5, a.t6, a.t7, a.t8, a.t9, a.t10, p12); + } + + public static Products.P13, Float, Float, Float, Integer, Boolean, Optional, ResourceLocation, Optional>, Optional, Optional>, Optional, P12, P13> codecWithSettings( + RecordCodecBuilder.Instance instance, + final RecordCodecBuilder p12, + final RecordCodecBuilder p13 + ) { + CodecAttributes a = new CodecAttributes<>(); + return instance.group(a.t0, a.t1, a.t2, a.t3, a.t4, a.t5, a.t6, a.t7, a.t8, a.t9, a.t10, p12, p13); + } + + public static Products.P11, Float, Float, Float, Integer, Boolean, Optional, ResourceLocation, Optional>, Optional, Optional>, Optional> codecWithSettings( + RecordCodecBuilder.Instance instance + ) { + CodecAttributes a = new CodecAttributes<>(); + return instance.group(a.t0, a.t1, a.t2, a.t3, a.t4, a.t5, a.t6, a.t7, a.t8, a.t9, a.t10); + } + + protected final WeightedList subbiomes = new WeightedList<>(); private final Map customData = Maps.newHashMap(); private final ResourceLocation biomeID; private final ResourceKey biomeKey; final Biome biomeToRegister; - private final List parameterPoints = Lists.newArrayList(); + protected final List parameterPoints = Lists.newArrayList(); private BCLBiome biomeParent; + private BiomeAPI.BiomeType intendedType = BiomeAPI.BiomeType.NONE; + + protected BCLBiome( + float terrainHeight, + float fogDensity, + float genChance, + int edgeSize, + boolean vertical, + Optional edge, + ResourceLocation biomeID, + Optional> parameterPoints, + Optional biomeParent, + Optional> subbiomes, + Optional intendedType + ) { + super(terrainHeight, fogDensity, genChance, edgeSize, vertical, edge.map(BiomeAPI::getBiome).orElse(null)); + biomeToRegister = null; + this.biomeID = biomeID; + this.biomeKey = ResourceKey.create(Registry.BIOME_REGISTRY, biomeID); + if (subbiomes.isEmpty() || subbiomes.get().size() == 0) { + this.subbiomes.add(this, 1); + } else { + this.subbiomes.addAll(subbiomes.get().map(BiomeAPI::getBiome)); + } + this.biomeParent = biomeParent.map(BiomeAPI::getBiome).orElse(null); + if (parameterPoints.isPresent()) this.parameterPoints.addAll(parameterPoints.get()); + this.setIntendedType(intendedType.map(t -> BiomeAPI.BiomeType.create(t)).orElse(BiomeAPI.BiomeType.NONE)); + + + } + /** * Create wrapper for existing biome using its {@link ResourceLocation} identifier. * @@ -81,6 +221,7 @@ public class BCLBiome extends BCLBiomeSettings { * @param biomeID Teh ResoureLocation for this Biome */ @Deprecated(forRemoval = true) + //this constructor should become package private and not get removed public BCLBiome(ResourceLocation biomeID, Biome biomeToRegister) { this(biomeID, biomeToRegister, null); } @@ -124,6 +265,25 @@ public class BCLBiome extends BCLBiomeSettings { } } + /** + * Changes the intended Type for this Biome + * + * @param type the new type + * @return the same instance + */ + protected BCLBiome setIntendedType(BiomeAPI.BiomeType type) { + return _setIntendedType(type); + } + + BCLBiome _setIntendedType(BiomeAPI.BiomeType type) { + this.intendedType = type; + return this; + } + + BiomeAPI.BiomeType getIntendedType() { + return this.intendedType; + } + /** * Get current biome edge. * @@ -250,6 +410,10 @@ public class BCLBiome extends BCLBiomeSettings { return biomeKey; } + public ResourceKey getBCLBiomeKey() { + return ResourceKey.create(BCLBiomeRegistry.BCL_BIOMES_REGISTRY, biomeID); + } + /** * For internal use from BiomeAPI only */ @@ -291,6 +455,7 @@ public class BCLBiome extends BCLBiomeSettings { * @param obj any data to add. * @return same {@link BCLBiome}. */ + @Deprecated(forRemoval = true) public BCLBiome addCustomData(String name, Object obj) { customData.put(name, obj); return this; @@ -302,6 +467,7 @@ public class BCLBiome extends BCLBiomeSettings { * @param data a {@link Map} with custom data. * @return same {@link BCLBiome}. */ + @Deprecated(forRemoval = true) public BCLBiome addCustomData(Map data) { customData.putAll(data); return this; diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeBuilder.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeBuilder.java index bd11dab7..a8bd1faf 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeBuilder.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeBuilder.java @@ -54,6 +54,7 @@ public class BCLBiomeBuilder { public interface BiomeSupplier extends TriFunction { } + private static final BCLBiomeBuilder INSTANCE = new BCLBiomeBuilder(); private static final SurfaceRules.ConditionSource SURFACE_NOISE = SurfaceRules.noiseCondition( Noises.SOUL_SAND_LAYER, @@ -709,6 +710,64 @@ public class BCLBiomeBuilder { return this; } + /** + * Changes the type for the Biome. The intended Type defines in which Dimension a + * Biome is allowed to spawn. Currently each Biome can only spawn in one dimension + * + * @param type The intended type + * @return same {@link BCLBiomeBuilder} instance. + */ + public BCLBiomeBuilder intendedType(BiomeAPI.BiomeType type) { + this.biomeType = type; + return this; + } + + + /** + * Changes the intended type for the Biome to an EndLand Biome + * + * @return same {@link BCLBiomeBuilder} instance. + */ + public BCLBiomeBuilder endLandBiome() { + return intendedType(BiomeAPI.BiomeType.BCL_END_LAND); + } + + /** + * Changes the intended type for the Biome to an EndVoid (aka small islands) Biome + * + * @return same {@link BCLBiomeBuilder} instance. + */ + public BCLBiomeBuilder endVoidBiome() { + return intendedType(BiomeAPI.BiomeType.BCL_END_VOID); + } + + /** + * Changes the intended type for the Biome to an Endbarrens Biome + * + * @return same {@link BCLBiomeBuilder} instance. + */ + public BCLBiomeBuilder endBarrensBiome() { + return intendedType(BiomeAPI.BiomeType.BCL_END_BARRENS); + } + + /** + * Changes the intended type for the Biome to an End Center Island Biome + * + * @return same {@link BCLBiomeBuilder} instance. + */ + public BCLBiomeBuilder endCenterBiome() { + return intendedType(BiomeAPI.BiomeType.BCL_END_CENTER); + } + + /** + * Changes the intended type for the Biome to a Nether Biome + * + * @return same {@link BCLBiomeBuilder} instance. + */ + public BCLBiomeBuilder netherBiome() { + return intendedType(BiomeAPI.BiomeType.BCL_NETHER); + } + public BCLBiomeBuilder tag(TagKey... tag) { for (TagKey t : tag) { tags.add(t); @@ -850,6 +909,8 @@ public class BCLBiomeBuilder { //res.setSurface(surfaceRule); SurfaceRuleRegistry.registerRule(biomeID, surfaceRule, biomeID); res.addClimateParameters(parameters); + if (biomeType != null) + res._setIntendedType(biomeType); //carvers.forEach(cfg -> BiomeAPI.addBiomeCarver(biome, cfg.second, cfg.first)); diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeRegistry.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeRegistry.java new file mode 100644 index 00000000..bf7e9c72 --- /dev/null +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeRegistry.java @@ -0,0 +1,145 @@ +package org.betterx.bclib.api.v2.levelgen.biomes; + +import org.betterx.bclib.BCLib; +import org.betterx.worlds.together.WorldsTogether; +import org.betterx.worlds.together.world.event.WorldBootstrap; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.Lifecycle; +import net.minecraft.core.Holder; +import net.minecraft.core.MappedRegistry; +import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; +import net.minecraft.data.BuiltinRegistries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.KeyDispatchDataCodec; +import net.minecraft.world.level.biome.Biomes; + +import java.util.Optional; +import java.util.stream.Stream; +import org.jetbrains.annotations.ApiStatus; + +public class BCLBiomeRegistry { + public static final ResourceKey> BCL_BIOMES_REGISTRY = + createRegistryKey(WorldsTogether.makeID("worldgen/betterx/biome")); + + public static final ResourceKey>> BCL_BIOME_CODEC_REGISTRY = + createRegistryKey(WorldsTogether.makeID("worldgen/betterx/biome_codec")); + + public static Registry> BIOME_CODECS = Registry.registerSimple( + BCL_BIOME_CODEC_REGISTRY, + BCLBiomeRegistry::bootstrapCodecs + ); + public static Registry BUILTIN_BCL_BIOMES = new MappedRegistry<>( + BCL_BIOMES_REGISTRY, + Lifecycle.stable(), null + ); + + /** + * Empty biome used as default value if requested biome doesn't exist or linked. Shouldn't be registered anywhere to prevent bugs. + * Have {@code Biomes.THE_VOID} as the reference biome. + **/ + public static final BCLBiome EMPTY_BIOME = new BCLBiome(Biomes.THE_VOID.location()); + + public static Codec registerBiomeCodec( + ResourceLocation location, + KeyDispatchDataCodec codec + ) { + Registry.register(BIOME_CODECS, location, codec.codec()); + return codec.codec(); + } + + public static ResourceKey register(BCLBiome biome) { + Registry.register(BUILTIN_BCL_BIOMES, biome.getBCLBiomeKey(), biome); + return biome.getBCLBiomeKey(); + } + + private static ResourceKey> createRegistryKey(ResourceLocation location) { + return ResourceKey.createRegistryKey(location); + } + + private static Codec bootstrapCodecs(Registry> registry) { + return Registry.register(registry, BCLib.makeID("biome"), BCLBiome.KEY_CODEC.codec()); + } + + + @ApiStatus.Internal + public static Holder bootstrap(Registry registry) { + BuiltinRegistries.register(registry, BiomeAPI.SMALL_END_ISLANDS.getBCLBiomeKey(), BiomeAPI.SMALL_END_ISLANDS); + BuiltinRegistries.register(registry, BiomeAPI.END_BARRENS.getBCLBiomeKey(), BiomeAPI.END_BARRENS); + BuiltinRegistries.register(registry, BiomeAPI.END_HIGHLANDS.getBCLBiomeKey(), BiomeAPI.END_HIGHLANDS); + BuiltinRegistries.register(registry, BiomeAPI.END_MIDLANDS.getBCLBiomeKey(), BiomeAPI.END_MIDLANDS); + BuiltinRegistries.register(registry, BiomeAPI.THE_END.getBCLBiomeKey(), BiomeAPI.THE_END); + BuiltinRegistries.register( + registry, + BiomeAPI.BASALT_DELTAS_BIOME.getBCLBiomeKey(), + BiomeAPI.BASALT_DELTAS_BIOME + ); + BuiltinRegistries.register( + registry, + BiomeAPI.SOUL_SAND_VALLEY_BIOME.getBCLBiomeKey(), + BiomeAPI.SOUL_SAND_VALLEY_BIOME + ); + BuiltinRegistries.register( + registry, + BiomeAPI.WARPED_FOREST_BIOME.getBCLBiomeKey(), + BiomeAPI.WARPED_FOREST_BIOME + ); + BuiltinRegistries.register( + registry, + BiomeAPI.CRIMSON_FOREST_BIOME.getBCLBiomeKey(), + BiomeAPI.CRIMSON_FOREST_BIOME + ); + BuiltinRegistries.register( + registry, + BiomeAPI.NETHER_WASTES_BIOME.getBCLBiomeKey(), + BiomeAPI.NETHER_WASTES_BIOME + ); + return BuiltinRegistries.register(registry, EMPTY_BIOME.getBCLBiomeKey(), EMPTY_BIOME); + } + + public static BCLBiome get(ResourceLocation loc) { + return get(WorldBootstrap.getLastRegistryAccessOrElseBuiltin(), loc); + } + + public static BCLBiome get(RegistryAccess access, ResourceLocation loc) { + return getBclBiomesRegistry(access).get(loc); + } + + public static BCLBiome getOrElseEmpty(ResourceLocation loc) { + return getOrElseEmpty(WorldBootstrap.getLastRegistryAccessOrElseBuiltin(), loc); + } + + public static BCLBiome getOrElseEmpty(RegistryAccess access, ResourceLocation loc) { + BCLBiome res = get(access, loc); + if (res == null) return EMPTY_BIOME; + return res; + } + + public static Stream> getAll(BiomeAPI.BiomeType dim) { + return getAll(WorldBootstrap.getLastRegistryAccessOrElseBuiltin(), dim); + } + + public static Stream> getAll(RegistryAccess access, BiomeAPI.BiomeType dim) { + return getBclBiomesRegistry(access) + .entrySet() + .stream() + .filter(e -> e.getValue().getIntendedType().is(BiomeAPI.BiomeType.END)) + .map(e -> e.getKey()); + } + + private static Registry getBclBiomesRegistry(RegistryAccess access) { + if (access != null) { + return ((Optional>) access + .registry(BCLBiomeRegistry.BCL_BIOMES_REGISTRY)) + .orElse(BUILTIN_BCL_BIOMES); + } else { + return BUILTIN_BCL_BIOMES; + } + } + + public static void ensureStaticallyLoaded() { + + } +} diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeSettings.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeSettings.java index 6f2a560b..948702c6 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeSettings.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiomeSettings.java @@ -103,6 +103,22 @@ public class BCLBiomeSettings { } } + BCLBiomeSettings( + float terrainHeight, + float fogDensity, + float genChance, + int edgeSize, + boolean vertical, + BCLBiome edge + ) { + this.terrainHeight = terrainHeight; + this.fogDensity = fogDensity; + this.genChance = genChance; + this.edgeSize = edgeSize; + this.vertical = vertical; + this.edge = edge; + } + protected BCLBiomeSettings() { this.terrainHeight = 0.1F; this.fogDensity = 1.0F; diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java index a7169b94..7353db38 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java @@ -8,8 +8,10 @@ import org.betterx.bclib.mixin.common.MobSpawnSettingsAccessor; import org.betterx.bclib.util.CollectionsUtil; import org.betterx.worlds.together.tag.v3.CommonBiomeTags; import org.betterx.worlds.together.tag.v3.TagManager; +import org.betterx.worlds.together.world.event.WorldBootstrap; -import net.minecraft.client.Minecraft; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; @@ -38,53 +40,142 @@ import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.placement.PlacedFeature; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.biome.v1.NetherBiomes; import net.fabricmc.fabric.api.biome.v1.TheEndBiomes; import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.function.BiConsumer; import java.util.function.Supplier; import java.util.stream.Collectors; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class BiomeAPI { public static class BiomeType { + public static final Codec DIRECT_CODEC = RecordCodecBuilder.create(instance -> instance + .group( + Codec.STRING.fieldOf("name") + .orElse("undefined") + .forGetter(o -> o.name) + + ).apply(instance, BiomeType::create)); + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + Codec.STRING.fieldOf("name") + .orElse("undefined") + .forGetter(o -> o.name), + Codec.STRING.fieldOf("parent") + .orElse("none") + .forGetter(o -> o.parentOrNull == null ? "none" : o.parentOrNull.name) + + ).apply(instance, BiomeType::create)); + + private static final Map KNOWN_TYPES = new HashMap<>(); + public static final BiomeType NONE = new BiomeType("NONE"); public static final BiomeType OVERWORLD = new BiomeType("OVERWORLD"); public static final BiomeType NETHER = new BiomeType("NETHER"); - public static final BiomeType BCL_NETHER = new BiomeType("BCL_NETHER", NETHER); + public static final BiomeType BCL_NETHER = new BiomeType("BCL_NETHER", NETHER, (biome, ignored) -> { + ResourceKey key = biome.getBiomeKey(); + if (!biome.isEdgeBiome()) { + biome.forEachClimateParameter(p -> NetherBiomes.addNetherBiome(key, p)); + } + }); public static final BiomeType END = new BiomeType("END"); public static final BiomeType END_IGNORE = new BiomeType("END_IGNORE", END); public static final BiomeType END_LAND = new BiomeType("END_LAND", END); public static final BiomeType END_VOID = new BiomeType("END_VOID", END); public static final BiomeType END_CENTER = new BiomeType("END_CENTER", END); public static final BiomeType END_BARRENS = new BiomeType("END_BARRENS", END); - public static final BiomeType BCL_END_LAND = new BiomeType("BCL_END_LAND", END_LAND); - public static final BiomeType BCL_END_VOID = new BiomeType("BCL_END_VOID", END_VOID); - public static final BiomeType BCL_END_CENTER = new BiomeType("BCL_END_CENTER", END_CENTER); - public static final BiomeType BCL_END_BARRENS = new BiomeType("BCL_END_BARRENS", END_BARRENS); + public static final BiomeType BCL_END_LAND = new BiomeType("BCL_END_LAND", END_LAND, (biome, ignored) -> { + float weight = biome.getGenChance(); + ResourceKey key = biome.getBiomeKey(); + + if (biome.isEdgeBiome()) { + ResourceKey parentKey = biome.getParentBiome().getBiomeKey(); + TheEndBiomes.addMidlandsBiome(parentKey, key, weight); + } else { + TheEndBiomes.addHighlandsBiome(key, weight); + } + }); + public static final BiomeType BCL_END_VOID = new BiomeType("BCL_END_VOID", END_VOID, (biome, ignored) -> { + float weight = biome.getGenChance(); + ResourceKey key = biome.getBiomeKey(); + if (!biome.isEdgeBiome()) { + TheEndBiomes.addSmallIslandsBiome(key, weight); + } + }); + public static final BiomeType BCL_END_CENTER = new BiomeType("BCL_END_CENTER", END_CENTER, (biome, ignored) -> { + float weight = biome.getGenChance(); + ResourceKey key = biome.getBiomeKey(); + if (!biome.isEdgeBiome()) { + TheEndBiomes.addMainIslandBiome(key, weight); + } + }); + + public static final BiomeType BCL_END_BARRENS = new BiomeType( + "BCL_END_BARRENS", + END_BARRENS, + (biome, highlandBiome) -> { + float weight = biome.getGenChance(); + ResourceKey key = biome.getBiomeKey(); + if (!biome.isEdgeBiome()) { + ResourceKey parentKey = highlandBiome.getBiomeKey(); + TheEndBiomes.addBarrensBiome(parentKey, key, weight); + } + } + ); - static final Map BIOME_TYPE_MAP = Maps.newHashMap(); public final BiomeType parentOrNull; private final String name; + @FunctionalInterface + interface ExtraRegisterTaks { + void register(@NotNull BCLBiome biome, @Nullable BCLBiome parent); + } + + final ExtraRegisterTaks extraRegisterTask; + + private static BiomeType create(String name, String parentOrNull) { + BiomeType known = KNOWN_TYPES.get(name); + BiomeType parent = parentOrNull == null || "none".equals(parentOrNull) + ? null + : KNOWN_TYPES.get(parentOrNull); + if (known != null) { + if (known.parentOrNull != parent) { + BCLib.LOGGER.warning("BiomeType " + name + " was deserialized with parent " + parent + " but already has " + known.parentOrNull); + } + return known; + } + return new BiomeType(name, parent); + } + + static BiomeType create(String name) { + BiomeType known = KNOWN_TYPES.get(name); + if (known != null) { + return known; + } + return NONE; + } + public BiomeType(String name) { this(name, null); } public BiomeType(String name, BiomeType parentOrNull) { + this(name, parentOrNull, (b, a) -> { + }); + } + + public BiomeType(String name, BiomeType parentOrNull, ExtraRegisterTaks extraRegisterTask) { this.parentOrNull = parentOrNull; this.name = name; + this.extraRegisterTask = extraRegisterTask; + KNOWN_TYPES.put(name, this); } public boolean is(BiomeType d) { @@ -108,10 +199,10 @@ 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. * Have {@code Biomes.THE_VOID} as the reference biome. + * + * @deprecated use {@link BCLBiomeRegistry#EMPTY_BIOME} instead */ - public static final BCLBiome EMPTY_BIOME = new BCLBiome(Biomes.THE_VOID.location()); - - private static final Map ID_MAP = Maps.newHashMap(); + public static final BCLBiome EMPTY_BIOME = BCLBiomeRegistry.EMPTY_BIOME; public static final BCLBiome NETHER_WASTES_BIOME = InternalBiomeAPI.wrapNativeBiome( Biomes.NETHER_WASTES, @@ -166,6 +257,16 @@ public class BiomeAPI { InternalBiomeAPI.OTHER_END_VOID ); + /** + * Register {@link BCLBiome} instance and its {@link Biome} if necessary. + * + * @param bclbiome {@link BCLBiome} + * @return {@link BCLBiome} + */ + public static BCLBiome registerBiome(BCLBiome bclbiome) { + return registerBiome(bclbiome, BuiltinRegistries.BIOME); + } + /** * Register {@link BCLBiome} instance and its {@link Biome} if necessary. * @@ -173,6 +274,7 @@ public class BiomeAPI { * @param dim The Dimension fo rthis Biome * @return {@link BCLBiome} */ + @Deprecated(forRemoval = true) public static BCLBiome registerBiome(BCLBiome bclbiome, BiomeType dim) { return registerBiome(bclbiome, dim, BuiltinRegistries.BIOME); } @@ -184,15 +286,27 @@ public class BiomeAPI { * @param dim The Dimension fo rthis Biome * @return {@link BCLBiome} */ + @Deprecated(forRemoval = true) static BCLBiome registerBiome(BCLBiome bclbiome, BiomeType dim, Registry registryOrNull) { + bclbiome._setIntendedType(dim); + return registerBiome(bclbiome, registryOrNull); + } + + /** + * Register {@link BCLBiome} instance and its {@link Biome} if necessary. + * + * @param bclbiome {@link BCLBiome} + * @return {@link BCLBiome} + */ + static BCLBiome registerBiome(BCLBiome bclbiome, Registry registryOrNull) { + BiomeType dim = bclbiome.getIntendedType(); if (registryOrNull != null && bclbiome.biomeToRegister != null && registryOrNull.get(bclbiome.getID()) == null) { Registry.register(registryOrNull, bclbiome.getBiomeKey(), bclbiome.biomeToRegister); - } - ID_MAP.put(bclbiome.getID(), bclbiome); - BiomeType.BIOME_TYPE_MAP.put(bclbiome.getID(), dim); + BCLBiomeRegistry.register(bclbiome); + } if (dim != null && dim.is(BiomeType.NETHER)) { TagManager.BIOMES.add(BiomeTags.IS_NETHER, bclbiome.getBiomeKey()); @@ -211,7 +325,7 @@ public class BiomeAPI { return registerSubBiome( parent, subBiome, - BiomeType.BIOME_TYPE_MAP.getOrDefault(parent.getID(), BiomeType.NONE) + parent.getIntendedType() ); } @@ -220,7 +334,7 @@ public class BiomeAPI { parent, subBiome, genChance, - BiomeType.BIOME_TYPE_MAP.getOrDefault(parent.getID(), BiomeType.NONE) + parent.getIntendedType() ); } @@ -248,14 +362,14 @@ public class BiomeAPI { float weight = biome.getGenChance(); ResourceKey key = biome.getBiomeKey(); - if (biome.allowFabricRegistration()) { - if (biome.isEdgeBiome()) { - ResourceKey parentKey = biome.getParentBiome().getBiomeKey(); - TheEndBiomes.addMidlandsBiome(parentKey, key, weight); - } else { - TheEndBiomes.addHighlandsBiome(key, weight); - } + + if (biome.isEdgeBiome()) { + ResourceKey parentKey = biome.getParentBiome().getBiomeKey(); + TheEndBiomes.addMidlandsBiome(parentKey, key, weight); + } else { + TheEndBiomes.addHighlandsBiome(key, weight); } + return biome; } @@ -272,7 +386,7 @@ public class BiomeAPI { float weight = biome.getGenChance(); ResourceKey key = biome.getBiomeKey(); - if (biome.allowFabricRegistration()) { + if (!biome.isEdgeBiome()) { TheEndBiomes.addSmallIslandsBiome(key, weight); } return biome; @@ -291,7 +405,7 @@ public class BiomeAPI { float weight = biome.getGenChance(); ResourceKey key = biome.getBiomeKey(); - if (biome.allowFabricRegistration()) { + if (!biome.isEdgeBiome()) { TheEndBiomes.addMainIslandBiome(key, weight); } return biome; @@ -310,7 +424,7 @@ public class BiomeAPI { float weight = biome.getGenChance(); ResourceKey key = biome.getBiomeKey(); - if (biome.allowFabricRegistration()) { + if (!biome.isEdgeBiome()) { ResourceKey parentKey = highlandBiome.getBiomeKey(); TheEndBiomes.addBarrensBiome(parentKey, key, weight); } @@ -318,17 +432,20 @@ public class BiomeAPI { } - public static BCLBiome registerEndBiome(Holder biome) { - BCLBiome bclBiome = new BCLBiome(biome.value(), null); + /** + * Register {@link BCLBiome} instance and its {@link Biome} if necessary. + * After that biome will be added to BCLib Nether Biome Generator and into Fabric Biome API. + * + * @param bclBiome {@link BCLBiome} + * @return {@link BCLBiome} + */ + public static BCLBiome registerNetherBiome(BCLBiome bclBiome) { + registerBiome(bclBiome, BiomeType.BCL_NETHER); - registerBiome(bclBiome, BiomeType.END); - return bclBiome; - } - - public static BCLBiome registerCenterBiome(Holder biome) { - BCLBiome bclBiome = new BCLBiome(biome.value(), null); - - registerBiome(bclBiome, BiomeType.END_CENTER); + ResourceKey key = bclBiome.getBiomeKey(); + if (!bclBiome.isEdgeBiome()) { + bclBiome.forEachClimateParameter(p -> NetherBiomes.addNetherBiome(key, p)); + } return bclBiome; } @@ -342,9 +459,13 @@ public class BiomeAPI { @Deprecated(forRemoval = true) public static BCLBiome getFromBiome(Holder biome) { if (InternalBiomeAPI.biomeRegistry == null) { - return EMPTY_BIOME; + return BCLBiomeRegistry.EMPTY_BIOME; } - return ID_MAP.getOrDefault(biome.unwrapKey().orElseThrow().location(), EMPTY_BIOME); + return BCLBiomeRegistry + .getOrElseEmpty( + InternalBiomeAPI.registryAccess, + biome.unwrapKey().orElseThrow().location() + ); } /** @@ -353,15 +474,15 @@ public class BiomeAPI { * @param biome - {@link Biome} from client world. * @return {@link BCLBiome} or {@code BiomeAPI.EMPTY_BIOME}. */ - @Environment(EnvType.CLIENT) public static BCLBiome getRenderBiome(Biome biome) { BCLBiome endBiome = InternalBiomeAPI.CLIENT.get(biome); if (endBiome == null) { - Minecraft minecraft = Minecraft.getInstance(); - ResourceLocation id = minecraft.level.registryAccess() - .registryOrThrow(Registry.BIOME_REGISTRY) - .getKey(biome); - endBiome = id == null ? EMPTY_BIOME : ID_MAP.getOrDefault(id, EMPTY_BIOME); + ResourceLocation id = WorldBootstrap.getLastRegistryAccessOrElseBuiltin() + .registryOrThrow(Registry.BIOME_REGISTRY) + .getKey(biome); + endBiome = id == null + ? BCLBiomeRegistry.EMPTY_BIOME + : BCLBiomeRegistry.getOrElseEmpty(id); InternalBiomeAPI.CLIENT.put(biome, endBiome); } return endBiome; @@ -401,7 +522,7 @@ public class BiomeAPI { if (id == null) { BCLib.LOGGER.error("Unable to get ID for " + biome + ". Falling back to empty Biome..."); - id = EMPTY_BIOME.getID(); + id = BCLBiomeRegistry.EMPTY_BIOME.getID(); } return id; @@ -414,11 +535,10 @@ public class BiomeAPI { * @return biome {@link ResourceLocation}. */ public static ResourceLocation getBiomeID(Holder biome) { - var oKey = biome.unwrapKey(); - if (oKey.isPresent()) { - return oKey.get().location(); - } - return null; + return biome + .unwrapKey() + .map(h -> h.location()) + .orElse(null); } public static ResourceKey getBiomeKey(Holder biome) { @@ -462,7 +582,8 @@ public class BiomeAPI { * @return {@link BCLBiome} or {@code BiomeAPI.EMPTY_BIOME}. */ public static BCLBiome getBiome(ResourceLocation biomeID) { - return ID_MAP.getOrDefault(biomeID, EMPTY_BIOME); + if (biomeID == null) return BCLBiomeRegistry.EMPTY_BIOME; + return BCLBiomeRegistry.getOrElseEmpty(biomeID); } /** @@ -492,7 +613,7 @@ public class BiomeAPI { * @return {@code true} if biome exists in API registry and {@code false} if not. */ public static boolean hasBiome(ResourceLocation biomeID) { - return ID_MAP.containsKey(biomeID); + return BCLBiomeRegistry.get(biomeID) != null; } public static Holder getFromRegistry(ResourceLocation biomeID) { @@ -537,12 +658,9 @@ public class BiomeAPI { } public static boolean wasRegisteredAs(ResourceLocation biomeID, BiomeType dim) { - if (BiomeType.BIOME_TYPE_MAP.containsKey(biomeID) && BiomeType.BIOME_TYPE_MAP.get(biomeID).is(dim)) return true; - BCLBiome biome = getBiome(biomeID); - if (biome != null && biome != BiomeAPI.EMPTY_BIOME && biome.getParentBiome() != null) { - return wasRegisteredAs(biome.getParentBiome().getID(), dim); - } - return false; + if (BCLBiomeRegistry.EMPTY_BIOME.getID().equals(biomeID)) + return false; + return BCLBiomeRegistry.getOrElseEmpty(biomeID).getIntendedType().is(dim); } public static boolean wasRegisteredAsNetherBiome(ResourceLocation biomeID) { @@ -883,22 +1001,6 @@ public class BiomeAPI { return features.get(index).stream().collect(Collectors.toList()); } - /** - * Register {@link BCLBiome} instance and its {@link Biome} if necessary. - * After that biome will be added to BCLib Nether Biome Generator and into Fabric Biome API. - * - * @param bclBiome {@link BCLBiome} - * @return {@link BCLBiome} - */ - public static BCLBiome registerNetherBiome(BCLBiome bclBiome) { - registerBiome(bclBiome, BiomeType.BCL_NETHER); - - ResourceKey key = bclBiome.getBiomeKey(); - if (bclBiome.allowFabricRegistration()) { - bclBiome.forEachClimateParameter(p -> NetherBiomes.addNetherBiome(key, p)); - } - return bclBiome; - } /** * Register {@link BCLBiome} instance and its {@link Biome} if necessary. @@ -962,4 +1064,22 @@ public class BiomeAPI { InternalBiomeAPI.OTHER_END_VOID ); } + + + @Deprecated(forRemoval = true) + public static BCLBiome registerEndBiome(Holder biome) { + BCLBiome bclBiome = new BCLBiome(biome.value(), null); + + registerBiome(bclBiome, BiomeType.END); + return bclBiome; + } + + + @Deprecated(forRemoval = true) + public static BCLBiome registerCenterBiome(Holder biome) { + BCLBiome bclBiome = new BCLBiome(biome.value(), null); + + registerBiome(bclBiome, BiomeType.END_CENTER); + return bclBiome; + } } diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeData.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeData.java new file mode 100644 index 00000000..2997ef38 --- /dev/null +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeData.java @@ -0,0 +1,15 @@ +package org.betterx.bclib.api.v2.levelgen.biomes; + +import com.mojang.serialization.Codec; +import net.minecraft.util.KeyDispatchDataCodec; + +import java.util.function.Function; + +public interface BiomeData { + Codec CODEC = BCLBiomeRegistry + .BIOME_CODECS + .byNameCodec() + .dispatch(b -> b.codec().codec(), Function.identity()); + + KeyDispatchDataCodec codec(); +} diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java index ba14625f..0b0cce96 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/InternalBiomeAPI.java @@ -165,16 +165,10 @@ public class InternalBiomeAPI { public static void _runBiomeTagAdders() { for (var mod : TAG_ADDERS.entrySet()) { Stream s = null; - if (mod.getKey() == Level.NETHER) s = BiomeAPI.BiomeType.BIOME_TYPE_MAP.entrySet() - .stream() - .filter(e -> e.getValue() - .is(BiomeAPI.BiomeType.NETHER)) - .map(e -> e.getKey()); - else if (mod.getKey() == Level.END) s = BiomeAPI.BiomeType.BIOME_TYPE_MAP.entrySet() - .stream() - .filter(e -> e.getValue().is( - BiomeAPI.BiomeType.END)) - .map(e -> e.getKey()); + if (mod.getKey() == Level.NETHER) + s = BCLBiomeRegistry.getAll(BiomeAPI.BiomeType.NETHER).map(k -> k.location()); + else if (mod.getKey() == Level.END) + s = BCLBiomeRegistry.getAll(BiomeAPI.BiomeType.END).map(k -> k.location()); if (s != null) { s.forEach(id -> { Holder biomeHolder = BiomeAPI.getFromRegistry(id); @@ -326,11 +320,12 @@ public class InternalBiomeAPI { BiomeAPI.BiomeType type ) { BCLBiome bclBiome = BiomeAPI.getBiome(biomeKey.location()); - if (bclBiome == BiomeAPI.EMPTY_BIOME) { + if (bclBiome == BCLBiomeRegistry.EMPTY_BIOME) { bclBiome = new BCLBiome(biomeKey, setings); + bclBiome._setIntendedType(type); } - BiomeAPI.registerBiome(bclBiome, type); + BiomeAPI.registerBiome(bclBiome); return bclBiome; } @@ -345,7 +340,7 @@ public class InternalBiomeAPI { @Deprecated(forRemoval = true) static BCLBiome wrapNativeBiome(Biome biome, float genChance, BiomeAPI.BiomeType type) { BCLBiome bclBiome = BiomeAPI.getBiome(biome); - if (bclBiome == BiomeAPI.EMPTY_BIOME) { + if (bclBiome == BCLBiomeRegistry.EMPTY_BIOME) { bclBiome = new BCLBiome( biome, genChance < 0 ? null : VanillaBiomeSettings.createVanilla().setGenChance(genChance).build() @@ -363,7 +358,7 @@ public class InternalBiomeAPI { .event(oBiomeRegistry.get()) .register((rawId, id, biome) -> { BCLBiome b = BiomeAPI.getBiome(id); - if (!"minecraft".equals(id.getNamespace()) && (b == null || b == BiomeAPI.EMPTY_BIOME)) { + if (!"minecraft".equals(id.getNamespace()) && (b == null || b == BCLBiomeRegistry.EMPTY_BIOME)) { //BCLib.LOGGER.info(" #### " + rawId + ", " + biome + ", " + id); BIOMES_TO_SORT.add(id); } diff --git a/src/main/java/org/betterx/bclib/client/render/CustomFogRenderer.java b/src/main/java/org/betterx/bclib/client/render/CustomFogRenderer.java index c2308d9e..b4f122fd 100644 --- a/src/main/java/org/betterx/bclib/client/render/CustomFogRenderer.java +++ b/src/main/java/org/betterx/bclib/client/render/CustomFogRenderer.java @@ -1,6 +1,7 @@ package org.betterx.bclib.client.render; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.config.Configs; import org.betterx.bclib.util.BackgroundInfo; @@ -116,7 +117,7 @@ public class CustomFogRenderer { private static boolean shouldIgnore(Level level, int x, int y, int z) { Biome biome = level.getBiome(MUT_POS.set(x, y, z)).value(); - return BiomeAPI.getRenderBiome(biome) == BiomeAPI.EMPTY_BIOME; + return BiomeAPI.getRenderBiome(biome) == BCLBiomeRegistry.EMPTY_BIOME; } private static float getFogDensityI(Level level, int x, int y, int z) { diff --git a/src/main/java/org/betterx/bclib/commands/DumpDatapack.java b/src/main/java/org/betterx/bclib/commands/DumpDatapack.java index bd8187f1..5f3d4003 100644 --- a/src/main/java/org/betterx/bclib/commands/DumpDatapack.java +++ b/src/main/java/org/betterx/bclib/commands/DumpDatapack.java @@ -1,9 +1,10 @@ package org.betterx.bclib.commands; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; +import org.betterx.bclib.BCLib; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeData; +import org.betterx.bclib.blocks.BaseStairsBlock; + import com.mojang.brigadier.Command; import com.mojang.brigadier.context.CommandContext; import com.mojang.serialization.Codec; @@ -27,8 +28,11 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.RuleTestType; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorType; import net.minecraft.world.level.material.Fluid; -import org.betterx.bclib.BCLib; -import org.betterx.bclib.blocks.BaseStairsBlock; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import java.awt.Taskbar.Feature; import java.io.File; @@ -113,13 +117,15 @@ public class DumpDatapack { while (obj instanceof Holder) { obj = ((Holder) obj).value(); } - + if (obj instanceof BiomeSource || obj instanceof Feature) { System.out.print(""); } - + if (obj instanceof Structure s) { codec[0] = s.type().codec(); + } else if (obj instanceof BCLBiome s) { + codec[0] = BiomeData.CODEC; } else if (obj instanceof StructureProcessorList s) { codec[0] = StructureProcessorType.LIST_OBJECT_CODEC; } else if (obj instanceof GameEvent) { @@ -134,9 +140,9 @@ public class DumpDatapack { codec[0] = registry.value().byNameCodec(); } else if (obj instanceof PosRuleTestType) { codec[0] = registry.value().byNameCodec(); - }else if (obj instanceof WorldGenSettings) { + } else if (obj instanceof WorldGenSettings) { codec[0] = registry.value().byNameCodec(); - }else if (obj instanceof LevelStem) { + } else if (obj instanceof LevelStem) { codec[0] = registry.value().byNameCodec(); } @@ -225,8 +231,8 @@ public class DumpDatapack { } } } - - if (codec[0]==null){ + + if (codec[0] == null) { codec[0] = registry.value().byNameCodec(); } diff --git a/src/main/java/org/betterx/bclib/mixin/common/BuiltinRegistriesMixin.java b/src/main/java/org/betterx/bclib/mixin/common/BuiltinRegistriesMixin.java new file mode 100644 index 00000000..b5733252 --- /dev/null +++ b/src/main/java/org/betterx/bclib/mixin/common/BuiltinRegistriesMixin.java @@ -0,0 +1,40 @@ +package org.betterx.bclib.mixin.common; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; + +import com.mojang.serialization.Lifecycle; +import net.minecraft.core.MappedRegistry; +import net.minecraft.core.Registry; +import net.minecraft.core.WritableRegistry; +import net.minecraft.data.BuiltinRegistries; +import net.minecraft.resources.ResourceKey; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(BuiltinRegistries.class) +public abstract class BuiltinRegistriesMixin { + @Shadow + protected static > R internalRegister( + ResourceKey> resourceKey, + R writableRegistry, + BuiltinRegistries.RegistryBootstrap registryBootstrap, + Lifecycle lifecycle + ) { + throw new RuntimeException("Shadowed Call"); + } + + //this needs to be added BEFORE the WORLD_PRESET-Registry. Otherwise decoding will fail! + @Inject(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/data/BuiltinRegistries;registerSimple(Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/data/BuiltinRegistries$RegistryBootstrap;)Lnet/minecraft/core/Registry;", ordinal = 0)) + private static void bcl_registerBuiltin(CallbackInfo ci) { + BCLBiomeRegistry.BUILTIN_BCL_BIOMES = internalRegister( + BCLBiomeRegistry.BCL_BIOMES_REGISTRY, + (MappedRegistry) BCLBiomeRegistry.BUILTIN_BCL_BIOMES, + BCLBiomeRegistry::bootstrap, + Lifecycle.stable() + ); + } +} diff --git a/src/main/java/org/betterx/bclib/mixin/common/RegistryAccessMixin.java b/src/main/java/org/betterx/bclib/mixin/common/RegistryAccessMixin.java new file mode 100644 index 00000000..79b6478e --- /dev/null +++ b/src/main/java/org/betterx/bclib/mixin/common/RegistryAccessMixin.java @@ -0,0 +1,48 @@ +package org.betterx.bclib.mixin.common; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeData; + +import com.mojang.serialization.Codec; +import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; +import net.minecraft.resources.ResourceKey; + +import com.google.common.collect.ImmutableMap; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +import java.util.Map; +import java.util.function.Supplier; + +@Mixin(RegistryAccess.class) +public interface RegistryAccessMixin { + + @ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;make(Ljava/util/function/Supplier;)Ljava/lang/Object;")) + private static Supplier>, RegistryAccess.RegistryData>> together_addRegistry( + Supplier>, RegistryAccess.RegistryData>> supplier + ) { + return () -> { + ImmutableMap.Builder>, RegistryAccess.RegistryData> builder = ImmutableMap.builder(); + //Make sure this gets added before WORLD_PRESETS + put(builder, BCLBiomeRegistry.BCL_BIOMES_REGISTRY, BiomeData.CODEC); + + Map>, RegistryAccess.RegistryData> res = supplier.get(); + builder.putAll(res); + + return builder.build(); + }; + } + + @Shadow + static void put( + ImmutableMap.Builder>, RegistryAccess.RegistryData> builder, + ResourceKey> resourceKey, + Codec codec + ) { + throw new RuntimeException("Shadowed Call"); + } + +} diff --git a/src/main/java/org/betterx/bclib/util/Pair.java b/src/main/java/org/betterx/bclib/util/Pair.java index 44c9db97..5495c16b 100644 --- a/src/main/java/org/betterx/bclib/util/Pair.java +++ b/src/main/java/org/betterx/bclib/util/Pair.java @@ -1,8 +1,20 @@ package org.betterx.bclib.util; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + import java.util.Objects; public class Pair { + public static Codec> pairCodec(Codec a, Codec b, String first, String second) { + return RecordCodecBuilder.create(instance -> instance + .group( + a.fieldOf(first).forGetter(o -> o.first), + b.fieldOf(second).forGetter(o -> o.second) + ) + .apply(instance, Pair::new)); + } + public final A first; public final B second; diff --git a/src/main/java/org/betterx/bclib/util/WeightedList.java b/src/main/java/org/betterx/bclib/util/WeightedList.java index 70a90f4a..330d48d7 100644 --- a/src/main/java/org/betterx/bclib/util/WeightedList.java +++ b/src/main/java/org/betterx/bclib/util/WeightedList.java @@ -1,17 +1,71 @@ package org.betterx.bclib.util; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.util.RandomSource; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.function.Consumer; +import java.util.function.Function; public class WeightedList { + + private final List weights = new ArrayList(); private final List values = new ArrayList(); private float maxWeight; + public static Codec> pairCodec(Codec elementCodec, String fieldName) { + return Pair.pairCodec(Codec.FLOAT, elementCodec, "weight", fieldName); + } + + public static Codec> listCodec(Codec elementCodec, String fieldName, String elementName) { + return RecordCodecBuilder.create(instance -> instance + .group( + pairCodec(elementCodec, elementName).listOf() + .fieldOf(fieldName) + .forGetter(WeightedList::pairs) + ) + .apply(instance, WeightedList::new) + ); + } + + private List> pairs() { + List> pairs = new ArrayList<>(weights.size()); + for (int i = 0; i < weights.size(); i++) { + pairs.add(new Pair<>(weights.get(i), values.get(i))); + } + return pairs; + } + + private WeightedList(List> pairs) { + maxWeight = 0; + for (var pair : pairs) { + maxWeight += pair.first; + weights.add(pair.first); + values.add(pair.second); + } + } + + public WeightedList() { + } + + public WeightedList map(Function map) { + List> pairs = new ArrayList<>(weights.size()); + for (int i = 0; i < weights.size(); i++) { + pairs.add(new Pair<>(weights.get(i), map.apply(values.get(i)))); + } + return new WeightedList<>(pairs); + } + + public void addAll(WeightedList other) { + weights.addAll(other.weights); + values.addAll(other.values); + maxWeight += other.maxWeight; + } + /** * Adds value with specified weight to the list * diff --git a/src/main/java/org/betterx/worlds/together/biomesource/ReloadableBiomeSource.java b/src/main/java/org/betterx/worlds/together/biomesource/ReloadableBiomeSource.java new file mode 100644 index 00000000..377c3110 --- /dev/null +++ b/src/main/java/org/betterx/worlds/together/biomesource/ReloadableBiomeSource.java @@ -0,0 +1,5 @@ +package org.betterx.worlds.together.biomesource; + +public interface ReloadableBiomeSource { + void reloadBiomes(); +} diff --git a/src/main/java/org/betterx/worlds/together/chunkgenerator/RestorableBiomeSource.java b/src/main/java/org/betterx/worlds/together/chunkgenerator/RestorableBiomeSource.java index 90d3e45e..11ca787f 100644 --- a/src/main/java/org/betterx/worlds/together/chunkgenerator/RestorableBiomeSource.java +++ b/src/main/java/org/betterx/worlds/together/chunkgenerator/RestorableBiomeSource.java @@ -4,6 +4,6 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.dimension.LevelStem; -public interface RestorableBiomeSource { +public interface RestorableBiomeSource { void restoreInitialBiomeSource(ResourceKey dimensionKey); } diff --git a/src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java b/src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java index 4a82f11f..3fe9c066 100644 --- a/src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java +++ b/src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java @@ -2,6 +2,7 @@ package org.betterx.worlds.together.levelgen; import org.betterx.worlds.together.WorldsTogether; import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig; +import org.betterx.worlds.together.biomesource.ReloadableBiomeSource; import org.betterx.worlds.together.chunkgenerator.EnforceableChunkGenerator; import org.betterx.worlds.together.world.BiomeSourceWithNoiseRelatedSettings; import org.betterx.worlds.together.world.BiomeSourceWithSeed; @@ -141,6 +142,7 @@ public class WorldGenUtil { ) { var dimensions = TogetherWorldPreset.loadWorldDimensions(); for (var entry : settings.dimensions().entrySet()) { + boolean didRepair = false; ResourceKey key = entry.getKey(); LevelStem loadedStem = entry.getValue(); @@ -156,6 +158,7 @@ public class WorldGenUtil { loadedChunkGenerator, settings ); + didRepair = true; } else if (loadedChunkGenerator.getBiomeSource() instanceof BiomeSourceWithConfig bs) { if (referenceGenerator.getBiomeSource() instanceof BiomeSourceWithConfig refbs) { if (!refbs.getTogetherConfig().sameConfig(bs.getTogetherConfig())) { @@ -164,6 +167,12 @@ public class WorldGenUtil { } } } + + if (!didRepair) { + if (loadedStem.generator().getBiomeSource() instanceof ReloadableBiomeSource reload) { + reload.reloadBiomes(); + } + } } return settings; } diff --git a/src/main/java/org/betterx/worlds/together/mixin/common/WorldLoaderMixin.java b/src/main/java/org/betterx/worlds/together/mixin/common/WorldLoaderMixin.java new file mode 100644 index 00000000..d2ea695a --- /dev/null +++ b/src/main/java/org/betterx/worlds/together/mixin/common/WorldLoaderMixin.java @@ -0,0 +1,22 @@ +package org.betterx.worlds.together.mixin.common; + +import org.betterx.worlds.together.world.event.WorldBootstrap; + +import net.minecraft.core.RegistryAccess; +import net.minecraft.server.WorldLoader; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +@Mixin(WorldLoader.class) +public class WorldLoaderMixin { + //this is the place a new Registry access gets first istantiated + //either when a new Datapack was added to a world on the create-screen + //or because we did start world loading + @ModifyArg(method = "load", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/ReloadableServerResources;loadResources(Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/core/RegistryAccess$Frozen;Lnet/minecraft/commands/Commands$CommandSelection;ILjava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;")) + private static RegistryAccess.Frozen wt_newRegistry(RegistryAccess.Frozen frozen) { + WorldBootstrap.InGUI.registryReady(frozen); + return frozen; + } +} diff --git a/src/main/java/org/betterx/worlds/together/surfaceRules/SurfaceRuleRegistry.java b/src/main/java/org/betterx/worlds/together/surfaceRules/SurfaceRuleRegistry.java index 6f465c83..6aba4351 100644 --- a/src/main/java/org/betterx/worlds/together/surfaceRules/SurfaceRuleRegistry.java +++ b/src/main/java/org/betterx/worlds/together/surfaceRules/SurfaceRuleRegistry.java @@ -16,7 +16,7 @@ import org.jetbrains.annotations.ApiStatus; public class SurfaceRuleRegistry { public static final ResourceKey> SURFACE_RULES_REGISTRY = - createRegistryKey(WorldsTogether.makeID("worldgen/surface_rules")); + createRegistryKey(WorldsTogether.makeID("worldgen/betterx/surface_rules")); public static final Predicate> NON_MANAGED_DIMENSIONS = dim -> dim != LevelStem.NETHER && dim != LevelStem.END; public static final Predicate> ALL_DIMENSIONS = dim -> true; diff --git a/src/main/java/org/betterx/worlds/together/world/event/WorldBootstrap.java b/src/main/java/org/betterx/worlds/together/world/event/WorldBootstrap.java index fd64e9b9..a87d5db2 100644 --- a/src/main/java/org/betterx/worlds/together/world/event/WorldBootstrap.java +++ b/src/main/java/org/betterx/worlds/together/world/event/WorldBootstrap.java @@ -154,6 +154,10 @@ public class WorldBootstrap { } } + public static void registryReady(RegistryAccess access) { + Helpers.onRegistryReady(access); + } + public static void setupNewWorld( Optional levelStorageAccess, WorldGenSettingsComponent worldGenSettingsComponent diff --git a/src/main/resources/bclib.accesswidener b/src/main/resources/bclib.accesswidener index f79bad60..35c028ec 100644 --- a/src/main/resources/bclib.accesswidener +++ b/src/main/resources/bclib.accesswidener @@ -11,10 +11,12 @@ accessible class net/minecraft/world/level/levelgen/SurfaceRules$SequenceRuleSou accessible class net/minecraft/world/level/levelgen/presets/WorldPresets$Bootstrap extendable class net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator accessible class net/minecraft/data/BuiltinRegistries$RegistryBootstrap +accessible class net/minecraft/core/Registry$RegistryBootstrap accessible class net/minecraft/world/level/levelgen/SurfaceRules$SequenceRuleSource #Methods accessible method net/minecraft/client/gui/screens/worldselection/WorldGenSettingsComponent updateSettings (Lnet/minecraft/client/gui/screens/worldselection/WorldCreationContext$Updater;)V accessible method net/minecraft/world/level/storage/loot/LootPool ([Lnet/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer;[Lnet/minecraft/world/level/storage/loot/predicates/LootItemCondition;[Lnet/minecraft/world/level/storage/loot/functions/LootItemFunction;Lnet/minecraft/world/level/storage/loot/providers/number/NumberProvider;Lnet/minecraft/world/level/storage/loot/providers/number/NumberProvider;)V accessible method net/minecraft/world/entity/ai/village/poi/PoiTypes register (Lnet/minecraft/core/Registry;Lnet/minecraft/resources/ResourceKey;Ljava/util/Set;II)Lnet/minecraft/world/entity/ai/village/poi/PoiType; -accessible method net/minecraft/world/level/levelgen/SurfaceRules$SequenceRuleSource (Ljava/util/List;)V \ No newline at end of file +accessible method net/minecraft/world/level/levelgen/SurfaceRules$SequenceRuleSource (Ljava/util/List;)V +accessible method net/minecraft/core/Registry registerSimple (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/core/Registry$RegistryBootstrap;)Lnet/minecraft/core/Registry; \ No newline at end of file diff --git a/src/main/resources/bclib.mixins.common.json b/src/main/resources/bclib.mixins.common.json index 8b7bf1aa..538b02ed 100644 --- a/src/main/resources/bclib.mixins.common.json +++ b/src/main/resources/bclib.mixins.common.json @@ -10,6 +10,7 @@ "BiomeMixin", "BiomeSourceMixin", "BoneMealItemMixin", + "BuiltinRegistriesMixin", "ChunkGeneratorAccessor", "ChunkGeneratorMixin", "ChunkGeneratorsMixin", @@ -28,6 +29,7 @@ "PotionBrewingAccessor", "RecipeManagerAccessor", "RecipeManagerMixin", + "RegistryAccessMixin", "ServerLevelMixin", "ShovelItemAccessor", "StructuresAccessor", diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index ea76eab7..ef506323 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "id": "bclib", - "version": "2.0.10", + "version": "2.0.11", "name": "BCLib", "description": "A library for BetterX team mods", "authors": [ diff --git a/src/main/resources/together.mixins.common.json b/src/main/resources/together.mixins.common.json index 75e009db..45f965d9 100644 --- a/src/main/resources/together.mixins.common.json +++ b/src/main/resources/together.mixins.common.json @@ -17,6 +17,7 @@ "RegistryOpsAccessor", "TagLoaderMixin", "WorldGenPropertiesMixin", + "WorldLoaderMixin", "WorldPresetAccessor", "WorldPresetMixin", "WorldPresetsBootstrapMixin" From 020b8880e1b2da8db43cc2a288437638f7744f81 Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 7 Jul 2022 19:33:32 +0200 Subject: [PATCH 45/50] [Feature] Reconfigure default WorldPresets if Nullscape (Mod Version) is present --- src/main/java/org/betterx/bclib/BCLib.java | 4 ++++ .../api/v2/generator/config/BCLEndBiomeSourceConfig.java | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/betterx/bclib/BCLib.java b/src/main/java/org/betterx/bclib/BCLib.java index e839214c..fb4e3bed 100644 --- a/src/main/java/org/betterx/bclib/BCLib.java +++ b/src/main/java/org/betterx/bclib/BCLib.java @@ -39,6 +39,10 @@ public class BCLib implements ModInitializer { public static final String MOD_ID = "bclib"; public static final Logger LOGGER = new Logger(MOD_ID); + public static final boolean RUNS_NULLSCAPE = FabricLoader.getInstance() + .getModContainer("nullscape") + .isPresent(); + @Override public void onInitialize() { LevelGenEvents.register(); diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java b/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java index d43d1005..b52bb069 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java @@ -1,5 +1,6 @@ package org.betterx.bclib.api.v2.generator.config; +import org.betterx.bclib.BCLib; import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource; import org.betterx.bclib.api.v2.generator.BiomePicker; import org.betterx.bclib.api.v2.generator.map.hex.HexBiomeMap; @@ -39,8 +40,8 @@ public class BCLEndBiomeSourceConfig implements BiomeSourceConfig Date: Thu, 7 Jul 2022 19:33:55 +0200 Subject: [PATCH 46/50] Serialize Cave Features --- .../betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java index 70bdd5f9..f5694e8f 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java @@ -127,6 +127,16 @@ public class BCLBiome extends BCLBiomeSettings implements BiomeData { return instance.group(a.t0, a.t1, a.t2, a.t3, a.t4, a.t5, a.t6, a.t7, a.t8, a.t9, a.t10, p12, p13); } + public static Products.P14, Float, Float, Float, Integer, Boolean, Optional, ResourceLocation, Optional>, Optional, Optional>, Optional, P12, P13, P14> codecWithSettings( + RecordCodecBuilder.Instance instance, + final RecordCodecBuilder p12, + final RecordCodecBuilder p13, + final RecordCodecBuilder p14 + ) { + CodecAttributes a = new CodecAttributes<>(); + return instance.group(a.t0, a.t1, a.t2, a.t3, a.t4, a.t5, a.t6, a.t7, a.t8, a.t9, a.t10, p12, p13, p14); + } + public static Products.P11, Float, Float, Float, Integer, Boolean, Optional, ResourceLocation, Optional>, Optional, Optional>, Optional> codecWithSettings( RecordCodecBuilder.Instance instance ) { From 8861c0645f309590d0509749df3b84d8422359b4 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 8 Jul 2022 00:12:39 +0200 Subject: [PATCH 47/50] [Feature] More flexible/extensible End-Biome Placement --- .../api/v2/generator/BCLibEndBiomeSource.java | 144 +++++++--- .../v2/generator/BCLibNetherBiomeSource.java | 6 +- .../bclib/api/v2/generator/BiomeDecider.java | 264 ++++++++++++++++++ .../api/v2/generator/GeneratorOptions.java | 10 +- .../config/BCLEndBiomeSourceConfig.java | 7 +- .../config/BCLNetherBiomeSourceConfig.java | 7 +- .../generator/config/MapBuilderFunction.java | 9 + .../bclib/api/v2/generator/map/MapStack.java | 6 +- .../api/v2/levelgen/biomes/BCLBiome.java | 2 +- 9 files changed, 394 insertions(+), 61 deletions(-) create mode 100644 src/main/java/org/betterx/bclib/api/v2/generator/BiomeDecider.java create mode 100644 src/main/java/org/betterx/bclib/api/v2/generator/config/MapBuilderFunction.java diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java index bd4ef2e1..927c3709 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibEndBiomeSource.java @@ -67,6 +67,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi private BiomePicker endVoidBiomePicker; private BiomePicker endCenterBiomePicker; private BiomePicker endBarrensBiomePicker; + private List deciders; private BCLEndBiomeSourceConfig config; @@ -111,6 +112,11 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi var includeMap = Configs.BIOMES_CONFIG.getBiomeIncludeMap(); var excludeList = Configs.BIOMES_CONFIG.getExcludeMatching(BiomeAPI.BiomeType.END); + this.deciders = BiomeDecider.DECIDERS.stream() + .filter(d -> d.canProvideFor(this)) + .map(d -> d.createInstance(this)) + .toList(); + this.endLandBiomePicker = new BiomePicker(biomeRegistry); this.endVoidBiomePicker = new BiomePicker(biomeRegistry); this.endCenterBiomePicker = new BiomePicker(biomeRegistry); @@ -160,24 +166,36 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi } if (!didForceAdd) { - if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_IGNORE)) { + if (biomeID.equals(BCLBiomeRegistry.EMPTY_BIOME.getID()) + || bclBiome.getIntendedType().is(BiomeAPI.BiomeType.END_IGNORE)) { //we should not add this biome anywhere, so just ignore it - } else if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_CENTER) - || TheEndBiomesHelper.canGenerateAsMainIslandBiome(key)) { - endCenterBiomePicker.addBiome(bclBiome); - } else if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_LAND) - || TheEndBiomesHelper.canGenerateAsHighlandsBiome(key)) { - if (!config.withVoidBiomes) endVoidBiomePicker.addBiome(bclBiome); - endLandBiomePicker.addBiome(bclBiome); - } else if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_BARRENS) - || TheEndBiomesHelper.canGenerateAsEndBarrens(key)) { - endBarrensBiomePicker.addBiome(bclBiome); - } else if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_VOID) - || TheEndBiomesHelper.canGenerateAsSmallIslandsBiome(key)) { - endVoidBiomePicker.addBiome(bclBiome); } else { - BCLib.LOGGER.info("Found End Biome " + biomeStr + " that was not registers with fabric or bclib. Assuming end-land Biome..."); - endLandBiomePicker.addBiome(bclBiome); + didForceAdd = false; + for (BiomeDecider decider : deciders) { + if (decider.addToPicker(bclBiome)) { + didForceAdd = true; + break; + } + } + if (!didForceAdd) { + if (bclBiome.getIntendedType().is(BiomeAPI.BiomeType.END_CENTER) + || TheEndBiomesHelper.canGenerateAsMainIslandBiome(key)) { + endCenterBiomePicker.addBiome(bclBiome); + } else if (bclBiome.getIntendedType().is(BiomeAPI.BiomeType.END_LAND) + || TheEndBiomesHelper.canGenerateAsHighlandsBiome(key)) { + if (!config.withVoidBiomes) endVoidBiomePicker.addBiome(bclBiome); + endLandBiomePicker.addBiome(bclBiome); + } else if (bclBiome.getIntendedType().is(BiomeAPI.BiomeType.END_BARRENS) + || TheEndBiomesHelper.canGenerateAsEndBarrens(key)) { + endBarrensBiomePicker.addBiome(bclBiome); + } else if (bclBiome.getIntendedType().is(BiomeAPI.BiomeType.END_VOID) + || TheEndBiomesHelper.canGenerateAsSmallIslandsBiome(key)) { + endVoidBiomePicker.addBiome(bclBiome); + } else { + BCLib.LOGGER.info("Found End Biome " + biomeStr + " that was not registers with fabric or bclib. Assuming end-land Biome..."); + endLandBiomePicker.addBiome(bclBiome); + } + } } } } @@ -189,6 +207,10 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi endBarrensBiomePicker.rebuild(); endCenterBiomePicker.rebuild(); + for (BiomeDecider decider : deciders) { + decider.rebuild(); + } + if (endVoidBiomePicker.isEmpty()) { BCLib.LOGGER.info("No Void Biomes found. Disabling by using barrens"); endVoidBiomePicker = endBarrensBiomePicker; @@ -266,25 +288,32 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi @Override protected void onInitMap(long seed) { - this.mapLand = config.mapVersion.mapBuilder.apply( + for (BiomeDecider decider : deciders) { + decider.createMap((picker, size) -> config.mapVersion.mapBuilder.create( + seed, + size <= 0 ? config.landBiomesSize : size, + picker + )); + } + this.mapLand = config.mapVersion.mapBuilder.create( seed, config.landBiomesSize, endLandBiomePicker ); - this.mapVoid = config.mapVersion.mapBuilder.apply( + this.mapVoid = config.mapVersion.mapBuilder.create( seed, config.voidBiomesSize, endVoidBiomePicker ); - this.mapCenter = config.mapVersion.mapBuilder.apply( + this.mapCenter = config.mapVersion.mapBuilder.create( seed, config.centerBiomesSize, endCenterBiomePicker ); - this.mapBarrens = config.mapVersion.mapBuilder.apply( + this.mapBarrens = config.mapVersion.mapBuilder.create( seed, config.barrensBiomesSize, endBarrensBiomePicker @@ -315,39 +344,74 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi mapVoid.clearCache(); mapCenter.clearCache(); mapVoid.clearCache(); + for (BiomeDecider decider : deciders) { + decider.clearMapCache(); + } } - if (config.generatorVersion == BCLEndBiomeSourceConfig.EndBiomeGeneratorType.VANILLA || endLandFunction == null) { - if (dist <= (long) config.innerVoidRadiusSquared) { - return mapCenter.getBiome(posX, biomeY << 2, posZ).biome; - } + BiomeAPI.BiomeType suggestedType; + + if (config.generatorVersion == BCLEndBiomeSourceConfig.EndBiomeGeneratorType.VANILLA) { int x = (SectionPos.blockToSectionCoord(posX) * 2 + 1) * 8; int z = (SectionPos.blockToSectionCoord(posZ) * 2 + 1) * 8; double d = sampler.erosion().compute(new DensityFunction.SinglePointContext(x, posY, z)); - if (d > 0.25) { - return mapLand.getBiome(posX, biomeY << 2, posZ).biome; //highlands - } else if (d >= -0.0625) { - return mapLand.getBiome(posX, biomeY << 2, posZ).biome; //midlands + if (dist <= (long) config.innerVoidRadiusSquared) { + suggestedType = BiomeAPI.BiomeType.END_CENTER; } else { - return d < -0.21875 - ? mapVoid.getBiome(posX, biomeY << 2, posZ).biome //small islands - : (config.withVoidBiomes ? mapBarrens : mapLand).getBiome( + if (d > 0.25) { + suggestedType = BiomeAPI.BiomeType.END_LAND; //highlands + } else if (d >= -0.0625) { + suggestedType = BiomeAPI.BiomeType.END_LAND; //midlands + } else { + suggestedType = d < -0.21875 + ? BiomeAPI.BiomeType.END_VOID //small islands + : (config.withVoidBiomes + ? BiomeAPI.BiomeType.END_BARRENS + : BiomeAPI.BiomeType.END_LAND); //barrens + } + } + + final BiomeAPI.BiomeType originalType = suggestedType; + for (BiomeDecider decider : deciders) { + suggestedType = decider + .suggestType( + originalType, + suggestedType, + d, + maxHeight, posX, - biomeY << 2, - posZ - ).biome; //barrens + posY, + posZ, + biomeX, + biomeY, + biomeZ + ); } } else { pos.setLocation(biomeX, biomeZ); - if (endLandFunction.apply(pos, maxHeight)) { - return (dist <= (long) config.innerVoidRadiusSquared ? mapCenter : mapLand) - .getBiome(posX, biomeY << 2, posZ).biome; - } else { - return (dist <= (long) config.innerVoidRadiusSquared ? mapBarrens : mapVoid) - .getBiome(posX, biomeY << 2, posZ).biome; + final BiomeAPI.BiomeType originalType = (dist <= (long) config.innerVoidRadiusSquared + ? BiomeAPI.BiomeType.END_CENTER + : BiomeAPI.BiomeType.END_LAND); + suggestedType = originalType; + + for (BiomeDecider decider : deciders) { + suggestedType = decider + .suggestType(originalType, suggestedType, maxHeight, posX, posY, posZ, biomeX, biomeY, biomeZ); } } + BiomePicker.ActualBiome result; + for (BiomeDecider decider : deciders) { + if (decider.canProvideBiome(suggestedType)) { + result = decider.provideBiome(suggestedType, posX, posY, posZ); + if (result != null) return result.biome; + } + } + + if (suggestedType.is(BiomeAPI.BiomeType.END_CENTER)) return mapCenter.getBiome(posX, posY, posZ).biome; + if (suggestedType.is(BiomeAPI.BiomeType.END_VOID)) return mapVoid.getBiome(posX, posY, posZ).biome; + if (suggestedType.is(BiomeAPI.BiomeType.END_BARRENS)) return mapBarrens.getBiome(posX, posY, posZ).biome; + return mapLand.getBiome(posX, posY, posZ).biome; } diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibNetherBiomeSource.java b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibNetherBiomeSource.java index dc614b86..60e87d0a 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BCLibNetherBiomeSource.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BCLibNetherBiomeSource.java @@ -2,13 +2,13 @@ package org.betterx.bclib.api.v2.generator; import org.betterx.bclib.BCLib; import org.betterx.bclib.api.v2.generator.config.BCLNetherBiomeSourceConfig; +import org.betterx.bclib.api.v2.generator.config.MapBuilderFunction; import org.betterx.bclib.api.v2.generator.map.MapStack; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.config.Configs; import org.betterx.bclib.interfaces.BiomeMap; -import org.betterx.bclib.util.TriFunction; import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig; import org.betterx.worlds.together.biomesource.ReloadableBiomeSource; @@ -181,7 +181,7 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc @Override protected void onInitMap(long seed) { - TriFunction mapConstructor = config.mapVersion.mapBuilder; + MapBuilderFunction mapConstructor = config.mapVersion.mapBuilder; if (maxHeight > config.biomeSizeVertical * 1.5 && config.useVerticalBiomes) { this.biomeMap = new MapStack( seed, @@ -192,7 +192,7 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc mapConstructor ); } else { - this.biomeMap = mapConstructor.apply( + this.biomeMap = mapConstructor.create( seed, config.biomeSize, biomePicker diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BiomeDecider.java b/src/main/java/org/betterx/bclib/api/v2/generator/BiomeDecider.java new file mode 100644 index 00000000..4b4c3394 --- /dev/null +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BiomeDecider.java @@ -0,0 +1,264 @@ +package org.betterx.bclib.api.v2.generator; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.bclib.interfaces.BiomeMap; + +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeSource; + +import java.util.LinkedList; +import java.util.List; + + +/** + * Used to extend the BiomePlacement in the {@link BCLBiomeSource} + */ +public abstract class BiomeDecider { + + /** + * used to create new {@link BiomeMap} instances + */ + @FunctionalInterface + public interface BiomeMapBuilderFunction { + /** + * Constructs a new {@link BiomeMap} + * + * @param picker The picker the BiomeMap should use + * @param biomeSize The biomeSize the map will use or -1 for the default size + * @return a new {@link BiomeMap} instance + */ + BiomeMap create(BiomePicker picker, int biomeSize); + } + + /** + * used to determine wether or not a decider can provide this biome + */ + @FunctionalInterface + public interface BiomePredicate { + boolean test(BCLBiome biome); + } + + protected BiomePicker picker; + protected BiomeMap map; + private final BiomePredicate predicate; + + static List DECIDERS = new LinkedList<>(); + + /** + * Register a high priority Decider for the {@link BCLibEndBiomeSource}. + * Normally you should not need to register a high priority decider and instead use + * {@link BiomeDecider#registerDecider(ResourceLocation, BiomeDecider)}. + * BetterEnd (for example) will add + * + * @param location The {@link ResourceLocation} for the decider + * @param decider The initial decider Instance. Each Instance of the {@link BCLibEndBiomeSource} + * will call {@link BiomeDecider#createInstance(BCLBiomeSource)} to build a + * new instance of this decider + */ + public static void registerHighPriorityDecider(ResourceLocation location, BiomeDecider decider) { + if (DECIDERS.size() == 0) DECIDERS.add(decider); + else DECIDERS.add(0, decider); + } + + /** + * Register a new Decider for the {@link BCLibEndBiomeSource} + * + * @param location The {@link ResourceLocation} for the decider + * @param decider The initial decider Instance. Each Instance of the {@link BCLibEndBiomeSource} + * will call {@link BiomeDecider#createInstance(BCLBiomeSource)} to build a + * new instance of this decider + */ + public static void registerDecider(ResourceLocation location, BiomeDecider decider) { + DECIDERS.add(decider); + } + + protected BiomeDecider(BiomePredicate predicate) { + this(null, predicate); + } + + /** + * @param biomeRegistry The biome registry assigned to the creating BiomeSource + * @param predicate A predicate that decides if a given Biome can be provided by this decider + */ + protected BiomeDecider( + Registry biomeRegistry, BiomePredicate predicate + ) { + this.predicate = predicate; + this.map = null; + if (biomeRegistry == null) { + this.picker = null; + } else { + this.picker = new BiomePicker(biomeRegistry); + } + } + + /** + * Called to test, if a decider is suitable for the given BiomeSource. + * + * @param source The BiomeSource that wants to use the decider + * @return true, if this decider is usable by that source + */ + public abstract boolean canProvideFor(BiomeSource source); + + /** + * Called from the BiomeSource whenever it needs to create a new instance of this decider. + *

+ * Inheriting classes should overwrite this method and return Instances of the class. For + * the base {@link BiomeDecider} you would return new BiomeDecider(biomeSource.biomeRegistry, this.predicate); + * + * @param biomeSource The biome source this decider is used from + * @return A new instance + */ + public abstract BiomeDecider createInstance(BCLBiomeSource biomeSource); + + /** + * Called when the BiomeSources needs to construct a new {@link BiomeMap} for the picker. + *

+ * The default implementation creates a new map with the instances picker and a default biome size + * + * @param mapBuilder A function you can use to create a new {@link BiomeMap} that conforms to the settings + * of the current BiomeSource. + */ + public void createMap(BiomeMapBuilderFunction mapBuilder) { + this.map = mapBuilder.create(picker, -1); + } + + /** + * called whenever the BiomeSource needs to clear caches + */ + public void clearMapCache() { + map.clearCache(); + } + + /** + * This method get's called whenever the BiomeSource populates the Biome Pickers. You need to + * determine if the passed Biome is valid for your picker. + *

+ * If this method returns false, the Biome wil not get added to any other Deciders/Pickers. + *

+ * The default implementation will use the instances {@link BiomeDecider#predicate} to determine if + * a biome should get added and return true if it was added. + * + * @param biome The biome that should get added if it matches the criteria of the picker + * @return false, if other pickers/deciders are allowed to use the biome as well + */ + public boolean addToPicker(BCLBiome biome) { + if (predicate.test(biome)) { + picker.addBiome(biome); + return true; + } + + return false; + } + + /** + * Called whenever the picker needs to rebuild it's contents + */ + public void rebuild() { + picker.rebuild(); + } + + /** + * Called from the BiomeSource to determine the type of Biome it needs to place. + * + * @param originalType The original biome type the source did select + * @param suggestedType The currently suggested type. This will differ from originalType if other + * {@link BiomeDecider} instances already had a new suggestion. You implementation should return the + * suggestedType if it does not want to provide the Biome for this location + * @param maxHeight The maximum terrain height for this world + * @param blockX The block coordinate where we are at + * @param blockY The block coordinate where we are at + * @param blockZ The block coordinate where we are at + * @param quarterX The quarter Block Coordinate (which is blockX/4) + * @param quarterY The quarter Block Coordinate (which is blockY/4) + * @param quarterZ The quarter Block Coordinate (which is blockZ/4) + * @return The suggestedType if this decider does not plan to provide a Biome, or a unique BiomeType. + * The Biome Source will call {@link BiomeDecider#selectBiome(BiomeAPI.BiomeType)} with the finally chosen type + * for all available Deciders. + */ + public BiomeAPI.BiomeType suggestType( + BiomeAPI.BiomeType originalType, + BiomeAPI.BiomeType suggestedType, + int maxHeight, + int blockX, + int blockY, + int blockZ, + int quarterX, + int quarterY, + int quarterZ + ) { + return suggestType( + originalType, + suggestedType, + 0, + maxHeight, + blockX, + blockY, + blockZ, + quarterX, + quarterY, + quarterZ + ); + } + + /** + * Called from the BiomeSource to determine the type of Biome it needs to place. + * + * @param originalType The original biome type the source did select + * @param suggestedType The currently suggested type. This will differ from originalType if other + * {@link BiomeDecider} instances already had a new suggestion. You implementation should return the + * suggestedType if it does not want to provide the Biome for this location + * @param density The terrain density at this location. Currently only valid if for {@link BCLibEndBiomeSource} + * that use the {@link org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig.EndBiomeGeneratorType#VANILLA} + * @param maxHeight The maximum terrain height for this world + * @param blockX The block coordinate where we are at + * @param blockY The block coordinate where we are at + * @param blockZ The block coordinate where we are at + * @param quarterX The quarter Block Coordinate (which is blockX/4) + * @param quarterY The quarter Block Coordinate (which is blockY/4) + * @param quarterZ The quarter Block Coordinate (which is blockZ/4) + * @param maxHeight + * @return The suggestedType if this decider does not plan to provide a Biome, or a unique BiomeType. + * The Biome Source will call {@link BiomeDecider#selectBiome(BiomeAPI.BiomeType)} with the finally chosen type + * for all available Deciders. + */ + public abstract BiomeAPI.BiomeType suggestType( + BiomeAPI.BiomeType originalType, + BiomeAPI.BiomeType suggestedType, + double density, + int maxHeight, + int blockX, + int blockY, + int blockZ, + int quarterX, + int quarterY, + int quarterZ + ); + + + /** + * Called to check if this decider can place a biome for the specified type + * + * @param suggestedType The type of biome we need to place + * @return true, if this type of biome can be provided by the current picker. If true + * is returned, the BiomeSource will call {@link BiomeDecider#provideBiome(BiomeAPI.BiomeType, int, int, int)} + * next + */ + public abstract boolean canProvideBiome(BiomeAPI.BiomeType suggestedType); + + /** + * Called to check if this decider can place a biome for the specified type + *

+ * The default implementation will return map.getBiome(posX, posY, posZ) + * + * @param suggestedType The type of biome we need to place + * @return The methode should return a Biome from its {@link BiomeMap}. If null is returned, the next + * decider (or the default map) will provide the biome + */ + public BiomePicker.ActualBiome provideBiome(BiomeAPI.BiomeType suggestedType, int posX, int posY, int posZ) { + return map.getBiome(posX, posY, posZ); + } +} diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/GeneratorOptions.java b/src/main/java/org/betterx/bclib/api/v2/generator/GeneratorOptions.java index a15eef3e..79679d8b 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/GeneratorOptions.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/GeneratorOptions.java @@ -7,7 +7,7 @@ import java.util.function.BiFunction; import java.util.function.Function; public class GeneratorOptions { - private static BiFunction endLandFunction; + //private static BiFunction endLandFunction; private static boolean fixEndBiomeSource = true; private static boolean fixNetherBiomeSource = true; @@ -42,15 +42,17 @@ public class GeneratorOptions { */ @Deprecated(forRemoval = true) public static void setEndLandFunction(Function endLandFunction) { - GeneratorOptions.endLandFunction = (p, h) -> endLandFunction.apply(p); + //GeneratorOptions.endLandFunction = (p, h) -> endLandFunction.apply(p); } + @Deprecated(forRemoval = true) public static void setEndLandFunction(BiFunction endLandFunction) { - GeneratorOptions.endLandFunction = endLandFunction; + ///GeneratorOptions.endLandFunction = endLandFunction; } + @Deprecated(forRemoval = true) public static BiFunction getEndLandFunction() { - return endLandFunction; + return (a, b) -> true;//endLandFunction; } @Deprecated(forRemoval = true) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java b/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java index b52bb069..558773e6 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLEndBiomeSourceConfig.java @@ -2,11 +2,8 @@ package org.betterx.bclib.api.v2.generator.config; import org.betterx.bclib.BCLib; import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource; -import org.betterx.bclib.api.v2.generator.BiomePicker; import org.betterx.bclib.api.v2.generator.map.hex.HexBiomeMap; import org.betterx.bclib.api.v2.generator.map.square.SquareBiomeMap; -import org.betterx.bclib.interfaces.BiomeMap; -import org.betterx.bclib.util.TriFunction; import org.betterx.worlds.together.biomesource.config.BiomeSourceConfig; import com.mojang.serialization.Codec; @@ -114,9 +111,9 @@ public class BCLEndBiomeSourceConfig implements BiomeSourceConfig CODEC = StringRepresentable.fromEnum(EndBiomeMapType::values); public final String name; - public final @NotNull TriFunction mapBuilder; + public final @NotNull MapBuilderFunction mapBuilder; - EndBiomeMapType(String name, @NotNull TriFunction mapBuilder) { + EndBiomeMapType(String name, @NotNull MapBuilderFunction mapBuilder) { this.name = name; this.mapBuilder = mapBuilder; } diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLNetherBiomeSourceConfig.java b/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLNetherBiomeSourceConfig.java index d50e7313..4d8c5249 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLNetherBiomeSourceConfig.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/config/BCLNetherBiomeSourceConfig.java @@ -1,11 +1,8 @@ package org.betterx.bclib.api.v2.generator.config; import org.betterx.bclib.api.v2.generator.BCLibNetherBiomeSource; -import org.betterx.bclib.api.v2.generator.BiomePicker; import org.betterx.bclib.api.v2.generator.map.hex.HexBiomeMap; import org.betterx.bclib.api.v2.generator.map.square.SquareBiomeMap; -import org.betterx.bclib.interfaces.BiomeMap; -import org.betterx.bclib.util.TriFunction; import org.betterx.worlds.together.biomesource.config.BiomeSourceConfig; import com.mojang.serialization.Codec; @@ -110,9 +107,9 @@ public class BCLNetherBiomeSourceConfig implements BiomeSourceConfig CODEC = StringRepresentable.fromEnum(NetherBiomeMapType::values); public final String name; - public final TriFunction mapBuilder; + public final MapBuilderFunction mapBuilder; - NetherBiomeMapType(String name, TriFunction mapBuilder) { + NetherBiomeMapType(String name, MapBuilderFunction mapBuilder) { this.name = name; this.mapBuilder = mapBuilder; } diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/config/MapBuilderFunction.java b/src/main/java/org/betterx/bclib/api/v2/generator/config/MapBuilderFunction.java new file mode 100644 index 00000000..cfb9e206 --- /dev/null +++ b/src/main/java/org/betterx/bclib/api/v2/generator/config/MapBuilderFunction.java @@ -0,0 +1,9 @@ +package org.betterx.bclib.api.v2.generator.config; + +import org.betterx.bclib.api.v2.generator.BiomePicker; +import org.betterx.bclib.interfaces.BiomeMap; + +@FunctionalInterface +public interface MapBuilderFunction { + BiomeMap create(long seed, int biomeSize, BiomePicker picker); +} diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/map/MapStack.java b/src/main/java/org/betterx/bclib/api/v2/generator/map/MapStack.java index 0340d06c..74dbb00f 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/map/MapStack.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/map/MapStack.java @@ -1,11 +1,11 @@ package org.betterx.bclib.api.v2.generator.map; import org.betterx.bclib.api.v2.generator.BiomePicker; +import org.betterx.bclib.api.v2.generator.config.MapBuilderFunction; import org.betterx.bclib.interfaces.BiomeChunk; import org.betterx.bclib.interfaces.BiomeMap; import org.betterx.bclib.interfaces.TriConsumer; import org.betterx.bclib.noise.OpenSimplexNoise; -import org.betterx.bclib.util.TriFunction; import net.minecraft.util.Mth; @@ -26,7 +26,7 @@ public class MapStack implements BiomeMap { BiomePicker picker, int mapHeight, int worldHeight, - TriFunction mapConstructor + MapBuilderFunction mapConstructor ) { final int mapCount = Mth.ceil((float) worldHeight / mapHeight); this.maxIndex = mapCount - 1; @@ -37,7 +37,7 @@ public class MapStack implements BiomeMap { maps = new BiomeMap[mapCount]; Random random = new Random(seed); for (int i = 0; i < mapCount; i++) { - maps[i] = mapConstructor.apply(random.nextLong(), size, picker); + maps[i] = mapConstructor.create(random.nextLong(), size, picker); maps[i].setChunkProcessor(this::onChunkCreation); } noise = new OpenSimplexNoise(random.nextInt()); diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java index f5694e8f..fe7a699f 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BCLBiome.java @@ -290,7 +290,7 @@ public class BCLBiome extends BCLBiomeSettings implements BiomeData { return this; } - BiomeAPI.BiomeType getIntendedType() { + public BiomeAPI.BiomeType getIntendedType() { return this.intendedType; } From c4077a42fd75ff8027d8ec6bc2cc213c3971747b Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 8 Jul 2022 00:13:07 +0200 Subject: [PATCH 48/50] [Fix] WeightedList does not always return a value --- src/main/java/org/betterx/bclib/util/WeightedList.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/betterx/bclib/util/WeightedList.java b/src/main/java/org/betterx/bclib/util/WeightedList.java index 330d48d7..a78d5428 100644 --- a/src/main/java/org/betterx/bclib/util/WeightedList.java +++ b/src/main/java/org/betterx/bclib/util/WeightedList.java @@ -93,6 +93,7 @@ public class WeightedList { if (weight <= weights.get(i)) { return values.get(i); } + weight -= weights.get(i); } return null; } From beb2d97304fbe4c25d20d90d9dc2a5f0fabb006d Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 8 Jul 2022 00:38:35 +0200 Subject: [PATCH 49/50] Simplified BiomeDecider --- .../api/v2/generator/TypeBiomeDecider.java | 24 +++++++++++++++++++ .../api/v2/levelgen/biomes/BiomeAPI.java | 13 ++++++++++ 2 files changed, 37 insertions(+) create mode 100644 src/main/java/org/betterx/bclib/api/v2/generator/TypeBiomeDecider.java diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/TypeBiomeDecider.java b/src/main/java/org/betterx/bclib/api/v2/generator/TypeBiomeDecider.java new file mode 100644 index 00000000..559de7d2 --- /dev/null +++ b/src/main/java/org/betterx/bclib/api/v2/generator/TypeBiomeDecider.java @@ -0,0 +1,24 @@ +package org.betterx.bclib.api.v2.generator; + +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; + +import net.minecraft.core.Registry; +import net.minecraft.world.level.biome.Biome; + +public abstract class TypeBiomeDecider extends BiomeDecider { + protected final BiomeAPI.BiomeType assignedType; + + public TypeBiomeDecider(BiomeAPI.BiomeType assignedType) { + this(null, assignedType); + } + + protected TypeBiomeDecider(Registry biomeRegistry, BiomeAPI.BiomeType assignedType) { + super(biomeRegistry, (biome) -> biome.getIntendedType().is(assignedType)); + this.assignedType = assignedType; + } + + @Override + public boolean canProvideBiome(BiomeAPI.BiomeType suggestedType) { + return suggestedType.equals(assignedType); + } +} diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java index 7353db38..7dff6925 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java @@ -194,6 +194,19 @@ public class BiomeAPI { if (parentOrNull != null) str += " -> " + parentOrNull; return str; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BiomeType biomeType = (BiomeType) o; + return name.equals(biomeType.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } } /** From 92ff27f2f8daaffeffa7a7a1c61639cc8dc8f005 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 8 Jul 2022 01:25:28 +0200 Subject: [PATCH 50/50] Fixed broken javaDoc links --- .../java/org/betterx/bclib/api/v2/generator/BiomeDecider.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v2/generator/BiomeDecider.java b/src/main/java/org/betterx/bclib/api/v2/generator/BiomeDecider.java index 4b4c3394..37255815 100644 --- a/src/main/java/org/betterx/bclib/api/v2/generator/BiomeDecider.java +++ b/src/main/java/org/betterx/bclib/api/v2/generator/BiomeDecider.java @@ -176,7 +176,7 @@ public abstract class BiomeDecider { * @param quarterY The quarter Block Coordinate (which is blockY/4) * @param quarterZ The quarter Block Coordinate (which is blockZ/4) * @return The suggestedType if this decider does not plan to provide a Biome, or a unique BiomeType. - * The Biome Source will call {@link BiomeDecider#selectBiome(BiomeAPI.BiomeType)} with the finally chosen type + * The Biome Source will call {@link BiomeDecider#canProvideBiome(BiomeAPI.BiomeType)} with the finally chosen type * for all available Deciders. */ public BiomeAPI.BiomeType suggestType( @@ -222,7 +222,7 @@ public abstract class BiomeDecider { * @param quarterZ The quarter Block Coordinate (which is blockZ/4) * @param maxHeight * @return The suggestedType if this decider does not plan to provide a Biome, or a unique BiomeType. - * The Biome Source will call {@link BiomeDecider#selectBiome(BiomeAPI.BiomeType)} with the finally chosen type + * The Biome Source will call {@link BiomeDecider#canProvideBiome(BiomeAPI.BiomeType)} with the finally chosen type * for all available Deciders. */ public abstract BiomeAPI.BiomeType suggestType(