From 6cb75406cb3d5a7189fe2ac5be0fdb09249a048f Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sat, 11 Dec 2021 19:33:53 +0300 Subject: [PATCH] Vertical biomes distribution prototype --- gradle.properties | 2 +- src/main/java/ru/bclib/BCLibPatch.java | 1 - .../java/ru/bclib/api/biomes/BiomeAPI.java | 28 +++++------ .../java/ru/bclib/interfaces/BiomeChunk.java | 9 ++++ .../java/ru/bclib/interfaces/BiomeMap.java | 5 +- .../java/ru/bclib/util/StructureHelper.java | 19 ++++---- .../java/ru/bclib/world/biomes/BCLBiome.java | 27 +++++++++++ .../ru/bclib/world/features/ListFeature.java | 6 +-- .../world/features/NBTStructureFeature.java | 8 ++-- .../bclib/world/generator/BCLBiomeSource.java | 4 +- .../world/generator/BCLibEndBiomeSource.java | 8 ++-- .../generator/BCLibNetherBiomeSource.java | 4 +- .../bclib/world/generator/map/MapStack.java | 46 ++++++++++++++++++ .../generator/map/hex/HexBiomeChunk.java | 14 +++++- .../world/generator/map/hex/HexBiomeMap.java | 48 +++++++++++++------ .../map/square/SquareBiomeChunk.java | 14 +++++- .../generator/map/square/SquareBiomeMap.java | 35 ++++++++++++-- 17 files changed, 213 insertions(+), 65 deletions(-) create mode 100644 src/main/java/ru/bclib/interfaces/BiomeChunk.java diff --git a/gradle.properties b/gradle.properties index d7d52b78..b07b76c7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ loader_version= 0.12.9 fabric_version = 0.44.0+1.18 # Mod Properties -mod_version = 1.0.3 +mod_version = 1.1.0 maven_group = ru.bclib archives_base_name = bclib diff --git a/src/main/java/ru/bclib/BCLibPatch.java b/src/main/java/ru/bclib/BCLibPatch.java index 0c1bd70a..ffdd9710 100644 --- a/src/main/java/ru/bclib/BCLibPatch.java +++ b/src/main/java/ru/bclib/BCLibPatch.java @@ -1,7 +1,6 @@ package ru.bclib; import net.minecraft.nbt.CompoundTag; -import org.jetbrains.annotations.NotNull; import ru.bclib.api.datafixer.DataFixerAPI; import ru.bclib.api.datafixer.ForcedLevelPatch; import ru.bclib.api.datafixer.MigrationProfile; diff --git a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java index ac7d563a..6d357af7 100644 --- a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java @@ -1,19 +1,5 @@ package ru.bclib.api.biomes; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Random; -import java.util.Set; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -import org.jetbrains.annotations.Nullable; - import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMultimap; @@ -21,7 +7,6 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; - import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.impl.biome.NetherBiomeData; @@ -59,6 +44,7 @@ import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; import net.minecraft.world.level.levelgen.feature.StructureFeature; import net.minecraft.world.level.levelgen.placement.PlacedFeature; import org.apache.commons.lang3.mutable.MutableInt; +import org.jetbrains.annotations.Nullable; import ru.bclib.BCLib; import ru.bclib.config.Configs; import ru.bclib.entity.BCLEntityWrapper; @@ -76,6 +62,18 @@ import ru.bclib.world.features.BCLFeature; import ru.bclib.world.generator.BiomePicker; import ru.bclib.world.structures.BCLStructureFeature; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Random; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.stream.Collectors; + 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. diff --git a/src/main/java/ru/bclib/interfaces/BiomeChunk.java b/src/main/java/ru/bclib/interfaces/BiomeChunk.java new file mode 100644 index 00000000..688245c7 --- /dev/null +++ b/src/main/java/ru/bclib/interfaces/BiomeChunk.java @@ -0,0 +1,9 @@ +package ru.bclib.interfaces; + +import ru.bclib.world.biomes.BCLBiome; + +public interface BiomeChunk { + void setBiome(int x, int z, BCLBiome biome); + BCLBiome getBiome(int x, int z); + int getSide(); +} diff --git a/src/main/java/ru/bclib/interfaces/BiomeMap.java b/src/main/java/ru/bclib/interfaces/BiomeMap.java index a30a3f64..eda351d1 100644 --- a/src/main/java/ru/bclib/interfaces/BiomeMap.java +++ b/src/main/java/ru/bclib/interfaces/BiomeMap.java @@ -3,7 +3,8 @@ package ru.bclib.interfaces; import ru.bclib.world.biomes.BCLBiome; public interface BiomeMap { - void clearCache(); - + void setChunkProcessor(TriConsumer processor); + BiomeChunk getChunk(int cx, int cz, boolean update); BCLBiome getBiome(double x, double y, double z); + void clearCache(); } diff --git a/src/main/java/ru/bclib/util/StructureHelper.java b/src/main/java/ru/bclib/util/StructureHelper.java index f4c89261..322b84d6 100644 --- a/src/main/java/ru/bclib/util/StructureHelper.java +++ b/src/main/java/ru/bclib/util/StructureHelper.java @@ -1,16 +1,6 @@ package ru.bclib.util; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.Enumeration; -import java.util.Random; -import java.util.Set; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - import com.google.common.collect.Sets; - import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos.MutableBlockPos; import net.minecraft.core.Direction; @@ -32,6 +22,15 @@ import net.minecraft.world.phys.Vec3; import ru.bclib.api.TagAPI; import ru.bclib.api.biomes.BiomeAPI; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.Random; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + public class StructureHelper { private static final Direction[] DIR = BlocksHelper.makeHorizontal(); diff --git a/src/main/java/ru/bclib/world/biomes/BCLBiome.java b/src/main/java/ru/bclib/world/biomes/BCLBiome.java index 8b62ee66..9336ac39 100644 --- a/src/main/java/ru/bclib/world/biomes/BCLBiome.java +++ b/src/main/java/ru/bclib/world/biomes/BCLBiome.java @@ -36,6 +36,7 @@ public class BCLBiome { private float fogDensity = 1.0F; private float genChance = 1.0F; private float edgeSize = 0.0F; + private boolean vertical; /** * Create wrapper for existing biome using its {@link ResourceLocation} identifier. @@ -291,6 +292,32 @@ public class BCLBiome { return terrainHeight; } + /** + * Set biome vertical distribution (for tall Nether only). + * @return same {@link BCLBiome}. + */ + public BCLBiome setVertical() { + return setVertical(true); + } + + /** + * Set biome vertical distribution (for tall Nether only). + * @param vertical {@code boolean} value. + * @return same {@link BCLBiome}. + */ + public BCLBiome setVertical(boolean vertical) { + this.vertical = vertical; + return this; + } + + /** + * Checks if biome is vertical, for tall Nether only (or for custom generators). + * @return is biome vertical or not. + */ + public boolean isVertical() { + return vertical; + } + @Override public boolean equals(Object obj) { if (obj == this) { diff --git a/src/main/java/ru/bclib/world/features/ListFeature.java b/src/main/java/ru/bclib/world/features/ListFeature.java index 6357c86b..bfe545ae 100644 --- a/src/main/java/ru/bclib/world/features/ListFeature.java +++ b/src/main/java/ru/bclib/world/features/ListFeature.java @@ -1,8 +1,5 @@ package ru.bclib.world.features; -import java.util.List; -import java.util.Random; - import net.minecraft.core.BlockPos; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.block.Mirror; @@ -12,6 +9,9 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlac import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; import ru.bclib.util.StructureHelper; +import java.util.List; +import java.util.Random; + public class ListFeature extends NBTStructureFeature { private final List list; private StructureInfo selected; diff --git a/src/main/java/ru/bclib/world/features/NBTStructureFeature.java b/src/main/java/ru/bclib/world/features/NBTStructureFeature.java index 190eb86a..69227f66 100644 --- a/src/main/java/ru/bclib/world/features/NBTStructureFeature.java +++ b/src/main/java/ru/bclib/world/features/NBTStructureFeature.java @@ -1,9 +1,5 @@ package ru.bclib.world.features; -import java.io.IOException; -import java.io.InputStream; -import java.util.Random; - import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos.MutableBlockPos; import net.minecraft.core.Direction; @@ -27,6 +23,10 @@ import ru.bclib.api.biomes.BiomeAPI; import ru.bclib.util.BlocksHelper; import ru.bclib.world.processors.DestructionStructureProcessor; +import java.io.IOException; +import java.io.InputStream; +import java.util.Random; + public abstract class NBTStructureFeature extends DefaultFeature { private final BlockState defaultBlock; public NBTStructureFeature(BlockState defaultBlock){ diff --git a/src/main/java/ru/bclib/world/generator/BCLBiomeSource.java b/src/main/java/ru/bclib/world/generator/BCLBiomeSource.java index beb414f4..9c8d8b8d 100644 --- a/src/main/java/ru/bclib/world/generator/BCLBiomeSource.java +++ b/src/main/java/ru/bclib/world/generator/BCLBiomeSource.java @@ -1,12 +1,12 @@ package ru.bclib.world.generator; -import java.util.List; - import net.minecraft.core.Registry; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeSource; import ru.bclib.api.biomes.BiomeAPI; +import java.util.List; + public abstract class BCLBiomeSource extends BiomeSource { protected final Registry biomeRegistry; protected final long seed; diff --git a/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java b/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java index c9317a3a..dad925a8 100644 --- a/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java +++ b/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java @@ -1,9 +1,5 @@ package ru.bclib.world.generator; -import java.awt.Point; -import java.util.List; -import java.util.function.Function; - import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.Registry; @@ -28,6 +24,10 @@ import ru.bclib.world.biomes.BCLBiome; import ru.bclib.world.generator.map.hex.HexBiomeMap; import ru.bclib.world.generator.map.square.SquareBiomeMap; +import java.awt.Point; +import java.util.List; +import java.util.function.Function; + public class BCLibEndBiomeSource extends BCLBiomeSource { public static final Codec CODEC = RecordCodecBuilder.create((instance) -> { return instance.group(RegistryLookupCodec.create(Registry.BIOME_REGISTRY).forGetter((theEndBiomeSource) -> { diff --git a/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java b/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java index 337bb51b..8be7fafa 100644 --- a/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java +++ b/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java @@ -1,7 +1,5 @@ package ru.bclib.world.generator; -import java.util.List; - import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.Registry; @@ -22,6 +20,8 @@ import ru.bclib.world.generator.map.MapStack; import ru.bclib.world.generator.map.hex.HexBiomeMap; import ru.bclib.world.generator.map.square.SquareBiomeMap; +import java.util.List; + public class BCLibNetherBiomeSource extends BCLBiomeSource { public static final Codec CODEC = RecordCodecBuilder.create((instance) -> { return instance.group(RegistryLookupCodec.create(Registry.BIOME_REGISTRY).forGetter((theEndBiomeSource) -> { diff --git a/src/main/java/ru/bclib/world/generator/map/MapStack.java b/src/main/java/ru/bclib/world/generator/map/MapStack.java index 2ec610e3..2674e3f1 100644 --- a/src/main/java/ru/bclib/world/generator/map/MapStack.java +++ b/src/main/java/ru/bclib/world/generator/map/MapStack.java @@ -2,7 +2,9 @@ package ru.bclib.world.generator.map; import net.minecraft.util.Mth; import org.apache.commons.lang3.function.TriFunction; +import ru.bclib.interfaces.BiomeChunk; import ru.bclib.interfaces.BiomeMap; +import ru.bclib.interfaces.TriConsumer; import ru.bclib.noise.OpenSimplexNoise; import ru.bclib.world.biomes.BCLBiome; import ru.bclib.world.generator.BiomePicker; @@ -29,6 +31,7 @@ public class MapStack implements BiomeMap { Random random = new Random(seed); for (int i = 0; i < mapCount; i++) { maps[i] = mapConstructor.apply(random.nextLong(), size, picker); + maps[i].setChunkProcessor(this::onChunkCreation); } noise = new OpenSimplexNoise(random.nextInt()); } @@ -40,6 +43,14 @@ public class MapStack implements BiomeMap { } } + @Override + public void setChunkProcessor(TriConsumer processor) {} + + @Override + public BiomeChunk getChunk(int cx, int cz, boolean update) { + return null; + } + @Override public BCLBiome getBiome(double x, double y, double z) { int mapIndex; @@ -57,4 +68,39 @@ public class MapStack implements BiomeMap { return maps[mapIndex].getBiome(x, y, z); } + + private void onChunkCreation(int cx, int cz, int side) { + System.out.println("Creation " + cx + " " + cz); + + BCLBiome[][] biomeMap = new BCLBiome[side][side]; + BiomeChunk[] chunks = new BiomeChunk[maps.length]; + + boolean isNoEmpty = false; + for (int i = 0; i < maps.length; i++) { + chunks[i] = maps[i].getChunk(cx, cz, false); + for (int x = 0; x < side; x++) { + for (int z = 0; z < side; z++) { + if (biomeMap[x][z] == null) { + BCLBiome biome = chunks[i].getBiome(x, z); + if (biome.isVertical()) { + biomeMap[x][z] = biome; + isNoEmpty = true; + } + } + } + } + } + + if (isNoEmpty) { + for (int i = 0; i < maps.length; i++) { + for (int x = 0; x < side; x++) { + for (int z = 0; z < side; z++) { + if (biomeMap[x][z] != null) { + chunks[i].setBiome(x, z, biomeMap[x][z]); + } + } + } + } + } + } } diff --git a/src/main/java/ru/bclib/world/generator/map/hex/HexBiomeChunk.java b/src/main/java/ru/bclib/world/generator/map/hex/HexBiomeChunk.java index 8493e31f..667f15b8 100644 --- a/src/main/java/ru/bclib/world/generator/map/hex/HexBiomeChunk.java +++ b/src/main/java/ru/bclib/world/generator/map/hex/HexBiomeChunk.java @@ -1,12 +1,13 @@ package ru.bclib.world.generator.map.hex; +import ru.bclib.interfaces.BiomeChunk; import ru.bclib.world.biomes.BCLBiome; import ru.bclib.world.generator.BiomePicker; import java.util.Arrays; import java.util.Random; -public class HexBiomeChunk { +public class HexBiomeChunk implements BiomeChunk { private static final short SIDE = 32; private static final byte SIDE_PRE = 4; private static final short SIZE = SIDE * SIDE; @@ -104,10 +105,21 @@ public class HexBiomeChunk { return (short) ((short) x << SIDE_OFFSET | z); } + @Override public BCLBiome getBiome(int x, int z) { return biomes[getIndex(wrap(x), wrap(z))]; } + @Override + public void setBiome(int x, int z, BCLBiome biome) { + biomes[getIndex(wrap(x), wrap(z))] = biome; + } + + @Override + public int getSide() { + return SIDE; + } + public static int scaleCoordinate(int value) { return value >> SIDE_OFFSET; } diff --git a/src/main/java/ru/bclib/world/generator/map/hex/HexBiomeMap.java b/src/main/java/ru/bclib/world/generator/map/hex/HexBiomeMap.java index 216663e4..d93769b9 100644 --- a/src/main/java/ru/bclib/world/generator/map/hex/HexBiomeMap.java +++ b/src/main/java/ru/bclib/world/generator/map/hex/HexBiomeMap.java @@ -1,6 +1,8 @@ package ru.bclib.world.generator.map.hex; +import ru.bclib.interfaces.BiomeChunk; import ru.bclib.interfaces.BiomeMap; +import ru.bclib.interfaces.TriConsumer; import ru.bclib.noise.OpenSimplexNoise; import ru.bclib.util.MHelper; import ru.bclib.world.biomes.BCLBiome; @@ -25,6 +27,7 @@ public class HexBiomeMap implements BiomeMap { private final BiomePicker picker; private final OpenSimplexNoise[] noises = new OpenSimplexNoise[2]; + private TriConsumer processor; private final byte noiseIterations; private final float scale; private final int seed; @@ -71,6 +74,35 @@ public class HexBiomeMap implements BiomeMap { return biome; } + @Override + public BiomeChunk getChunk(int cx, int cz, boolean update) { + HexBiomeChunk chunk; + + synchronized (selector) { + selector.setLocation(cx, cz); + chunk = chunks.get(selector); + } + + if (chunk == null) { + synchronized (RANDOM) { + RANDOM.setSeed(MHelper.getSeed(seed, cx, cz)); + chunk = new HexBiomeChunk(RANDOM, picker); + } + chunks.put(new Point(cx, cz), chunk); + + if (update && processor != null) { + processor.accept(cx, cz, chunk.getSide()); + } + } + + return chunk; + } + + @Override + public void setChunkProcessor(TriConsumer processor) { + this.processor = processor; + } + private BCLBiome getRawBiome(double x, double z) { double px = x / scale * RAD_INNER; double pz = z / scale; @@ -123,21 +155,7 @@ public class HexBiomeMap implements BiomeMap { cz += 1; } - HexBiomeChunk chunk; - synchronized (selector) { - selector.setLocation(cx, cz); - chunk = chunks.get(selector); - } - - if (chunk == null) { - synchronized (RANDOM) { - RANDOM.setSeed(MHelper.getSeed(seed, cx, cz)); - chunk = new HexBiomeChunk(RANDOM, picker); - } - chunks.put(new Point(cx, cz), chunk); - } - - return chunk.getBiome(x, z); + return getChunk(cx, cz, true).getBiome(x, z); } private boolean insideHexagon(float centerX, float centerZ, float radius, float x, float z) { diff --git a/src/main/java/ru/bclib/world/generator/map/square/SquareBiomeChunk.java b/src/main/java/ru/bclib/world/generator/map/square/SquareBiomeChunk.java index c4d366b6..e1427555 100644 --- a/src/main/java/ru/bclib/world/generator/map/square/SquareBiomeChunk.java +++ b/src/main/java/ru/bclib/world/generator/map/square/SquareBiomeChunk.java @@ -1,11 +1,12 @@ package ru.bclib.world.generator.map.square; +import ru.bclib.interfaces.BiomeChunk; import ru.bclib.world.biomes.BCLBiome; import ru.bclib.world.generator.BiomePicker; import java.util.Random; -public class SquareBiomeChunk { +public class SquareBiomeChunk implements BiomeChunk { private static final int BIT_OFFSET = 4; protected static final int WIDTH = 1 << BIT_OFFSET; private static final int SM_WIDTH = WIDTH >> 1; @@ -37,10 +38,21 @@ public class SquareBiomeChunk { } } + @Override public BCLBiome getBiome(int x, int z) { return biomes[getIndex(x & MASK_WIDTH, z & MASK_WIDTH)]; } + @Override + public void setBiome(int x, int z, BCLBiome biome) { + biomes[getIndex(x & MASK_WIDTH, z & MASK_WIDTH)] = biome; + } + + @Override + public int getSide() { + return WIDTH; + } + private int offsetXZ(int x, Random random) { return ((x + random.nextInt(2)) >> 1) & MASK_OFFSET; } diff --git a/src/main/java/ru/bclib/world/generator/map/square/SquareBiomeMap.java b/src/main/java/ru/bclib/world/generator/map/square/SquareBiomeMap.java index 5441c8aa..78a78417 100644 --- a/src/main/java/ru/bclib/world/generator/map/square/SquareBiomeMap.java +++ b/src/main/java/ru/bclib/world/generator/map/square/SquareBiomeMap.java @@ -4,7 +4,9 @@ import com.google.common.collect.Maps; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.levelgen.LegacyRandomSource; import net.minecraft.world.level.levelgen.WorldgenRandom; +import ru.bclib.interfaces.BiomeChunk; import ru.bclib.interfaces.BiomeMap; +import ru.bclib.interfaces.TriConsumer; import ru.bclib.noise.OpenSimplexNoise; import ru.bclib.util.MHelper; import ru.bclib.world.biomes.BCLBiome; @@ -23,6 +25,8 @@ public class SquareBiomeMap implements BiomeMap { private final int depth; private final int size; + private TriConsumer processor; + public SquareBiomeMap(long seed, int size, BiomePicker picker) { maps.clear(); random = new WorldgenRandom(new LegacyRandomSource(seed)); @@ -69,18 +73,40 @@ public class SquareBiomeMap implements BiomeMap { return biome; } + @Override + public void setChunkProcessor(TriConsumer processor) { + this.processor = processor; + } + + @Override + public BiomeChunk getChunk(int cx, int cz, boolean update) { + ChunkPos cpos = new ChunkPos(cx, cz); + SquareBiomeChunk chunk = maps.get(cpos); + if (chunk == null) { + synchronized (random) { + random.setLargeFeatureWithSalt(0, cpos.x, cpos.z, 0); + chunk = new SquareBiomeChunk(random, picker); + } + maps.put(cpos, chunk); + + if (update && processor != null) { + processor.accept(cx, cz, chunk.getSide()); + } + } + + return chunk; + } + private BCLBiome getRawBiome(double bx, double bz) { double x = bx * size / sizeXZ; double z = bz * size / sizeXZ; - double nx = x; - double nz = z; double px = bx * 0.2; double pz = bz * 0.2; for (int i = 0; i < depth; i++) { - nx = (x + noiseX.eval(px, pz)) / 2F; - nz = (z + noiseZ.eval(px, pz)) / 2F; + double nx = (x + noiseX.eval(px, pz)) / 2F; + double nz = (z + noiseZ.eval(px, pz)) / 2F; x = nx; z = nz; @@ -91,6 +117,7 @@ public class SquareBiomeMap implements BiomeMap { int ix = MHelper.floor(x); int iz = MHelper.floor(z); + if ((ix & SquareBiomeChunk.MASK_WIDTH) == SquareBiomeChunk.MASK_WIDTH) { x += (iz / 2) & 1; }