From 86ea607d6498a6b77b154b7db39e9d5fbe704c79 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Tue, 6 Oct 2020 11:16:38 +0300 Subject: [PATCH 1/7] Structure pieces --- .../betterend/registry/StructureRegistry.java | 14 ++ .../util/sdf/primitive/SDFPrimitive.java | 4 + .../features/MossyGlowshroomFeature.java | 4 + .../world/structures/piece/BasePiece.java | 18 +++ .../structures/piece/StructureWorld.java | 126 ++++++++++++++++++ .../world/structures/piece/VoxelPiece.java | 43 ++++++ 6 files changed, 209 insertions(+) create mode 100644 src/main/java/ru/betterend/registry/StructureRegistry.java create mode 100644 src/main/java/ru/betterend/world/structures/piece/BasePiece.java create mode 100644 src/main/java/ru/betterend/world/structures/piece/StructureWorld.java create mode 100644 src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java diff --git a/src/main/java/ru/betterend/registry/StructureRegistry.java b/src/main/java/ru/betterend/registry/StructureRegistry.java new file mode 100644 index 00000000..c555fb85 --- /dev/null +++ b/src/main/java/ru/betterend/registry/StructureRegistry.java @@ -0,0 +1,14 @@ +package ru.betterend.registry; + +import net.minecraft.structure.StructurePieceType; +import net.minecraft.util.registry.Registry; +import ru.betterend.BetterEnd; +import ru.betterend.world.structures.piece.VoxelPiece; + +public class StructureRegistry { + public static final StructurePieceType VOXEL_PIECE = register("sdf", VoxelPiece::new); + + private static StructurePieceType register(String id, StructurePieceType pieceType) { + return Registry.register(Registry.STRUCTURE_PIECE, BetterEnd.makeID(id), pieceType); + } +} diff --git a/src/main/java/ru/betterend/util/sdf/primitive/SDFPrimitive.java b/src/main/java/ru/betterend/util/sdf/primitive/SDFPrimitive.java index 707c8d0b..5f8cf461 100644 --- a/src/main/java/ru/betterend/util/sdf/primitive/SDFPrimitive.java +++ b/src/main/java/ru/betterend/util/sdf/primitive/SDFPrimitive.java @@ -32,4 +32,8 @@ public abstract class SDFPrimitive extends SDF { public BlockState getBlockState(BlockPos pos) { return placerFunction.apply(pos); } + + /*public abstract CompoundTag toNBT(CompoundTag root) { + + }*/ } diff --git a/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java b/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java index 85364689..3f64ce72 100644 --- a/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java +++ b/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java @@ -78,6 +78,10 @@ public class MossyGlowshroomFeature extends DefaultFeature { Vector3f pos = spline.get(spline.size() - 1); float scale = MHelper.randRange(0.75F, 1.1F, random); + if (featureConfig != null && random.nextInt(32) == 0) { + scale *= MHelper.randRange(2F, 3F, random); + } + Vector3f vec = spline.get(0); float x1 = blockPos.getX() + vec.getX() * scale; float y1 = blockPos.getY() + vec.getY() * scale; diff --git a/src/main/java/ru/betterend/world/structures/piece/BasePiece.java b/src/main/java/ru/betterend/world/structures/piece/BasePiece.java new file mode 100644 index 00000000..aa8fe1a4 --- /dev/null +++ b/src/main/java/ru/betterend/world/structures/piece/BasePiece.java @@ -0,0 +1,18 @@ +package ru.betterend.world.structures.piece; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.structure.StructurePiece; +import net.minecraft.structure.StructurePieceType; + +public abstract class BasePiece extends StructurePiece { + protected BasePiece(StructurePieceType type, int i) { + super(type, i); + } + + protected BasePiece(StructurePieceType type, CompoundTag tag) { + super(type, tag); + fromNbt(tag); + } + + protected abstract void fromNbt(CompoundTag tag); +} \ No newline at end of file diff --git a/src/main/java/ru/betterend/world/structures/piece/StructureWorld.java b/src/main/java/ru/betterend/world/structures/piece/StructureWorld.java new file mode 100644 index 00000000..ab9f9942 --- /dev/null +++ b/src/main/java/ru/betterend/world/structures/piece/StructureWorld.java @@ -0,0 +1,126 @@ +package ru.betterend.world.structures.piece; + +import java.util.Map; + +import com.google.common.collect.Maps; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtHelper; +import net.minecraft.util.math.BlockBox; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.StructureWorldAccess; +import net.minecraft.world.chunk.Chunk; + +public class StructureWorld { + private Map parts = Maps.newHashMap(); + private int minX = Integer.MAX_VALUE; + private int minZ = Integer.MAX_VALUE; + private int maxX = Integer.MIN_VALUE; + private int maxZ = Integer.MIN_VALUE; + + public StructureWorld() {} + + public StructureWorld(CompoundTag tag) { + minX = tag.getInt("minX"); + maxX = tag.getInt("maxX"); + minZ = tag.getInt("minZ"); + maxZ = tag.getInt("maxZ"); + ListTag map = tag.getList("parts", 10); + map.forEach((element) -> { + CompoundTag compound = (CompoundTag) element; + Part part = new Part(compound); + int x = compound.getInt("x"); + int z = compound.getInt("z"); + parts.put(new ChunkPos(x, z), part); + }); + } + + public void setBlock(BlockPos pos, BlockState state) { + ChunkPos cPos = new ChunkPos(pos); + Part part = parts.get(cPos); + if (part == null) { + part = new Part(); + parts.put(cPos, part); + + if (cPos.x < minX) minX = cPos.x; + if (cPos.x > maxX) maxX = cPos.x; + if (cPos.z < minZ) minZ = cPos.z; + if (cPos.z > maxZ) maxZ = cPos.z; + } + part.addBlock(pos, state); + } + + public boolean placeChunk(StructureWorldAccess world, ChunkPos chunkPos) { + Part part = parts.get(chunkPos); + if (part != null) { + Chunk chunk = world.getChunk(chunkPos.x, chunkPos.z); + part.placeChunk(chunk); + return true; + } + return false; + } + + public CompoundTag toBNT() { + CompoundTag tag = new CompoundTag(); + tag.putInt("minX", minX); + tag.putInt("maxX", maxX); + tag.putInt("minZ", minZ); + tag.putInt("maxZ", maxZ); + ListTag map = new ListTag(); + tag.put("parts", map); + parts.forEach((pos, part) -> { + map.add(part.toNBT(pos.x, pos.z)); + }); + return tag; + } + + public BlockBox getBounds() { + return new BlockBox(minX << 4, minZ << 4, (maxX << 4) | 15, (maxZ << 4) | 15); + } + + private static final class Part { + Map blocks = Maps.newHashMap(); + + public Part() {} + + public Part(CompoundTag tag) { + ListTag map = tag.getList("blocks", 10); + map.forEach((element) -> { + CompoundTag block = (CompoundTag) element; + BlockPos pos = NbtHelper.toBlockPos(block.getCompound("pos")); + BlockState state = Block.getStateFromRawId(block.getInt("state")); + blocks.put(pos, state); + }); + } + + void addBlock(BlockPos pos, BlockState state) { + BlockPos inner = new BlockPos(pos.getX() & 15, pos.getY(), pos.getZ() & 15); + blocks.put(inner, state); + } + + void placeChunk(Chunk chunk) { + blocks.forEach((pos, state) -> { + chunk.setBlockState(pos, state, false); + }); + } + + CompoundTag toNBT(int x, int z) { + CompoundTag tag = new CompoundTag(); + tag.putInt("x", x); + tag.putInt("z", z); + ListTag map = new ListTag(); + tag.put("blocks", map); + blocks.forEach((pos, state) -> { + CompoundTag block = new CompoundTag(); + block.put("pos", NbtHelper.fromBlockPos(pos)); + block.putInt("state", Block.getRawIdFromState(state)); + map.add(block); + }); + return tag; + } + } +} diff --git a/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java b/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java new file mode 100644 index 00000000..4216c710 --- /dev/null +++ b/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java @@ -0,0 +1,43 @@ +package ru.betterend.world.structures.piece; + +import java.util.Random; +import java.util.function.Consumer; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.structure.StructureManager; +import net.minecraft.util.math.BlockBox; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.StructureWorldAccess; +import net.minecraft.world.gen.StructureAccessor; +import net.minecraft.world.gen.chunk.ChunkGenerator; +import ru.betterend.registry.StructureRegistry; + +public class VoxelPiece extends BasePiece { + private StructureWorld world; + + public VoxelPiece(Consumer function, int id) { + super(StructureRegistry.VOXEL_PIECE, id); + world = new StructureWorld(); + function.accept(world); + this.boundingBox = world.getBounds(); + } + + public VoxelPiece(StructureManager manager, CompoundTag tag) { + super(StructureRegistry.VOXEL_PIECE, tag); + } + + @Override + protected void toNbt(CompoundTag tag) { + tag.put("world", world.toBNT()); + } + + protected void fromNbt(CompoundTag tag) { + world = new StructureWorld(tag.getCompound("world")); + } + + @Override + public boolean generate(StructureWorldAccess world, StructureAccessor arg, ChunkGenerator chunkGenerator, Random random, BlockBox blockBox, ChunkPos chunkPos, BlockPos blockPos) { + return true; + } +} From 2afdc1e2eb7b2ae8612526333cc3d57a1e63e228 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Tue, 6 Oct 2020 11:17:41 +0300 Subject: [PATCH 2/7] Move --- .../betterend/world/structures/{piece => }/StructureWorld.java | 2 +- .../java/ru/betterend/world/structures/piece/VoxelPiece.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) rename src/main/java/ru/betterend/world/structures/{piece => }/StructureWorld.java (95%) diff --git a/src/main/java/ru/betterend/world/structures/piece/StructureWorld.java b/src/main/java/ru/betterend/world/structures/StructureWorld.java similarity index 95% rename from src/main/java/ru/betterend/world/structures/piece/StructureWorld.java rename to src/main/java/ru/betterend/world/structures/StructureWorld.java index ab9f9942..5ecde77b 100644 --- a/src/main/java/ru/betterend/world/structures/piece/StructureWorld.java +++ b/src/main/java/ru/betterend/world/structures/StructureWorld.java @@ -1,4 +1,4 @@ -package ru.betterend.world.structures.piece; +package ru.betterend.world.structures; import java.util.Map; diff --git a/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java b/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java index 4216c710..6a5bda8c 100644 --- a/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java +++ b/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java @@ -12,6 +12,7 @@ import net.minecraft.world.StructureWorldAccess; import net.minecraft.world.gen.StructureAccessor; import net.minecraft.world.gen.chunk.ChunkGenerator; import ru.betterend.registry.StructureRegistry; +import ru.betterend.world.structures.StructureWorld; public class VoxelPiece extends BasePiece { private StructureWorld world; From 150b005257b3bb1142c68ec7e488cfa422f33196 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Tue, 6 Oct 2020 12:26:13 +0300 Subject: [PATCH 3/7] Giant Mushroom --- src/main/java/ru/betterend/BetterEnd.java | 2 + .../betterend/registry/StructureRegistry.java | 9 +- src/main/java/ru/betterend/util/sdf/SDF.java | 41 ++++++ .../betterend/util/sdf/operator/SDFRound.java | 15 +++ .../world/biome/BiomeDefinition.java | 6 + .../world/biome/BiomeFoggyMushroomland.java | 2 + .../features/MossyGlowshroomFeature.java | 4 - .../betterend/world/features/VineFeature.java | 2 +- .../world/structures/EndStructureFeature.java | 46 +++++++ .../features/SDFStructureFeature.java | 47 +++++++ .../StructureGiantMossyGlowshroom.java | 119 ++++++++++++++++++ .../world/structures/piece/VoxelPiece.java | 1 + 12 files changed, 288 insertions(+), 6 deletions(-) create mode 100644 src/main/java/ru/betterend/util/sdf/operator/SDFRound.java create mode 100644 src/main/java/ru/betterend/world/structures/EndStructureFeature.java create mode 100644 src/main/java/ru/betterend/world/structures/features/SDFStructureFeature.java create mode 100644 src/main/java/ru/betterend/world/structures/features/StructureGiantMossyGlowshroom.java diff --git a/src/main/java/ru/betterend/BetterEnd.java b/src/main/java/ru/betterend/BetterEnd.java index a381077d..32a04c43 100644 --- a/src/main/java/ru/betterend/BetterEnd.java +++ b/src/main/java/ru/betterend/BetterEnd.java @@ -14,6 +14,7 @@ import ru.betterend.registry.FeatureRegistry; import ru.betterend.registry.ItemRegistry; import ru.betterend.registry.ItemTagRegistry; import ru.betterend.registry.SoundRegistry; +import ru.betterend.registry.StructureRegistry; import ru.betterend.util.Logger; import ru.betterend.world.generator.BetterEndBiomeSource; import ru.betterend.world.surface.DoubleBlockSurfaceBuilder; @@ -38,6 +39,7 @@ public class BetterEnd implements ModInitializer { BlockTagRegistry.register(); CraftingRecipes.register(); AlloyingRecipes.register(); + StructureRegistry.register(); } public static Identifier makeID(String path) { diff --git a/src/main/java/ru/betterend/registry/StructureRegistry.java b/src/main/java/ru/betterend/registry/StructureRegistry.java index c555fb85..a4f1e987 100644 --- a/src/main/java/ru/betterend/registry/StructureRegistry.java +++ b/src/main/java/ru/betterend/registry/StructureRegistry.java @@ -2,11 +2,18 @@ package ru.betterend.registry; import net.minecraft.structure.StructurePieceType; import net.minecraft.util.registry.Registry; +import net.minecraft.world.gen.GenerationStep.Feature; import ru.betterend.BetterEnd; +import ru.betterend.world.structures.EndStructureFeature; +import ru.betterend.world.structures.features.StructureGiantMossyGlowshroom; import ru.betterend.world.structures.piece.VoxelPiece; public class StructureRegistry { - public static final StructurePieceType VOXEL_PIECE = register("sdf", VoxelPiece::new); + public static final StructurePieceType VOXEL_PIECE = register("voxel", VoxelPiece::new); + + public static final EndStructureFeature GIANT_MOSSY_GLOWSHROOM = new EndStructureFeature("giant_mossy_glowshroom", new StructureGiantMossyGlowshroom(), Feature.RAW_GENERATION, 32, 8); + + public static void register() {} private static StructurePieceType register(String id, StructurePieceType pieceType) { return Registry.register(Registry.STRUCTURE_PIECE, BetterEnd.makeID(id), pieceType); diff --git a/src/main/java/ru/betterend/util/sdf/SDF.java b/src/main/java/ru/betterend/util/sdf/SDF.java index d3dc2bb8..b9a532b4 100644 --- a/src/main/java/ru/betterend/util/sdf/SDF.java +++ b/src/main/java/ru/betterend/util/sdf/SDF.java @@ -12,6 +12,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.ServerWorldAccess; import ru.betterend.util.BlocksHelper; +import ru.betterend.world.structures.StructureWorld; public abstract class SDF { private Function postProcess = (info) -> { @@ -120,4 +121,44 @@ public abstract class SDF { return mapWorld.keySet(); } + + public Set fillRecursive(StructureWorld world, BlockPos start) { + Map mapWorld = Maps.newHashMap(); + 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)) { + if (this.getDistance(pos.getX(), pos.getY(), pos.getZ()) < 0) { + BlockState state = getBlockState(wpos); + PosInfo.create(mapWorld, wpos).setState(state); + add.add(pos); + } + } + } + } + + blocks.addAll(ends); + ends.clear(); + ends.addAll(add); + add.clear(); + + run &= !ends.isEmpty(); + } + + mapWorld.forEach((pos, info) -> { + BlockState state = postProcess.apply(info); + world.setBlock(pos, state); + }); + + return mapWorld.keySet(); + } } diff --git a/src/main/java/ru/betterend/util/sdf/operator/SDFRound.java b/src/main/java/ru/betterend/util/sdf/operator/SDFRound.java new file mode 100644 index 00000000..fe081381 --- /dev/null +++ b/src/main/java/ru/betterend/util/sdf/operator/SDFRound.java @@ -0,0 +1,15 @@ +package ru.betterend.util.sdf.operator; + +public class SDFRound extends SDFUnary { + private float radius; + + public SDFRound setRadius(float radius) { + this.radius = radius; + return this; + } + + @Override + public float getDistance(float x, float y, float z) { + return this.source.getDistance(x, y, z) - radius; + } +} diff --git a/src/main/java/ru/betterend/world/biome/BiomeDefinition.java b/src/main/java/ru/betterend/world/biome/BiomeDefinition.java index fc94591d..aa43737f 100644 --- a/src/main/java/ru/betterend/world/biome/BiomeDefinition.java +++ b/src/main/java/ru/betterend/world/biome/BiomeDefinition.java @@ -33,6 +33,7 @@ import net.minecraft.world.gen.surfacebuilder.TernarySurfaceConfig; import ru.betterend.BetterEnd; import ru.betterend.util.MHelper; import ru.betterend.world.features.EndFeature; +import ru.betterend.world.structures.EndStructureFeature; import ru.betterend.world.surface.DoubleBlockSurfaceBuilder; public class BiomeDefinition { @@ -112,6 +113,11 @@ public class BiomeDefinition { return this; } + public BiomeDefinition addStructureFeature(EndStructureFeature feature) { + structures.add(feature.getFeatureConfigured()); + return this; + } + public BiomeDefinition addFeature(EndFeature feature) { FeatureInfo info = new FeatureInfo(); info.featureStep = feature.getFeatureStep(); diff --git a/src/main/java/ru/betterend/world/biome/BiomeFoggyMushroomland.java b/src/main/java/ru/betterend/world/biome/BiomeFoggyMushroomland.java index d494512b..bb1e2fce 100644 --- a/src/main/java/ru/betterend/world/biome/BiomeFoggyMushroomland.java +++ b/src/main/java/ru/betterend/world/biome/BiomeFoggyMushroomland.java @@ -6,6 +6,7 @@ import ru.betterend.registry.EntityRegistry; import ru.betterend.registry.FeatureRegistry; import ru.betterend.registry.ParticleRegistry; import ru.betterend.registry.SoundRegistry; +import ru.betterend.registry.StructureRegistry; public class BiomeFoggyMushroomland extends EndBiome { public BiomeFoggyMushroomland() { @@ -18,6 +19,7 @@ public class BiomeFoggyMushroomland extends EndBiome { .setParticles(ParticleRegistry.GLOWING_SPHERE, 0.001F) .setLoop(SoundRegistry.AMBIENT_FOGGY_MUSHROOMLAND) .setMusic(SoundRegistry.MUSIC_FOGGY_MUSHROOMLAND) + .addStructureFeature(StructureRegistry.GIANT_MOSSY_GLOWSHROOM) .addFeature(FeatureRegistry.ENDER_ORE) .addFeature(FeatureRegistry.END_LAKE) .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 index 3f64ce72..85364689 100644 --- a/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java +++ b/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java @@ -78,10 +78,6 @@ public class MossyGlowshroomFeature extends DefaultFeature { Vector3f pos = spline.get(spline.size() - 1); float scale = MHelper.randRange(0.75F, 1.1F, random); - if (featureConfig != null && random.nextInt(32) == 0) { - scale *= MHelper.randRange(2F, 3F, random); - } - Vector3f vec = spline.get(0); float x1 = blockPos.getX() + vec.getX() * scale; float y1 = blockPos.getY() + vec.getY() * scale; diff --git a/src/main/java/ru/betterend/world/features/VineFeature.java b/src/main/java/ru/betterend/world/features/VineFeature.java index c4cddc5e..5ffb6e92 100644 --- a/src/main/java/ru/betterend/world/features/VineFeature.java +++ b/src/main/java/ru/betterend/world/features/VineFeature.java @@ -21,7 +21,7 @@ public class VineFeature extends InvertedScatterFeature { @Override public boolean canGenerate(StructureWorldAccess world, Random random, BlockPos center, BlockPos blockPos, float radius) { - return vineBlock.canPlaceAt(AIR, world, blockPos); + return world.isAir(blockPos) && vineBlock.canPlaceAt(AIR, world, blockPos); } @Override diff --git a/src/main/java/ru/betterend/world/structures/EndStructureFeature.java b/src/main/java/ru/betterend/world/structures/EndStructureFeature.java new file mode 100644 index 00000000..f883fbaa --- /dev/null +++ b/src/main/java/ru/betterend/world/structures/EndStructureFeature.java @@ -0,0 +1,46 @@ +package ru.betterend.world.structures; + +import java.util.Random; + +import net.fabricmc.fabric.api.structure.v1.FabricStructureBuilder; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.BuiltinRegistries; +import net.minecraft.world.gen.GenerationStep; +import net.minecraft.world.gen.feature.ConfiguredStructureFeature; +import net.minecraft.world.gen.feature.DefaultFeatureConfig; +import net.minecraft.world.gen.feature.StructureFeature; +import ru.betterend.BetterEnd; + +public class EndStructureFeature { + private static final Random RANDOM = new Random(354); + private final StructureFeature structure; + private final ConfiguredStructureFeature featureConfigured; + private final GenerationStep.Feature featureStep; + + public EndStructureFeature(String name, StructureFeature structure, GenerationStep.Feature step, int spacing, int separation) { + Identifier id = BetterEnd.makeID(name); + + this.featureStep = step; + this.structure = FabricStructureBuilder.create(id, structure) + .step(step) + .defaultConfig(spacing, separation, RANDOM.nextInt(8192)) + .adjustsSurface() + .register(); + + this.featureConfigured = this.structure.configure(DefaultFeatureConfig.DEFAULT); + + BuiltinRegistries.add(BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE, id, this.featureConfigured); + } + + public StructureFeature getStructure() { + return structure; + } + + public ConfiguredStructureFeature getFeatureConfigured() { + return featureConfigured; + } + + public GenerationStep.Feature getFeatureStep() { + return featureStep; + } +} diff --git a/src/main/java/ru/betterend/world/structures/features/SDFStructureFeature.java b/src/main/java/ru/betterend/world/structures/features/SDFStructureFeature.java new file mode 100644 index 00000000..baee4af4 --- /dev/null +++ b/src/main/java/ru/betterend/world/structures/features/SDFStructureFeature.java @@ -0,0 +1,47 @@ +package ru.betterend.world.structures.features; + +import java.util.Random; + +import net.minecraft.structure.StructureManager; +import net.minecraft.structure.StructureStart; +import net.minecraft.util.math.BlockBox; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.registry.DynamicRegistryManager; +import net.minecraft.world.Heightmap.Type; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.chunk.ChunkGenerator; +import net.minecraft.world.gen.feature.DefaultFeatureConfig; +import net.minecraft.world.gen.feature.StructureFeature; +import ru.betterend.util.MHelper; +import ru.betterend.util.sdf.SDF; +import ru.betterend.world.structures.piece.VoxelPiece; + +public abstract class SDFStructureFeature extends StructureFeature { + public SDFStructureFeature() { + super(DefaultFeatureConfig.CODEC); + } + + protected abstract SDF getSDF(BlockPos pos, Random random); + + @Override + public StructureFeature.StructureStartFactory getStructureStartFactory() { + return SDFStructureStart::new; + } + + public static class SDFStructureStart extends StructureStart { + public SDFStructureStart(StructureFeature feature, int chunkX, int chunkZ, BlockBox box, int references, long seed) { + super(feature, chunkX, chunkZ, box, references, seed); + } + + @Override + public void init(DynamicRegistryManager registryManager, ChunkGenerator chunkGenerator, StructureManager manager, int chunkX, int chunkZ, Biome biome, DefaultFeatureConfig config) { + int x = (chunkX << 4) | MHelper.randRange(4, 12, random); + int z = (chunkZ << 4) | MHelper.randRange(4, 12, random); + int y = chunkGenerator.getHeight(x, z, Type.WORLD_SURFACE_WG); + BlockPos start = new BlockPos(x, y, z); + VoxelPiece piece = new VoxelPiece((world) -> { ((SDFStructureFeature) this.getFeature()).getSDF(start, this.random).fillRecursive(world, start); }, random.nextInt()); + this.children.add(piece); + this.boundingBox = piece.getBoundingBox(); + } + } +} diff --git a/src/main/java/ru/betterend/world/structures/features/StructureGiantMossyGlowshroom.java b/src/main/java/ru/betterend/world/structures/features/StructureGiantMossyGlowshroom.java new file mode 100644 index 00000000..126fb8df --- /dev/null +++ b/src/main/java/ru/betterend/world/structures/features/StructureGiantMossyGlowshroom.java @@ -0,0 +1,119 @@ +package ru.betterend.world.structures.features; + +import java.util.List; +import java.util.Random; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.client.util.math.Vector3f; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import ru.betterend.blocks.BlockMossyGlowshroomCap; +import ru.betterend.noise.OpenSimplexNoise; +import ru.betterend.registry.BlockRegistry; +import ru.betterend.util.MHelper; +import ru.betterend.util.SplineHelper; +import ru.betterend.util.sdf.SDF; +import ru.betterend.util.sdf.operator.SDFBinary; +import ru.betterend.util.sdf.operator.SDFCoordModify; +import ru.betterend.util.sdf.operator.SDFFlatWave; +import ru.betterend.util.sdf.operator.SDFRound; +import ru.betterend.util.sdf.operator.SDFScale; +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.operator.SDFUnion; +import ru.betterend.util.sdf.primitive.SDFCapedCone; +import ru.betterend.util.sdf.primitive.SDFPrimitive; +import ru.betterend.util.sdf.primitive.SDFSphere; + +public class StructureGiantMossyGlowshroom extends SDFStructureFeature { + private static final BlockState AIR = Blocks.AIR.getDefaultState(); + + @Override + protected SDF getSDF(BlockPos center, Random random) { + System.out.println(center); + + SDFCapedCone cone1 = new SDFCapedCone().setHeight(2.5F).setRadius1(1.5F).setRadius2(2.5F); + SDFCapedCone cone2 = new SDFCapedCone().setHeight(3F).setRadius1(2.5F).setRadius2(13F); + SDF posedCone2 = new SDFTranslate().setTranslate(0, 5, 0).setSource(cone2); + SDF posedCone3 = new SDFTranslate().setTranslate(0, 12F, 0).setSource(new SDFScale().setScale(2).setSource(cone2)); + SDF upCone = new SDFSubtraction().setSourceA(posedCone2).setSourceB(posedCone3); + SDF wave = new SDFFlatWave().setRaysCount(12).setIntensity(1.3F).setSource(upCone); + SDF cones = new SDFSmoothUnion().setRadius(3).setSourceA(cone1).setSourceB(wave); + + SDF innerCone = new SDFTranslate().setTranslate(0, 1.25F, 0).setSource(upCone); + innerCone = new SDFScale3D().setScale(1.2F, 1F, 1.2F).setSource(innerCone); + cones = new SDFUnion().setSourceA(cones).setSourceB(innerCone); + + SDF glowCone = new SDFCapedCone().setHeight(3F).setRadius1(2F).setRadius2(12.5F); + SDFPrimitive priGlowCone = (SDFPrimitive) glowCone; + glowCone = new SDFTranslate().setTranslate(0, 4.25F, 0).setSource(glowCone); + glowCone = new SDFSubtraction().setSourceA(glowCone).setSourceB(posedCone3); + + cones = new SDFUnion().setSourceA(cones).setSourceB(glowCone); + + OpenSimplexNoise noise = new OpenSimplexNoise(1234); + cones = new SDFCoordModify().setFunction((pos) -> { + float dist = MHelper.length(pos.getX(), pos.getZ()); + float y = pos.getY() + (float) noise.eval(pos.getX() * 0.1 + center.getX(), pos.getZ() * 0.1 + center.getZ()) * dist * 0.3F - dist * 0.15F; + pos.set(pos.getX(), y, pos.getZ()); + }).setSource(cones); + + SDFTranslate HEAD_POS = (SDFTranslate) new SDFTranslate().setSource(new SDFTranslate().setTranslate(0, 2.5F, 0).setSource(cones)); + + SDF roots = new SDFSphere().setRadius(4F); + SDFPrimitive primRoots = (SDFPrimitive) roots; + roots = new SDFScale3D().setScale(1, 0.7F, 1).setSource(roots); + SDFFlatWave rotRoots = (SDFFlatWave) new SDFFlatWave().setRaysCount(5).setIntensity(1.5F).setSource(roots); + + SDFBinary function = new SDFSmoothUnion().setRadius(4).setSourceB(new SDFUnion().setSourceA(HEAD_POS).setSourceB(rotRoots)); + + cone1.setBlock(BlockRegistry.MOSSY_GLOWSHROOM_CAP); + cone2.setBlock(BlockRegistry.MOSSY_GLOWSHROOM_CAP); + priGlowCone.setBlock(BlockRegistry.MOSSY_GLOWSHROOM_HYMENOPHORE); + primRoots.setBlock(BlockRegistry.MOSSY_GLOWSHROOM.bark); + + float height = MHelper.randRange(10F, 25F, random); + int count = MHelper.floor(height / 4); + List spline = SplineHelper.makeSpline(0, 0, 0, 0, height, 0, count); + SplineHelper.offsetParts(spline, random, 1F, 0, 1F); + SDF sdf = SplineHelper.buildSDF(spline, 2.1F, 1.5F, (pos) -> { + return BlockRegistry.MOSSY_GLOWSHROOM.log.getDefaultState(); + }); + Vector3f pos = spline.get(spline.size() - 1); + float scale = MHelper.randRange(2F, 3.5F, random); + + HEAD_POS.setTranslate(pos.getX(), pos.getY(), pos.getZ()); + rotRoots.setAngle(random.nextFloat() * MHelper.PI2); + function.setSourceA(sdf); + + return new SDFRound().setRadius(1.5F).setSource(new SDFScale() + .setScale(scale) + .setSource(function) + .setPostProcess((info) -> { + if (BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getState())) { + if (!BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateUp()) || !BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown())) { + return BlockRegistry.MOSSY_GLOWSHROOM.bark.getDefaultState(); + } + } + else if (info.getState().getBlock() == BlockRegistry.MOSSY_GLOWSHROOM_CAP) { + if (BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown())) { + return info.getState().with(BlockMossyGlowshroomCap.TRANSITION, true); + } + + int air = 0; + for (Direction dir: Direction.values()) { + if (info.getState(dir).isAir()) { + air ++; + } + } + if (air > 4) { + info.setState(AIR); + return AIR; + } + } + return info.getState(); + })); + } +} diff --git a/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java b/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java index 6a5bda8c..84c56f49 100644 --- a/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java +++ b/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java @@ -39,6 +39,7 @@ public class VoxelPiece extends BasePiece { @Override public boolean generate(StructureWorldAccess world, StructureAccessor arg, ChunkGenerator chunkGenerator, Random random, BlockBox blockBox, ChunkPos chunkPos, BlockPos blockPos) { + this.world.placeChunk(world, chunkPos); return true; } } From 31e33ba2d3a560ec8f885610c02d307483113b81 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Tue, 6 Oct 2020 13:59:55 +0300 Subject: [PATCH 4/7] Mushroom fixes --- .../java/ru/betterend/util/sdf/PosInfo.java | 19 ++++- src/main/java/ru/betterend/util/sdf/SDF.java | 40 +++++---- .../features/MossyGlowshroomFeature.java | 83 ++++++------------- .../StructureGiantMossyGlowshroom.java | 32 ++++--- 4 files changed, 83 insertions(+), 91 deletions(-) diff --git a/src/main/java/ru/betterend/util/sdf/PosInfo.java b/src/main/java/ru/betterend/util/sdf/PosInfo.java index d072c6c9..7c71dc67 100644 --- a/src/main/java/ru/betterend/util/sdf/PosInfo.java +++ b/src/main/java/ru/betterend/util/sdf/PosInfo.java @@ -7,7 +7,7 @@ import net.minecraft.block.Blocks; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; -public class PosInfo { +public class PosInfo implements Comparable { private static final BlockState AIR = Blocks.AIR.getDefaultState(); private final Map blocks; private final BlockPos pos; @@ -39,6 +39,14 @@ public class PosInfo { return info.getState(); } + public BlockState getState(Direction dir, int distance) { + PosInfo info = blocks.get(pos.offset(dir, distance)); + if (info == null) { + return AIR; + } + return info.getState(); + } + public BlockState getStateUp() { return getState(Direction.UP); } @@ -57,4 +65,13 @@ public class PosInfo { } return pos.equals(((PosInfo) obj).pos); } + + @Override + public int compareTo(PosInfo info) { + return this.pos.getY() - info.pos.getY(); + } + + public BlockPos getPos() { + return pos; + } } diff --git a/src/main/java/ru/betterend/util/sdf/SDF.java b/src/main/java/ru/betterend/util/sdf/SDF.java index b9a532b4..f822198b 100644 --- a/src/main/java/ru/betterend/util/sdf/SDF.java +++ b/src/main/java/ru/betterend/util/sdf/SDF.java @@ -1,5 +1,8 @@ package ru.betterend.util.sdf; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Function; @@ -36,7 +39,7 @@ public abstract class SDF { return this; } - public Set fillRecursive(ServerWorldAccess world, BlockPos start, int dx, int dy, int dz) { + public void fillRecursive(ServerWorldAccess world, BlockPos start, int dx, int dy, int dz) { Map mapWorld = Maps.newHashMap(); Set blocks = Sets.newHashSet(); Set ends = Sets.newHashSet(); @@ -74,15 +77,17 @@ public abstract class SDF { run &= !ends.isEmpty(); } - mapWorld.forEach((pos, info) -> { - BlockState state = postProcess.apply(info); - BlocksHelper.setWithoutUpdate(world, pos, state); - }); - - return mapWorld.keySet(); + List infos = new ArrayList(mapWorld.values()); + if (infos.size() > 0) { + Collections.sort(infos); + infos.forEach((info) -> { + BlockState state = postProcess.apply(info); + BlocksHelper.setWithoutUpdate(world, info.getPos(), state); + }); + } } - public Set fillRecursive(ServerWorldAccess world, BlockPos start) { + public void fillRecursive(ServerWorldAccess world, BlockPos start) { Map mapWorld = Maps.newHashMap(); Set blocks = Sets.newHashSet(); Set ends = Sets.newHashSet(); @@ -119,10 +124,17 @@ public abstract class SDF { BlocksHelper.setWithoutUpdate(world, pos, state); }); - return mapWorld.keySet(); + List infos = new ArrayList(mapWorld.values()); + if (infos.size() > 0) { + Collections.sort(infos); + infos.forEach((info) -> { + BlockState state = postProcess.apply(info); + BlocksHelper.setWithoutUpdate(world, info.getPos(), state); + }); + } } - public Set fillRecursive(StructureWorld world, BlockPos start) { + public void fillRecursive(StructureWorld world, BlockPos start) { Map mapWorld = Maps.newHashMap(); Set blocks = Sets.newHashSet(); Set ends = Sets.newHashSet(); @@ -154,11 +166,11 @@ public abstract class SDF { run &= !ends.isEmpty(); } - mapWorld.forEach((pos, info) -> { + List infos = new ArrayList(mapWorld.values()); + Collections.sort(infos); + infos.forEach((info) -> { BlockState state = postProcess.apply(info); - world.setBlock(pos, state); + world.setBlock(info.getPos(), state); }); - - return mapWorld.keySet(); } } diff --git a/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java b/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java index 85364689..86535057 100644 --- a/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java +++ b/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java @@ -2,7 +2,6 @@ package ru.betterend.world.features; import java.util.List; import java.util.Random; -import java.util.Set; import java.util.function.Function; import net.minecraft.block.BlockState; @@ -10,20 +9,17 @@ import net.minecraft.block.Material; import net.minecraft.client.util.math.Vector3f; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos.Mutable; -import net.minecraft.util.math.Direction; import net.minecraft.util.math.MathHelper; import net.minecraft.world.StructureWorldAccess; import net.minecraft.world.gen.chunk.ChunkGenerator; import net.minecraft.world.gen.feature.DefaultFeatureConfig; import ru.betterend.blocks.BlockMossyGlowshroomCap; -import ru.betterend.blocks.basis.BlockGlowingFur; import ru.betterend.noise.OpenSimplexNoise; import ru.betterend.registry.BlockRegistry; import ru.betterend.registry.BlockTagRegistry; import ru.betterend.util.BlocksHelper; import ru.betterend.util.MHelper; import ru.betterend.util.SplineHelper; -import ru.betterend.util.sdf.PosInfo; import ru.betterend.util.sdf.SDF; import ru.betterend.util.sdf.operator.SDFBinary; import ru.betterend.util.sdf.operator.SDFCoordModify; @@ -39,7 +35,6 @@ import ru.betterend.util.sdf.primitive.SDFPrimitive; import ru.betterend.util.sdf.primitive.SDFSphere; public class MossyGlowshroomFeature extends DefaultFeature { - private static final Function POST_PROCESS; private static final Function REPLACE; private static final Vector3f CENTER = new Vector3f(); private static final SDFBinary FUNCTION; @@ -112,38 +107,33 @@ public class MossyGlowshroomFeature extends DefaultFeature { ROOTS_ROT.setAngle(random.nextFloat() * MHelper.PI2); FUNCTION.setSourceA(sdf); - Set blocks = new SDFScale() - .setScale(scale) + new SDFScale().setScale(scale) .setSource(FUNCTION) .setReplaceFunction(REPLACE) - .setPostProcess(POST_PROCESS) + .setPostProcess((info) -> { + if (BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getState())) { + if (random.nextBoolean() && info.getStateUp().getBlock() == BlockRegistry.MOSSY_GLOWSHROOM_CAP) { + info.setState(BlockRegistry.MOSSY_GLOWSHROOM_CAP.getDefaultState().with(BlockMossyGlowshroomCap.TRANSITION, true)); + return info.getState(); + } + else if (!BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateUp()) || !BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown())) { + info.setState(BlockRegistry.MOSSY_GLOWSHROOM.bark.getDefaultState()); + return info.getState(); + } + } + else if (info.getState().getBlock() == BlockRegistry.MOSSY_GLOWSHROOM_CAP) { + if (BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown().getBlock())) { + info.setState(BlockRegistry.MOSSY_GLOWSHROOM_CAP.getDefaultState().with(BlockMossyGlowshroomCap.TRANSITION, true)); + return info.getState(); + } + + info.setState(BlockRegistry.MOSSY_GLOWSHROOM_CAP.getDefaultState()); + return info.getState(); + } + return info.getState(); + }) .fillRecursive(world, blockPos); - for (BlockPos bpos: blocks) { - BlockState state = world.getBlockState(bpos); - if (state.getBlock() == BlockRegistry.MOSSY_GLOWSHROOM_HYMENOPHORE) { - if (world.isAir(bpos.north())) { - BlocksHelper.setWithoutUpdate(world, bpos.north(), BlockRegistry.MOSSY_GLOWSHROOM_FUR.getDefaultState().with(BlockGlowingFur.FACING, Direction.NORTH)); - } - if (world.isAir(bpos.east())) { - BlocksHelper.setWithoutUpdate(world, bpos.east(), BlockRegistry.MOSSY_GLOWSHROOM_FUR.getDefaultState().with(BlockGlowingFur.FACING, Direction.EAST)); - } - if (world.isAir(bpos.south())) { - BlocksHelper.setWithoutUpdate(world, bpos.south(), BlockRegistry.MOSSY_GLOWSHROOM_FUR.getDefaultState().with(BlockGlowingFur.FACING, Direction.SOUTH)); - } - if (world.isAir(bpos.west())) { - BlocksHelper.setWithoutUpdate(world, bpos.west(), BlockRegistry.MOSSY_GLOWSHROOM_FUR.getDefaultState().with(BlockGlowingFur.FACING, Direction.WEST)); - } - if (world.getBlockState(bpos.down()).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, bpos.down(), BlockRegistry.MOSSY_GLOWSHROOM_FUR.getDefaultState().with(BlockGlowingFur.FACING, Direction.DOWN)); - } - } - else if (BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(state) && random.nextBoolean() && world.getBlockState(bpos.up()).getBlock() == BlockRegistry.MOSSY_GLOWSHROOM_CAP) { - BlocksHelper.setWithoutUpdate(world, bpos, BlockRegistry.MOSSY_GLOWSHROOM_CAP.getDefaultState().with(BlockMossyGlowshroomCap.TRANSITION, true)); - BlocksHelper.setWithoutUpdate(world, bpos.up(), BlockRegistry.MOSSY_GLOWSHROOM_CAP); - } - } - return true; } @@ -151,7 +141,7 @@ public class MossyGlowshroomFeature extends DefaultFeature { SDFCapedCone cone1 = new SDFCapedCone().setHeight(2.5F).setRadius1(1.5F).setRadius2(2.5F); SDFCapedCone cone2 = new SDFCapedCone().setHeight(3F).setRadius1(2.5F).setRadius2(13F); SDF posedCone2 = new SDFTranslate().setTranslate(0, 5, 0).setSource(cone2); - SDF posedCone3 = new SDFTranslate().setTranslate(0, 7F, 0).setSource(cone2); + SDF posedCone3 = new SDFTranslate().setTranslate(0, 12F, 0).setSource(new SDFScale().setScale(2).setSource(cone2)); SDF upCone = new SDFSubtraction().setSourceA(posedCone2).setSourceB(posedCone3); SDF wave = new SDFFlatWave().setRaysCount(12).setIntensity(1.3F).setSource(upCone); SDF cones = new SDFSmoothUnion().setRadius(3).setSourceA(cone1).setSourceB(wave); @@ -195,30 +185,5 @@ public class MossyGlowshroomFeature extends DefaultFeature { } return state.getMaterial().isReplaceable(); }; - - POST_PROCESS = (info) -> { - if (BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getState())) { - if (!BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateUp()) || !BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown())) { - return BlockRegistry.MOSSY_GLOWSHROOM.bark.getDefaultState(); - } - } - else if (info.getState().getBlock() == BlockRegistry.MOSSY_GLOWSHROOM_CAP) { - if (BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown())) { - return info.getState().with(BlockMossyGlowshroomCap.TRANSITION, true); - } - - int air = 0; - for (Direction dir: Direction.values()) { - if (info.getState(dir).isAir()) { - air ++; - } - } - if (air > 4) { - info.setState(AIR); - return AIR; - } - } - return info.getState(); - }; } } diff --git a/src/main/java/ru/betterend/world/structures/features/StructureGiantMossyGlowshroom.java b/src/main/java/ru/betterend/world/structures/features/StructureGiantMossyGlowshroom.java index 126fb8df..1a43c1ad 100644 --- a/src/main/java/ru/betterend/world/structures/features/StructureGiantMossyGlowshroom.java +++ b/src/main/java/ru/betterend/world/structures/features/StructureGiantMossyGlowshroom.java @@ -2,11 +2,11 @@ package ru.betterend.world.structures.features; import java.util.List; import java.util.Random; + import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.client.util.math.Vector3f; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; import ru.betterend.blocks.BlockMossyGlowshroomCap; import ru.betterend.noise.OpenSimplexNoise; import ru.betterend.registry.BlockRegistry; @@ -90,30 +90,28 @@ public class StructureGiantMossyGlowshroom extends SDFStructureFeature { return new SDFRound().setRadius(1.5F).setSource(new SDFScale() .setScale(scale) - .setSource(function) + .setSource(function)) .setPostProcess((info) -> { if (BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getState())) { - if (!BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateUp()) || !BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown())) { - return BlockRegistry.MOSSY_GLOWSHROOM.bark.getDefaultState(); + if (random.nextBoolean() && info.getStateUp().getBlock() == BlockRegistry.MOSSY_GLOWSHROOM_CAP) { + info.setState(BlockRegistry.MOSSY_GLOWSHROOM_CAP.getDefaultState().with(BlockMossyGlowshroomCap.TRANSITION, true)); + return info.getState(); + } + else if (!BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateUp()) || !BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown())) { + info.setState(BlockRegistry.MOSSY_GLOWSHROOM.bark.getDefaultState()); + return info.getState(); } } else if (info.getState().getBlock() == BlockRegistry.MOSSY_GLOWSHROOM_CAP) { - if (BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown())) { - return info.getState().with(BlockMossyGlowshroomCap.TRANSITION, true); + if (BlockRegistry.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown().getBlock())) { + info.setState(BlockRegistry.MOSSY_GLOWSHROOM_CAP.getDefaultState().with(BlockMossyGlowshroomCap.TRANSITION, true)); + return info.getState(); } - int air = 0; - for (Direction dir: Direction.values()) { - if (info.getState(dir).isAir()) { - air ++; - } - } - if (air > 4) { - info.setState(AIR); - return AIR; - } + info.setState(BlockRegistry.MOSSY_GLOWSHROOM_CAP.getDefaultState()); + return info.getState(); } return info.getState(); - })); + }); } } From 42ef270e2eb4214afed27d674c8080261c209cef Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Tue, 6 Oct 2020 16:40:26 +0300 Subject: [PATCH 5/7] Mushroom fixes --- .../mixin/common/LocateCommandMixin.java | 45 ++++++++++++++ .../betterend/registry/StructureRegistry.java | 2 +- .../ru/betterend/util/StructureHelper.java | 62 +++++++++++++++++++ .../world/structures/EndStructureFeature.java | 1 - .../world/structures/StructureWorld.java | 15 ++++- .../features/SDFStructureFeature.java | 17 +++-- .../features/StructureFeatureBase.java | 46 ++++++++++++++ .../StructureGiantMossyGlowshroom.java | 4 -- .../world/structures/piece/VoxelPiece.java | 3 + .../resources/betterend.mixins.common.json | 3 +- 10 files changed, 181 insertions(+), 17 deletions(-) create mode 100644 src/main/java/ru/betterend/mixin/common/LocateCommandMixin.java create mode 100644 src/main/java/ru/betterend/util/StructureHelper.java create mode 100644 src/main/java/ru/betterend/world/structures/features/StructureFeatureBase.java diff --git a/src/main/java/ru/betterend/mixin/common/LocateCommandMixin.java b/src/main/java/ru/betterend/mixin/common/LocateCommandMixin.java new file mode 100644 index 00000000..331df4e3 --- /dev/null +++ b/src/main/java/ru/betterend/mixin/common/LocateCommandMixin.java @@ -0,0 +1,45 @@ +package ru.betterend.mixin.common; + +import org.spongepowered.asm.mixin.Final; +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.CallbackInfoReturnable; + +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; + +import net.minecraft.server.command.LocateCommand; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.StructureFeature; +import ru.betterend.util.StructureHelper; + +@Mixin(LocateCommand.class) +public class LocateCommandMixin { + @Shadow + @Final + private static SimpleCommandExceptionType FAILED_EXCEPTION; + + @Shadow + public static int sendCoordinates(ServerCommandSource source, String structure, BlockPos sourcePos, + BlockPos structurePos, String successMessage) { + return 0; + } + + @Inject(method = "execute", at = @At("HEAD"), cancellable = true) + private static void execute(ServerCommandSource source, StructureFeature structureFeature, CallbackInfoReturnable info) throws CommandSyntaxException { + if (source.getWorld().getRegistryKey() == World.END) { + BlockPos blockPos = new BlockPos(source.getPosition()); + BlockPos blockPos2 = StructureHelper.getNearestStructure(structureFeature, source.getWorld(), blockPos, 100); + if (blockPos2 == null) { + throw FAILED_EXCEPTION.create(); + } else { + info.setReturnValue(sendCoordinates(source, structureFeature.getName(), blockPos, blockPos2, "commands.locate.success")); + info.cancel(); + } + } + } +} diff --git a/src/main/java/ru/betterend/registry/StructureRegistry.java b/src/main/java/ru/betterend/registry/StructureRegistry.java index a4f1e987..68889457 100644 --- a/src/main/java/ru/betterend/registry/StructureRegistry.java +++ b/src/main/java/ru/betterend/registry/StructureRegistry.java @@ -11,7 +11,7 @@ import ru.betterend.world.structures.piece.VoxelPiece; public class StructureRegistry { public static final StructurePieceType VOXEL_PIECE = register("voxel", VoxelPiece::new); - public static final EndStructureFeature GIANT_MOSSY_GLOWSHROOM = new EndStructureFeature("giant_mossy_glowshroom", new StructureGiantMossyGlowshroom(), Feature.RAW_GENERATION, 32, 8); + public static final EndStructureFeature GIANT_MOSSY_GLOWSHROOM = new EndStructureFeature("giant_mossy_glowshroom", new StructureGiantMossyGlowshroom(), Feature.SURFACE_STRUCTURES, 16, 8); public static void register() {} diff --git a/src/main/java/ru/betterend/util/StructureHelper.java b/src/main/java/ru/betterend/util/StructureHelper.java new file mode 100644 index 00000000..5b1ddf06 --- /dev/null +++ b/src/main/java/ru/betterend/util/StructureHelper.java @@ -0,0 +1,62 @@ +package ru.betterend.util; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.gen.ChunkRandom; +import net.minecraft.world.gen.chunk.StructureConfig; +import net.minecraft.world.gen.feature.StructureFeature; + +public class StructureHelper { + private static final Set POSITIONS = new HashSet(64); + + private static void collectNearby(ServerWorld world, StructureFeature feature, int chunkX, int chunkZ, int radius, StructureConfig config, long worldSeed, ChunkRandom chunkRandom) { + int x1 = chunkX - radius; + int x2 = chunkX + radius; + int z1 = chunkZ - radius; + int z2 = chunkZ + radius; + + POSITIONS.clear(); + for (int x = x1; x <= x2; x += 8) { + for (int z = z1; z <= z2; z += 8) { + ChunkPos chunk = feature.getStartChunk(config, worldSeed, chunkRandom, x, z); + if (world.getBiome(chunk.getStartPos()).getGenerationSettings().hasStructureFeature(feature)) + POSITIONS.add(chunk); + } + } + } + + private static long sqr(int x) { + return (long) x * (long) x; + } + + public static BlockPos getNearestStructure(StructureFeature feature, ServerWorld world, BlockPos pos, int radius) { + int cx = pos.getX() >> 4; + int cz = pos.getZ() >> 4; + + StructureConfig config = world.getChunkManager().getChunkGenerator().getStructuresConfig().getForType(feature); + if (config == null) + return null; + + collectNearby(world, feature, cx, cz, radius, config, world.getSeed(), new ChunkRandom()); + Iterator iterator = POSITIONS.iterator(); + if (iterator.hasNext()) { + ChunkPos nearest = POSITIONS.iterator().next(); + long d = sqr(nearest.x - cx) + sqr(nearest.z - cz); + while (iterator.hasNext()) { + ChunkPos n = iterator.next(); + long d2 = sqr(n.x - cx) + sqr(n.z - cz); + if (d2 < d) { + d = d2; + nearest = n; + } + } + return nearest.getStartPos(); + } + return null; + } +} diff --git a/src/main/java/ru/betterend/world/structures/EndStructureFeature.java b/src/main/java/ru/betterend/world/structures/EndStructureFeature.java index f883fbaa..5e10a5fa 100644 --- a/src/main/java/ru/betterend/world/structures/EndStructureFeature.java +++ b/src/main/java/ru/betterend/world/structures/EndStructureFeature.java @@ -24,7 +24,6 @@ public class EndStructureFeature { this.structure = FabricStructureBuilder.create(id, structure) .step(step) .defaultConfig(spacing, separation, RANDOM.nextInt(8192)) - .adjustsSurface() .register(); this.featureConfigured = this.structure.configure(DefaultFeatureConfig.DEFAULT); diff --git a/src/main/java/ru/betterend/world/structures/StructureWorld.java b/src/main/java/ru/betterend/world/structures/StructureWorld.java index 5ecde77b..eb2d712f 100644 --- a/src/main/java/ru/betterend/world/structures/StructureWorld.java +++ b/src/main/java/ru/betterend/world/structures/StructureWorld.java @@ -18,8 +18,10 @@ import net.minecraft.world.chunk.Chunk; public class StructureWorld { private Map parts = Maps.newHashMap(); private int minX = Integer.MAX_VALUE; + private int minY = Integer.MAX_VALUE; private int minZ = Integer.MAX_VALUE; private int maxX = Integer.MIN_VALUE; + private int maxY = Integer.MIN_VALUE; private int maxZ = Integer.MIN_VALUE; public StructureWorld() {} @@ -27,8 +29,11 @@ public class StructureWorld { public StructureWorld(CompoundTag tag) { minX = tag.getInt("minX"); maxX = tag.getInt("maxX"); + minY = tag.getInt("minY"); + maxY = tag.getInt("maxY"); minZ = tag.getInt("minZ"); maxZ = tag.getInt("maxZ"); + ListTag map = tag.getList("parts", 10); map.forEach((element) -> { CompoundTag compound = (CompoundTag) element; @@ -51,6 +56,8 @@ public class StructureWorld { if (cPos.z < minZ) minZ = cPos.z; if (cPos.z > maxZ) maxZ = cPos.z; } + if (pos.getY() < minY) minY = pos.getY(); + if (pos.getY() > maxY) maxY = pos.getY(); part.addBlock(pos, state); } @@ -68,6 +75,8 @@ public class StructureWorld { CompoundTag tag = new CompoundTag(); tag.putInt("minX", minX); tag.putInt("maxX", maxX); + tag.putInt("minY", minY); + tag.putInt("maxY", maxY); tag.putInt("minZ", minZ); tag.putInt("maxZ", maxZ); ListTag map = new ListTag(); @@ -79,7 +88,10 @@ public class StructureWorld { } public BlockBox getBounds() { - return new BlockBox(minX << 4, minZ << 4, (maxX << 4) | 15, (maxZ << 4) | 15); + if (minX == Integer.MAX_VALUE || maxX == Integer.MIN_VALUE || minZ == Integer.MAX_VALUE || maxZ == Integer.MIN_VALUE) { + return BlockBox.empty(); + } + return new BlockBox(minX << 4, minY, minZ << 4, (maxX << 4) | 15, maxY, (maxZ << 4) | 15); } private static final class Part { @@ -104,6 +116,7 @@ public class StructureWorld { void placeChunk(Chunk chunk) { blocks.forEach((pos, state) -> { + //if (pos.getY() > 10) chunk.setBlockState(pos, state, false); }); } diff --git a/src/main/java/ru/betterend/world/structures/features/SDFStructureFeature.java b/src/main/java/ru/betterend/world/structures/features/SDFStructureFeature.java index baee4af4..42a31a73 100644 --- a/src/main/java/ru/betterend/world/structures/features/SDFStructureFeature.java +++ b/src/main/java/ru/betterend/world/structures/features/SDFStructureFeature.java @@ -16,11 +16,8 @@ import ru.betterend.util.MHelper; import ru.betterend.util.sdf.SDF; import ru.betterend.world.structures.piece.VoxelPiece; -public abstract class SDFStructureFeature extends StructureFeature { - public SDFStructureFeature() { - super(DefaultFeatureConfig.CODEC); - } - +public abstract class SDFStructureFeature extends StructureFeatureBase { + protected abstract SDF getSDF(BlockPos pos, Random random); @Override @@ -38,10 +35,12 @@ public abstract class SDFStructureFeature extends StructureFeature { ((SDFStructureFeature) this.getFeature()).getSDF(start, this.random).fillRecursive(world, start); }, random.nextInt()); - this.children.add(piece); - this.boundingBox = piece.getBoundingBox(); + if (y > 5) { + BlockPos start = new BlockPos(x, y, z); + VoxelPiece piece = new VoxelPiece((world) -> { ((SDFStructureFeature) this.getFeature()).getSDF(start, this.random).fillRecursive(world, start); }, random.nextInt()); + this.children.add(piece); + } + this.setBoundingBoxFromChildren(); } } } diff --git a/src/main/java/ru/betterend/world/structures/features/StructureFeatureBase.java b/src/main/java/ru/betterend/world/structures/features/StructureFeatureBase.java new file mode 100644 index 00000000..167fae91 --- /dev/null +++ b/src/main/java/ru/betterend/world/structures/features/StructureFeatureBase.java @@ -0,0 +1,46 @@ +package ru.betterend.world.structures.features; + +import java.util.Random; + +import net.minecraft.util.BlockRotation; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.Heightmap; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.source.BiomeSource; +import net.minecraft.world.gen.ChunkRandom; +import net.minecraft.world.gen.chunk.ChunkGenerator; +import net.minecraft.world.gen.feature.DefaultFeatureConfig; +import net.minecraft.world.gen.feature.StructureFeature; + +public abstract class StructureFeatureBase extends StructureFeature { + public StructureFeatureBase() { + super(DefaultFeatureConfig.CODEC); + } + + protected boolean shouldStartAt(ChunkGenerator chunkGenerator, BiomeSource biomeSource, long worldSeed, ChunkRandom chunkRandom, int chunkX, int chunkZ, Biome biome, ChunkPos chunkPos, DefaultFeatureConfig featureConfig) { + return getGenerationHeight(chunkX, chunkZ, chunkGenerator) >= 50; + } + + private static int getGenerationHeight(int chunkX, int chunkZ, ChunkGenerator chunkGenerator) { + Random random = new Random((long) (chunkX + chunkZ * 10387313)); + BlockRotation blockRotation = BlockRotation.random(random); + int i = 5; + int j = 5; + if (blockRotation == BlockRotation.CLOCKWISE_90) { + i = -5; + } else if (blockRotation == BlockRotation.CLOCKWISE_180) { + i = -5; + j = -5; + } else if (blockRotation == BlockRotation.COUNTERCLOCKWISE_90) { + j = -5; + } + + int k = (chunkX << 4) + 7; + int l = (chunkZ << 4) + 7; + int m = chunkGenerator.getHeightInGround(k, l, Heightmap.Type.WORLD_SURFACE_WG); + int n = chunkGenerator.getHeightInGround(k, l + j, Heightmap.Type.WORLD_SURFACE_WG); + int o = chunkGenerator.getHeightInGround(k + i, l, Heightmap.Type.WORLD_SURFACE_WG); + int p = chunkGenerator.getHeightInGround(k + i, l + j, Heightmap.Type.WORLD_SURFACE_WG); + return Math.min(Math.min(m, n), Math.min(o, p)); + } +} diff --git a/src/main/java/ru/betterend/world/structures/features/StructureGiantMossyGlowshroom.java b/src/main/java/ru/betterend/world/structures/features/StructureGiantMossyGlowshroom.java index 1a43c1ad..88fd448b 100644 --- a/src/main/java/ru/betterend/world/structures/features/StructureGiantMossyGlowshroom.java +++ b/src/main/java/ru/betterend/world/structures/features/StructureGiantMossyGlowshroom.java @@ -3,8 +3,6 @@ package ru.betterend.world.structures.features; import java.util.List; import java.util.Random; -import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; import net.minecraft.client.util.math.Vector3f; import net.minecraft.util.math.BlockPos; import ru.betterend.blocks.BlockMossyGlowshroomCap; @@ -28,8 +26,6 @@ import ru.betterend.util.sdf.primitive.SDFPrimitive; import ru.betterend.util.sdf.primitive.SDFSphere; public class StructureGiantMossyGlowshroom extends SDFStructureFeature { - private static final BlockState AIR = Blocks.AIR.getDefaultState(); - @Override protected SDF getSDF(BlockPos center, Random random) { System.out.println(center); diff --git a/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java b/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java index 84c56f49..89c63bce 100644 --- a/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java +++ b/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java @@ -22,10 +22,13 @@ public class VoxelPiece extends BasePiece { world = new StructureWorld(); function.accept(world); this.boundingBox = world.getBounds(); + System.out.println(this.boundingBox); } public VoxelPiece(StructureManager manager, CompoundTag tag) { super(StructureRegistry.VOXEL_PIECE, tag); + this.boundingBox = world.getBounds(); + System.out.println(this.boundingBox); } @Override diff --git a/src/main/resources/betterend.mixins.common.json b/src/main/resources/betterend.mixins.common.json index 19458ad8..33fd2062 100644 --- a/src/main/resources/betterend.mixins.common.json +++ b/src/main/resources/betterend.mixins.common.json @@ -14,7 +14,8 @@ "AbstractBlockMixin", "LivingEntityMixin", "BiomeMixin", - "SlimeEntityMixin" + "SlimeEntityMixin", + "LocateCommandMixin" ], "injectors": { "defaultRequire": 1 From b47607cb6acbff5973130fa65d33c89233c9d978 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Tue, 6 Oct 2020 17:02:56 +0300 Subject: [PATCH 6/7] Fixes --- .../java/ru/betterend/util/sdf/PosInfo.java | 17 ++++++++-- src/main/java/ru/betterend/util/sdf/SDF.java | 34 ++++++++++++++----- .../features/MossyGlowshroomFeature.java | 13 +++++++ 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/main/java/ru/betterend/util/sdf/PosInfo.java b/src/main/java/ru/betterend/util/sdf/PosInfo.java index 7c71dc67..a93e52b7 100644 --- a/src/main/java/ru/betterend/util/sdf/PosInfo.java +++ b/src/main/java/ru/betterend/util/sdf/PosInfo.java @@ -1,6 +1,7 @@ package ru.betterend.util.sdf; import java.util.Map; +import java.util.Set; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; @@ -10,15 +11,17 @@ import net.minecraft.util.math.Direction; public class PosInfo implements Comparable { private static final BlockState AIR = Blocks.AIR.getDefaultState(); private final Map blocks; + private final Set add; private final BlockPos pos; private BlockState state; - public static PosInfo create(Map blocks, BlockPos pos) { - return new PosInfo(blocks, pos); + public static PosInfo create(Map blocks, Set add, BlockPos pos) { + return new PosInfo(blocks, add, pos); } - private PosInfo(Map blocks, BlockPos pos) { + private PosInfo(Map blocks, Set add, BlockPos pos) { this.blocks = blocks; + this.add = add; this.pos = pos; blocks.put(pos, this); } @@ -55,10 +58,12 @@ public class PosInfo implements Comparable { return getState(Direction.DOWN); } + @Override public int hashCode() { return pos.hashCode(); } + @Override public boolean equals(Object obj) { if (!(obj instanceof PosInfo)) { return false; @@ -74,4 +79,10 @@ public class PosInfo implements Comparable { public BlockPos getPos() { return pos; } + + public void setBlockPos(BlockPos pos, BlockState state) { + PosInfo info = new PosInfo(blocks, add, pos); + info.state = state; + add.add(info); + } } diff --git a/src/main/java/ru/betterend/util/sdf/SDF.java b/src/main/java/ru/betterend/util/sdf/SDF.java index f822198b..b2434ef6 100644 --- a/src/main/java/ru/betterend/util/sdf/SDF.java +++ b/src/main/java/ru/betterend/util/sdf/SDF.java @@ -41,6 +41,7 @@ public abstract class SDF { public void fillRecursive(ServerWorldAccess world, BlockPos start, int dx, int dy, int dz) { Map mapWorld = Maps.newHashMap(); + Set addInfo = Sets.newHashSet(); Set blocks = Sets.newHashSet(); Set ends = Sets.newHashSet(); Set add = Sets.newHashSet(); @@ -60,7 +61,7 @@ public abstract class SDF { if (!blocks.contains(pos) && canReplace.apply(world.getBlockState(wpos))) { if (this.getDistance(pos.getX(), pos.getY(), pos.getZ()) < 0) { BlockState state = getBlockState(wpos); - PosInfo.create(mapWorld, wpos).setState(state); + PosInfo.create(mapWorld, addInfo, wpos).setState(state); if (Math.abs(pos.getX()) < dx && Math.abs(pos.getY()) < dy && Math.abs(pos.getZ()) < dz) { add.add(pos); } @@ -85,10 +86,18 @@ public abstract class SDF { BlocksHelper.setWithoutUpdate(world, info.getPos(), state); }); } + + addInfo.forEach((info) -> { + if (canReplace.apply(world.getBlockState(info.getPos()))) { + BlockState state = postProcess.apply(info); + BlocksHelper.setWithoutUpdate(world, info.getPos(), state); + } + }); } public void fillRecursive(ServerWorldAccess world, BlockPos start) { Map mapWorld = Maps.newHashMap(); + Set addInfo = Sets.newHashSet(); Set blocks = Sets.newHashSet(); Set ends = Sets.newHashSet(); Set add = Sets.newHashSet(); @@ -104,7 +113,7 @@ public abstract class SDF { if (!blocks.contains(pos) && canReplace.apply(world.getBlockState(wpos))) { if (this.getDistance(pos.getX(), pos.getY(), pos.getZ()) < 0) { BlockState state = getBlockState(wpos); - PosInfo.create(mapWorld, wpos).setState(state); + PosInfo.create(mapWorld, addInfo, wpos).setState(state); add.add(pos); } } @@ -119,11 +128,6 @@ public abstract class SDF { run &= !ends.isEmpty(); } - mapWorld.forEach((pos, info) -> { - BlockState state = postProcess.apply(info); - BlocksHelper.setWithoutUpdate(world, pos, state); - }); - List infos = new ArrayList(mapWorld.values()); if (infos.size() > 0) { Collections.sort(infos); @@ -132,10 +136,18 @@ public abstract class SDF { BlocksHelper.setWithoutUpdate(world, info.getPos(), state); }); } + + addInfo.forEach((info) -> { + if (canReplace.apply(world.getBlockState(info.getPos()))) { + BlockState state = postProcess.apply(info); + BlocksHelper.setWithoutUpdate(world, info.getPos(), state); + } + }); } public void fillRecursive(StructureWorld world, BlockPos start) { Map mapWorld = Maps.newHashMap(); + Set addInfo = Sets.newHashSet(); Set blocks = Sets.newHashSet(); Set ends = Sets.newHashSet(); Set add = Sets.newHashSet(); @@ -151,7 +163,7 @@ public abstract class SDF { if (!blocks.contains(pos)) { if (this.getDistance(pos.getX(), pos.getY(), pos.getZ()) < 0) { BlockState state = getBlockState(wpos); - PosInfo.create(mapWorld, wpos).setState(state); + PosInfo.create(mapWorld, addInfo, wpos).setState(state); add.add(pos); } } @@ -167,10 +179,16 @@ public abstract class SDF { } List infos = new ArrayList(mapWorld.values()); + infos.addAll(addInfo); Collections.sort(infos); infos.forEach((info) -> { BlockState state = postProcess.apply(info); world.setBlock(info.getPos(), state); }); + + addInfo.forEach((info) -> { + BlockState state = postProcess.apply(info); + world.setBlock(info.getPos(), state); + }); } } diff --git a/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java b/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java index 86535057..8fcedc2c 100644 --- a/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java +++ b/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java @@ -9,11 +9,13 @@ import net.minecraft.block.Material; import net.minecraft.client.util.math.Vector3f; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos.Mutable; +import net.minecraft.util.math.Direction; import net.minecraft.util.math.MathHelper; import net.minecraft.world.StructureWorldAccess; import net.minecraft.world.gen.chunk.ChunkGenerator; import net.minecraft.world.gen.feature.DefaultFeatureConfig; import ru.betterend.blocks.BlockMossyGlowshroomCap; +import ru.betterend.blocks.basis.BlockGlowingFur; import ru.betterend.noise.OpenSimplexNoise; import ru.betterend.registry.BlockRegistry; import ru.betterend.registry.BlockTagRegistry; @@ -130,6 +132,17 @@ public class MossyGlowshroomFeature extends DefaultFeature { info.setState(BlockRegistry.MOSSY_GLOWSHROOM_CAP.getDefaultState()); return info.getState(); } + else if (info.getState().getBlock() == BlockRegistry.MOSSY_GLOWSHROOM_HYMENOPHORE) { + for (Direction dir: BlocksHelper.HORIZONTAL) { + if (info.getState(dir) == AIR) { + info.setBlockPos(info.getPos().offset(dir), BlockRegistry.MOSSY_GLOWSHROOM_FUR.getDefaultState().with(BlockGlowingFur.FACING, dir)); + } + } + + if (info.getStateDown() == AIR) { + info.setBlockPos(info.getPos().down(), BlockRegistry.MOSSY_GLOWSHROOM_FUR.getDefaultState().with(BlockGlowingFur.FACING, Direction.DOWN)); + } + } return info.getState(); }) .fillRecursive(world, blockPos); From d2148baf66ddb2b32be9cd1aeded8d7aefe348bd Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Tue, 6 Oct 2020 17:24:46 +0300 Subject: [PATCH 7/7] Fixes --- .../java/ru/betterend/util/sdf/PosInfo.java | 12 ++--- src/main/java/ru/betterend/util/sdf/SDF.java | 46 +++++++++++-------- .../features/MossyGlowshroomFeature.java | 2 +- .../features/StructureFeatureBase.java | 4 ++ .../StructureGiantMossyGlowshroom.java | 14 ++++++ 5 files changed, 52 insertions(+), 26 deletions(-) diff --git a/src/main/java/ru/betterend/util/sdf/PosInfo.java b/src/main/java/ru/betterend/util/sdf/PosInfo.java index a93e52b7..b4d9f465 100644 --- a/src/main/java/ru/betterend/util/sdf/PosInfo.java +++ b/src/main/java/ru/betterend/util/sdf/PosInfo.java @@ -1,7 +1,6 @@ package ru.betterend.util.sdf; import java.util.Map; -import java.util.Set; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; @@ -11,15 +10,15 @@ import net.minecraft.util.math.Direction; public class PosInfo implements Comparable { private static final BlockState AIR = Blocks.AIR.getDefaultState(); private final Map blocks; - private final Set add; + private final Map add; private final BlockPos pos; private BlockState state; - public static PosInfo create(Map blocks, Set add, BlockPos pos) { + public static PosInfo create(Map blocks, Map add, BlockPos pos) { return new PosInfo(blocks, add, pos); } - private PosInfo(Map blocks, Set add, BlockPos pos) { + private PosInfo(Map blocks, Map add, BlockPos pos) { this.blocks = blocks; this.add = add; this.pos = pos; @@ -37,7 +36,8 @@ public class PosInfo implements Comparable { public BlockState getState(Direction dir) { PosInfo info = blocks.get(pos.offset(dir)); if (info == null) { - return AIR; + info = add.get(pos.offset(dir)); + return info == null ? AIR : info.getState(); } return info.getState(); } @@ -83,6 +83,6 @@ public class PosInfo implements Comparable { public void setBlockPos(BlockPos pos, BlockState state) { PosInfo info = new PosInfo(blocks, add, pos); info.state = state; - add.add(info); + add.put(pos, info); } } diff --git a/src/main/java/ru/betterend/util/sdf/SDF.java b/src/main/java/ru/betterend/util/sdf/SDF.java index b2434ef6..6e980188 100644 --- a/src/main/java/ru/betterend/util/sdf/SDF.java +++ b/src/main/java/ru/betterend/util/sdf/SDF.java @@ -41,7 +41,7 @@ public abstract class SDF { public void fillRecursive(ServerWorldAccess world, BlockPos start, int dx, int dy, int dz) { Map mapWorld = Maps.newHashMap(); - Set addInfo = Sets.newHashSet(); + Map addInfo = Maps.newHashMap(); Set blocks = Sets.newHashSet(); Set ends = Sets.newHashSet(); Set add = Sets.newHashSet(); @@ -85,19 +85,22 @@ public abstract class SDF { BlockState state = postProcess.apply(info); BlocksHelper.setWithoutUpdate(world, info.getPos(), state); }); - } - addInfo.forEach((info) -> { - if (canReplace.apply(world.getBlockState(info.getPos()))) { - BlockState state = postProcess.apply(info); - BlocksHelper.setWithoutUpdate(world, info.getPos(), state); - } - }); + infos.clear(); + infos.addAll(addInfo.values()); + Collections.sort(infos); + infos.forEach((info) -> { + if (canReplace.apply(world.getBlockState(info.getPos()))) { + BlockState state = postProcess.apply(info); + BlocksHelper.setWithoutUpdate(world, info.getPos(), state); + } + }); + } } public void fillRecursive(ServerWorldAccess world, BlockPos start) { Map mapWorld = Maps.newHashMap(); - Set addInfo = Sets.newHashSet(); + Map addInfo = Maps.newHashMap(); Set blocks = Sets.newHashSet(); Set ends = Sets.newHashSet(); Set add = Sets.newHashSet(); @@ -135,19 +138,22 @@ public abstract class SDF { BlockState state = postProcess.apply(info); BlocksHelper.setWithoutUpdate(world, info.getPos(), state); }); + + infos.clear(); + infos.addAll(addInfo.values()); + Collections.sort(infos); + infos.forEach((info) -> { + if (canReplace.apply(world.getBlockState(info.getPos()))) { + BlockState state = postProcess.apply(info); + BlocksHelper.setWithoutUpdate(world, info.getPos(), state); + } + }); } - - addInfo.forEach((info) -> { - if (canReplace.apply(world.getBlockState(info.getPos()))) { - BlockState state = postProcess.apply(info); - BlocksHelper.setWithoutUpdate(world, info.getPos(), state); - } - }); } public void fillRecursive(StructureWorld world, BlockPos start) { Map mapWorld = Maps.newHashMap(); - Set addInfo = Sets.newHashSet(); + Map addInfo = Maps.newHashMap(); Set blocks = Sets.newHashSet(); Set ends = Sets.newHashSet(); Set add = Sets.newHashSet(); @@ -179,14 +185,16 @@ public abstract class SDF { } List infos = new ArrayList(mapWorld.values()); - infos.addAll(addInfo); Collections.sort(infos); infos.forEach((info) -> { BlockState state = postProcess.apply(info); world.setBlock(info.getPos(), state); }); - addInfo.forEach((info) -> { + infos.clear(); + infos.addAll(addInfo.values()); + Collections.sort(infos); + infos.forEach((info) -> { BlockState state = postProcess.apply(info); world.setBlock(info.getPos(), state); }); diff --git a/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java b/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java index 8fcedc2c..5e61420c 100644 --- a/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java +++ b/src/main/java/ru/betterend/world/features/MossyGlowshroomFeature.java @@ -139,7 +139,7 @@ public class MossyGlowshroomFeature extends DefaultFeature { } } - if (info.getStateDown() == AIR) { + if (info.getStateDown().getBlock() != BlockRegistry.MOSSY_GLOWSHROOM_HYMENOPHORE) { info.setBlockPos(info.getPos().down(), BlockRegistry.MOSSY_GLOWSHROOM_FUR.getDefaultState().with(BlockGlowingFur.FACING, Direction.DOWN)); } } diff --git a/src/main/java/ru/betterend/world/structures/features/StructureFeatureBase.java b/src/main/java/ru/betterend/world/structures/features/StructureFeatureBase.java index 167fae91..845a4ad0 100644 --- a/src/main/java/ru/betterend/world/structures/features/StructureFeatureBase.java +++ b/src/main/java/ru/betterend/world/structures/features/StructureFeatureBase.java @@ -2,6 +2,8 @@ package ru.betterend.world.structures.features; import java.util.Random; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.util.BlockRotation; import net.minecraft.util.math.ChunkPos; import net.minecraft.world.Heightmap; @@ -13,6 +15,8 @@ import net.minecraft.world.gen.feature.DefaultFeatureConfig; import net.minecraft.world.gen.feature.StructureFeature; public abstract class StructureFeatureBase extends StructureFeature { + protected static final BlockState AIR = Blocks.AIR.getDefaultState(); + public StructureFeatureBase() { super(DefaultFeatureConfig.CODEC); } diff --git a/src/main/java/ru/betterend/world/structures/features/StructureGiantMossyGlowshroom.java b/src/main/java/ru/betterend/world/structures/features/StructureGiantMossyGlowshroom.java index 88fd448b..648d23c2 100644 --- a/src/main/java/ru/betterend/world/structures/features/StructureGiantMossyGlowshroom.java +++ b/src/main/java/ru/betterend/world/structures/features/StructureGiantMossyGlowshroom.java @@ -5,9 +5,12 @@ import java.util.Random; import net.minecraft.client.util.math.Vector3f; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import ru.betterend.blocks.BlockMossyGlowshroomCap; +import ru.betterend.blocks.basis.BlockGlowingFur; import ru.betterend.noise.OpenSimplexNoise; import ru.betterend.registry.BlockRegistry; +import ru.betterend.util.BlocksHelper; import ru.betterend.util.MHelper; import ru.betterend.util.SplineHelper; import ru.betterend.util.sdf.SDF; @@ -107,6 +110,17 @@ public class StructureGiantMossyGlowshroom extends SDFStructureFeature { info.setState(BlockRegistry.MOSSY_GLOWSHROOM_CAP.getDefaultState()); return info.getState(); } + else if (info.getState().getBlock() == BlockRegistry.MOSSY_GLOWSHROOM_HYMENOPHORE) { + for (Direction dir: BlocksHelper.HORIZONTAL) { + if (info.getState(dir) == AIR) { + info.setBlockPos(info.getPos().offset(dir), BlockRegistry.MOSSY_GLOWSHROOM_FUR.getDefaultState().with(BlockGlowingFur.FACING, dir)); + } + } + + if (info.getStateDown().getBlock() != BlockRegistry.MOSSY_GLOWSHROOM_HYMENOPHORE) { + info.setBlockPos(info.getPos().down(), BlockRegistry.MOSSY_GLOWSHROOM_FUR.getDefaultState().with(BlockGlowingFur.FACING, Direction.DOWN)); + } + } return info.getState(); }); }