Merge branch '1.19' of github.com:quiqueck/BCLib into 1.19
This commit is contained in:
commit
51bd560fa0
11 changed files with 414 additions and 238 deletions
|
@ -15,7 +15,6 @@ 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.BlockPlaceFeatureConfig;
|
|
||||||
import org.betterx.bclib.api.features.config.ScatterFeatureConfig;
|
import org.betterx.bclib.api.features.config.ScatterFeatureConfig;
|
||||||
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
@ -25,11 +24,7 @@ public class BCLFeature {
|
||||||
public static final Feature<ScatterFeatureConfig.OnSolid> SCATTER_ON_SOLID = register(
|
public static final Feature<ScatterFeatureConfig.OnSolid> SCATTER_ON_SOLID = register(
|
||||||
BCLib.makeID("scatter_on_solid"),
|
BCLib.makeID("scatter_on_solid"),
|
||||||
new ScatterFeature<>(ScatterFeatureConfig.OnSolid.CODEC)
|
new ScatterFeature<>(ScatterFeatureConfig.OnSolid.CODEC)
|
||||||
);
|
);
|
||||||
public static final Feature<BlockPlaceFeatureConfig> PLACE_BLOCK = register(
|
|
||||||
BCLib.makeID("place_block"),
|
|
||||||
new BlockPlaceFeature<>(BlockPlaceFeatureConfig.CODEC)
|
|
||||||
);
|
|
||||||
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;
|
||||||
|
@ -67,12 +62,12 @@ public class BCLFeature {
|
||||||
Holder<ConfiguredFeature<?, ?>> configuredFeature;
|
Holder<ConfiguredFeature<?, ?>> configuredFeature;
|
||||||
if (!BuiltinRegistries.CONFIGURED_FEATURE.containsKey(id)) {
|
if (!BuiltinRegistries.CONFIGURED_FEATURE.containsKey(id)) {
|
||||||
configuredFeature = (Holder<ConfiguredFeature<?, ?>>) (Object) FeatureUtils.register(id.toString(),
|
configuredFeature = (Holder<ConfiguredFeature<?, ?>>) (Object) FeatureUtils.register(id.toString(),
|
||||||
feature,
|
feature,
|
||||||
configuration);
|
configuration);
|
||||||
} else {
|
} else {
|
||||||
configuredFeature = BuiltinRegistries.CONFIGURED_FEATURE
|
configuredFeature = BuiltinRegistries.CONFIGURED_FEATURE
|
||||||
.getHolder(ResourceKey.create(BuiltinRegistries.CONFIGURED_FEATURE.key(),
|
.getHolder(ResourceKey.create(BuiltinRegistries.CONFIGURED_FEATURE.key(),
|
||||||
id))
|
id))
|
||||||
.orElseThrow();
|
.orElseThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +75,7 @@ public class BCLFeature {
|
||||||
return PlacementUtils.register(id.toString(), configuredFeature, modifiers);
|
return PlacementUtils.register(id.toString(), configuredFeature, modifiers);
|
||||||
} else {
|
} else {
|
||||||
return BuiltinRegistries.PLACED_FEATURE.getHolder(ResourceKey.create(BuiltinRegistries.PLACED_FEATURE.key(),
|
return BuiltinRegistries.PLACED_FEATURE.getHolder(ResourceKey.create(BuiltinRegistries.PLACED_FEATURE.key(),
|
||||||
id)).orElseThrow();
|
id)).orElseThrow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,10 +189,26 @@ public class BCLFeatureBuilder<FC extends FeatureConfiguration, F extends Featur
|
||||||
return modifier(IsEmptyAboveSampledFilter.emptyAbove4());
|
return modifier(IsEmptyAboveSampledFilter.emptyAbove4());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BCLFeatureBuilder isEmptyAbove2() {
|
||||||
|
return modifier(IsEmptyAboveSampledFilter.emptyAbove2());
|
||||||
|
}
|
||||||
|
|
||||||
public BCLFeatureBuilder isEmptyAbove() {
|
public BCLFeatureBuilder isEmptyAbove() {
|
||||||
return modifier(IsEmptyAboveSampledFilter.emptyAbove());
|
return modifier(IsEmptyAboveSampledFilter.emptyAbove());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BCLFeatureBuilder isEmptyBelow4() {
|
||||||
|
return modifier(IsEmptyAboveSampledFilter.emptyBelow4());
|
||||||
|
}
|
||||||
|
|
||||||
|
public BCLFeatureBuilder isEmptyBelow2() {
|
||||||
|
return modifier(IsEmptyAboveSampledFilter.emptyBelow2());
|
||||||
|
}
|
||||||
|
|
||||||
|
public BCLFeatureBuilder isEmptyBelow() {
|
||||||
|
return modifier(IsEmptyAboveSampledFilter.emptyBelow());
|
||||||
|
}
|
||||||
|
|
||||||
public BCLFeatureBuilder isEmptyAbove(int d1, int d2) {
|
public BCLFeatureBuilder isEmptyAbove(int d1, int d2) {
|
||||||
return modifier(new IsEmptyAboveSampledFilter(d1, d2));
|
return modifier(new IsEmptyAboveSampledFilter(d1, d2));
|
||||||
}
|
}
|
||||||
|
@ -275,6 +291,10 @@ public class BCLFeatureBuilder<FC extends FeatureConfiguration, F extends Featur
|
||||||
return modifier(new FindSolidInDirection(dir, distance));
|
return modifier(new FindSolidInDirection(dir, distance));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BCLFeatureBuilder findSolidSurface(List<Direction> dir, int distance) {
|
||||||
|
return modifier(new FindSolidInDirection(dir, distance));
|
||||||
|
}
|
||||||
|
|
||||||
public BCLFeatureBuilder heightmap() {
|
public BCLFeatureBuilder heightmap() {
|
||||||
return modifier(PlacementUtils.HEIGHTMAP);
|
return modifier(PlacementUtils.HEIGHTMAP);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
package org.betterx.bclib.api.features;
|
|
||||||
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import org.betterx.bclib.api.features.config.BlockPlaceFeatureConfig;
|
|
||||||
import org.betterx.bclib.util.BlocksHelper;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class BlockPlaceFeature<FC extends BlockPlaceFeatureConfig> extends Feature<FC> {
|
|
||||||
public BlockPlaceFeature(Codec<FC> codec) {
|
|
||||||
super(codec);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean place(FeaturePlaceContext<FC> ctx) {
|
|
||||||
Optional<BlockState> state = ctx.config().getRandomBlock(ctx.random());
|
|
||||||
if (state.isPresent())
|
|
||||||
BlocksHelper.setWithoutUpdate(ctx.level(), ctx.origin(), state.get());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -40,21 +40,21 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
Feature<T> inlineFeature) {
|
Feature<T> inlineFeature) {
|
||||||
List<Holder<PlacedFeature>> set = new ArrayList<>(2);
|
List<Holder<PlacedFeature>> set = new ArrayList<>(2);
|
||||||
if (cfg.floorChance > 0) set.add(PlacementUtils.inlinePlaced(inlineFeature,
|
if (cfg.floorChance > 0) set.add(PlacementUtils.inlinePlaced(inlineFeature,
|
||||||
cfg,
|
cfg,
|
||||||
EnvironmentScanPlacement.scanningFor(Direction.DOWN,
|
EnvironmentScanPlacement.scanningFor(Direction.DOWN,
|
||||||
BlockPredicate.solid(),
|
BlockPredicate.solid(),
|
||||||
BlockPredicate.ONLY_IN_AIR_PREDICATE,
|
BlockPredicate.ONLY_IN_AIR_PREDICATE,
|
||||||
12),
|
12),
|
||||||
RandomOffsetPlacement.vertical(ConstantInt.of(1))));
|
RandomOffsetPlacement.vertical(ConstantInt.of(1))));
|
||||||
|
|
||||||
if (cfg.floorChance < 1) {
|
if (cfg.floorChance < 1) {
|
||||||
set.add(PlacementUtils.inlinePlaced(inlineFeature,
|
set.add(PlacementUtils.inlinePlaced(inlineFeature,
|
||||||
cfg,
|
cfg,
|
||||||
EnvironmentScanPlacement.scanningFor(Direction.UP,
|
EnvironmentScanPlacement.scanningFor(Direction.UP,
|
||||||
BlockPredicate.solid(),
|
BlockPredicate.solid(),
|
||||||
BlockPredicate.ONLY_IN_AIR_PREDICATE,
|
BlockPredicate.ONLY_IN_AIR_PREDICATE,
|
||||||
12),
|
12),
|
||||||
RandomOffsetPlacement.vertical(ConstantInt.of(-1))));
|
RandomOffsetPlacement.vertical(ConstantInt.of(-1))));
|
||||||
}
|
}
|
||||||
SimpleRandomFeatureConfiguration configuration = new SimpleRandomFeatureConfiguration(HolderSet.direct(set));
|
SimpleRandomFeatureConfiguration configuration = new SimpleRandomFeatureConfiguration(HolderSet.direct(set));
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
.modifier(RandomOffsetPlacement.of(
|
.modifier(RandomOffsetPlacement.of(
|
||||||
ClampedNormalInt.of(0.0f, 2.0f, -6, 6),
|
ClampedNormalInt.of(0.0f, 2.0f, -6, 6),
|
||||||
ClampedNormalInt.of(0.0f, 0.6f, -2, 2)))
|
ClampedNormalInt.of(0.0f, 0.6f, -2, 2)))
|
||||||
.modifier(BiomeFilter.biome())
|
.onlyInBiome()
|
||||||
.buildAndRegister(configuration);
|
.buildAndRegister(configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,8 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
if (direction.isEmpty()) {
|
if (direction.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
BlockPos basePos = origin.relative(direction.get().getOpposite());
|
BlockPos basePos = origin.relative(direction.get(), -1);
|
||||||
|
|
||||||
|
|
||||||
int i = (int) (random.nextFloat() * (1 + config.maxHeight - config.minHeight) + config.minHeight);
|
int i = (int) (random.nextFloat() * (1 + config.maxHeight - config.minHeight) + config.minHeight);
|
||||||
growCenterPillar(level, origin, basePos, direction.get(), i, config, random);
|
growCenterPillar(level, origin, basePos, direction.get(), i, config, random);
|
||||||
|
@ -104,10 +105,8 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
if (config.isValidBase(level.getBlockState(basePos))) {
|
if (config.isValidBase(level.getBlockState(basePos))) {
|
||||||
final Direction surfaceDirection = direction.getOpposite();
|
final Direction surfaceDirection = direction.getOpposite();
|
||||||
BlockPos.MutableBlockPos POS = new BlockPos.MutableBlockPos();
|
BlockPos.MutableBlockPos POS = new BlockPos.MutableBlockPos();
|
||||||
basePos = basePos.relative(direction, 1);
|
|
||||||
buildPillarWithBase(level, origin, basePos, direction, centerHeight, config, random);
|
buildPillarWithBase(level, origin, basePos, direction, centerHeight, config, random);
|
||||||
|
|
||||||
|
|
||||||
final double distNormalizer = (config.maxSpread * Math.sqrt(2));
|
final double distNormalizer = (config.maxSpread * Math.sqrt(2));
|
||||||
final int tryCount = config.spreadCount.sample(random);
|
final int tryCount = config.spreadCount.sample(random);
|
||||||
for (int i = 0; i < tryCount; i++) {
|
for (int i = 0; i < tryCount; i++) {
|
||||||
|
@ -119,10 +118,10 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
int myHeight;
|
int myHeight;
|
||||||
if (config.growWhileFree) {
|
if (config.growWhileFree) {
|
||||||
myHeight = BlocksHelper.blockCount(level,
|
myHeight = BlocksHelper.blockCount(level,
|
||||||
POS,
|
POS,
|
||||||
direction,
|
direction,
|
||||||
config.maxHeight,
|
config.maxHeight,
|
||||||
state -> state.getMaterial().isReplaceable());
|
state -> state.getMaterial().isReplaceable());
|
||||||
} else {
|
} else {
|
||||||
myHeight = centerHeight;
|
myHeight = centerHeight;
|
||||||
}
|
}
|
||||||
|
@ -135,15 +134,15 @@ public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
myHeight = (int) Math.min(Math.max(
|
myHeight = (int) Math.min(Math.max(
|
||||||
config.minHeight,
|
config.minHeight,
|
||||||
config.minHeight + sizeFactor * (myHeight - config.minHeight)
|
config.minHeight + sizeFactor * (myHeight - config.minHeight)
|
||||||
), config.maxHeight);
|
), config.maxHeight);
|
||||||
|
|
||||||
buildPillarWithBase(level,
|
buildPillarWithBase(level,
|
||||||
POS,
|
POS,
|
||||||
POS.relative(direction.getOpposite()),
|
POS.relative(direction.getOpposite()),
|
||||||
direction,
|
direction,
|
||||||
myHeight,
|
myHeight,
|
||||||
config,
|
config,
|
||||||
random);
|
random);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
package org.betterx.bclib.api.features.config;
|
|
||||||
|
|
||||||
import net.minecraft.util.RandomSource;
|
|
||||||
import net.minecraft.util.random.SimpleWeightedRandomList;
|
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.DataResult;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class BlockPlaceFeatureConfig implements FeatureConfiguration {
|
|
||||||
public static final Codec<BlockPlaceFeatureConfig> CODEC = SimpleWeightedRandomList
|
|
||||||
.wrappedCodec(BlockState.CODEC)
|
|
||||||
.comapFlatMap(BlockPlaceFeatureConfig::create, cfg -> cfg.weightedList)
|
|
||||||
.fieldOf("entries").codec();
|
|
||||||
|
|
||||||
private final SimpleWeightedRandomList<BlockState> weightedList;
|
|
||||||
|
|
||||||
private static DataResult<BlockPlaceFeatureConfig> create(SimpleWeightedRandomList<BlockState> simpleWeightedRandomList) {
|
|
||||||
if (simpleWeightedRandomList.isEmpty()) {
|
|
||||||
return DataResult.error("BlockPlaceFeatureConfig with no states");
|
|
||||||
}
|
|
||||||
return DataResult.success(new BlockPlaceFeatureConfig(simpleWeightedRandomList));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static SimpleWeightedRandomList<BlockState> convert(List<BlockState> states) {
|
|
||||||
var builder = SimpleWeightedRandomList.<BlockState>builder();
|
|
||||||
for (BlockState s : states) builder.add(s, 1);
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockPlaceFeatureConfig(Block block) {
|
|
||||||
this(block.defaultBlockState());
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockPlaceFeatureConfig(BlockState state) {
|
|
||||||
this(SimpleWeightedRandomList
|
|
||||||
.<BlockState>builder()
|
|
||||||
.add(state, 1)
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockPlaceFeatureConfig(List<BlockState> states) {
|
|
||||||
this(convert(states));
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockPlaceFeatureConfig(SimpleWeightedRandomList<BlockState> blocks) {
|
|
||||||
this.weightedList = blocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<BlockState> getRandomBlock(RandomSource random) {
|
|
||||||
return this.weightedList.getRandomValue(random);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,7 +17,7 @@ import org.betterx.bclib.util.BlocksHelper;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
public interface Instancer<T extends ScatterFeatureConfig> extends Function15<BlockState, BlockState, BlockState, Optional<BlockState>, Float, Float, Float, Float, Integer, Integer, Float, Float, Float, Boolean, IntProvider, T> {
|
public interface Instancer<T extends ScatterFeatureConfig> extends Function15<BlockState, Optional<BlockState>, Optional<BlockState>, Optional<BlockState>, Float, Float, Float, Float, Integer, Integer, Float, Float, Float, Boolean, IntProvider, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public final BlockState clusterBlock;
|
public final BlockState clusterBlock;
|
||||||
|
@ -39,8 +39,8 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
public final boolean growWhileFree;
|
public final boolean growWhileFree;
|
||||||
|
|
||||||
public ScatterFeatureConfig(BlockState clusterBlock,
|
public ScatterFeatureConfig(BlockState clusterBlock,
|
||||||
BlockState tipBlock,
|
Optional<BlockState> tipBlock,
|
||||||
BlockState bottomBlock,
|
Optional<BlockState> bottomBlock,
|
||||||
Optional<BlockState> baseState,
|
Optional<BlockState> baseState,
|
||||||
float baseReplaceChance,
|
float baseReplaceChance,
|
||||||
float chanceOfDirectionalSpread,
|
float chanceOfDirectionalSpread,
|
||||||
|
@ -54,8 +54,8 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
boolean growWhileFree,
|
boolean growWhileFree,
|
||||||
IntProvider spreadCount) {
|
IntProvider spreadCount) {
|
||||||
this.clusterBlock = clusterBlock;
|
this.clusterBlock = clusterBlock;
|
||||||
this.tipBlock = tipBlock == null ? clusterBlock : tipBlock;
|
this.tipBlock = tipBlock.orElse(clusterBlock);
|
||||||
this.bottomBlock = bottomBlock == null ? clusterBlock : bottomBlock;
|
this.bottomBlock = bottomBlock.orElse(clusterBlock);
|
||||||
this.baseState = baseState;
|
this.baseState = baseState;
|
||||||
this.baseReplaceChance = baseReplaceChance;
|
this.baseReplaceChance = baseReplaceChance;
|
||||||
this.chanceOfDirectionalSpread = chanceOfDirectionalSpread;
|
this.chanceOfDirectionalSpread = chanceOfDirectionalSpread;
|
||||||
|
@ -81,77 +81,81 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
|
|
||||||
public static <T extends ScatterFeatureConfig> Codec<T> buildCodec(Instancer<T> instancer) {
|
public static <T extends ScatterFeatureConfig> Codec<T> buildCodec(Instancer<T> instancer) {
|
||||||
return RecordCodecBuilder.create((instance) -> instance
|
return RecordCodecBuilder.create((instance) -> instance
|
||||||
.group(BlockState.CODEC
|
.group(BlockState.CODEC
|
||||||
.fieldOf("cluster_block")
|
.fieldOf("cluster_block")
|
||||||
.forGetter((T cfg) -> cfg.clusterBlock),
|
.forGetter((T cfg) -> cfg.clusterBlock),
|
||||||
BlockState.CODEC
|
BlockState.CODEC
|
||||||
.fieldOf("tip_block")
|
.optionalFieldOf("tip_block")
|
||||||
.orElse(null)
|
.orElse(Optional.empty())
|
||||||
.forGetter((T cfg) -> cfg.tipBlock),
|
.forGetter((T cfg) -> cfg.tipBlock == cfg.clusterBlock
|
||||||
BlockState.CODEC
|
? Optional.empty()
|
||||||
.fieldOf("bottom_block")
|
: Optional.of(cfg.tipBlock)),
|
||||||
.orElse(null)
|
BlockState.CODEC
|
||||||
.forGetter((T cfg) -> cfg.bottomBlock),
|
.optionalFieldOf("bottom_block")
|
||||||
BlockState.CODEC
|
.orElse(Optional.empty())
|
||||||
.optionalFieldOf("base_state")
|
.forGetter((T cfg) -> cfg.bottomBlock == cfg.clusterBlock
|
||||||
.forGetter((T cfg) -> cfg.baseState),
|
? Optional.empty()
|
||||||
Codec
|
: Optional.of(cfg.bottomBlock)),
|
||||||
.floatRange(0.0F, 1.0F)
|
BlockState.CODEC
|
||||||
.fieldOf("baseReplaceChance")
|
.optionalFieldOf("base_state")
|
||||||
.orElse(1.0F)
|
.forGetter((T cfg) -> cfg.baseState),
|
||||||
.forGetter((T cfg) -> cfg.baseReplaceChance),
|
Codec
|
||||||
Codec
|
.floatRange(0.0F, 1.0F)
|
||||||
.floatRange(0.0F, 1.0F)
|
.fieldOf("baseReplaceChance")
|
||||||
.fieldOf("chance_of_directional_spread")
|
.orElse(1.0F)
|
||||||
.orElse(0.7F)
|
.forGetter((T cfg) -> cfg.baseReplaceChance),
|
||||||
.forGetter((T cfg) -> cfg.chanceOfDirectionalSpread),
|
Codec
|
||||||
Codec
|
.floatRange(0.0F, 1.0F)
|
||||||
.floatRange(0.0F, 1.0F)
|
.fieldOf("chance_of_directional_spread")
|
||||||
.fieldOf("chance_of_spread_radius2")
|
.orElse(0.7F)
|
||||||
.orElse(0.5F)
|
.forGetter((T cfg) -> cfg.chanceOfDirectionalSpread),
|
||||||
.forGetter((T cfg) -> cfg.chanceOfSpreadRadius2),
|
Codec
|
||||||
Codec
|
.floatRange(0.0F, 1.0F)
|
||||||
.floatRange(0.0F, 1.0F)
|
.fieldOf("chance_of_spread_radius2")
|
||||||
.fieldOf("chance_of_spread_radius3")
|
.orElse(0.5F)
|
||||||
.orElse(0.5F)
|
.forGetter((T cfg) -> cfg.chanceOfSpreadRadius2),
|
||||||
.forGetter((T cfg) -> cfg.chanceOfSpreadRadius3),
|
Codec
|
||||||
Codec
|
.floatRange(0.0F, 1.0F)
|
||||||
.intRange(1, 20)
|
.fieldOf("chance_of_spread_radius3")
|
||||||
.fieldOf("min_height")
|
.orElse(0.5F)
|
||||||
.orElse(2)
|
.forGetter((T cfg) -> cfg.chanceOfSpreadRadius3),
|
||||||
.forGetter((T cfg) -> cfg.minHeight),
|
Codec
|
||||||
Codec
|
.intRange(1, 20)
|
||||||
.intRange(1, 20)
|
.fieldOf("min_height")
|
||||||
.fieldOf("max_height")
|
.orElse(2)
|
||||||
.orElse(7)
|
.forGetter((T cfg) -> cfg.minHeight),
|
||||||
.forGetter((T cfg) -> cfg.maxHeight),
|
Codec
|
||||||
Codec
|
.intRange(1, 20)
|
||||||
.floatRange(0, 10)
|
.fieldOf("max_height")
|
||||||
.fieldOf("max_spread")
|
.orElse(7)
|
||||||
.orElse(2f)
|
.forGetter((T cfg) -> cfg.maxHeight),
|
||||||
.forGetter((T cfg) -> cfg.maxSpread),
|
Codec
|
||||||
Codec
|
.floatRange(0, 10)
|
||||||
.floatRange(0, 1)
|
.fieldOf("max_spread")
|
||||||
.fieldOf("size_variation")
|
.orElse(2f)
|
||||||
.orElse(0.7f)
|
.forGetter((T cfg) -> cfg.maxSpread),
|
||||||
.forGetter((T cfg) -> cfg.sizeVariation),
|
Codec
|
||||||
Codec
|
.floatRange(0, 1)
|
||||||
.floatRange(0, 1)
|
.fieldOf("size_variation")
|
||||||
.fieldOf("floor_chance")
|
.orElse(0.7f)
|
||||||
.orElse(0.5f)
|
.forGetter((T cfg) -> cfg.sizeVariation),
|
||||||
.forGetter((T cfg) -> cfg.floorChance),
|
Codec
|
||||||
Codec
|
.floatRange(0, 1)
|
||||||
.BOOL
|
.fieldOf("floor_chance")
|
||||||
.fieldOf("grow_while_empty")
|
.orElse(0.5f)
|
||||||
.orElse(false)
|
.forGetter((T cfg) -> cfg.floorChance),
|
||||||
.forGetter((T cfg) -> cfg.growWhileFree),
|
Codec
|
||||||
IntProvider.codec(0, 64)
|
.BOOL
|
||||||
.fieldOf("length")
|
.fieldOf("grow_while_empty")
|
||||||
.orElse(UniformInt.of(0, 3))
|
.orElse(false)
|
||||||
.forGetter(cfg -> cfg.spreadCount)
|
.forGetter((T cfg) -> cfg.growWhileFree),
|
||||||
)
|
IntProvider.codec(0, 64)
|
||||||
.apply(instance, instancer)
|
.fieldOf("length")
|
||||||
);
|
.orElse(UniformInt.of(0, 3))
|
||||||
|
.forGetter(cfg -> cfg.spreadCount)
|
||||||
|
)
|
||||||
|
.apply(instance, instancer)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder<T extends ScatterFeatureConfig> {
|
public static class Builder<T extends ScatterFeatureConfig> {
|
||||||
|
@ -240,10 +244,10 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
float chanceOfSpreadRadius2,
|
float chanceOfSpreadRadius2,
|
||||||
float chanceOfSpreadRadius3) {
|
float chanceOfSpreadRadius3) {
|
||||||
return generateBaseBlock(baseState,
|
return generateBaseBlock(baseState,
|
||||||
1,
|
1,
|
||||||
chanceOfDirectionalSpread,
|
chanceOfDirectionalSpread,
|
||||||
chanceOfSpreadRadius2,
|
chanceOfSpreadRadius2,
|
||||||
chanceOfSpreadRadius3);
|
chanceOfSpreadRadius3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder<T> generateBaseBlock(BlockState baseState,
|
public Builder<T> generateBaseBlock(BlockState baseState,
|
||||||
|
@ -291,8 +295,8 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
public T build() {
|
public T build() {
|
||||||
return instancer.apply(
|
return instancer.apply(
|
||||||
this.clusterBlock,
|
this.clusterBlock,
|
||||||
this.tipBlock,
|
Optional.of(this.tipBlock),
|
||||||
this.bottomBlock,
|
Optional.of(this.bottomBlock),
|
||||||
this.baseState,
|
this.baseState,
|
||||||
this.baseReplaceChance,
|
this.baseReplaceChance,
|
||||||
this.chanceOfDirectionalSpread,
|
this.chanceOfDirectionalSpread,
|
||||||
|
@ -305,7 +309,7 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
this.floorChance,
|
this.floorChance,
|
||||||
this.growWhileFree,
|
this.growWhileFree,
|
||||||
this.spreadCount
|
this.spreadCount
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,8 +317,8 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
public static final Codec<OnSolid> CODEC = buildCodec(OnSolid::new);
|
public static final Codec<OnSolid> CODEC = buildCodec(OnSolid::new);
|
||||||
|
|
||||||
public OnSolid(BlockState clusterBlock,
|
public OnSolid(BlockState clusterBlock,
|
||||||
BlockState tipBlock,
|
Optional<BlockState> tipBlock,
|
||||||
BlockState bottomBlock,
|
Optional<BlockState> bottomBlock,
|
||||||
Optional<BlockState> baseState,
|
Optional<BlockState> baseState,
|
||||||
float baseReplaceChance,
|
float baseReplaceChance,
|
||||||
float chanceOfDirectionalSpread,
|
float chanceOfDirectionalSpread,
|
||||||
|
@ -328,20 +332,20 @@ public abstract class ScatterFeatureConfig implements FeatureConfiguration {
|
||||||
boolean growWhileFree,
|
boolean growWhileFree,
|
||||||
IntProvider spreadCount) {
|
IntProvider spreadCount) {
|
||||||
super(clusterBlock,
|
super(clusterBlock,
|
||||||
tipBlock,
|
tipBlock,
|
||||||
bottomBlock,
|
bottomBlock,
|
||||||
baseState,
|
baseState,
|
||||||
baseReplaceChance,
|
baseReplaceChance,
|
||||||
chanceOfDirectionalSpread,
|
chanceOfDirectionalSpread,
|
||||||
chanceOfSpreadRadius2,
|
chanceOfSpreadRadius2,
|
||||||
chanceOfSpreadRadius3,
|
chanceOfSpreadRadius3,
|
||||||
minHeight,
|
minHeight,
|
||||||
maxHeight,
|
maxHeight,
|
||||||
maxSpread,
|
maxSpread,
|
||||||
sizeVariation,
|
sizeVariation,
|
||||||
floorChance,
|
floorChance,
|
||||||
growWhileFree,
|
growWhileFree,
|
||||||
spreadCount);
|
spreadCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.betterx.bclib.api.features.placement;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.util.ExtraCodecs;
|
||||||
import net.minecraft.util.RandomSource;
|
import net.minecraft.util.RandomSource;
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementContext;
|
import net.minecraft.world.level.levelgen.placement.PlacementContext;
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||||
|
@ -12,20 +13,30 @@ import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import org.betterx.bclib.api.tag.CommonBlockTags;
|
import org.betterx.bclib.api.tag.CommonBlockTags;
|
||||||
import org.betterx.bclib.util.BlocksHelper;
|
import org.betterx.bclib.util.BlocksHelper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class FindSolidInDirection extends PlacementModifier {
|
public class FindSolidInDirection extends PlacementModifier {
|
||||||
|
|
||||||
|
public static final Codec<FindSolidInDirection> CODEC = RecordCodecBuilder
|
||||||
|
.create((instance) -> instance.group(
|
||||||
|
ExtraCodecs.nonEmptyList(Direction.CODEC.listOf())
|
||||||
|
.fieldOf("dir")
|
||||||
|
.orElse(List.of(Direction.DOWN))
|
||||||
|
.forGetter(a -> a.direction),
|
||||||
|
Codec.intRange(1, 32).fieldOf("dist").orElse(12).forGetter((p) -> p.maxSearchDistance))
|
||||||
|
.apply(instance,
|
||||||
|
FindSolidInDirection::new));
|
||||||
protected static final FindSolidInDirection DOWN = new FindSolidInDirection(Direction.DOWN, 6);
|
protected static final FindSolidInDirection DOWN = new FindSolidInDirection(Direction.DOWN, 6);
|
||||||
protected static final FindSolidInDirection UP = new FindSolidInDirection(Direction.UP, 6);
|
protected static final FindSolidInDirection UP = new FindSolidInDirection(Direction.UP, 6);
|
||||||
public static final Codec<FindSolidInDirection> CODEC = RecordCodecBuilder.create((instance) -> instance
|
private final List<Direction> direction;
|
||||||
.group(
|
private final int maxSearchDistance;
|
||||||
Direction.CODEC.fieldOf("dir").orElse(Direction.DOWN).forGetter((p) -> p.direction),
|
|
||||||
Codec.intRange(1, 32).fieldOf("dist").orElse(12).forGetter((p) -> p.maxSearchDistance)
|
|
||||||
)
|
|
||||||
.apply(instance, FindSolidInDirection::new));
|
|
||||||
|
|
||||||
public FindSolidInDirection(Direction direction, int maxSearchDistance) {
|
public FindSolidInDirection(Direction direction, int maxSearchDistance) {
|
||||||
|
this(List.of(direction), maxSearchDistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FindSolidInDirection(List<Direction> direction, int maxSearchDistance) {
|
||||||
this.direction = direction;
|
this.direction = direction;
|
||||||
this.maxSearchDistance = maxSearchDistance;
|
this.maxSearchDistance = maxSearchDistance;
|
||||||
}
|
}
|
||||||
|
@ -48,25 +59,26 @@ public class FindSolidInDirection extends PlacementModifier {
|
||||||
return new FindSolidInDirection(Direction.UP, dist);
|
return new FindSolidInDirection(Direction.UP, dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Direction randomDirection(RandomSource random) {
|
||||||
|
return direction.get(Math.max(0, Math.min(direction.size(), random.nextInt(direction.size()))));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<BlockPos> getPositions(PlacementContext placementContext,
|
public Stream<BlockPos> getPositions(PlacementContext placementContext,
|
||||||
RandomSource randomSource,
|
RandomSource randomSource,
|
||||||
BlockPos blockPos) {
|
BlockPos blockPos) {
|
||||||
BlockPos.MutableBlockPos POS = blockPos.mutable();
|
BlockPos.MutableBlockPos POS = blockPos.mutable();
|
||||||
if (BlocksHelper.findSurroundingSurface(placementContext.getLevel(),
|
Direction d = randomDirection(randomSource);
|
||||||
POS,
|
if (BlocksHelper.findOnSurroundingSurface(placementContext.getLevel(),
|
||||||
direction,
|
POS,
|
||||||
maxSearchDistance,
|
d,
|
||||||
state -> state.is(CommonBlockTags.TERRAIN))
|
maxSearchDistance,
|
||||||
) return Stream.of(POS);
|
state -> state.is(CommonBlockTags.TERRAIN)))
|
||||||
|
return Stream.of(POS);
|
||||||
|
|
||||||
return Stream.of();
|
return Stream.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Direction direction;
|
|
||||||
private final int maxSearchDistance;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlacementModifierType<?> type() {
|
public PlacementModifierType<?> type() {
|
||||||
return PlacementModifiers.SOLID_IN_DIR;
|
return PlacementModifiers.SOLID_IN_DIR;
|
||||||
|
|
|
@ -16,21 +16,42 @@ import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
public class IsEmptyAboveSampledFilter extends PlacementFilter {
|
public class IsEmptyAboveSampledFilter extends PlacementFilter {
|
||||||
private static final IsEmptyAboveSampledFilter DEFAULT = new IsEmptyAboveSampledFilter(4, 2);
|
private static final IsEmptyAboveSampledFilter DEFAULT = new IsEmptyAboveSampledFilter(4, 2);
|
||||||
private static final IsEmptyAboveSampledFilter DEFAULT1 = new IsEmptyAboveSampledFilter(1, 1);
|
private static final IsEmptyAboveSampledFilter DEFAULT1 = new IsEmptyAboveSampledFilter(1, 1);
|
||||||
|
private static final IsEmptyAboveSampledFilter DEFAULT2 = new IsEmptyAboveSampledFilter(1, 2);
|
||||||
|
|
||||||
|
private static final IsEmptyAboveSampledFilter BELOW_DEFAULT = new IsEmptyAboveSampledFilter(-4, -2);
|
||||||
|
private static final IsEmptyAboveSampledFilter BELOW_DEFAULT1 = new IsEmptyAboveSampledFilter(-1, -1);
|
||||||
|
private static final IsEmptyAboveSampledFilter BELOW_DEFAULT2 = new IsEmptyAboveSampledFilter(-1, -2);
|
||||||
public static final Codec<IsEmptyAboveSampledFilter> CODEC = RecordCodecBuilder.create((instance) -> instance
|
public static final Codec<IsEmptyAboveSampledFilter> CODEC = RecordCodecBuilder.create((instance) -> instance
|
||||||
.group(
|
.group(
|
||||||
Codec.intRange(1, 32).fieldOf("d1").orElse(2).forGetter((p) -> p.distance1),
|
Codec.intRange(-32, 32).fieldOf("d1").orElse(4).forGetter((p) -> p.distance1),
|
||||||
Codec.intRange(1, 32).fieldOf("d2").orElse(4).forGetter((p) -> p.distance1)
|
Codec.intRange(-32, 32).fieldOf("d2").orElse(2).forGetter((p) -> p.distance1)
|
||||||
)
|
)
|
||||||
.apply(instance, IsEmptyAboveSampledFilter::new));
|
.apply(instance, IsEmptyAboveSampledFilter::new));
|
||||||
|
|
||||||
public static PlacementFilter emptyAbove4() {
|
public static PlacementFilter emptyAbove4() {
|
||||||
return DEFAULT;
|
return DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PlacementFilter emptyAbove2() {
|
||||||
|
return DEFAULT2;
|
||||||
|
}
|
||||||
|
|
||||||
public static PlacementFilter emptyAbove() {
|
public static PlacementFilter emptyAbove() {
|
||||||
return DEFAULT1;
|
return DEFAULT1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PlacementFilter emptyBelow4() {
|
||||||
|
return BELOW_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlacementFilter emptyBelow2() {
|
||||||
|
return BELOW_DEFAULT2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlacementFilter emptyBelow() {
|
||||||
|
return BELOW_DEFAULT1;
|
||||||
|
}
|
||||||
|
|
||||||
public IsEmptyAboveSampledFilter(int d1, int d2) {
|
public IsEmptyAboveSampledFilter(int d1, int d2) {
|
||||||
this.distance1 = d1;
|
this.distance1 = d1;
|
||||||
this.distance2 = d2;
|
this.distance2 = d2;
|
||||||
|
|
|
@ -2,18 +2,44 @@ 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 {
|
||||||
|
@ -30,6 +56,7 @@ public class BCLibClient implements ClientModInitializer, ModelResourceProvider,
|
||||||
ModelLoadingRegistry.INSTANCE.registerVariantProvider(rm -> this);
|
ModelLoadingRegistry.INSTANCE.registerVariantProvider(rm -> this);
|
||||||
|
|
||||||
WorldPresetsUI.setupClientside();
|
WorldPresetsUI.setupClientside();
|
||||||
|
//dumpDatapack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -45,4 +72,160 @@ public class BCLibClient implements ClientModInitializer, ModelResourceProvider,
|
||||||
? modelBakery.getItemModel(modelId)
|
? modelBakery.getItemModel(modelId)
|
||||||
: 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");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,4 +14,5 @@ public class BCLibServer implements DedicatedServerModInitializer {
|
||||||
|
|
||||||
PostInitAPI.postInit(false);
|
PostInitAPI.postInit(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,6 +221,31 @@ public class BlocksHelper {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean findOnSurroundingSurface(LevelAccessor level,
|
||||||
|
MutableBlockPos startPos,
|
||||||
|
Direction dir,
|
||||||
|
int length,
|
||||||
|
Predicate<BlockState> surface) {
|
||||||
|
for (int len = 0; len < length; len++) {
|
||||||
|
if (surface.test(level.getBlockState(startPos))) {
|
||||||
|
if (len == 0) { //we started inside of the surface
|
||||||
|
for (int lenUp = 0; lenUp < length; lenUp++) {
|
||||||
|
startPos.move(dir, -1);
|
||||||
|
if (!surface.test(level.getBlockState(startPos))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
startPos.move(dir, -1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
startPos.move(dir, 1);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean findSurroundingSurface(LevelAccessor level,
|
public static boolean findSurroundingSurface(LevelAccessor level,
|
||||||
MutableBlockPos startPos,
|
MutableBlockPos startPos,
|
||||||
Direction dir,
|
Direction dir,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue