Some changes to TemplateFeatures
This commit is contained in:
parent
2623a817d0
commit
3512f82775
4 changed files with 106 additions and 35 deletions
|
@ -2,6 +2,7 @@ package org.betterx.bclib.world.features;
|
||||||
|
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.levelgen.GenerationStep;
|
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||||
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
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 com.mojang.serialization.Codec;
|
||||||
import org.betterx.bclib.api.features.BCLFeatureBuilder;
|
import org.betterx.bclib.api.features.BCLFeatureBuilder;
|
||||||
import org.betterx.bclib.world.structures.StructureNBT;
|
import org.betterx.bclib.world.structures.StructureNBT;
|
||||||
|
import org.betterx.bclib.world.structures.StructureWorldNBT;
|
||||||
|
|
||||||
public class TemplateFeature<FC extends TemplateFeatureConfig> extends Feature<FC> {
|
public class TemplateFeature<FC extends TemplateFeatureConfig> extends Feature<FC> {
|
||||||
public static final Feature<TemplateFeatureConfig> INSTANCE = BCLFeature.register("template",
|
public static final Feature<TemplateFeatureConfig> INSTANCE = BCLFeature.register("template",
|
||||||
new TemplateFeature(
|
new TemplateFeature(
|
||||||
TemplateFeatureConfig.CODEC));
|
TemplateFeatureConfig.CODEC));
|
||||||
|
|
||||||
public static <T extends TemplateFeatureConfig> BCLFeature createAndRegister(TemplateFeatureConfig configuration,
|
public static <T extends TemplateFeatureConfig> BCLFeature createAndRegister(ResourceLocation location,
|
||||||
|
TemplateFeatureConfig configuration,
|
||||||
int onveEveryChunk) {
|
int onveEveryChunk) {
|
||||||
return BCLFeatureBuilder
|
return BCLFeatureBuilder
|
||||||
.start(new ResourceLocation(configuration.structure.location.getNamespace(),
|
.start(location, INSTANCE)
|
||||||
"feature_" + configuration.structure.location.getPath()), INSTANCE)
|
|
||||||
.decoration(GenerationStep.Decoration.SURFACE_STRUCTURES)
|
.decoration(GenerationStep.Decoration.SURFACE_STRUCTURES)
|
||||||
.oncePerChunks(onveEveryChunk)
|
.oncePerChunks(onveEveryChunk)
|
||||||
.squarePlacement()
|
.squarePlacement()
|
||||||
.distanceToTopAndBottom10()
|
.distanceToTopAndBottom10()
|
||||||
.modifier(EnvironmentScanPlacement.scanningFor(Direction.DOWN,
|
.modifier(EnvironmentScanPlacement.scanningFor(Direction.DOWN,
|
||||||
BlockPredicate.solid(),
|
BlockPredicate.solid(),
|
||||||
BlockPredicate.matchesBlocks(Blocks.AIR,
|
BlockPredicate.matchesBlocks(Blocks.AIR,
|
||||||
Blocks.WATER,
|
Blocks.WATER,
|
||||||
Blocks.LAVA),
|
Blocks.LAVA),
|
||||||
12))
|
12))
|
||||||
.modifier(BiomeFilter.biome())
|
.modifier(BiomeFilter.biome())
|
||||||
.buildAndRegister(configuration);
|
.buildAndRegister(configuration);
|
||||||
}
|
}
|
||||||
|
@ -42,12 +44,30 @@ public class TemplateFeature<FC extends TemplateFeatureConfig> extends Feature<F
|
||||||
super(codec);
|
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
|
@Override
|
||||||
public boolean place(FeaturePlaceContext<FC> ctx) {
|
public boolean place(FeaturePlaceContext<FC> ctx) {
|
||||||
return ctx.config().structure.generateIfPlaceable(ctx.level(),
|
StructureWorldNBT structure = randomStructure(ctx.config(), ctx.random());
|
||||||
ctx.origin(),
|
return structure.generateIfPlaceable(ctx.level(),
|
||||||
StructureNBT.getRandomRotation(ctx.random()),
|
ctx.origin(),
|
||||||
StructureNBT.getRandomMirror(ctx.random())
|
StructureNBT.getRandomRotation(ctx.random()),
|
||||||
);
|
StructureNBT.getRandomMirror(ctx.random())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.betterx.bclib.world.features;
|
package org.betterx.bclib.world.features;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.ExtraCodecs;
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
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.StructurePlacementType;
|
||||||
import org.betterx.bclib.world.structures.StructureWorldNBT;
|
import org.betterx.bclib.world.structures.StructureWorldNBT;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class TemplateFeatureConfig implements FeatureConfiguration {
|
public class TemplateFeatureConfig implements FeatureConfiguration {
|
||||||
public static final Codec<TemplateFeatureConfig> CODEC = RecordCodecBuilder.create((instance) -> instance
|
public static final Codec<TemplateFeatureConfig> CODEC = RecordCodecBuilder.create((instance) -> instance
|
||||||
.group(ResourceLocation.CODEC
|
.group(
|
||||||
.fieldOf("location")
|
ExtraCodecs.nonEmptyList(StructureWorldNBT.CODEC.listOf())
|
||||||
.forGetter((TemplateFeatureConfig cfg) -> cfg.structure.location),
|
.fieldOf("structures")
|
||||||
|
.forGetter((TemplateFeatureConfig ruinedPortalStructure) -> ruinedPortalStructure.structures)
|
||||||
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)
|
|
||||||
)
|
)
|
||||||
.apply(instance, TemplateFeatureConfig::new)
|
.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) {
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.betterx.bclib.world.structures;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.BlockPos.MutableBlockPos;
|
import net.minecraft.core.BlockPos.MutableBlockPos;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
import net.minecraft.world.level.ServerLevelAccessor;
|
import net.minecraft.world.level.ServerLevelAccessor;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
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 net.minecraft.world.level.levelgen.structure.BoundingBox;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import org.betterx.bclib.util.BlocksHelper;
|
import org.betterx.bclib.util.BlocksHelper;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class StructureWorldNBT extends StructureNBT {
|
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 StructurePlacementType type;
|
||||||
public final int offsetY;
|
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);
|
super(location);
|
||||||
this.offsetY = offsetY;
|
this.offsetY = offsetY;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.chance = chance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Map<String, StructureWorldNBT> READER_CACHE = Maps.newHashMap();
|
private static final Map<String, StructureWorldNBT> READER_CACHE = Maps.newHashMap();
|
||||||
|
|
||||||
public static StructureWorldNBT create(ResourceLocation location, int offsetY, StructurePlacementType type) {
|
public static StructureWorldNBT create(ResourceLocation location, int offsetY, StructurePlacementType type) {
|
||||||
String key = location.toString() + "::" + offsetY + "::" + type.getSerializedName();
|
return create(location, offsetY, type, 1.0f);
|
||||||
return READER_CACHE.computeIfAbsent(key, r -> new StructureWorldNBT(location, offsetY, type));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
public boolean generateIfPlaceable(ServerLevelAccessor level,
|
||||||
BlockPos pos,
|
BlockPos pos,
|
||||||
|
|
|
@ -55,7 +55,6 @@ public abstract class TemplateStructure extends Structure {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Config randomConfig(RandomSource random) {
|
protected Config randomConfig(RandomSource random) {
|
||||||
Config config = null;
|
|
||||||
if (this.configs.size() > 1) {
|
if (this.configs.size() > 1) {
|
||||||
final float chanceSum = configs.parallelStream().map(c -> c.chance()).reduce(0.0f, (p, c) -> p + c);
|
final float chanceSum = configs.parallelStream().map(c -> c.chance()).reduce(0.0f, (p, c) -> p + c);
|
||||||
float rnd = random.nextFloat() * chanceSum;
|
float rnd = random.nextFloat() * chanceSum;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue