From cf8955ea4b87232f6e88524e41310212847d5295 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Tue, 29 Sep 2020 00:07:47 +0300 Subject: [PATCH] SDF, tags registry --- src/main/java/ru/betterend/BetterEnd.java | 2 + .../betterend/mixin/common/TagAccessor.java | 1 + .../betterend/registry/BlockTagRegistry.java | 21 +++++ .../betterend/registry/FeatureRegistry.java | 2 + .../java/ru/betterend/util/BlocksHelper.java | 4 + src/main/java/ru/betterend/util/sdf/ISDF.java | 78 +++++++++++++++++++ .../util/sdf/operator/SDFScale3D.java | 19 +++++ .../util/sdf/operator/SDFSubtraction.java | 2 +- .../util/sdf/operator/SDFTranslate.java | 19 +++++ .../util/sdf/primitive/SDFCapsule.java | 2 +- .../world/biome/BiomeFoggyMushroomland.java | 2 +- .../features/MossyGlowshroomFeature.java | 58 ++++++++++++++ .../betterend/world/generator/BiomeMap.java | 1 + .../betterend/tags/blocks/end_ground.json | 6 ++ 14 files changed, 214 insertions(+), 3 deletions(-) create mode 100644 src/main/java/ru/betterend/registry/BlockTagRegistry.java create mode 100644 src/main/java/ru/betterend/util/sdf/operator/SDFScale3D.java create mode 100644 src/main/java/ru/betterend/util/sdf/operator/SDFTranslate.java create mode 100644 src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java create mode 100644 src/main/resources/data/betterend/tags/blocks/end_ground.json diff --git a/src/main/java/ru/betterend/BetterEnd.java b/src/main/java/ru/betterend/BetterEnd.java index 8a767d6c..14a4a6bc 100644 --- a/src/main/java/ru/betterend/BetterEnd.java +++ b/src/main/java/ru/betterend/BetterEnd.java @@ -7,6 +7,7 @@ import ru.betterend.recipe.CraftingRecipes; import ru.betterend.registry.BiomeRegistry; import ru.betterend.registry.BlockEntityRegistry; import ru.betterend.registry.BlockRegistry; +import ru.betterend.registry.BlockTagRegistry; import ru.betterend.registry.FeatureRegistry; import ru.betterend.registry.ItemRegistry; import ru.betterend.util.Logger; @@ -28,5 +29,6 @@ public class BetterEnd implements ModInitializer { BiomeRegistry.register(); BetterEndBiomeSource.register(); CraftingRecipes.register(); + BlockTagRegistry.register(); } } diff --git a/src/main/java/ru/betterend/mixin/common/TagAccessor.java b/src/main/java/ru/betterend/mixin/common/TagAccessor.java index 546bcd4e..7a59df45 100644 --- a/src/main/java/ru/betterend/mixin/common/TagAccessor.java +++ b/src/main/java/ru/betterend/mixin/common/TagAccessor.java @@ -5,6 +5,7 @@ import org.spongepowered.asm.mixin.gen.Accessor; import net.minecraft.tag.Tag; +@Deprecated @Mixin(targets = "net.minecraft.tag.RequiredTagList$TagWrapper") public interface TagAccessor { @Accessor diff --git a/src/main/java/ru/betterend/registry/BlockTagRegistry.java b/src/main/java/ru/betterend/registry/BlockTagRegistry.java new file mode 100644 index 00000000..b19db7c1 --- /dev/null +++ b/src/main/java/ru/betterend/registry/BlockTagRegistry.java @@ -0,0 +1,21 @@ +package ru.betterend.registry; + +import net.fabricmc.fabric.api.tag.TagRegistry; +import net.minecraft.block.Block; +import net.minecraft.tag.Tag; +import net.minecraft.tag.Tag.Identified; +import net.minecraft.util.Identifier; +import ru.betterend.BetterEnd; +import ru.betterend.util.TagHelper; + +public class BlockTagRegistry { + public static final Tag.Identified END_GROUND = makeTag("end_ground"); + + private static Tag.Identified makeTag(String name) { + return (Identified) TagRegistry.block(new Identifier(BetterEnd.MOD_ID, name)); + } + + public static void register() { + TagHelper.addTag(END_GROUND, BlockRegistry.END_MOSS, BlockRegistry.END_MYCELIUM); + } +} diff --git a/src/main/java/ru/betterend/registry/FeatureRegistry.java b/src/main/java/ru/betterend/registry/FeatureRegistry.java index b045d1d1..5ab4ee9c 100644 --- a/src/main/java/ru/betterend/registry/FeatureRegistry.java +++ b/src/main/java/ru/betterend/registry/FeatureRegistry.java @@ -2,10 +2,12 @@ package ru.betterend.registry; import ru.betterend.world.features.EndFeature; import ru.betterend.world.features.EndLakeFeature; +import ru.betterend.world.features.MossyGlowshroomFeature; import ru.betterend.world.features.StoneSpiralFeature; public class FeatureRegistry { public static final EndFeature STONE_SPIRAL = new EndFeature("stone_spiral", new StoneSpiralFeature(), 2); + public static final EndFeature MOSSY_GLOWSHROOM = new EndFeature("mossy_glowshroom", new MossyGlowshroomFeature(), 1); public static final EndFeature END_LAKE = EndFeature.MakeRawGenFeature("end_lake", new EndLakeFeature(), 100); public static void register() {} diff --git a/src/main/java/ru/betterend/util/BlocksHelper.java b/src/main/java/ru/betterend/util/BlocksHelper.java index 741a8751..e16aa6c8 100644 --- a/src/main/java/ru/betterend/util/BlocksHelper.java +++ b/src/main/java/ru/betterend/util/BlocksHelper.java @@ -42,6 +42,10 @@ public class BlocksHelper { public static void setWithoutUpdate(WorldAccess world, BlockPos pos, BlockState state) { world.setBlockState(pos, state, SET_SILENT); } + + public static void setWithoutUpdate(WorldAccess world, BlockPos pos, Block block) { + world.setBlockState(pos, block.getDefaultState(), SET_SILENT); + } public static int upRay(WorldAccess world, BlockPos pos, int maxDist) { int length = 0; diff --git a/src/main/java/ru/betterend/util/sdf/ISDF.java b/src/main/java/ru/betterend/util/sdf/ISDF.java index 83e91d21..1c53465d 100644 --- a/src/main/java/ru/betterend/util/sdf/ISDF.java +++ b/src/main/java/ru/betterend/util/sdf/ISDF.java @@ -1,5 +1,83 @@ package ru.betterend.util.sdf; +import java.util.Set; +import java.util.function.Function; + +import com.google.common.collect.Sets; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.ServerWorldAccess; +import ru.betterend.util.BlocksHelper; + public interface ISDF { public float getDistance(float x, float y, float z); + + default void fillRecursive(ServerWorldAccess world, BlockPos start, Function canReplace, int dx, int dy, int dz) { + Set blocks = Sets.newHashSet(); + Set ends = Sets.newHashSet(); + Set add = Sets.newHashSet(); + ends.add(new BlockPos(0, 0, 0)); + boolean run = true; + + while (run) { + for (BlockPos center: ends) { + for (Direction dir: Direction.values()) { + BlockPos pos = center.offset(dir); + BlockPos wpos = pos.add(start); + + run &= Math.abs(pos.getX()) < dx; + run &= Math.abs(pos.getY()) < dy; + run &= Math.abs(pos.getZ()) < dz; + + if (!blocks.contains(pos) && canReplace.apply(world.getBlockState(wpos))) { + if (this.getDistance(pos.getX(), pos.getY(), pos.getZ()) <= 0) { + BlocksHelper.setWithoutUpdate(world, wpos, Blocks.STONE); + add.add(pos); + } + } + } + } + + blocks.addAll(ends); + ends.clear(); + ends.addAll(add); + add.clear(); + + run &= !ends.isEmpty(); + } + } + + default void fillRecursive(ServerWorldAccess world, BlockPos start, Function canReplace) { + Set blocks = Sets.newHashSet(); + Set ends = Sets.newHashSet(); + Set add = Sets.newHashSet(); + ends.add(new BlockPos(0, 0, 0)); + boolean run = true; + + while (run) { + for (BlockPos center: ends) { + for (Direction dir: Direction.values()) { + BlockPos pos = center.offset(dir); + BlockPos wpos = pos.add(start); + + if (!blocks.contains(pos) && canReplace.apply(world.getBlockState(wpos))) { + if (this.getDistance(pos.getX(), pos.getY(), pos.getZ()) <= 0) { + BlocksHelper.setWithoutUpdate(world, wpos, Blocks.STONE); + add.add(pos); + } + } + } + } + + blocks.addAll(ends); + ends.clear(); + ends.addAll(add); + add.clear(); + + run &= !ends.isEmpty(); + } + } } diff --git a/src/main/java/ru/betterend/util/sdf/operator/SDFScale3D.java b/src/main/java/ru/betterend/util/sdf/operator/SDFScale3D.java new file mode 100644 index 00000000..aee54e49 --- /dev/null +++ b/src/main/java/ru/betterend/util/sdf/operator/SDFScale3D.java @@ -0,0 +1,19 @@ +package ru.betterend.util.sdf.operator; + +public class SDFScale3D extends SDFUnary { + private float x; + private float y; + private float z; + + public SDFScale3D setScale(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + return this; + } + + @Override + public float getDistance(float x, float y, float z) { + return source.getDistance(x / this.x, y / this.y, z / this.z); + } +} diff --git a/src/main/java/ru/betterend/util/sdf/operator/SDFSubtraction.java b/src/main/java/ru/betterend/util/sdf/operator/SDFSubtraction.java index cb44d10d..0a5c2b20 100644 --- a/src/main/java/ru/betterend/util/sdf/operator/SDFSubtraction.java +++ b/src/main/java/ru/betterend/util/sdf/operator/SDFSubtraction.java @@ -7,6 +7,6 @@ public class SDFSubtraction extends SDFBinary { public float getDistance(float x, float y, float z) { float a = this.sourceA.getDistance(x, y, z); float b = this.sourceB.getDistance(x, y, z); - return MHelper.max(-a, b); + return MHelper.max(a, -b); } } diff --git a/src/main/java/ru/betterend/util/sdf/operator/SDFTranslate.java b/src/main/java/ru/betterend/util/sdf/operator/SDFTranslate.java new file mode 100644 index 00000000..980e4d49 --- /dev/null +++ b/src/main/java/ru/betterend/util/sdf/operator/SDFTranslate.java @@ -0,0 +1,19 @@ +package ru.betterend.util.sdf.operator; + +public class SDFTranslate extends SDFUnary { + float x; + float y; + float z; + + public SDFTranslate setTranslate(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + return this; + } + + @Override + public float getDistance(float x, float y, float z) { + return source.getDistance(x - this.x, y - this.y, z - this.z); + } +} diff --git a/src/main/java/ru/betterend/util/sdf/primitive/SDFCapsule.java b/src/main/java/ru/betterend/util/sdf/primitive/SDFCapsule.java index f766744e..3736c2ae 100644 --- a/src/main/java/ru/betterend/util/sdf/primitive/SDFCapsule.java +++ b/src/main/java/ru/betterend/util/sdf/primitive/SDFCapsule.java @@ -20,6 +20,6 @@ public class SDFCapsule implements ISDF { @Override public float getDistance(float x, float y, float z) { - return MHelper.length(x, MathHelper.clamp(y, 0F, height), z) - radius; + return MHelper.length(x, MathHelper.clamp(y, -height, 0), z) - radius; } } diff --git a/src/main/java/ru/betterend/world/biome/BiomeFoggyMushroomland.java b/src/main/java/ru/betterend/world/biome/BiomeFoggyMushroomland.java index c707dcb1..ebfd6934 100644 --- a/src/main/java/ru/betterend/world/biome/BiomeFoggyMushroomland.java +++ b/src/main/java/ru/betterend/world/biome/BiomeFoggyMushroomland.java @@ -12,6 +12,6 @@ public class BiomeFoggyMushroomland extends EndBiome { .setWaterFogColor(119, 227, 250) .setSurface(BlockRegistry.END_MOSS, BlockRegistry.END_MYCELIUM) .addFeature(FeatureRegistry.END_LAKE) - .addFeature(FeatureRegistry.STONE_SPIRAL)); + .addFeature(FeatureRegistry.MOSSY_GLOWSHROOM)); } } diff --git a/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java b/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java new file mode 100644 index 00000000..abe4deca --- /dev/null +++ b/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java @@ -0,0 +1,58 @@ +package ru.betterend.world.features; + +import java.util.Random; +import java.util.function.Function; + +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.StructureWorldAccess; +import net.minecraft.world.gen.chunk.ChunkGenerator; +import net.minecraft.world.gen.feature.DefaultFeatureConfig; +import ru.betterend.registry.BlockTagRegistry; +import ru.betterend.util.sdf.ISDF; +import ru.betterend.util.sdf.operator.SDFScale3D; +import ru.betterend.util.sdf.operator.SDFSmoothUnion; +import ru.betterend.util.sdf.operator.SDFSubtraction; +import ru.betterend.util.sdf.operator.SDFTranslate; +import ru.betterend.util.sdf.primitive.SDFCapsule; +import ru.betterend.util.sdf.primitive.SDFSphere; + +public class MossyGlowshroomFeature extends DefaultFeature { + private static final Function REPLACE; + private static final ISDF FUNCTION; + + @Override + public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos blockPos, DefaultFeatureConfig featureConfig) { + blockPos = getTopPos(world, blockPos); + if (blockPos.getY() < 5) { + return false; + } + if (!world.getBlockState(blockPos.down()).isIn(BlockTagRegistry.END_GROUND)) { + return false; + } + FUNCTION.fillRecursive(world, getTopPos(world, blockPos), REPLACE, 10, 20, 10); + return true; + } + + static { + SDFCapsule capsule = new SDFCapsule().setRadius(1.7F).setHeight(5); + + SDFSphere outerSphere = new SDFSphere().setRadius(10); + SDFSphere innerSphere = new SDFSphere().setRadius(30); + + ISDF scaled1 = new SDFScale3D().setScale(1, 0.3F, 1).setSource(outerSphere); + ISDF scaled2 = new SDFScale3D().setScale(1, 0.3F, 1).setSource(innerSphere); + SDFTranslate sphereOffset = new SDFTranslate().setTranslate(0, -10F, 0); + + ISDF head = new SDFSubtraction().setSourceA(scaled1).setSourceB(sphereOffset.setSource(scaled2)); + + SDFTranslate headOffset = new SDFTranslate().setTranslate(0, 10, 0); + + //FUNCTION = new SDFSmoothUnion().setRadius(3).setSourceA(capsule).setSourceB(headOffset.setSource(head)); + FUNCTION = headOffset.setSource(head); + + REPLACE = (state) -> { + return state.getMaterial().isReplaceable(); + }; + } +} diff --git a/src/main/java/ru/betterend/world/generator/BiomeMap.java b/src/main/java/ru/betterend/world/generator/BiomeMap.java index ce02d2ab..3fcc3a2d 100644 --- a/src/main/java/ru/betterend/world/generator/BiomeMap.java +++ b/src/main/java/ru/betterend/world/generator/BiomeMap.java @@ -22,6 +22,7 @@ public class BiomeMap public BiomeMap(long seed, int size, BiomePicker picker) { + MAPS.clear(); RANDOM.setSeed(seed); noiseX = new OpenSimplexNoise(RANDOM.nextLong()); noiseZ = new OpenSimplexNoise(RANDOM.nextLong()); diff --git a/src/main/resources/data/betterend/tags/blocks/end_ground.json b/src/main/resources/data/betterend/tags/blocks/end_ground.json new file mode 100644 index 00000000..39033127 --- /dev/null +++ b/src/main/resources/data/betterend/tags/blocks/end_ground.json @@ -0,0 +1,6 @@ +{ + "replace": "false", + "values": [ + "minecraft:end_stone" + ] +} \ No newline at end of file