Adapted Feature Classes

This commit is contained in:
Frank 2021-12-07 14:38:16 +01:00
parent 6a8ad29a70
commit 6097311ca6
9 changed files with 273 additions and 263 deletions

View file

@ -1,80 +1,70 @@
package ru.betterend.world.structures.features;
import java.util.Random;
import net.minecraft.core.BlockPos;
import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.Heightmap.Types;
import net.minecraft.world.level.levelgen.WorldgenRandom;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import net.minecraft.world.level.levelgen.structure.pieces.PieceGenerator;
import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import ru.bclib.util.StructureHelper;
import ru.betterend.BetterEnd;
import ru.betterend.world.structures.piece.NBTPiece;
public class EternalPortalStructure extends FeatureBaseStructure {
private static final ResourceLocation STRUCTURE_ID = BetterEnd.makeID("portal/eternal_portal");
private static final StructureTemplate STRUCTURE = StructureHelper.readStructure(STRUCTURE_ID);
@Override
protected boolean isFeatureChunk(ChunkGenerator chunkGenerator, BiomeSource biomeSource, long worldSeed, WorldgenRandom chunkRandom, ChunkPos pos, Biome biome, ChunkPos chunkPos, NoneFeatureConfiguration featureConfig, LevelHeightAccessor levelHeightAccessor) {
long x = (long) chunkPos.x * (long) chunkPos.x;
long z = (long) chunkPos.z * (long) chunkPos.z;
if (x + z < 1024L) {
return false;
}
if (chunkGenerator.getBaseHeight(
pos.getBlockX(8),
pos.getBlockX(8),
Heightmap.Types.WORLD_SURFACE_WG,
levelHeightAccessor
) < 5) {
return false;
}
return super.isFeatureChunk(
chunkGenerator,
biomeSource,
worldSeed,
chunkRandom,
pos,
biome,
chunkPos,
featureConfig,
levelHeightAccessor
);
}
@Override
public StructureFeature.StructureStartFactory<NoneFeatureConfiguration> getStartFactory() {
return PortalStructureStart::new;
}
public static class PortalStructureStart extends StructureStart<NoneFeatureConfiguration> {
public PortalStructureStart(StructureFeature<NoneFeatureConfiguration> feature, ChunkPos pos, int references, long seed) {
super(feature, pos, references, seed);
}
@Override
public void generatePieces(RegistryAccess registryManager, ChunkGenerator chunkGenerator, StructureManager structureManager, ChunkPos chunkPos, Biome biome, NoneFeatureConfiguration featureConfiguration, LevelHeightAccessor levelHeightAccessor) {
int x = chunkPos.getBlockX(8);
int z = chunkPos.getBlockZ(8);
int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor);
this.pieces.add(new NBTPiece(
STRUCTURE_ID,
STRUCTURE,
new BlockPos(x, y - 4, z),
random.nextInt(5),
true,
random
));
}
}
private static final ResourceLocation STRUCTURE_ID = BetterEnd.makeID("portal/eternal_portal");
private static final StructureTemplate STRUCTURE = StructureHelper.readStructure(STRUCTURE_ID);
public EternalPortalStructure() {
super(PieceGeneratorSupplier.simple(
EternalPortalStructure::checkLocation,
EternalPortalStructure::generatePieces
));
}
protected static boolean checkLocation(PieceGeneratorSupplier.Context<NoneFeatureConfiguration> context) {
final ChunkPos chunkPos = context.chunkPos();
final ChunkGenerator chunkGenerator = context.chunkGenerator();
final LevelHeightAccessor levelHeightAccessor = context.heightAccessor();
long x = (long) chunkPos.x * (long) chunkPos.x;
long z = (long) chunkPos.z * (long) chunkPos.z;
if (x + z < 1024L) {
return false;
}
if (chunkGenerator.getBaseHeight(
chunkPos.getBlockX(8),
chunkPos.getBlockZ(8),
Heightmap.Types.WORLD_SURFACE_WG,
levelHeightAccessor
) < 5) {
return false;
}
return FeatureBaseStructure.checkLocation(context);
}
protected static void generatePieces(StructurePiecesBuilder structurePiecesBuilder, PieceGenerator.Context<NoneFeatureConfiguration> context) {
final Random random = context.random();
final ChunkPos chunkPos = context.chunkPos();
final ChunkGenerator chunkGenerator = context.chunkGenerator();
final LevelHeightAccessor levelHeightAccessor = context.heightAccessor();
int x = chunkPos.getBlockX(8);
int z = chunkPos.getBlockZ(8);
int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor);
structurePiecesBuilder.addPiece(new NBTPiece(
STRUCTURE_ID,
STRUCTURE,
new BlockPos(x, y - 4, z),
random.nextInt(5),
true,
random
));
}
}

View file

@ -1,30 +1,27 @@
package ru.betterend.world.structures.features;
import java.util.Random;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.WorldgenRandom;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
import java.util.Random;
import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier;
public abstract class FeatureBaseStructure extends StructureFeature<NoneFeatureConfiguration> {
protected static final BlockState AIR = Blocks.AIR.defaultBlockState();
public FeatureBaseStructure() {
super(NoneFeatureConfiguration.CODEC);
public FeatureBaseStructure(PieceGeneratorSupplier<NoneFeatureConfiguration> pieceGeneratorSupplier) {
super(NoneFeatureConfiguration.CODEC, pieceGeneratorSupplier);
}
@Override
protected boolean isFeatureChunk(ChunkGenerator chunkGenerator, BiomeSource biomeSource, long worldSeed, WorldgenRandom chunkRandom, ChunkPos pos, Biome biome, ChunkPos chunkPos, NoneFeatureConfiguration featureConfig, LevelHeightAccessor levelHeightAccessor) {
return getGenerationHeight(pos, chunkGenerator, levelHeightAccessor) >= 20;
protected static boolean checkLocation(PieceGeneratorSupplier.Context<NoneFeatureConfiguration> context) {
return getGenerationHeight(context.chunkPos(), context.chunkGenerator(), context.heightAccessor()) >= 20;
}
private static int getGenerationHeight(ChunkPos chunkPos, ChunkGenerator chunkGenerator, LevelHeightAccessor levelHeightAccessor) {

View file

@ -1,17 +1,18 @@
package ru.betterend.world.structures.features;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.mojang.math.Vector3f;
import net.minecraft.core.BlockPos;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import net.minecraft.world.level.levelgen.structure.pieces.PieceGenerator;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder;
import ru.bclib.sdf.SDF;
import ru.bclib.sdf.operator.SDFRotation;
import ru.bclib.sdf.operator.SDFTranslate;
@ -21,18 +22,17 @@ import ru.bclib.util.MHelper;
import ru.betterend.registry.EndBlocks;
import ru.betterend.world.structures.piece.VoxelPiece;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class GiantIceStarStructure extends SDFStructureFeature {
private final float minSize = 20;
private final float maxSize = 35;
private final int minCount = 25;
private final int maxCount = 40;
@Override
protected SDF getSDF(BlockPos pos, Random random) {
private static final float minSize = 20;
private static final float maxSize = 35;
private static final int minCount = 25;
private static final int maxCount = 40;
public GiantIceStarStructure() {
super(GiantIceStarStructure::generatePieces);
}
protected static SDF getSDF(BlockPos pos, Random random) {
float size = MHelper.randRange(minSize, maxSize, random);
int count = MHelper.randRange(minCount, maxCount, random);
List<Vector3f> points = getFibonacciPoints(count);
@ -90,7 +90,7 @@ public class GiantIceStarStructure extends SDFStructureFeature {
});
}
private List<Vector3f> getFibonacciPoints(int count) {
private static List<Vector3f> getFibonacciPoints(int count) {
float max = count - 1;
List<Vector3f> result = new ArrayList<Vector3f>(count);
for (int i = 0; i < count; i++) {
@ -103,28 +103,21 @@ public class GiantIceStarStructure extends SDFStructureFeature {
}
return result;
}
@Override
public StructureFeature.StructureStartFactory<NoneFeatureConfiguration> getStartFactory() {
return StarStructureStart::new;
}
public static class StarStructureStart extends StructureStart<NoneFeatureConfiguration> {
public StarStructureStart(StructureFeature<NoneFeatureConfiguration> feature, ChunkPos pos, int references, long seed) {
super(feature, pos, references, seed);
}
@Override
public void generatePieces(RegistryAccess registryManager, ChunkGenerator chunkGenerator, StructureManager structureManager, ChunkPos chunkPos, Biome biome, NoneFeatureConfiguration featureConfiguration, LevelHeightAccessor levelHeightAccessor) {
int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random));
int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random));
BlockPos start = new BlockPos(x, MHelper.randRange(32, 128, random), z);
VoxelPiece piece = new VoxelPiece((world) -> {
((SDFStructureFeature) this.getFeature()).getSDF(start, this.random).fillRecursive(world, start);
}, random.nextInt());
this.pieces.add(piece);
//this.calculateBoundingBox();
}
public static void generatePieces(StructurePiecesBuilder structurePiecesBuilder, PieceGenerator.Context<NoneFeatureConfiguration> context) {
final Random random = context.random();
final ChunkPos chunkPos = context.chunkPos();
final ChunkGenerator chunkGenerator = context.chunkGenerator();
final LevelHeightAccessor levelHeightAccessor = context.heightAccessor();
int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random));
int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random));
BlockPos start = new BlockPos(x, MHelper.randRange(32, 128, random), z);
VoxelPiece piece = new VoxelPiece((world) -> {
getSDF(start, random).fillRecursive(world, start);
}, random.nextInt());
structurePiecesBuilder.addPiece(piece);
//this.calculateBoundingBox();
}
}

View file

@ -1,8 +1,14 @@
package ru.betterend.world.structures.features;
import java.util.List;
import java.util.Random;
import com.mojang.math.Vector3f;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
import net.minecraft.world.level.levelgen.structure.pieces.PieceGenerator;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder;
import ru.bclib.sdf.SDF;
import ru.bclib.sdf.operator.SDFBinary;
import ru.bclib.sdf.operator.SDFCoordModify;
@ -25,12 +31,16 @@ import ru.betterend.blocks.basis.FurBlock;
import ru.betterend.noise.OpenSimplexNoise;
import ru.betterend.registry.EndBlocks;
import java.util.List;
import java.util.Random;
public class GiantMossyGlowshroomStructure extends SDFStructureFeature {
@Override
protected SDF getSDF(BlockPos center, Random random) {
public GiantMossyGlowshroomStructure() {
super(GiantMossyGlowshroomStructure::generatePieces);
}
public static void generatePieces(StructurePiecesBuilder structurePiecesBuilder, PieceGenerator.Context<NoneFeatureConfiguration> context) {
SDFStructureFeature.generatePieces(structurePiecesBuilder, context, GiantMossyGlowshroomStructure::getSDF);
}
protected static SDF getSDF(BlockPos center, Random random) {
SDFCappedCone cone1 = new SDFCappedCone().setHeight(2.5F).setRadius1(1.5F).setRadius2(2.5F);
SDFCappedCone cone2 = new SDFCappedCone().setHeight(3F).setRadius1(2.5F).setRadius2(13F);
SDF posedCone2 = new SDFTranslate().setTranslate(0, 5, 0).setSource(cone2);

View file

@ -1,43 +1,48 @@
package ru.betterend.world.structures.features;
import java.util.Random;
import net.minecraft.core.BlockPos;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.Heightmap.Types;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import net.minecraft.world.level.levelgen.structure.pieces.PieceGenerator;
import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder;
import ru.bclib.util.MHelper;
import ru.betterend.world.structures.piece.LakePiece;
public class MegaLakeSmallStructure extends FeatureBaseStructure {
@Override
public StructureFeature.StructureStartFactory<NoneFeatureConfiguration> getStartFactory() {
return SDFStructureStart::new;
}
public static class SDFStructureStart extends StructureStart<NoneFeatureConfiguration> {
public SDFStructureStart(StructureFeature<NoneFeatureConfiguration> feature, ChunkPos chunkPos, int references, long seed) {
super(feature, chunkPos, references, seed);
}
@Override
public void generatePieces(RegistryAccess registryManager, ChunkGenerator chunkGenerator, StructureManager structureManager, ChunkPos chunkPos, Biome biome, NoneFeatureConfiguration featureConfiguration, LevelHeightAccessor levelHeightAccessor) {
int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random));
int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random));
int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor);
if (y > 5) {
float radius = MHelper.randRange(20, 40, random);
float depth = MHelper.randRange(5, 10, random);
LakePiece piece = new LakePiece(new BlockPos(x, y, z), radius, depth, random, biome);
this.pieces.add(piece);
}
//this.calculateBoundingBox();
}
}
public MegaLakeSmallStructure() {
super(PieceGeneratorSupplier.simple(
FeatureBaseStructure::checkLocation,
MegaLakeSmallStructure::generatePieces
));
}
protected static void generatePieces(StructurePiecesBuilder structurePiecesBuilder, PieceGenerator.Context<NoneFeatureConfiguration> context) {
final Random random = context.random();
final ChunkPos chunkPos = context.chunkPos();
final ChunkGenerator chunkGenerator = context.chunkGenerator();
final LevelHeightAccessor levelHeightAccessor = context.heightAccessor();
int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random));
int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random));
int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor);
//TODO: 1.18 right way to get biome?
Biome biome = chunkGenerator.getNoiseBiome(x, y, z);
if (y > 5) {
float radius = MHelper.randRange(20, 40, random);
float depth = MHelper.randRange(5, 10, random);
LakePiece piece = new LakePiece(new BlockPos(x, y, z), radius, depth, random, biome);
structurePiecesBuilder.addPiece(piece);
}
//this.calculateBoundingBox();
}
}

View file

@ -1,43 +1,51 @@
package ru.betterend.world.structures.features;
import java.util.Random;
import net.minecraft.core.BlockPos;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.Heightmap.Types;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import net.minecraft.world.level.levelgen.structure.pieces.PieceGenerator;
import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder;
import ru.bclib.util.MHelper;
import ru.betterend.world.structures.piece.LakePiece;
public class MegaLakeStructure extends FeatureBaseStructure {
@Override
public StructureFeature.StructureStartFactory<NoneFeatureConfiguration> getStartFactory() {
return SDFStructureStart::new;
}
public static class SDFStructureStart extends StructureStart<NoneFeatureConfiguration> {
public SDFStructureStart(StructureFeature<NoneFeatureConfiguration> feature, ChunkPos chunkPos, int references, long seed) {
super(feature, chunkPos, references, seed);
}
@Override
public void generatePieces(RegistryAccess registryManager, ChunkGenerator chunkGenerator, StructureManager structureManager, ChunkPos chunkPos, Biome biome, NoneFeatureConfiguration featureConfiguration, LevelHeightAccessor levelHeightAccessor) {
int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random));
int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random));
int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor);
if (y > 5) {
float radius = MHelper.randRange(32, 64, random);
float depth = MHelper.randRange(7, 15, random);
LakePiece piece = new LakePiece(new BlockPos(x, y, z), radius, depth, random, biome);
this.pieces.add(piece);
}
//this.calculateBoundingBox();
}
}
public MegaLakeStructure() {
super(PieceGeneratorSupplier.simple(
FeatureBaseStructure::checkLocation,
MegaLakeStructure::generatePieces
));
}
protected static void generatePieces(StructurePiecesBuilder structurePiecesBuilder, PieceGenerator.Context<NoneFeatureConfiguration> context) {
final Random random = context.random();
final ChunkPos chunkPos = context.chunkPos();
final ChunkGenerator chunkGenerator = context.chunkGenerator();
final LevelHeightAccessor levelHeightAccessor = context.heightAccessor();
int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random));
int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random));
int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor);
if (y > 5) {
//TODO: 1.18 right way to get biome?
Biome biome = chunkGenerator.getNoiseBiome(x, y, z);
float radius = MHelper.randRange(32, 64, random);
float depth = MHelper.randRange(7, 15, random);
LakePiece piece = new LakePiece(new BlockPos(x, y, z), radius, depth, random, biome);
structurePiecesBuilder.addPiece(piece);
}
//this.calculateBoundingBox();
}
}

View file

@ -1,49 +1,55 @@
package ru.betterend.world.structures.features;
import java.util.Random;
import net.minecraft.core.BlockPos;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.Heightmap.Types;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import net.minecraft.world.level.levelgen.structure.pieces.PieceGenerator;
import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder;
import ru.bclib.util.MHelper;
import ru.betterend.world.structures.piece.CrystalMountainPiece;
public class MountainStructure extends FeatureBaseStructure {
@Override
public StructureFeature.StructureStartFactory<NoneFeatureConfiguration> getStartFactory() {
return SDFStructureStart::new;
}
public static class SDFStructureStart extends StructureStart<NoneFeatureConfiguration> {
public SDFStructureStart(StructureFeature<NoneFeatureConfiguration> feature, ChunkPos chunkPos, int references, long seed) {
super(feature, chunkPos, references, seed);
}
@Override
public void generatePieces(RegistryAccess registryManager, ChunkGenerator chunkGenerator, StructureManager structureManager, ChunkPos chunkPos, Biome biome, NoneFeatureConfiguration featureConfiguration, LevelHeightAccessor levelHeightAccessor) {
int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random));
int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random));
int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor);
if (y > 5) {
float radius = MHelper.randRange(50, 100, random);
float height = radius * MHelper.randRange(0.8F, 1.2F, random);
CrystalMountainPiece piece = new CrystalMountainPiece(
new BlockPos(x, y, z),
radius,
height,
random,
biome
);
this.pieces.add(piece);
}
//this.calculateBoundingBox();
}
}
public MountainStructure() {
super(PieceGeneratorSupplier.simple(
FeatureBaseStructure::checkLocation,
MountainStructure::generatePieces
));
}
protected static void generatePieces(StructurePiecesBuilder structurePiecesBuilder, PieceGenerator.Context<NoneFeatureConfiguration> context) {
final Random random = context.random();
final ChunkPos chunkPos = context.chunkPos();
final ChunkGenerator chunkGenerator = context.chunkGenerator();
final LevelHeightAccessor levelHeightAccessor = context.heightAccessor();
int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random));
int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random));
int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor);
if (y > 5) {
//TODO: 1.18 right way to get biome?
Biome biome = chunkGenerator.getNoiseBiome(x, y, z);
float radius = MHelper.randRange(50, 100, random);
float height = radius * MHelper.randRange(0.8F, 1.2F, random);
CrystalMountainPiece piece = new CrystalMountainPiece(
new BlockPos(x, y, z),
radius,
height,
random,
biome
);
structurePiecesBuilder.addPiece(piece);
}
//this.calculateBoundingBox();
}
}

View file

@ -1,7 +1,8 @@
package ru.betterend.world.structures.features;
import java.util.Random;
import net.minecraft.core.BlockPos;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.biome.Biome;
@ -9,33 +10,37 @@ import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.Heightmap.Types;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import net.minecraft.world.level.levelgen.structure.pieces.PieceGenerator;
import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder;
import ru.bclib.util.MHelper;
import ru.betterend.registry.EndBlocks;
import ru.betterend.world.structures.piece.PaintedMountainPiece;
public class PaintedMountainStructure extends FeatureBaseStructure {
private static final BlockState[] VARIANTS;
@Override
public StructureFeature.StructureStartFactory<NoneFeatureConfiguration> getStartFactory() {
return SDFStructureStart::new;
public PaintedMountainStructure() {
super(PieceGeneratorSupplier.simple(
FeatureBaseStructure::checkLocation,
PaintedMountainStructure::generatePieces
));
}
public static class SDFStructureStart extends StructureStart<NoneFeatureConfiguration> {
public SDFStructureStart(StructureFeature<NoneFeatureConfiguration> feature, ChunkPos chunkPos, int references, long seed) {
super(feature, chunkPos, references, seed);
}
@Override
public void generatePieces(RegistryAccess registryManager, ChunkGenerator chunkGenerator, StructureManager structureManager, ChunkPos chunkPos, Biome biome, NoneFeatureConfiguration featureConfiguration, LevelHeightAccessor levelHeightAccessor) {
int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random));
protected static void generatePieces(StructurePiecesBuilder structurePiecesBuilder, PieceGenerator.Context<NoneFeatureConfiguration> context) {
final Random random = context.random();
final ChunkPos chunkPos = context.chunkPos();
final ChunkGenerator chunkGenerator = context.chunkGenerator();
final LevelHeightAccessor levelHeightAccessor = context.heightAccessor();
int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random));
int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random));
int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor);
if (y > 50) {
//TODO: 1.18 right way to get biome?
Biome biome = chunkGenerator.getNoiseBiome(x, y, z);
float radius = MHelper.randRange(50, 100, random);
float height = radius * MHelper.randRange(0.4F, 0.6F, random);
int count = MHelper.floor(height * MHelper.randRange(0.1F, 0.35F, random) + 1);
@ -43,12 +48,12 @@ public class PaintedMountainStructure extends FeatureBaseStructure {
for (int i = 0; i < count; i++) {
slises[i] = VARIANTS[random.nextInt(VARIANTS.length)];
}
this.pieces.add(new PaintedMountainPiece(new BlockPos(x, y, z), radius, height, random, biome, slises));
structurePiecesBuilder.addPiece(new PaintedMountainPiece(new BlockPos(x, y, z), radius, height, random, biome, slises));
}
//this.calculateBoundingBox();
}
}
static {
VARIANTS = new BlockState[] {

View file

@ -1,50 +1,46 @@
package ru.betterend.world.structures.features;
import java.util.Random;
import java.util.function.BiFunction;
import net.minecraft.core.BlockPos;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.Heightmap.Types;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import net.minecraft.world.level.levelgen.structure.pieces.PieceGenerator;
import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder;
import ru.bclib.sdf.SDF;
import ru.bclib.util.MHelper;
import ru.betterend.world.structures.piece.VoxelPiece;
import java.util.Random;
public abstract class SDFStructureFeature extends FeatureBaseStructure {
protected abstract SDF getSDF(BlockPos pos, Random random);
@Override
public StructureFeature.StructureStartFactory<NoneFeatureConfiguration> getStartFactory() {
return SDFStructureStart::new;
public SDFStructureFeature(PieceGenerator<NoneFeatureConfiguration> generator) {
super(PieceGeneratorSupplier.simple(
FeatureBaseStructure::checkLocation,
generator
));
}
public static class SDFStructureStart extends StructureStart<NoneFeatureConfiguration> {
public SDFStructureStart(StructureFeature<NoneFeatureConfiguration> feature, ChunkPos chunkPos, int references, long seed) {
super(feature, chunkPos, references, seed);
}
@Override
public void generatePieces(RegistryAccess registryManager, ChunkGenerator chunkGenerator, StructureManager structureManager, ChunkPos chunkPos, Biome biome, NoneFeatureConfiguration featureConfiguration, LevelHeightAccessor levelHeightAccessor) {
int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random));
int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random));
int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor);
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.pieces.add(piece);
}
//this.calculateBoundingBox();
public static void generatePieces(StructurePiecesBuilder structurePiecesBuilder, PieceGenerator.Context<NoneFeatureConfiguration> context, BiFunction<BlockPos, Random, SDF> sdf) {
final Random random = context.random();
final ChunkPos chunkPos = context.chunkPos();
final ChunkGenerator chunkGenerator = context.chunkGenerator();
final LevelHeightAccessor levelHeightAccessor = context.heightAccessor();
int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random));
int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random));
int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor);
if (y > 5) {
BlockPos start = new BlockPos(x, y, z);
VoxelPiece piece = new VoxelPiece((world) -> {
sdf.apply(start, random).fillRecursive(world, start);
}, random.nextInt());
structurePiecesBuilder.addPiece(piece);
}
//this.calculateBoundingBox();
}
}