Flooded Deltas
This commit is contained in:
parent
f94a8f158f
commit
db0c89e7e7
19 changed files with 559 additions and 237 deletions
|
@ -14,9 +14,11 @@ import net.fabricmc.loader.api.FabricLoader;
|
|||
import org.betterx.bclib.api.WorldDataAPI;
|
||||
import org.betterx.bclib.api.dataexchange.DataExchangeAPI;
|
||||
import org.betterx.bclib.api.dataexchange.handler.autosync.*;
|
||||
import org.betterx.bclib.api.features.blockpredicates.Types;
|
||||
import org.betterx.bclib.api.features.placement.PlacementModifiers;
|
||||
import org.betterx.bclib.api.surface.rules.Conditions;
|
||||
import org.betterx.bclib.api.tag.TagAPI;
|
||||
import org.betterx.bclib.commands.CommandRegistry;
|
||||
import org.betterx.bclib.config.Configs;
|
||||
import org.betterx.bclib.presets.worldgen.BCLWorldPresets;
|
||||
import org.betterx.bclib.recipes.AnvilRecipe;
|
||||
|
@ -38,6 +40,7 @@ public class BCLib implements ModInitializer {
|
|||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
Types.ensureStaticInitialization();
|
||||
BaseRegistry.register();
|
||||
GeneratorOptions.init();
|
||||
BaseBlockEntities.register();
|
||||
|
@ -51,6 +54,7 @@ public class BCLib implements ModInitializer {
|
|||
BCLWorldPresets.registerPresets();
|
||||
AnvilRecipe.register();
|
||||
Conditions.registerAll();
|
||||
CommandRegistry.register();
|
||||
|
||||
DataExchangeAPI.registerDescriptors(List.of(
|
||||
HelloClient.DESCRIPTOR,
|
||||
|
|
|
@ -11,14 +11,13 @@ import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
|
|||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.RandomFeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.features.config.PlaceFacingBlockConfig;
|
||||
import org.betterx.bclib.api.features.config.ScatterFeatureConfig;
|
||||
import org.betterx.bclib.api.features.config.TemplateFeatureConfig;
|
||||
import org.betterx.bclib.api.features.config.*;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
|
@ -37,6 +36,16 @@ public class BCLFeature {
|
|||
public static final Feature<TemplateFeatureConfig> TEMPLATE = register(BCLib.makeID("template"),
|
||||
new TemplateFeature(
|
||||
TemplateFeatureConfig.CODEC));
|
||||
|
||||
public static final Feature<NoneFeatureConfiguration> MARK_POSTPROCESSING = register(BCLib.makeID(
|
||||
"mark_postprocessing"),
|
||||
new MarkPostProcessingFeature());
|
||||
|
||||
public static final Feature<SequenceFeatureConfig> SEQUENCE = register(BCLib.makeID("sequence"),
|
||||
new SequenceFeature());
|
||||
|
||||
public static final Feature<ConditionFeatureConfig> CONDITION = register(BCLib.makeID("condition"),
|
||||
new ConditionFeature());
|
||||
private final Holder<PlacedFeature> placedFeature;
|
||||
private final Decoration featureStep;
|
||||
private final Feature<?> feature;
|
||||
|
|
|
@ -6,10 +6,15 @@ import net.minecraft.data.worldgen.placement.PlacementUtils;
|
|||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.valueproviders.IntProvider;
|
||||
import net.minecraft.util.valueproviders.UniformInt;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
|
||||
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.feature.SimpleBlockFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.SimpleBlockConfiguration;
|
||||
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
|
||||
import net.minecraft.world.level.levelgen.placement.*;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
|
||||
|
@ -24,6 +29,7 @@ public class BCLFeatureBuilder<FC extends FeatureConfiguration, F extends Featur
|
|||
private ResourceLocation featureID;
|
||||
private Decoration decoration = Decoration.VEGETAL_DECORATION;
|
||||
private final F feature;
|
||||
private BlockStateProvider provider;
|
||||
|
||||
private BCLFeatureBuilder(ResourceLocation featureID, F feature) {
|
||||
this.featureID = featureID;
|
||||
|
@ -41,6 +47,26 @@ public class BCLFeatureBuilder<FC extends FeatureConfiguration, F extends Featur
|
|||
return new BCLFeatureBuilder(featureID, feature);
|
||||
}
|
||||
|
||||
public static BCLFeatureBuilder<SimpleBlockConfiguration, SimpleBlockFeature> start(ResourceLocation featureID,
|
||||
Block block) {
|
||||
return start(featureID, BlockStateProvider.simple(block));
|
||||
}
|
||||
|
||||
public static BCLFeatureBuilder<SimpleBlockConfiguration, SimpleBlockFeature> start(ResourceLocation featureID,
|
||||
BlockState state) {
|
||||
return start(featureID, BlockStateProvider.simple(state));
|
||||
}
|
||||
|
||||
public static BCLFeatureBuilder<SimpleBlockConfiguration, SimpleBlockFeature> start(ResourceLocation featureID,
|
||||
BlockStateProvider provider) {
|
||||
BCLFeatureBuilder<SimpleBlockConfiguration, SimpleBlockFeature> builder = new BCLFeatureBuilder(
|
||||
featureID,
|
||||
Feature.SIMPLE_BLOCK
|
||||
);
|
||||
builder.provider = provider;
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set generation step for the feature. Default is {@code VEGETAL_DECORATION}.
|
||||
*
|
||||
|
@ -143,6 +169,10 @@ public class BCLFeatureBuilder<FC extends FeatureConfiguration, F extends Featur
|
|||
return modifier(Stencil.all());
|
||||
}
|
||||
|
||||
public BCLFeatureBuilder all() {
|
||||
return modifier(All.simple());
|
||||
}
|
||||
|
||||
public BCLFeatureBuilder stencilOneIn4() {
|
||||
return modifier(Stencil.oneIn4());
|
||||
}
|
||||
|
@ -331,6 +361,8 @@ public class BCLFeatureBuilder<FC extends FeatureConfiguration, F extends Featur
|
|||
* @return created {@link BCLFeature} instance.
|
||||
*/
|
||||
public BCLFeature buildAndRegister() {
|
||||
if (this.feature == Feature.SIMPLE_BLOCK && provider != null)
|
||||
return buildAndRegister((FC) new SimpleBlockConfiguration(provider));
|
||||
return buildAndRegister((FC) FeatureConfiguration.NONE);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package org.betterx.bclib.api.features;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementContext;
|
||||
|
||||
import org.betterx.bclib.api.features.config.ConditionFeatureConfig;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ConditionFeature extends Feature<ConditionFeatureConfig> {
|
||||
public ConditionFeature() {
|
||||
super(ConditionFeatureConfig.CODEC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean place(FeaturePlaceContext<ConditionFeatureConfig> ctx) {
|
||||
final ConditionFeatureConfig cfg = ctx.config();
|
||||
final WorldGenLevel level = ctx.level();
|
||||
final RandomSource random = ctx.random();
|
||||
final BlockPos pos = ctx.origin();
|
||||
|
||||
final PlacementContext c = new PlacementContext(level, ctx.chunkGenerator(), Optional.empty());
|
||||
|
||||
Stream<BlockPos> stream = cfg.filter.getPositions(c, ctx.random(), pos);
|
||||
Holder<PlacedFeature> state = (stream.findFirst().isPresent() ? cfg.okFeature : cfg.failFeature.orElse(null));
|
||||
if (state != null) {
|
||||
return state.value().place(level, ctx.chunkGenerator(), random, pos);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -90,6 +90,19 @@ public class FastFeatures {
|
|||
return simple(location, searchDist, rare, feature, NoneFeatureConfiguration.NONE);
|
||||
}
|
||||
|
||||
public static BCLFeature
|
||||
single(ResourceLocation location, Block block) {
|
||||
return single(location, BlockStateProvider.simple(block));
|
||||
|
||||
}
|
||||
|
||||
public static BCLFeature
|
||||
single(ResourceLocation location, BlockStateProvider provider) {
|
||||
return BCLFeatureBuilder
|
||||
.start(location, provider)
|
||||
.buildAndRegister();
|
||||
}
|
||||
|
||||
public static BCLFeature
|
||||
simple(ResourceLocation location,
|
||||
int searchDist,
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package org.betterx.bclib.api.features;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
||||
|
||||
public class MarkPostProcessingFeature extends Feature<NoneFeatureConfiguration> {
|
||||
public MarkPostProcessingFeature() {
|
||||
super(NoneFeatureConfiguration.CODEC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> ctx) {
|
||||
BlockPos pos = ctx.origin();
|
||||
ctx.level().getChunk(pos.getX() >> 4, pos.getZ() >> 4)
|
||||
.markPosForPostprocessing(new BlockPos(pos.getX() & 15, pos.getY(), pos.getZ() & 15));
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package org.betterx.bclib.api.features;
|
||||
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||
|
||||
import org.betterx.bclib.api.features.config.SequenceFeatureConfig;
|
||||
|
||||
public class SequenceFeature extends Feature<SequenceFeatureConfig> {
|
||||
public SequenceFeature() {
|
||||
super(SequenceFeatureConfig.CODEC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean place(FeaturePlaceContext<SequenceFeatureConfig> featurePlaceContext) {
|
||||
return featurePlaceContext.config().placeAll(featurePlaceContext);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package org.betterx.bclib.api.features.blockpredicates;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
||||
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicateType;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
public class IsFullShape implements BlockPredicate {
|
||||
public static final IsFullShape HERE = new IsFullShape();
|
||||
public static final Codec<IsFullShape> CODEC = RecordCodecBuilder.create(
|
||||
instance -> instance
|
||||
.group(
|
||||
Vec3i.offsetCodec(16).optionalFieldOf("offset", Vec3i.ZERO).forGetter((p) -> p.offset)
|
||||
).apply(instance, IsFullShape::new));
|
||||
|
||||
protected final Vec3i offset;
|
||||
|
||||
private IsFullShape() {
|
||||
this(Vec3i.ZERO);
|
||||
}
|
||||
|
||||
public IsFullShape(Vec3i offset) {
|
||||
super();
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
|
||||
public BlockPredicateType<IsFullShape> type() {
|
||||
return Types.FULL_SHAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(WorldGenLevel worldGenLevel, BlockPos blockPos) {
|
||||
BlockState state = worldGenLevel.getBlockState(blockPos.offset(this.offset));
|
||||
return state.isCollisionShapeFullBlock(worldGenLevel, blockPos);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.betterx.bclib.api.features.blockpredicates;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
||||
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicateType;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import org.betterx.bclib.BCLib;
|
||||
|
||||
public class Types {
|
||||
public static final BlockPredicateType<IsFullShape> FULL_SHAPE = register(BCLib.makeID("full_shape"),
|
||||
IsFullShape.CODEC);
|
||||
|
||||
public static <P extends BlockPredicate> BlockPredicateType<P> register(ResourceLocation location, Codec<P> codec) {
|
||||
return Registry.register(Registry.BLOCK_PREDICATE_TYPES, location, () -> codec);
|
||||
}
|
||||
|
||||
public static void ensureStaticInitialization() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package org.betterx.bclib.api.features.config;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementFilter;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import org.betterx.bclib.api.features.BCLFeature;
|
||||
|
||||
import java.util.Optional;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ConditionFeatureConfig implements FeatureConfiguration {
|
||||
public static final Codec<ConditionFeatureConfig> CODEC = RecordCodecBuilder.create(instance ->
|
||||
instance.group(
|
||||
PlacementModifier.CODEC.fieldOf("filter").forGetter(p -> p.filter),
|
||||
PlacedFeature.CODEC.fieldOf("filter_pass").forGetter(p -> p.okFeature),
|
||||
PlacedFeature.CODEC.optionalFieldOf("filter_fail").forGetter(p -> p.failFeature)
|
||||
).apply(instance, ConditionFeatureConfig::new)
|
||||
);
|
||||
|
||||
public final PlacementModifier filter;
|
||||
public final Holder<PlacedFeature> okFeature;
|
||||
public final Optional<Holder<PlacedFeature>> failFeature;
|
||||
|
||||
public ConditionFeatureConfig(@NotNull PlacementFilter filter,
|
||||
@NotNull BCLFeature okFeature) {
|
||||
this(filter, okFeature.getPlacedFeature(), Optional.empty());
|
||||
|
||||
}
|
||||
|
||||
public ConditionFeatureConfig(@NotNull PlacementFilter filter,
|
||||
@NotNull BCLFeature okFeature,
|
||||
@NotNull BCLFeature failFeature) {
|
||||
this(filter, okFeature.getPlacedFeature(), Optional.of(failFeature.getPlacedFeature()));
|
||||
}
|
||||
|
||||
public ConditionFeatureConfig(@NotNull PlacementFilter filter,
|
||||
@NotNull Holder<PlacedFeature> okFeature) {
|
||||
this(filter, okFeature, Optional.empty());
|
||||
|
||||
}
|
||||
|
||||
public ConditionFeatureConfig(@NotNull PlacementFilter filter,
|
||||
@NotNull Holder<PlacedFeature> okFeature,
|
||||
@NotNull Holder<PlacedFeature> failFeature) {
|
||||
this(filter, okFeature, Optional.of(failFeature));
|
||||
}
|
||||
|
||||
protected ConditionFeatureConfig(@NotNull PlacementModifier filter,
|
||||
@NotNull Holder<PlacedFeature> okFeature,
|
||||
@NotNull Optional<Holder<PlacedFeature>> failFeature) {
|
||||
this.filter = filter;
|
||||
this.okFeature = okFeature;
|
||||
this.failFeature = failFeature;
|
||||
}
|
||||
}
|
|
@ -8,22 +8,22 @@ import net.minecraft.world.level.block.Block;
|
|||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
|
||||
import net.minecraft.world.level.levelgen.feature.stateproviders.WeightedStateProvider;
|
||||
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class PlaceBlockFeatureConfig implements FeatureConfiguration {
|
||||
|
||||
protected static <T extends PlaceBlockFeatureConfig> RecordCodecBuilder<T, SimpleWeightedRandomList<BlockState>> blockStateCodec() {
|
||||
return SimpleWeightedRandomList
|
||||
.wrappedCodec(BlockState.CODEC)
|
||||
protected static <T extends PlaceBlockFeatureConfig> RecordCodecBuilder<T, BlockStateProvider> blockStateCodec() {
|
||||
return BlockStateProvider.CODEC
|
||||
.fieldOf("entries")
|
||||
.forGetter((T o) -> o.weightedList);
|
||||
.forGetter((T o) -> o.stateProvider);
|
||||
}
|
||||
|
||||
protected final SimpleWeightedRandomList<BlockState> weightedList;
|
||||
protected final BlockStateProvider stateProvider;
|
||||
|
||||
|
||||
protected static SimpleWeightedRandomList<BlockState> buildWeightedList(List<BlockState> states) {
|
||||
|
@ -44,7 +44,7 @@ public abstract class PlaceBlockFeatureConfig implements FeatureConfiguration {
|
|||
}
|
||||
|
||||
public PlaceBlockFeatureConfig(BlockState state) {
|
||||
this(buildWeightedList(state));
|
||||
this(BlockStateProvider.simple(state));
|
||||
}
|
||||
|
||||
|
||||
|
@ -53,19 +53,20 @@ public abstract class PlaceBlockFeatureConfig implements FeatureConfiguration {
|
|||
}
|
||||
|
||||
public PlaceBlockFeatureConfig(SimpleWeightedRandomList<BlockState> blocks) {
|
||||
this.weightedList = blocks;
|
||||
this.stateProvider = new WeightedStateProvider(blocks);
|
||||
}
|
||||
|
||||
public Optional<BlockState> getRandomBlock(RandomSource random) {
|
||||
return this.weightedList.getRandomValue(random);
|
||||
public PlaceBlockFeatureConfig(BlockStateProvider blocks) {
|
||||
this.stateProvider = blocks;
|
||||
}
|
||||
|
||||
public BlockState getRandomBlock(RandomSource random, BlockPos pos) {
|
||||
return this.stateProvider.getState(random, pos);
|
||||
}
|
||||
|
||||
public boolean place(FeaturePlaceContext<? extends PlaceBlockFeatureConfig> ctx) {
|
||||
Optional<BlockState> state = getRandomBlock(ctx.random());
|
||||
if (state.isPresent()) {
|
||||
return placeBlock(ctx, ctx.level(), ctx.origin(), state.get());
|
||||
}
|
||||
return false;
|
||||
BlockState state = getRandomBlock(ctx.random(), ctx.origin());
|
||||
return placeBlock(ctx, ctx.level(), ctx.origin(), state);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ import net.minecraft.world.level.block.Block;
|
|||
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
|
||||
import net.minecraft.world.level.levelgen.feature.stateproviders.WeightedStateProvider;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
@ -45,7 +47,7 @@ public class PlaceFacingBlockConfig extends PlaceBlockFeatureConfig {
|
|||
}
|
||||
|
||||
public PlaceFacingBlockConfig(BlockState state, List<Direction> dir) {
|
||||
this(buildWeightedList(state), dir);
|
||||
this(BlockStateProvider.simple(state), dir);
|
||||
}
|
||||
|
||||
public PlaceFacingBlockConfig(List<BlockState> states, List<Direction> dir) {
|
||||
|
@ -53,6 +55,10 @@ public class PlaceFacingBlockConfig extends PlaceBlockFeatureConfig {
|
|||
}
|
||||
|
||||
public PlaceFacingBlockConfig(SimpleWeightedRandomList<BlockState> blocks, List<Direction> dir) {
|
||||
this(new WeightedStateProvider(blocks), dir);
|
||||
}
|
||||
|
||||
public PlaceFacingBlockConfig(BlockStateProvider blocks, List<Direction> dir) {
|
||||
super(blocks);
|
||||
directions = dir;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package org.betterx.bclib.api.features.config;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import org.betterx.bclib.api.features.BCLFeature;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SequenceFeatureConfig implements FeatureConfiguration {
|
||||
public static final Codec<SequenceFeatureConfig> CODEC = RecordCodecBuilder.create(instance ->
|
||||
instance.group(
|
||||
ExtraCodecs.nonEmptyList(PlacedFeature.CODEC.listOf())
|
||||
.fieldOf("features")
|
||||
.forGetter(a -> a.features)
|
||||
).apply(instance, SequenceFeatureConfig::new)
|
||||
);
|
||||
|
||||
private final List<Holder<PlacedFeature>> features;
|
||||
|
||||
public static SequenceFeatureConfig create(List<BCLFeature> features) {
|
||||
return new SequenceFeatureConfig(features.stream().map(f -> f.getPlacedFeature()).toList());
|
||||
}
|
||||
|
||||
public SequenceFeatureConfig(List<Holder<PlacedFeature>> features) {
|
||||
this.features = features;
|
||||
}
|
||||
|
||||
public boolean placeAll(FeaturePlaceContext<SequenceFeatureConfig> ctx) {
|
||||
boolean placed = false;
|
||||
for (Holder<PlacedFeature> f : features) {
|
||||
placed |= f.value().place(ctx.level(), ctx.chunkGenerator(), ctx.random(), ctx.origin());
|
||||
}
|
||||
return placed;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package org.betterx.bclib.api.features.placement;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementContext;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class All extends PlacementModifier {
|
||||
private static final All INSTANCE = new All();
|
||||
public static final Codec<All> CODEC = Codec.unit(All::new);
|
||||
|
||||
@Override
|
||||
public Stream<BlockPos> getPositions(PlacementContext placementContext,
|
||||
RandomSource randomSource,
|
||||
BlockPos blockPos) {
|
||||
return IntStream.range(0, 16 * 16 - 1).mapToObj(i -> blockPos.offset(i & 0xF, 0, i >> 4));
|
||||
}
|
||||
|
||||
public static PlacementModifier simple() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlacementModifierType<?> type() {
|
||||
return PlacementModifiers.ALL;
|
||||
}
|
||||
}
|
|
@ -38,7 +38,7 @@ public class IsBasin extends PlacementFilter {
|
|||
this.topPredicate = topPredicate;
|
||||
}
|
||||
|
||||
public static IsBasin simple(BlockPredicate predicate) {
|
||||
public static PlacementFilter simple(BlockPredicate predicate) {
|
||||
return new IsBasin(predicate);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,10 @@ public class PlacementModifiers {
|
|||
"stencil",
|
||||
Stencil.CODEC);
|
||||
|
||||
public static final PlacementModifierType<All> ALL = register(
|
||||
"all",
|
||||
All.CODEC);
|
||||
|
||||
public static final PlacementModifierType<IsBasin> IS_BASIN = register(
|
||||
"is_basin",
|
||||
IsBasin.CODEC);
|
||||
|
|
|
@ -2,44 +2,18 @@ package org.betterx.bclib.client;
|
|||
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.KeyDispatchDataCodec;
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
import net.minecraft.world.level.gameevent.GameEvent;
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorType;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.model.*;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.mojang.serialization.codecs.KeyDispatchCodec;
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.ModIntegrationAPI;
|
||||
import org.betterx.bclib.api.PostInitAPI;
|
||||
import org.betterx.bclib.api.dataexchange.DataExchangeAPI;
|
||||
import org.betterx.bclib.blocks.BaseStairsBlock;
|
||||
import org.betterx.bclib.client.models.CustomModelBakery;
|
||||
import org.betterx.bclib.client.presets.WorldPresetsUI;
|
||||
import org.betterx.bclib.registry.BaseBlockEntityRenders;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class BCLibClient implements ClientModInitializer, ModelResourceProvider, ModelVariantProvider {
|
||||
|
@ -73,159 +47,5 @@ public class BCLibClient implements ClientModInitializer, ModelResourceProvider,
|
|||
: modelBakery.getBlockModel(modelId);
|
||||
}
|
||||
|
||||
public static void dumpDatapack() {
|
||||
final RegistryAccess registryAccess = RegistryAccess.builtinCopy();
|
||||
final RegistryOps<JsonElement> registryOps = RegistryOps.create(JsonOps.INSTANCE, registryAccess);
|
||||
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||
gsonBuilder = gsonBuilder.setPrettyPrinting(); //Sets pretty formatting
|
||||
Gson gson = gsonBuilder.create();
|
||||
registryAccess.registries().forEach(r -> dumpDatapack(r, registryOps, gson));
|
||||
}
|
||||
|
||||
public static <T> void dumpDatapack(RegistryAccess.RegistryEntry<T> registry,
|
||||
RegistryOps<JsonElement> registryOps,
|
||||
Gson gson) {
|
||||
File base = new File(System.getProperty("user.dir"), "bclib_datapack_dump");
|
||||
BCLib.LOGGER.info(registry.key().toString());
|
||||
|
||||
registry
|
||||
.value()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.map(e -> e.getKey()).map(key -> registry.value().getHolder(key).get())
|
||||
.forEach(holder -> {
|
||||
File f1 = new File(base, holder.unwrapKey().get().location().getNamespace());
|
||||
f1 = new File(f1, registry.key().location().getPath());
|
||||
f1.mkdirs();
|
||||
f1 = new File(f1, holder.unwrapKey().get().location().getPath() + ".json");
|
||||
|
||||
Codec[] codec = {null};
|
||||
|
||||
BCLib.LOGGER.info(" - " + f1);
|
||||
Object obj = holder;
|
||||
|
||||
while (obj instanceof Holder<?>) {
|
||||
obj = ((Holder<?>) obj).value();
|
||||
}
|
||||
|
||||
if (obj instanceof Structure s) {
|
||||
codec[0] = s.type().codec();
|
||||
} else if (obj instanceof StructureProcessorList s) {
|
||||
codec[0] = StructureProcessorType.LIST_OBJECT_CODEC;
|
||||
} else if (obj instanceof GameEvent) {
|
||||
return;
|
||||
} else if (obj instanceof Fluid) {
|
||||
return;
|
||||
} else if (obj instanceof MobEffect) {
|
||||
return;
|
||||
} else if (obj instanceof BaseStairsBlock) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (codec[0] == null) {
|
||||
for (Method m : obj.getClass().getMethods()) {
|
||||
if (!Modifier.isStatic(m.getModifiers())) {
|
||||
m.setAccessible(true);
|
||||
if (m.getParameterTypes().length == 0) {
|
||||
if (Codec.class.isAssignableFrom(m.getReturnType())) {
|
||||
try {
|
||||
codec[0] = (Codec) m.invoke(obj);
|
||||
BCLib.LOGGER.info(" Got Codec from " + m);
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error(" !!! Unable to get Codec from " + m);
|
||||
}
|
||||
} else if (KeyDispatchCodec.class.isAssignableFrom(m.getReturnType())) {
|
||||
try {
|
||||
codec[0] = ((KeyDispatchCodec) m.invoke(obj)).codec();
|
||||
BCLib.LOGGER.info(" Got Codec from " + m);
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error(" !!! Unable to get Codec from " + m);
|
||||
}
|
||||
} else if (KeyDispatchDataCodec.class.isAssignableFrom(m.getReturnType())) {
|
||||
try {
|
||||
codec[0] = ((KeyDispatchDataCodec) m.invoke(obj)).codec();
|
||||
BCLib.LOGGER.info(" Got Codec from " + m);
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error(" !!! Unable to get Codec from " + m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (codec[0] == null) {
|
||||
//Try to find DIRECT_CODEC field
|
||||
for (Field f : obj.getClass().getDeclaredFields()) {
|
||||
if (Modifier.isStatic(f.getModifiers())) {
|
||||
if ("DIRECT_CODEC".equals(f.getName())) {
|
||||
f.setAccessible(true);
|
||||
try {
|
||||
codec[0] = (Codec) f.get(null);
|
||||
BCLib.LOGGER.info(" Got Codec from " + f);
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error(" !!! Unable to get Codec from " + f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Try to find CODEC field
|
||||
if (codec[0] == null) {
|
||||
for (Field f : obj.getClass().getDeclaredFields()) {
|
||||
if (Modifier.isStatic(f.getModifiers())) {
|
||||
if ("CODEC".equals(f.getName())) {
|
||||
try {
|
||||
f.setAccessible(true);
|
||||
codec[0] = (Codec) f.get(null);
|
||||
BCLib.LOGGER.info(" Got Codec from " + f);
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error(" !!! Unable to get Codec from " + f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Try to find any Codec field
|
||||
if (codec[0] == null) {
|
||||
for (Field f : obj.getClass().getDeclaredFields()) {
|
||||
if (Modifier.isStatic(f.getModifiers())) {
|
||||
if (Codec.class.isAssignableFrom(f.getType())) {
|
||||
f.setAccessible(true);
|
||||
try {
|
||||
codec[0] = (Codec) f.get(null);
|
||||
BCLib.LOGGER.info(" Got Codec from " + f);
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error(" !!! Unable to get Codec from " + f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (codec[0] != null) {
|
||||
try {
|
||||
var o = codec[0]
|
||||
.encodeStart(registryOps, holder.value())
|
||||
.result()
|
||||
.orElse(new JsonObject());
|
||||
|
||||
String content = gson.toJson(o);
|
||||
try {
|
||||
Files.writeString(f1.toPath(), content, StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
BCLib.LOGGER.error(" ->> Unable to WRITE: " + e.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error(" ->> Unable to encode: " + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
BCLib.LOGGER.error(" !!! Could not determine Codec");
|
||||
}
|
||||
});
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
196
src/main/java/org/betterx/bclib/commands/DumpDatapack.java
Normal file
196
src/main/java/org/betterx/bclib/commands/DumpDatapack.java
Normal file
|
@ -0,0 +1,196 @@
|
|||
package org.betterx.bclib.commands;
|
||||
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import net.minecraft.util.KeyDispatchDataCodec;
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
import net.minecraft.world.level.gameevent.GameEvent;
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorType;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.mojang.serialization.codecs.KeyDispatchCodec;
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.blocks.BaseStairsBlock;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
|
||||
public class DumpDatapack {
|
||||
static int dumpDatapack(CommandContext<CommandSourceStack> ctx) {
|
||||
dumpDatapack();
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}
|
||||
|
||||
public static void dumpDatapack() {
|
||||
final RegistryAccess registryAccess = RegistryAccess.builtinCopy();
|
||||
final RegistryOps<JsonElement> registryOps = RegistryOps.create(JsonOps.INSTANCE, registryAccess);
|
||||
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||
gsonBuilder = gsonBuilder.setPrettyPrinting(); //Sets pretty formatting
|
||||
Gson gson = gsonBuilder.create();
|
||||
registryAccess.registries().forEach(r -> dumpDatapack(r, registryOps, gson));
|
||||
}
|
||||
|
||||
private static <T> void dumpDatapack(RegistryAccess.RegistryEntry<T> registry,
|
||||
RegistryOps<JsonElement> registryOps,
|
||||
Gson gson) {
|
||||
File base = new File(System.getProperty("user.dir"), "bclib_datapack_dump");
|
||||
BCLib.LOGGER.info(registry.key().toString());
|
||||
|
||||
registry
|
||||
.value()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.map(e -> e.getKey()).map(key -> registry.value().getHolder(key).get())
|
||||
.forEach(holder -> {
|
||||
File f1 = new File(base, holder.unwrapKey().get().location().getNamespace());
|
||||
f1 = new File(f1, registry.key().location().getPath());
|
||||
f1.mkdirs();
|
||||
f1 = new File(f1, holder.unwrapKey().get().location().getPath() + ".json");
|
||||
|
||||
Codec[] codec = {null};
|
||||
|
||||
BCLib.LOGGER.info(" - " + f1);
|
||||
Object obj = holder;
|
||||
|
||||
while (obj instanceof Holder<?>) {
|
||||
obj = ((Holder<?>) obj).value();
|
||||
}
|
||||
|
||||
if (obj instanceof Structure s) {
|
||||
codec[0] = s.type().codec();
|
||||
} else if (obj instanceof StructureProcessorList s) {
|
||||
codec[0] = StructureProcessorType.LIST_OBJECT_CODEC;
|
||||
} else if (obj instanceof GameEvent) {
|
||||
return;
|
||||
} else if (obj instanceof Fluid) {
|
||||
return;
|
||||
} else if (obj instanceof MobEffect) {
|
||||
return;
|
||||
} else if (obj instanceof BaseStairsBlock) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (codec[0] == null) {
|
||||
for (Method m : obj.getClass().getMethods()) {
|
||||
if (!Modifier.isStatic(m.getModifiers())) {
|
||||
m.setAccessible(true);
|
||||
if (m.getParameterTypes().length == 0) {
|
||||
if (Codec.class.isAssignableFrom(m.getReturnType())) {
|
||||
try {
|
||||
codec[0] = (Codec) m.invoke(obj);
|
||||
BCLib.LOGGER.info(" Got Codec from " + m);
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error(" !!! Unable to get Codec from " + m);
|
||||
}
|
||||
} else if (KeyDispatchCodec.class.isAssignableFrom(m.getReturnType())) {
|
||||
try {
|
||||
codec[0] = ((KeyDispatchCodec) m.invoke(obj)).codec();
|
||||
BCLib.LOGGER.info(" Got Codec from " + m);
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error(" !!! Unable to get Codec from " + m);
|
||||
}
|
||||
} else if (KeyDispatchDataCodec.class.isAssignableFrom(m.getReturnType())) {
|
||||
try {
|
||||
codec[0] = ((KeyDispatchDataCodec) m.invoke(obj)).codec();
|
||||
BCLib.LOGGER.info(" Got Codec from " + m);
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error(" !!! Unable to get Codec from " + m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (codec[0] == null) {
|
||||
//Try to find DIRECT_CODEC field
|
||||
for (Field f : obj.getClass().getDeclaredFields()) {
|
||||
if (Modifier.isStatic(f.getModifiers())) {
|
||||
if ("DIRECT_CODEC".equals(f.getName())) {
|
||||
f.setAccessible(true);
|
||||
try {
|
||||
codec[0] = (Codec) f.get(null);
|
||||
BCLib.LOGGER.info(" Got Codec from " + f);
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error(" !!! Unable to get Codec from " + f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Try to find CODEC field
|
||||
if (codec[0] == null) {
|
||||
for (Field f : obj.getClass().getDeclaredFields()) {
|
||||
if (Modifier.isStatic(f.getModifiers())) {
|
||||
if ("CODEC".equals(f.getName())) {
|
||||
try {
|
||||
f.setAccessible(true);
|
||||
codec[0] = (Codec) f.get(null);
|
||||
BCLib.LOGGER.info(" Got Codec from " + f);
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error(" !!! Unable to get Codec from " + f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Try to find any Codec field
|
||||
if (codec[0] == null) {
|
||||
for (Field f : obj.getClass().getDeclaredFields()) {
|
||||
if (Modifier.isStatic(f.getModifiers())) {
|
||||
if (Codec.class.isAssignableFrom(f.getType())) {
|
||||
f.setAccessible(true);
|
||||
try {
|
||||
codec[0] = (Codec) f.get(null);
|
||||
BCLib.LOGGER.info(" Got Codec from " + f);
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error(" !!! Unable to get Codec from " + f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (codec[0] != null) {
|
||||
try {
|
||||
var o = codec[0]
|
||||
.encodeStart(registryOps, holder.value())
|
||||
.result()
|
||||
.orElse(new JsonObject());
|
||||
|
||||
String content = gson.toJson(o);
|
||||
try {
|
||||
Files.writeString(f1.toPath(), content, StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
BCLib.LOGGER.error(" ->> Unable to WRITE: " + e.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error(" ->> Unable to encode: " + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
BCLib.LOGGER.error(" !!! Could not determine Codec");
|
||||
}
|
||||
});
|
||||
;
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
{
|
||||
"type": "minecraft:the_nether",
|
||||
"generator": {
|
||||
"biome_source": {
|
||||
"biomes": [
|
||||
{
|
||||
"parameters": {
|
||||
"erosion": 0.0,
|
||||
"depth": 0.0,
|
||||
"weirdness": 0.0,
|
||||
"offset": 0.0,
|
||||
"temperature": 0.4,
|
||||
"humidity": 0.0,
|
||||
"continentalness": 0.0
|
||||
},
|
||||
"biome": "minecraft:crimson_forest"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"erosion": 0.0,
|
||||
"depth": 0.0,
|
||||
"weirdness": 0.0,
|
||||
"offset": 0.375,
|
||||
"temperature": 0.0,
|
||||
"humidity": 0.5,
|
||||
"continentalness": 0.0
|
||||
},
|
||||
"biome": "minecraft:warped_forest"
|
||||
}
|
||||
],
|
||||
"type": "minecraft:multi_noise"
|
||||
},
|
||||
"seed": 41,
|
||||
"settings": "minecraft:nether",
|
||||
"type": "minecraft:noise"
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue