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.WorldDataAPI;
|
||||||
import org.betterx.bclib.api.dataexchange.DataExchangeAPI;
|
import org.betterx.bclib.api.dataexchange.DataExchangeAPI;
|
||||||
import org.betterx.bclib.api.dataexchange.handler.autosync.*;
|
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.features.placement.PlacementModifiers;
|
||||||
import org.betterx.bclib.api.surface.rules.Conditions;
|
import org.betterx.bclib.api.surface.rules.Conditions;
|
||||||
import org.betterx.bclib.api.tag.TagAPI;
|
import org.betterx.bclib.api.tag.TagAPI;
|
||||||
|
import org.betterx.bclib.commands.CommandRegistry;
|
||||||
import org.betterx.bclib.config.Configs;
|
import org.betterx.bclib.config.Configs;
|
||||||
import org.betterx.bclib.presets.worldgen.BCLWorldPresets;
|
import org.betterx.bclib.presets.worldgen.BCLWorldPresets;
|
||||||
import org.betterx.bclib.recipes.AnvilRecipe;
|
import org.betterx.bclib.recipes.AnvilRecipe;
|
||||||
|
@ -38,6 +40,7 @@ public class BCLib implements ModInitializer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
|
Types.ensureStaticInitialization();
|
||||||
BaseRegistry.register();
|
BaseRegistry.register();
|
||||||
GeneratorOptions.init();
|
GeneratorOptions.init();
|
||||||
BaseBlockEntities.register();
|
BaseBlockEntities.register();
|
||||||
|
@ -51,6 +54,7 @@ public class BCLib implements ModInitializer {
|
||||||
BCLWorldPresets.registerPresets();
|
BCLWorldPresets.registerPresets();
|
||||||
AnvilRecipe.register();
|
AnvilRecipe.register();
|
||||||
Conditions.registerAll();
|
Conditions.registerAll();
|
||||||
|
CommandRegistry.register();
|
||||||
|
|
||||||
DataExchangeAPI.registerDescriptors(List.of(
|
DataExchangeAPI.registerDescriptors(List.of(
|
||||||
HelloClient.DESCRIPTOR,
|
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.ConfiguredFeature;
|
||||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
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.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.feature.configurations.RandomFeatureConfiguration;
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||||
|
|
||||||
import org.betterx.bclib.BCLib;
|
import org.betterx.bclib.BCLib;
|
||||||
import org.betterx.bclib.api.features.config.PlaceFacingBlockConfig;
|
import org.betterx.bclib.api.features.config.*;
|
||||||
import org.betterx.bclib.api.features.config.ScatterFeatureConfig;
|
|
||||||
import org.betterx.bclib.api.features.config.TemplateFeatureConfig;
|
|
||||||
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -37,6 +36,16 @@ public class BCLFeature {
|
||||||
public static final Feature<TemplateFeatureConfig> TEMPLATE = register(BCLib.makeID("template"),
|
public static final Feature<TemplateFeatureConfig> TEMPLATE = register(BCLib.makeID("template"),
|
||||||
new TemplateFeature(
|
new TemplateFeature(
|
||||||
TemplateFeatureConfig.CODEC));
|
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 Holder<PlacedFeature> placedFeature;
|
||||||
private final Decoration featureStep;
|
private final Decoration featureStep;
|
||||||
private final Feature<?> feature;
|
private final Feature<?> feature;
|
||||||
|
|
|
@ -6,10 +6,15 @@ import net.minecraft.data.worldgen.placement.PlacementUtils;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.util.valueproviders.IntProvider;
|
import net.minecraft.util.valueproviders.IntProvider;
|
||||||
import net.minecraft.util.valueproviders.UniformInt;
|
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.GenerationStep.Decoration;
|
||||||
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
||||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
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.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.levelgen.placement.*;
|
||||||
import net.minecraft.world.level.material.Material;
|
import net.minecraft.world.level.material.Material;
|
||||||
|
|
||||||
|
@ -24,6 +29,7 @@ public class BCLFeatureBuilder<FC extends FeatureConfiguration, F extends Featur
|
||||||
private ResourceLocation featureID;
|
private ResourceLocation featureID;
|
||||||
private Decoration decoration = Decoration.VEGETAL_DECORATION;
|
private Decoration decoration = Decoration.VEGETAL_DECORATION;
|
||||||
private final F feature;
|
private final F feature;
|
||||||
|
private BlockStateProvider provider;
|
||||||
|
|
||||||
private BCLFeatureBuilder(ResourceLocation featureID, F feature) {
|
private BCLFeatureBuilder(ResourceLocation featureID, F feature) {
|
||||||
this.featureID = featureID;
|
this.featureID = featureID;
|
||||||
|
@ -41,6 +47,26 @@ public class BCLFeatureBuilder<FC extends FeatureConfiguration, F extends Featur
|
||||||
return new BCLFeatureBuilder(featureID, feature);
|
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}.
|
* 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());
|
return modifier(Stencil.all());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BCLFeatureBuilder all() {
|
||||||
|
return modifier(All.simple());
|
||||||
|
}
|
||||||
|
|
||||||
public BCLFeatureBuilder stencilOneIn4() {
|
public BCLFeatureBuilder stencilOneIn4() {
|
||||||
return modifier(Stencil.oneIn4());
|
return modifier(Stencil.oneIn4());
|
||||||
}
|
}
|
||||||
|
@ -331,6 +361,8 @@ public class BCLFeatureBuilder<FC extends FeatureConfiguration, F extends Featur
|
||||||
* @return created {@link BCLFeature} instance.
|
* @return created {@link BCLFeature} instance.
|
||||||
*/
|
*/
|
||||||
public BCLFeature buildAndRegister() {
|
public BCLFeature buildAndRegister() {
|
||||||
|
if (this.feature == Feature.SIMPLE_BLOCK && provider != null)
|
||||||
|
return buildAndRegister((FC) new SimpleBlockConfiguration(provider));
|
||||||
return buildAndRegister((FC) FeatureConfiguration.NONE);
|
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);
|
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
|
public static BCLFeature
|
||||||
simple(ResourceLocation location,
|
simple(ResourceLocation location,
|
||||||
int searchDist,
|
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.block.state.BlockState;
|
||||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
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 com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public abstract class PlaceBlockFeatureConfig implements FeatureConfiguration {
|
public abstract class PlaceBlockFeatureConfig implements FeatureConfiguration {
|
||||||
|
|
||||||
protected static <T extends PlaceBlockFeatureConfig> RecordCodecBuilder<T, SimpleWeightedRandomList<BlockState>> blockStateCodec() {
|
protected static <T extends PlaceBlockFeatureConfig> RecordCodecBuilder<T, BlockStateProvider> blockStateCodec() {
|
||||||
return SimpleWeightedRandomList
|
return BlockStateProvider.CODEC
|
||||||
.wrappedCodec(BlockState.CODEC)
|
|
||||||
.fieldOf("entries")
|
.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) {
|
protected static SimpleWeightedRandomList<BlockState> buildWeightedList(List<BlockState> states) {
|
||||||
|
@ -44,7 +44,7 @@ public abstract class PlaceBlockFeatureConfig implements FeatureConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlaceBlockFeatureConfig(BlockState state) {
|
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) {
|
public PlaceBlockFeatureConfig(SimpleWeightedRandomList<BlockState> blocks) {
|
||||||
this.weightedList = blocks;
|
this.stateProvider = new WeightedStateProvider(blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<BlockState> getRandomBlock(RandomSource random) {
|
public PlaceBlockFeatureConfig(BlockStateProvider blocks) {
|
||||||
return this.weightedList.getRandomValue(random);
|
this.stateProvider = blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockState getRandomBlock(RandomSource random, BlockPos pos) {
|
||||||
|
return this.stateProvider.getState(random, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean place(FeaturePlaceContext<? extends PlaceBlockFeatureConfig> ctx) {
|
public boolean place(FeaturePlaceContext<? extends PlaceBlockFeatureConfig> ctx) {
|
||||||
Optional<BlockState> state = getRandomBlock(ctx.random());
|
BlockState state = getRandomBlock(ctx.random(), ctx.origin());
|
||||||
if (state.isPresent()) {
|
return placeBlock(ctx, ctx.level(), ctx.origin(), state);
|
||||||
return placeBlock(ctx, ctx.level(), ctx.origin(), state.get());
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@ import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
|
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
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.Codec;
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
@ -45,7 +47,7 @@ public class PlaceFacingBlockConfig extends PlaceBlockFeatureConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlaceFacingBlockConfig(BlockState state, List<Direction> dir) {
|
public PlaceFacingBlockConfig(BlockState state, List<Direction> dir) {
|
||||||
this(buildWeightedList(state), dir);
|
this(BlockStateProvider.simple(state), dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlaceFacingBlockConfig(List<BlockState> states, List<Direction> 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) {
|
public PlaceFacingBlockConfig(SimpleWeightedRandomList<BlockState> blocks, List<Direction> dir) {
|
||||||
|
this(new WeightedStateProvider(blocks), dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlaceFacingBlockConfig(BlockStateProvider blocks, List<Direction> dir) {
|
||||||
super(blocks);
|
super(blocks);
|
||||||
directions = dir;
|
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;
|
this.topPredicate = topPredicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IsBasin simple(BlockPredicate predicate) {
|
public static PlacementFilter simple(BlockPredicate predicate) {
|
||||||
return new IsBasin(predicate);
|
return new IsBasin(predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,10 @@ public class PlacementModifiers {
|
||||||
"stencil",
|
"stencil",
|
||||||
Stencil.CODEC);
|
Stencil.CODEC);
|
||||||
|
|
||||||
|
public static final PlacementModifierType<All> ALL = register(
|
||||||
|
"all",
|
||||||
|
All.CODEC);
|
||||||
|
|
||||||
public static final PlacementModifierType<IsBasin> IS_BASIN = register(
|
public static final PlacementModifierType<IsBasin> IS_BASIN = register(
|
||||||
"is_basin",
|
"is_basin",
|
||||||
IsBasin.CODEC);
|
IsBasin.CODEC);
|
||||||
|
|
|
@ -2,44 +2,18 @@ package org.betterx.bclib.client;
|
||||||
|
|
||||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||||
import net.minecraft.client.resources.model.UnbakedModel;
|
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.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.api.ClientModInitializer;
|
||||||
import net.fabricmc.fabric.api.client.model.*;
|
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.ModIntegrationAPI;
|
||||||
import org.betterx.bclib.api.PostInitAPI;
|
import org.betterx.bclib.api.PostInitAPI;
|
||||||
import org.betterx.bclib.api.dataexchange.DataExchangeAPI;
|
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.models.CustomModelBakery;
|
||||||
import org.betterx.bclib.client.presets.WorldPresetsUI;
|
import org.betterx.bclib.client.presets.WorldPresetsUI;
|
||||||
import org.betterx.bclib.registry.BaseBlockEntityRenders;
|
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;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class BCLibClient implements ClientModInitializer, ModelResourceProvider, ModelVariantProvider {
|
public class BCLibClient implements ClientModInitializer, ModelResourceProvider, ModelVariantProvider {
|
||||||
|
@ -73,159 +47,5 @@ public class BCLibClient implements ClientModInitializer, ModelResourceProvider,
|
||||||
: modelBakery.getBlockModel(modelId);
|
: 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