From 3512f8277578e06873fcd7d9e0755a6a94e9af8d Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 31 May 2022 18:12:19 +0200 Subject: [PATCH] Some changes to TemplateFeatures --- .../bclib/world/features/TemplateFeature.java | 50 +++++++++++------ .../world/features/TemplateFeatureConfig.java | 36 +++++++------ .../world/structures/StructureWorldNBT.java | 54 +++++++++++++++++-- .../world/structures/TemplateStructure.java | 1 - 4 files changed, 106 insertions(+), 35 deletions(-) diff --git a/src/main/java/org/betterx/bclib/world/features/TemplateFeature.java b/src/main/java/org/betterx/bclib/world/features/TemplateFeature.java index 03a166da..9824da2c 100644 --- a/src/main/java/org/betterx/bclib/world/features/TemplateFeature.java +++ b/src/main/java/org/betterx/bclib/world/features/TemplateFeature.java @@ -2,6 +2,7 @@ package org.betterx.bclib.world.features; import net.minecraft.core.Direction; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.levelgen.GenerationStep; import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate; @@ -13,27 +14,28 @@ import net.minecraft.world.level.levelgen.placement.EnvironmentScanPlacement; import com.mojang.serialization.Codec; import org.betterx.bclib.api.features.BCLFeatureBuilder; import org.betterx.bclib.world.structures.StructureNBT; +import org.betterx.bclib.world.structures.StructureWorldNBT; public class TemplateFeature extends Feature { public static final Feature INSTANCE = BCLFeature.register("template", - new TemplateFeature( - TemplateFeatureConfig.CODEC)); + new TemplateFeature( + TemplateFeatureConfig.CODEC)); - public static BCLFeature createAndRegister(TemplateFeatureConfig configuration, + public static BCLFeature createAndRegister(ResourceLocation location, + TemplateFeatureConfig configuration, int onveEveryChunk) { return BCLFeatureBuilder - .start(new ResourceLocation(configuration.structure.location.getNamespace(), - "feature_" + configuration.structure.location.getPath()), INSTANCE) + .start(location, INSTANCE) .decoration(GenerationStep.Decoration.SURFACE_STRUCTURES) .oncePerChunks(onveEveryChunk) .squarePlacement() .distanceToTopAndBottom10() .modifier(EnvironmentScanPlacement.scanningFor(Direction.DOWN, - BlockPredicate.solid(), - BlockPredicate.matchesBlocks(Blocks.AIR, - Blocks.WATER, - Blocks.LAVA), - 12)) + BlockPredicate.solid(), + BlockPredicate.matchesBlocks(Blocks.AIR, + Blocks.WATER, + Blocks.LAVA), + 12)) .modifier(BiomeFilter.biome()) .buildAndRegister(configuration); } @@ -42,12 +44,30 @@ public class TemplateFeature extends Feature 1) { + final float chanceSum = cfg.structures.parallelStream().map(c -> c.chance).reduce(0.0f, (p, c) -> p + c); + float rnd = random.nextFloat() * chanceSum; + + for (StructureWorldNBT c : cfg.structures) { + rnd -= c.chance; + if (rnd <= 0) return c; + } + } else { + return cfg.structures.get(0); + } + + return null; + } + @Override public boolean place(FeaturePlaceContext ctx) { - return ctx.config().structure.generateIfPlaceable(ctx.level(), - ctx.origin(), - StructureNBT.getRandomRotation(ctx.random()), - StructureNBT.getRandomMirror(ctx.random()) - ); + StructureWorldNBT structure = randomStructure(ctx.config(), ctx.random()); + return structure.generateIfPlaceable(ctx.level(), + ctx.origin(), + StructureNBT.getRandomRotation(ctx.random()), + StructureNBT.getRandomMirror(ctx.random()) + ); } } diff --git a/src/main/java/org/betterx/bclib/world/features/TemplateFeatureConfig.java b/src/main/java/org/betterx/bclib/world/features/TemplateFeatureConfig.java index e9c4addb..63750ed1 100644 --- a/src/main/java/org/betterx/bclib/world/features/TemplateFeatureConfig.java +++ b/src/main/java/org/betterx/bclib/world/features/TemplateFeatureConfig.java @@ -1,6 +1,7 @@ package org.betterx.bclib.world.features; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.ExtraCodecs; import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; import com.mojang.serialization.Codec; @@ -8,29 +9,32 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import org.betterx.bclib.world.structures.StructurePlacementType; import org.betterx.bclib.world.structures.StructureWorldNBT; +import java.util.List; + public class TemplateFeatureConfig implements FeatureConfiguration { public static final Codec CODEC = RecordCodecBuilder.create((instance) -> instance - .group(ResourceLocation.CODEC - .fieldOf("location") - .forGetter((TemplateFeatureConfig cfg) -> cfg.structure.location), - - Codec - .INT - .fieldOf("offset_y") - .orElse(0) - .forGetter((TemplateFeatureConfig cfg) -> cfg.structure.offsetY), - - StructurePlacementType.CODEC - .fieldOf("placement") - .orElse(StructurePlacementType.FLOOR) - .forGetter((TemplateFeatureConfig cfg) -> cfg.structure.type) + .group( + ExtraCodecs.nonEmptyList(StructureWorldNBT.CODEC.listOf()) + .fieldOf("structures") + .forGetter((TemplateFeatureConfig ruinedPortalStructure) -> ruinedPortalStructure.structures) ) .apply(instance, TemplateFeatureConfig::new) ); - public final StructureWorldNBT structure; + public final List structures; + + public static StructureWorldNBT cfg(ResourceLocation location, + int offsetY, + StructurePlacementType type, + float chance) { + return StructureWorldNBT.create(location, offsetY, type, chance); + } public TemplateFeatureConfig(ResourceLocation location, int offsetY, StructurePlacementType type) { - structure = StructureWorldNBT.create(location, offsetY, type); + this(List.of(cfg(location, offsetY, type, 1.0f))); + } + + public TemplateFeatureConfig(List structures) { + this.structures = structures; } } diff --git a/src/main/java/org/betterx/bclib/world/structures/StructureWorldNBT.java b/src/main/java/org/betterx/bclib/world/structures/StructureWorldNBT.java index 7ef6a141..7e50e2a5 100644 --- a/src/main/java/org/betterx/bclib/world/structures/StructureWorldNBT.java +++ b/src/main/java/org/betterx/bclib/world/structures/StructureWorldNBT.java @@ -3,6 +3,7 @@ package org.betterx.bclib.world.structures; import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos.MutableBlockPos; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.level.block.Blocks; @@ -11,27 +12,74 @@ import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.levelgen.structure.BoundingBox; import com.google.common.collect.Maps; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import org.betterx.bclib.util.BlocksHelper; import java.util.Map; public class StructureWorldNBT extends StructureNBT { + public static final Codec CODEC = + RecordCodecBuilder.create((instance) -> + instance.group( + ResourceLocation.CODEC + .fieldOf("location") + .forGetter((cfg) -> cfg.location), + + Codec + .INT + .fieldOf("offset_y") + .orElse(0) + .forGetter((cfg) -> cfg.offsetY), + + StructurePlacementType.CODEC + .fieldOf("placement") + .orElse(StructurePlacementType.FLOOR) + .forGetter((cfg) -> cfg.type), + Codec + .FLOAT + .fieldOf("chance") + .orElse(1.0f) + .forGetter((cfg) -> cfg.chance) + ) + .apply(instance, StructureWorldNBT::new) + ); + public final StructurePlacementType type; public final int offsetY; + public final float chance; - protected StructureWorldNBT(ResourceLocation location, int offsetY, StructurePlacementType type) { + protected StructureWorldNBT(ResourceLocation location, int offsetY, StructurePlacementType type, float chance) { super(location); this.offsetY = offsetY; this.type = type; + this.chance = chance; } private static final Map READER_CACHE = Maps.newHashMap(); public static StructureWorldNBT create(ResourceLocation location, int offsetY, StructurePlacementType type) { - String key = location.toString() + "::" + offsetY + "::" + type.getSerializedName(); - return READER_CACHE.computeIfAbsent(key, r -> new StructureWorldNBT(location, offsetY, type)); + return create(location, offsetY, type, 1.0f); } + public static StructureWorldNBT create(ResourceLocation location, + int offsetY, + StructurePlacementType type, + float chance) { + String key = location.toString() + "::" + offsetY + "::" + type.getSerializedName(); + return READER_CACHE.computeIfAbsent(key, r -> new StructureWorldNBT(location, offsetY, type, chance)); + } + + public boolean generateIfPlaceable(ServerLevelAccessor level, + BlockPos pos, + RandomSource random + ) { + return generateIfPlaceable(level, + pos, + StructureNBT.getRandomRotation(random), + StructureNBT.getRandomMirror(random) + ); + } public boolean generateIfPlaceable(ServerLevelAccessor level, BlockPos pos, diff --git a/src/main/java/org/betterx/bclib/world/structures/TemplateStructure.java b/src/main/java/org/betterx/bclib/world/structures/TemplateStructure.java index 9f15a678..19161a96 100644 --- a/src/main/java/org/betterx/bclib/world/structures/TemplateStructure.java +++ b/src/main/java/org/betterx/bclib/world/structures/TemplateStructure.java @@ -55,7 +55,6 @@ public abstract class TemplateStructure extends Structure { } protected Config randomConfig(RandomSource random) { - Config config = null; if (this.configs.size() > 1) { final float chanceSum = configs.parallelStream().map(c -> c.chance()).reduce(0.0f, (p, c) -> p + c); float rnd = random.nextFloat() * chanceSum;