Some changes to TemplateFeatures

This commit is contained in:
Frank 2022-05-31 18:12:19 +02:00
parent 2623a817d0
commit 3512f82775
4 changed files with 106 additions and 35 deletions

View file

@ -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<FC extends TemplateFeatureConfig> extends Feature<FC> {
public static final Feature<TemplateFeatureConfig> INSTANCE = BCLFeature.register("template",
new TemplateFeature(
TemplateFeatureConfig.CODEC));
new TemplateFeature(
TemplateFeatureConfig.CODEC));
public static <T extends TemplateFeatureConfig> BCLFeature createAndRegister(TemplateFeatureConfig configuration,
public static <T extends TemplateFeatureConfig> 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<FC extends TemplateFeatureConfig> extends Feature<F
super(codec);
}
protected StructureWorldNBT randomStructure(TemplateFeatureConfig cfg, RandomSource random) {
if (cfg.structures.size() > 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<FC> 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())
);
}
}

View file

@ -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<TemplateFeatureConfig> 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<StructureWorldNBT> 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<StructureWorldNBT> structures) {
this.structures = structures;
}
}

View file

@ -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<StructureWorldNBT> 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<String, StructureWorldNBT> 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,

View file

@ -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;