Marked Deprecated API
This commit is contained in:
parent
5d85595c5a
commit
4367babec5
67 changed files with 2217 additions and 1721 deletions
|
@ -9,10 +9,10 @@ import org.betterx.bclib.api.v2.levelgen.LevelGenEvents;
|
||||||
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome;
|
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome;
|
||||||
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder;
|
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder;
|
||||||
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
|
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.blockpredicates.Types;
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.placement.PlacementModifiers;
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.structures.TemplatePiece;
|
import org.betterx.bclib.api.v2.levelgen.structures.TemplatePiece;
|
||||||
import org.betterx.bclib.api.v2.levelgen.surface.rules.Conditions;
|
import org.betterx.bclib.api.v2.levelgen.surface.rules.Conditions;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.blockpredicates.BlockPredicates;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers;
|
||||||
import org.betterx.bclib.commands.CommandRegistry;
|
import org.betterx.bclib.commands.CommandRegistry;
|
||||||
import org.betterx.bclib.config.Configs;
|
import org.betterx.bclib.config.Configs;
|
||||||
import org.betterx.bclib.recipes.AnvilRecipe;
|
import org.betterx.bclib.recipes.AnvilRecipe;
|
||||||
|
@ -42,7 +42,7 @@ public class BCLib implements ModInitializer {
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
LevelGenEvents.register();
|
LevelGenEvents.register();
|
||||||
WorldsTogether.onInitialize();
|
WorldsTogether.onInitialize();
|
||||||
Types.ensureStaticInitialization();
|
BlockPredicates.ensureStaticInitialization();
|
||||||
BaseRegistry.register();
|
BaseRegistry.register();
|
||||||
GeneratorOptions.init();
|
GeneratorOptions.init();
|
||||||
BaseBlockEntities.register();
|
BaseBlockEntities.register();
|
||||||
|
|
|
@ -17,6 +17,7 @@ import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.resources.RegistryOps;
|
import net.minecraft.resources.RegistryOps;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.tags.BiomeTags;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.biome.BiomeSource;
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
import net.minecraft.world.level.biome.Climate;
|
import net.minecraft.world.level.biome.Climate;
|
||||||
|
@ -135,11 +136,9 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc
|
||||||
|
|
||||||
|
|
||||||
private static boolean isValidNetherBiome(Holder<Biome> biome, ResourceLocation location) {
|
private static boolean isValidNetherBiome(Holder<Biome> biome, ResourceLocation location) {
|
||||||
return biome.unwrapKey().get().location().toString().contains("upside_down");
|
return NetherBiomes.canGenerateInNether(biome.unwrapKey().get()) ||
|
||||||
|
biome.is(BiomeTags.IS_NETHER) ||
|
||||||
// return NetherBiomes.canGenerateInNether(biome.unwrapKey().get()) ||
|
BiomeAPI.wasRegisteredAsNetherBiome(location);
|
||||||
// biome.is(BiomeTags.IS_NETHER) ||
|
|
||||||
// BiomeAPI.wasRegisteredAsNetherBiome(location);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isValidNonVanillaNetherBiome(Holder<Biome> biome, ResourceLocation location) {
|
private static boolean isValidNonVanillaNetherBiome(Holder<Biome> biome, ResourceLocation location) {
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features;
|
package org.betterx.bclib.api.v2.levelgen.features;
|
||||||
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.*;
|
import org.betterx.bclib.BCLib;
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.features.config.ScatterFeatureConfig;
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.features.features.ScatterFeature;
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.features.features.WeightedRandomSelectorFeature;
|
||||||
import org.betterx.bclib.api.v3.levelgen.features.BCLConfigureFeature;
|
import org.betterx.bclib.api.v3.levelgen.features.BCLConfigureFeature;
|
||||||
import org.betterx.bclib.api.v3.levelgen.features.BCLFeatureBuilder;
|
import org.betterx.bclib.api.v3.levelgen.features.BCLFeatureBuilder;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.UserGrowableFeature;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.config.ConditionFeatureConfig;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.config.PlaceFacingBlockConfig;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.config.SequenceFeatureConfig;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.config.TemplateFeatureConfig;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
|
@ -40,26 +48,31 @@ public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration>
|
||||||
*/
|
*/
|
||||||
@Deprecated(forRemoval = true)
|
@Deprecated(forRemoval = true)
|
||||||
public static final Feature<PlaceFacingBlockConfig> PLACE_BLOCK = org.betterx.bclib.api.v3.levelgen.features.BCLFeature.PLACE_BLOCK;
|
public static final Feature<PlaceFacingBlockConfig> PLACE_BLOCK = org.betterx.bclib.api.v3.levelgen.features.BCLFeature.PLACE_BLOCK;
|
||||||
/**
|
|
||||||
* @deprecated Replace by {@link org.betterx.bclib.api.v3.levelgen.features.BCLFeature#SCATTER_ON_SOLID}
|
|
||||||
*/
|
|
||||||
@Deprecated(forRemoval = true)
|
@Deprecated(forRemoval = true)
|
||||||
public static final Feature<ScatterFeatureConfig.OnSolid> SCATTER_ON_SOLID = org.betterx.bclib.api.v3.levelgen.features.BCLFeature.SCATTER_ON_SOLID;
|
public static final Feature<ScatterFeatureConfig.OnSolid> SCATTER_ON_SOLID = register(
|
||||||
/**
|
BCLib.makeID("scatter_on_solid"),
|
||||||
* @deprecated Replace by {@link org.betterx.bclib.api.v3.levelgen.features.BCLFeature#SCATTER_EXTEND_TOP}
|
new ScatterFeature<>(ScatterFeatureConfig.OnSolid.CODEC)
|
||||||
*/
|
);
|
||||||
|
|
||||||
@Deprecated(forRemoval = true)
|
@Deprecated(forRemoval = true)
|
||||||
public static final Feature<ScatterFeatureConfig.ExtendTop> SCATTER_EXTEND_TOP = org.betterx.bclib.api.v3.levelgen.features.BCLFeature.SCATTER_EXTEND_TOP;
|
public static final Feature<ScatterFeatureConfig.ExtendTop> SCATTER_EXTEND_TOP = register(
|
||||||
/**
|
BCLib.makeID("scatter_extend_top"),
|
||||||
* @deprecated Replace by {@link org.betterx.bclib.api.v3.levelgen.features.BCLFeature#SCATTER_EXTEND_BOTTOM}
|
new ScatterFeature<>(ScatterFeatureConfig.ExtendTop.CODEC)
|
||||||
*/
|
);
|
||||||
|
|
||||||
@Deprecated(forRemoval = true)
|
@Deprecated(forRemoval = true)
|
||||||
public static final Feature<ScatterFeatureConfig.ExtendBottom> SCATTER_EXTEND_BOTTOM = org.betterx.bclib.api.v3.levelgen.features.BCLFeature.SCATTER_EXTEND_BOTTOM;
|
public static final Feature<ScatterFeatureConfig.ExtendBottom> SCATTER_EXTEND_BOTTOM = register(
|
||||||
/**
|
BCLib.makeID("scatter_extend_bottom"),
|
||||||
* @deprecated Replace by {@link org.betterx.bclib.api.v3.levelgen.features.BCLFeature#RANDOM_SELECTOR}
|
new ScatterFeature<>(ScatterFeatureConfig.ExtendBottom.CODEC)
|
||||||
*/
|
);
|
||||||
|
|
||||||
@Deprecated(forRemoval = true)
|
@Deprecated(forRemoval = true)
|
||||||
public static final Feature<RandomFeatureConfiguration> RANDOM_SELECTOR = org.betterx.bclib.api.v3.levelgen.features.BCLFeature.RANDOM_SELECTOR;
|
public static final Feature<RandomFeatureConfiguration> RANDOM_SELECTOR = register(
|
||||||
|
BCLib.makeID("random_select"),
|
||||||
|
new WeightedRandomSelectorFeature()
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Replace by {@link org.betterx.bclib.api.v3.levelgen.features.BCLFeature#TEMPLATE}
|
* @deprecated Replace by {@link org.betterx.bclib.api.v3.levelgen.features.BCLFeature#TEMPLATE}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features;
|
package org.betterx.bclib.api.v2.levelgen.features;
|
||||||
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.placement.*;
|
import org.betterx.bclib.api.v2.levelgen.features.placement.IsEmptyAboveSampledFilter;
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.features.placement.MinEmptyFilter;
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.features.placement.Stencil;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.placement.*;
|
||||||
import org.betterx.worlds.together.tag.v3.CommonBlockTags;
|
import org.betterx.worlds.together.tag.v3.CommonBlockTags;
|
||||||
|
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
|
|
|
@ -1,257 +1,255 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features;
|
package org.betterx.bclib.api.v2.levelgen.features;
|
||||||
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.PlaceFacingBlockConfig;
|
@Deprecated(forRemoval = true)
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.ScatterFeatureConfig;
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.features.ScatterFeature;
|
|
||||||
|
|
||||||
import net.minecraft.data.worldgen.features.FeatureUtils;
|
|
||||||
import net.minecraft.data.worldgen.placement.PlacementUtils;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
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.block.state.properties.IntegerProperty;
|
|
||||||
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.RandomPatchConfiguration;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.SimpleBlockConfiguration;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.stateproviders.RandomizedIntStateProvider;
|
|
||||||
|
|
||||||
public class FastFeatures {
|
public class FastFeatures {
|
||||||
public static RandomPatchConfiguration grassPatch(BlockStateProvider stateProvider, int tries) {
|
// @Deprecated(forRemoval = true)
|
||||||
return FeatureUtils.simpleRandomPatchConfiguration(
|
// public static RandomPatchConfiguration grassPatch(BlockStateProvider stateProvider, int tries) {
|
||||||
tries,
|
// return FeatureUtils.simpleRandomPatchConfiguration(
|
||||||
PlacementUtils.onlyWhenEmpty(Feature.SIMPLE_BLOCK, new SimpleBlockConfiguration(stateProvider))
|
// tries,
|
||||||
);
|
// PlacementUtils.onlyWhenEmpty(Feature.SIMPLE_BLOCK, new SimpleBlockConfiguration(stateProvider))
|
||||||
}
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
public static BCLFeature<ScatterFeature<ScatterFeatureConfig.OnSolid>, ScatterFeatureConfig.OnSolid> vine(
|
// @Deprecated(forRemoval = true)
|
||||||
ResourceLocation location,
|
// public static BCLFeature<ScatterFeature<ScatterFeatureConfig.OnSolid>, ScatterFeatureConfig.OnSolid> vine(
|
||||||
boolean onFloor,
|
// ResourceLocation location,
|
||||||
boolean sparse,
|
// boolean onFloor,
|
||||||
ScatterFeatureConfig.Builder builder
|
// boolean sparse,
|
||||||
) {
|
// ScatterFeatureConfig.Builder builder
|
||||||
return scatter(location, onFloor, sparse, builder,
|
// ) {
|
||||||
org.betterx.bclib.api.v3.levelgen.features.BCLFeature.SCATTER_ON_SOLID
|
// return scatter(location, onFloor, sparse, builder,
|
||||||
);
|
// org.betterx.bclib.api.v3.levelgen.features.BCLFeature.SCATTER_ON_SOLID
|
||||||
}
|
// );
|
||||||
|
// }
|
||||||
public static BCLFeature scatter(
|
//
|
||||||
ResourceLocation location,
|
// @Deprecated(forRemoval = true)
|
||||||
boolean onFloor,
|
// public static BCLFeature scatter(
|
||||||
boolean sparse,
|
// ResourceLocation location,
|
||||||
ScatterFeatureConfig.Builder builder,
|
// boolean onFloor,
|
||||||
Feature scatterFeature
|
// boolean sparse,
|
||||||
) {
|
// ScatterFeatureConfig.Builder builder,
|
||||||
BCLFeatureBuilder fBuilder = BCLFeatureBuilder.start(location, scatterFeature);
|
// Feature scatterFeature
|
||||||
if (onFloor) {
|
// ) {
|
||||||
fBuilder.findSolidFloor(3).isEmptyAbove2();
|
// BCLFeatureBuilder fBuilder = BCLFeatureBuilder.start(location, scatterFeature);
|
||||||
builder.onFloor();
|
// if (onFloor) {
|
||||||
} else {
|
// fBuilder.findSolidFloor(3).isEmptyAbove2();
|
||||||
fBuilder.findSolidCeil(3).isEmptyBelow2();
|
// builder.onFloor();
|
||||||
builder.onCeil();
|
// } else {
|
||||||
}
|
// fBuilder.findSolidCeil(3).isEmptyBelow2();
|
||||||
if (sparse) {
|
// builder.onCeil();
|
||||||
fBuilder.onceEvery(3);
|
// }
|
||||||
}
|
// if (sparse) {
|
||||||
|
// fBuilder.onceEvery(3);
|
||||||
return fBuilder
|
// }
|
||||||
.is(BlockPredicate.ONLY_IN_AIR_PREDICATE)
|
//
|
||||||
.buildAndRegister(builder.build());
|
// return fBuilder
|
||||||
}
|
// .is(BlockPredicate.ONLY_IN_AIR_PREDICATE)
|
||||||
|
// .buildAndRegister(builder.build());
|
||||||
public static BCLFeature patch(ResourceLocation location, Block block) {
|
// }
|
||||||
return patch(location, block, 96, 7, 3);
|
//
|
||||||
}
|
// @Deprecated(forRemoval = true)
|
||||||
|
// public static BCLFeature patch(ResourceLocation location, Block block) {
|
||||||
public static BCLFeature
|
// return patch(location, block, 96, 7, 3);
|
||||||
patch(ResourceLocation location, Block block, int attempts, int xzSpread, int ySpread) {
|
// }
|
||||||
return patch(
|
//
|
||||||
location,
|
// @Deprecated(forRemoval = true)
|
||||||
attempts,
|
// public static BCLFeature
|
||||||
xzSpread,
|
// patch(ResourceLocation location, Block block, int attempts, int xzSpread, int ySpread) {
|
||||||
ySpread,
|
// return patch(
|
||||||
Feature.SIMPLE_BLOCK,
|
// location,
|
||||||
new SimpleBlockConfiguration(BlockStateProvider.simple(block))
|
// attempts,
|
||||||
);
|
// xzSpread,
|
||||||
}
|
// ySpread,
|
||||||
|
// Feature.SIMPLE_BLOCK,
|
||||||
public static BCLFeature
|
// new SimpleBlockConfiguration(BlockStateProvider.simple(block))
|
||||||
patch(ResourceLocation location, BlockStateProvider provider, int attempts, int xzSpread, int ySpread) {
|
// );
|
||||||
return patch(
|
// }
|
||||||
location,
|
//
|
||||||
attempts,
|
// @Deprecated(forRemoval = true)
|
||||||
xzSpread,
|
// public static BCLFeature
|
||||||
ySpread,
|
// patch(ResourceLocation location, BlockStateProvider provider, int attempts, int xzSpread, int ySpread) {
|
||||||
Feature.SIMPLE_BLOCK,
|
// return patch(
|
||||||
new SimpleBlockConfiguration(provider)
|
// location,
|
||||||
);
|
// attempts,
|
||||||
}
|
// xzSpread,
|
||||||
|
// ySpread,
|
||||||
public static BCLFeature patchWitRandomInt(ResourceLocation location, Block block, IntegerProperty prop) {
|
// Feature.SIMPLE_BLOCK,
|
||||||
return patchWitRandomInt(location, block, prop, 96, 7, 3);
|
// new SimpleBlockConfiguration(provider)
|
||||||
}
|
// );
|
||||||
|
// }
|
||||||
public static BCLFeature
|
//
|
||||||
patchWitRandomInt(
|
// @Deprecated(forRemoval = true)
|
||||||
ResourceLocation location,
|
// public static BCLFeature patchWitRandomInt(ResourceLocation location, Block block, IntegerProperty prop) {
|
||||||
Block block,
|
// return patchWitRandomInt(location, block, prop, 96, 7, 3);
|
||||||
IntegerProperty prop,
|
// }
|
||||||
int attempts,
|
//
|
||||||
int xzSpread,
|
// @Deprecated(forRemoval = true)
|
||||||
int ySpread
|
// public static BCLFeature
|
||||||
) {
|
// patchWitRandomInt(
|
||||||
return patch(
|
// ResourceLocation location,
|
||||||
location,
|
// Block block,
|
||||||
attempts,
|
// IntegerProperty prop,
|
||||||
xzSpread,
|
// int attempts,
|
||||||
ySpread,
|
// int xzSpread,
|
||||||
simple(location, ySpread, false, block.defaultBlockState(), prop)
|
// int ySpread
|
||||||
);
|
// ) {
|
||||||
}
|
// return patch(
|
||||||
|
// location,
|
||||||
public static BCLFeature
|
// attempts,
|
||||||
simple(
|
// xzSpread,
|
||||||
ResourceLocation location,
|
// ySpread,
|
||||||
int searchDist,
|
// simple(location, ySpread, false, block.defaultBlockState(), prop)
|
||||||
boolean rare,
|
// );
|
||||||
Feature<NoneFeatureConfiguration> feature
|
// }
|
||||||
) {
|
//
|
||||||
return simple(location, searchDist, rare, feature, NoneFeatureConfiguration.NONE);
|
// @Deprecated(forRemoval = true)
|
||||||
}
|
// public static BCLFeature
|
||||||
|
// simple(
|
||||||
public static BCLFeature
|
// ResourceLocation location,
|
||||||
single(ResourceLocation location, Block block) {
|
// int searchDist,
|
||||||
return single(location, BlockStateProvider.simple(block));
|
// boolean rare,
|
||||||
|
// Feature<NoneFeatureConfiguration> feature
|
||||||
}
|
// ) {
|
||||||
|
// return simple(location, searchDist, rare, feature, NoneFeatureConfiguration.NONE);
|
||||||
public static BCLFeature
|
// }
|
||||||
single(ResourceLocation location, BlockStateProvider provider) {
|
//
|
||||||
return BCLFeatureBuilder
|
// @Deprecated(forRemoval = true)
|
||||||
.start(location, provider)
|
// public static BCLFeature
|
||||||
.buildAndRegister();
|
// single(ResourceLocation location, Block block) {
|
||||||
}
|
// return single(location, BlockStateProvider.simple(block));
|
||||||
|
//
|
||||||
public static BCLFeature
|
// }
|
||||||
simple(ResourceLocation location, Feature<NoneFeatureConfiguration> feature) {
|
//
|
||||||
return BCLFeatureBuilder
|
// @Deprecated(forRemoval = true)
|
||||||
.start(location, feature)
|
// public static BCLFeature
|
||||||
.buildAndRegister();
|
// single(ResourceLocation location, BlockStateProvider provider) {
|
||||||
}
|
// return BCLFeatureBuilder
|
||||||
|
// .start(location, provider)
|
||||||
public static BCLFeature
|
// .buildAndRegister();
|
||||||
simple(
|
// }
|
||||||
ResourceLocation location,
|
//
|
||||||
int searchDist,
|
// @Deprecated(forRemoval = true)
|
||||||
boolean rare,
|
// public static BCLFeature
|
||||||
BlockState baseState,
|
// simple(ResourceLocation location, Feature<NoneFeatureConfiguration> feature) {
|
||||||
IntegerProperty property
|
// return BCLFeatureBuilder
|
||||||
) {
|
// .start(location, feature)
|
||||||
int min = Integer.MAX_VALUE;
|
// .buildAndRegister();
|
||||||
int max = Integer.MIN_VALUE;
|
// }
|
||||||
|
//
|
||||||
for (Integer i : property.getPossibleValues()) {
|
// @Deprecated(forRemoval = true)
|
||||||
if (i < min) min = i;
|
// public static BCLFeature
|
||||||
if (i > max) max = i;
|
// simple(
|
||||||
}
|
// ResourceLocation location,
|
||||||
|
// int searchDist,
|
||||||
return simple(
|
// boolean rare,
|
||||||
location,
|
// BlockState baseState,
|
||||||
searchDist,
|
// IntegerProperty property
|
||||||
rare,
|
// ) {
|
||||||
Feature.SIMPLE_BLOCK,
|
// int min = Integer.MAX_VALUE;
|
||||||
new SimpleBlockConfiguration(new RandomizedIntStateProvider(
|
// int max = Integer.MIN_VALUE;
|
||||||
BlockStateProvider.simple(baseState),
|
//
|
||||||
property,
|
// for (Integer i : property.getPossibleValues()) {
|
||||||
UniformInt.of(min, max)
|
// if (i < min) min = i;
|
||||||
))
|
// if (i > max) max = i;
|
||||||
);
|
// }
|
||||||
}
|
//
|
||||||
|
// return simple(
|
||||||
|
// location,
|
||||||
public static <FC extends FeatureConfiguration> BCLFeature<Feature<FC>, FC>
|
// searchDist,
|
||||||
simple(
|
// rare,
|
||||||
ResourceLocation location,
|
// Feature.SIMPLE_BLOCK,
|
||||||
int searchDist,
|
// new SimpleBlockConfiguration(new RandomizedIntStateProvider(
|
||||||
boolean rare,
|
// BlockStateProvider.simple(baseState),
|
||||||
Feature<FC> feature,
|
// property,
|
||||||
FC config
|
// UniformInt.of(min, max)
|
||||||
) {
|
// ))
|
||||||
BCLFeatureBuilder builder = BCLFeatureBuilder
|
// );
|
||||||
.start(location, feature)
|
// }
|
||||||
.findSolidFloor(Math.min(12, searchDist))
|
//
|
||||||
.is(BlockPredicate.ONLY_IN_AIR_PREDICATE);
|
// @Deprecated(forRemoval = true)
|
||||||
if (rare) {
|
//
|
||||||
builder.onceEvery(4);
|
// public static <FC extends FeatureConfiguration> BCLFeature<Feature<FC>, FC>
|
||||||
}
|
// simple(
|
||||||
return builder.buildAndRegister(config);
|
// ResourceLocation location,
|
||||||
}
|
// int searchDist,
|
||||||
|
// boolean rare,
|
||||||
public static BCLFeature
|
// Feature<FC> feature,
|
||||||
patch(ResourceLocation location, Feature<NoneFeatureConfiguration> feature) {
|
// FC config
|
||||||
return patch(location, 96, 7, 3, feature, FeatureConfiguration.NONE);
|
// ) {
|
||||||
}
|
// BCLFeatureBuilder builder = BCLFeatureBuilder
|
||||||
|
// .start(location, feature)
|
||||||
|
// .findSolidFloor(Math.min(12, searchDist))
|
||||||
public static BCLFeature
|
// .is(BlockPredicate.ONLY_IN_AIR_PREDICATE);
|
||||||
patch(
|
// if (rare) {
|
||||||
ResourceLocation location,
|
// builder.onceEvery(4);
|
||||||
int attempts,
|
// }
|
||||||
int xzSpread,
|
// return builder.buildAndRegister(config);
|
||||||
int ySpread,
|
// }
|
||||||
Feature<NoneFeatureConfiguration> feature
|
//
|
||||||
) {
|
// @Deprecated(forRemoval = true)
|
||||||
return patch(location, attempts, xzSpread, ySpread, feature, FeatureConfiguration.NONE);
|
// public static BCLFeature
|
||||||
}
|
// patch(ResourceLocation location, Feature<NoneFeatureConfiguration> feature) {
|
||||||
|
// return patch(location, 96, 7, 3, feature, FeatureConfiguration.NONE);
|
||||||
|
// }
|
||||||
public static <FC extends FeatureConfiguration> BCLFeature
|
//
|
||||||
patch(
|
//
|
||||||
ResourceLocation location,
|
// @Deprecated(forRemoval = true)
|
||||||
int attempts,
|
// public static BCLFeature
|
||||||
int xzSpread,
|
// patch(
|
||||||
int ySpread,
|
// ResourceLocation location,
|
||||||
Feature<FC> feature,
|
// int attempts,
|
||||||
FC config
|
// int xzSpread,
|
||||||
) {
|
// int ySpread,
|
||||||
final BCLFeature SINGLE = simple(location, ySpread, false, feature, config);
|
// Feature<NoneFeatureConfiguration> feature
|
||||||
return patch(location, attempts, xzSpread, ySpread, SINGLE);
|
// ) {
|
||||||
}
|
// return patch(location, attempts, xzSpread, ySpread, feature, FeatureConfiguration.NONE);
|
||||||
|
// }
|
||||||
public static BCLFeature
|
//
|
||||||
wallPatch(
|
// @Deprecated(forRemoval = true)
|
||||||
ResourceLocation location,
|
// public static <FC extends FeatureConfiguration> BCLFeature
|
||||||
Block block,
|
// patch(
|
||||||
int attempts,
|
// ResourceLocation location,
|
||||||
int xzSpread,
|
// int attempts,
|
||||||
int ySpread
|
// int xzSpread,
|
||||||
) {
|
// int ySpread,
|
||||||
final BCLFeature SINGLE = simple(location, ySpread, false,
|
// Feature<FC> feature,
|
||||||
org.betterx.bclib.api.v3.levelgen.features.BCLFeature.PLACE_BLOCK,
|
// FC config
|
||||||
new PlaceFacingBlockConfig(block, PlaceFacingBlockConfig.HORIZONTAL)
|
// ) {
|
||||||
);
|
// final BCLFeature SINGLE = simple(location, ySpread, false, feature, config);
|
||||||
return patch(location, attempts, xzSpread, ySpread, SINGLE);
|
// return patch(location, attempts, xzSpread, ySpread, SINGLE);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public static BCLFeature
|
// @Deprecated(forRemoval = true)
|
||||||
patch(
|
// public static BCLFeature
|
||||||
ResourceLocation location,
|
// wallPatch(
|
||||||
int attempts,
|
// ResourceLocation location,
|
||||||
int xzSpread,
|
// Block block,
|
||||||
int ySpread,
|
// int attempts,
|
||||||
BCLFeature single
|
// int xzSpread,
|
||||||
) {
|
// int ySpread
|
||||||
ResourceLocation patchLocation = new ResourceLocation(location.getNamespace(), location.getPath() + "_patch");
|
// ) {
|
||||||
|
// final BCLFeature SINGLE = simple(location, ySpread, false,
|
||||||
return BCLFeatureBuilder
|
// org.betterx.bclib.api.v3.levelgen.features.BCLFeature.PLACE_BLOCK,
|
||||||
.start(patchLocation, Feature.RANDOM_PATCH)
|
// new PlaceFacingBlockConfig(block, PlaceFacingBlockConfig.HORIZONTAL)
|
||||||
.buildAndRegister(new RandomPatchConfiguration(attempts, xzSpread, ySpread, single.getPlacedFeature()));
|
// );
|
||||||
}
|
// return patch(location, attempts, xzSpread, ySpread, SINGLE);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Deprecated(forRemoval = true)
|
||||||
|
// public static BCLFeature
|
||||||
|
// patch(
|
||||||
|
// ResourceLocation location,
|
||||||
|
// int attempts,
|
||||||
|
// int xzSpread,
|
||||||
|
// int ySpread,
|
||||||
|
// BCLFeature single
|
||||||
|
// ) {
|
||||||
|
// ResourceLocation patchLocation = new ResourceLocation(location.getNamespace(), location.getPath() + "_patch");
|
||||||
|
//
|
||||||
|
// return BCLFeatureBuilder
|
||||||
|
// .start(patchLocation, Feature.RANDOM_PATCH)
|
||||||
|
// .buildAndRegister(new RandomPatchConfiguration(attempts, xzSpread, ySpread, single.getPlacedFeature()));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features;
|
package org.betterx.bclib.api.v2.levelgen.features;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.util.RandomSource;
|
|
||||||
import net.minecraft.world.level.ServerLevelAccessor;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||||
|
|
||||||
public interface UserGrowableFeature<FC extends FeatureConfiguration> {
|
/**
|
||||||
boolean grow(
|
* @param <FC>
|
||||||
ServerLevelAccessor level,
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.UserGrowableFeature} instead
|
||||||
BlockPos pos,
|
*/
|
||||||
RandomSource random,
|
@Deprecated(forRemoval = true)
|
||||||
FC configuration
|
public interface UserGrowableFeature<FC extends FeatureConfiguration> extends org.betterx.bclib.api.v3.levelgen.features.UserGrowableFeature<FC> {
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,34 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.blockpredicates;
|
package org.betterx.bclib.api.v2.levelgen.features.blockpredicates;
|
||||||
|
|
||||||
import org.betterx.bclib.BCLib;
|
import org.betterx.bclib.api.v3.levelgen.features.blockpredicates.BlockPredicates;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.blockpredicates.IsFullShape;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import net.minecraft.core.Registry;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
||||||
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicateType;
|
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicateType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.blockpredicates.BlockPredicates} instead
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public class Types {
|
public class Types {
|
||||||
public static final BlockPredicateType<IsFullShape> FULL_SHAPE = register(
|
/**
|
||||||
BCLib.makeID("full_shape"),
|
* @deprecated Please use {@link BlockPredicates#FULL_SHAPE} instead
|
||||||
IsFullShape.CODEC
|
*/
|
||||||
);
|
@Deprecated(forRemoval = true)
|
||||||
|
public static final BlockPredicateType<IsFullShape> FULL_SHAPE = BlockPredicates.FULL_SHAPE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param location
|
||||||
|
* @param codec
|
||||||
|
* @param <P>
|
||||||
|
* @return
|
||||||
|
* @deprecated Please use {@link BlockPredicates#register(ResourceLocation, Codec)} instead
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public static <P extends BlockPredicate> BlockPredicateType<P> register(ResourceLocation location, Codec<P> codec) {
|
public static <P extends BlockPredicate> BlockPredicateType<P> register(ResourceLocation location, Codec<P> codec) {
|
||||||
return Registry.register(Registry.BLOCK_PREDICATE_TYPES, location, () -> codec);
|
return BlockPredicates.register(location, codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ensureStaticInitialization() {
|
public static void ensureStaticInitialization() {
|
||||||
|
|
|
@ -2,10 +2,7 @@ package org.betterx.bclib.api.v2.levelgen.features.config;
|
||||||
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.BCLFeature;
|
import org.betterx.bclib.api.v2.levelgen.features.BCLFeature;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
||||||
import net.minecraft.core.Holder;
|
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.PlacedFeature;
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementFilter;
|
import net.minecraft.world.level.levelgen.placement.PlacementFilter;
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||||
|
@ -13,25 +10,14 @@ import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class ConditionFeatureConfig implements FeatureConfiguration {
|
/**
|
||||||
public static final Codec<ConditionFeatureConfig> CODEC = RecordCodecBuilder.create(instance ->
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.config.ConditionFeatureConfig} instead
|
||||||
instance.group(
|
*/
|
||||||
PlacementModifier.CODEC.fieldOf("filter").forGetter(p -> p.filter),
|
@Deprecated(forRemoval = true)
|
||||||
PlacedFeature.CODEC.fieldOf("filter_pass").forGetter(p -> p.okFeature),
|
public class ConditionFeatureConfig extends org.betterx.bclib.api.v3.levelgen.features.config.ConditionFeatureConfig {
|
||||||
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) {
|
||||||
|
super(filter, okFeature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConditionFeatureConfig(
|
public ConditionFeatureConfig(
|
||||||
|
@ -39,15 +25,11 @@ public class ConditionFeatureConfig implements FeatureConfiguration {
|
||||||
@NotNull BCLFeature okFeature,
|
@NotNull BCLFeature okFeature,
|
||||||
@NotNull BCLFeature failFeature
|
@NotNull BCLFeature failFeature
|
||||||
) {
|
) {
|
||||||
this(filter, okFeature.getPlacedFeature(), Optional.of(failFeature.getPlacedFeature()));
|
super(filter, okFeature, failFeature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConditionFeatureConfig(
|
public ConditionFeatureConfig(@NotNull PlacementFilter filter, @NotNull Holder<PlacedFeature> okFeature) {
|
||||||
@NotNull PlacementFilter filter,
|
super(filter, okFeature);
|
||||||
@NotNull Holder<PlacedFeature> okFeature
|
|
||||||
) {
|
|
||||||
this(filter, okFeature, Optional.empty());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConditionFeatureConfig(
|
public ConditionFeatureConfig(
|
||||||
|
@ -55,7 +37,7 @@ public class ConditionFeatureConfig implements FeatureConfiguration {
|
||||||
@NotNull Holder<PlacedFeature> okFeature,
|
@NotNull Holder<PlacedFeature> okFeature,
|
||||||
@NotNull Holder<PlacedFeature> failFeature
|
@NotNull Holder<PlacedFeature> failFeature
|
||||||
) {
|
) {
|
||||||
this(filter, okFeature, Optional.of(failFeature));
|
super(filter, okFeature, failFeature);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ConditionFeatureConfig(
|
protected ConditionFeatureConfig(
|
||||||
|
@ -63,8 +45,6 @@ public class ConditionFeatureConfig implements FeatureConfiguration {
|
||||||
@NotNull Holder<PlacedFeature> okFeature,
|
@NotNull Holder<PlacedFeature> okFeature,
|
||||||
@NotNull Optional<Holder<PlacedFeature>> failFeature
|
@NotNull Optional<Holder<PlacedFeature>> failFeature
|
||||||
) {
|
) {
|
||||||
this.filter = filter;
|
super(filter, okFeature, failFeature);
|
||||||
this.okFeature = okFeature;
|
|
||||||
this.failFeature = failFeature;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,78 +1,32 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.config;
|
package org.betterx.bclib.api.v2.levelgen.features.config;
|
||||||
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.util.RandomSource;
|
|
||||||
import net.minecraft.util.random.SimpleWeightedRandomList;
|
import net.minecraft.util.random.SimpleWeightedRandomList;
|
||||||
import net.minecraft.world.level.WorldGenLevel;
|
|
||||||
import net.minecraft.world.level.block.Block;
|
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.configurations.FeatureConfiguration;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
|
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
|
||||||
import net.minecraft.world.level.levelgen.feature.stateproviders.WeightedStateProvider;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class PlaceBlockFeatureConfig implements FeatureConfiguration {
|
@Deprecated(forRemoval = true)
|
||||||
|
public abstract class PlaceBlockFeatureConfig extends org.betterx.bclib.api.v3.levelgen.features.config.PlaceBlockFeatureConfig {
|
||||||
protected static <T extends PlaceBlockFeatureConfig> RecordCodecBuilder<T, BlockStateProvider> blockStateCodec() {
|
|
||||||
return BlockStateProvider.CODEC
|
|
||||||
.fieldOf("entries")
|
|
||||||
.forGetter((T o) -> o.stateProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final BlockStateProvider stateProvider;
|
|
||||||
|
|
||||||
|
|
||||||
protected static SimpleWeightedRandomList<BlockState> buildWeightedList(List<BlockState> states) {
|
|
||||||
var builder = SimpleWeightedRandomList.<BlockState>builder();
|
|
||||||
for (BlockState s : states) builder.add(s, 1);
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static SimpleWeightedRandomList<BlockState> buildWeightedList(BlockState state) {
|
|
||||||
return SimpleWeightedRandomList
|
|
||||||
.<BlockState>builder()
|
|
||||||
.add(state, 1)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlaceBlockFeatureConfig(Block block) {
|
public PlaceBlockFeatureConfig(Block block) {
|
||||||
this(block.defaultBlockState());
|
super(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlaceBlockFeatureConfig(BlockState state) {
|
public PlaceBlockFeatureConfig(BlockState state) {
|
||||||
this(BlockStateProvider.simple(state));
|
super(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public PlaceBlockFeatureConfig(List<BlockState> states) {
|
public PlaceBlockFeatureConfig(List<BlockState> states) {
|
||||||
this(buildWeightedList(states));
|
super(states);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlaceBlockFeatureConfig(SimpleWeightedRandomList<BlockState> blocks) {
|
public PlaceBlockFeatureConfig(SimpleWeightedRandomList<BlockState> blocks) {
|
||||||
this.stateProvider = new WeightedStateProvider(blocks);
|
super(blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlaceBlockFeatureConfig(BlockStateProvider blocks) {
|
public PlaceBlockFeatureConfig(BlockStateProvider blocks) {
|
||||||
this.stateProvider = blocks;
|
super(blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockState getRandomBlock(RandomSource random, BlockPos pos) {
|
|
||||||
return this.stateProvider.getState(random, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean place(FeaturePlaceContext<? extends PlaceBlockFeatureConfig> ctx) {
|
|
||||||
BlockState state = getRandomBlock(ctx.random(), ctx.origin());
|
|
||||||
return placeBlock(ctx, ctx.level(), ctx.origin(), state);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected abstract boolean placeBlock(
|
|
||||||
FeaturePlaceContext<? extends PlaceBlockFeatureConfig> ctx,
|
|
||||||
WorldGenLevel level,
|
|
||||||
BlockPos pos,
|
|
||||||
BlockState targetState
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,92 +1,37 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.config;
|
package org.betterx.bclib.api.v2.levelgen.features.config;
|
||||||
|
|
||||||
import org.betterx.bclib.util.BlocksHelper;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.util.ExtraCodecs;
|
|
||||||
import net.minecraft.util.random.SimpleWeightedRandomList;
|
import net.minecraft.util.random.SimpleWeightedRandomList;
|
||||||
import net.minecraft.world.level.WorldGenLevel;
|
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
|
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
|
||||||
import net.minecraft.world.level.levelgen.feature.stateproviders.WeightedStateProvider;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class PlaceFacingBlockConfig extends PlaceBlockFeatureConfig {
|
|
||||||
public static final Codec<PlaceFacingBlockConfig> CODEC = RecordCodecBuilder.create(instance -> instance
|
|
||||||
.group(
|
|
||||||
blockStateCodec(),
|
|
||||||
ExtraCodecs.nonEmptyList(Direction.CODEC.listOf())
|
|
||||||
.fieldOf("dir")
|
|
||||||
.orElse(List.of(Direction.NORTH))
|
|
||||||
.forGetter(a -> a.directions)
|
|
||||||
).apply(instance, PlaceFacingBlockConfig::new)
|
|
||||||
);
|
|
||||||
public static final List<Direction> HORIZONTAL = List.of(
|
|
||||||
Direction.NORTH,
|
|
||||||
Direction.EAST,
|
|
||||||
Direction.WEST,
|
|
||||||
Direction.SOUTH
|
|
||||||
);
|
|
||||||
public static final List<Direction> VERTICAL = List.of(Direction.UP, Direction.DOWN);
|
|
||||||
public static final List<Direction> ALL = List.of(
|
|
||||||
Direction.NORTH,
|
|
||||||
Direction.EAST,
|
|
||||||
Direction.SOUTH,
|
|
||||||
Direction.WEST,
|
|
||||||
Direction.UP,
|
|
||||||
Direction.DOWN
|
|
||||||
);
|
|
||||||
|
|
||||||
private final List<Direction> directions;
|
/**
|
||||||
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.config.PlaceFacingBlockConfig} instead
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
public class PlaceFacingBlockConfig extends org.betterx.bclib.api.v3.levelgen.features.config.PlaceFacingBlockConfig {
|
||||||
|
|
||||||
public PlaceFacingBlockConfig(Block block, List<Direction> dir) {
|
public PlaceFacingBlockConfig(Block block, List<Direction> dir) {
|
||||||
this(block.defaultBlockState(), dir);
|
super(block, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlaceFacingBlockConfig(BlockState state, List<Direction> dir) {
|
public PlaceFacingBlockConfig(BlockState state, List<Direction> dir) {
|
||||||
this(BlockStateProvider.simple(state), dir);
|
super(state, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlaceFacingBlockConfig(List<BlockState> states, List<Direction> dir) {
|
public PlaceFacingBlockConfig(List<BlockState> states, List<Direction> dir) {
|
||||||
this(buildWeightedList(states), dir);
|
super(states, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlaceFacingBlockConfig(SimpleWeightedRandomList<BlockState> blocks, List<Direction> dir) {
|
public PlaceFacingBlockConfig(SimpleWeightedRandomList<BlockState> blocks, List<Direction> dir) {
|
||||||
this(new WeightedStateProvider(blocks), dir);
|
super(blocks, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlaceFacingBlockConfig(BlockStateProvider blocks, List<Direction> dir) {
|
public PlaceFacingBlockConfig(BlockStateProvider blocks, List<Direction> dir) {
|
||||||
super(blocks);
|
super(blocks, dir);
|
||||||
directions = dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
|
|
||||||
public boolean placeBlock(
|
|
||||||
FeaturePlaceContext<? extends PlaceBlockFeatureConfig> ctx,
|
|
||||||
WorldGenLevel level,
|
|
||||||
BlockPos pos,
|
|
||||||
BlockState targetState
|
|
||||||
) {
|
|
||||||
BlockState lookupState;
|
|
||||||
BlockPos testPos;
|
|
||||||
for (Direction dir : directions) {
|
|
||||||
testPos = pos.relative(dir.getOpposite());
|
|
||||||
lookupState = targetState.setValue(HorizontalDirectionalBlock.FACING, dir);
|
|
||||||
if (lookupState.canSurvive(level, testPos) && level.getBlockState(testPos).isAir()) {
|
|
||||||
BlocksHelper.setWithoutUpdate(level, testPos, lookupState);
|
|
||||||
//BlocksHelper.setWithoutUpdate(level, pos, level.getBlockState(pos.relative(dir.getOpposite())));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,46 +1,17 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.config;
|
package org.betterx.bclib.api.v2.levelgen.features.config;
|
||||||
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.BCLFeature;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
||||||
import net.minecraft.core.Holder;
|
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 net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SequenceFeatureConfig implements FeatureConfiguration {
|
/**
|
||||||
public static final Codec<SequenceFeatureConfig> CODEC = RecordCodecBuilder.create(instance ->
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.config.SequenceFeatureConfig instead}
|
||||||
instance.group(
|
*/
|
||||||
ExtraCodecs.nonEmptyList(PlacedFeature.CODEC.listOf())
|
@Deprecated(forRemoval = true)
|
||||||
.fieldOf("features")
|
public class SequenceFeatureConfig extends org.betterx.bclib.api.v3.levelgen.features.config.SequenceFeatureConfig {
|
||||||
.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 static SequenceFeatureConfig createSequence(List<org.betterx.bclib.api.v3.levelgen.features.BCLFeature<?, ?>> features) {
|
|
||||||
return new SequenceFeatureConfig(features.stream().map(f -> f.getPlacedFeature()).toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public SequenceFeatureConfig(List<Holder<PlacedFeature>> features) {
|
public SequenceFeatureConfig(List<Holder<PlacedFeature>> features) {
|
||||||
this.features = features;
|
super(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;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,40 +3,20 @@ package org.betterx.bclib.api.v2.levelgen.features.config;
|
||||||
import org.betterx.bclib.api.v2.levelgen.structures.StructurePlacementType;
|
import org.betterx.bclib.api.v2.levelgen.structures.StructurePlacementType;
|
||||||
import org.betterx.bclib.api.v2.levelgen.structures.StructureWorldNBT;
|
import org.betterx.bclib.api.v2.levelgen.structures.StructureWorldNBT;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.util.ExtraCodecs;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TemplateFeatureConfig implements FeatureConfiguration {
|
/**
|
||||||
public static final Codec<TemplateFeatureConfig> CODEC = RecordCodecBuilder.create((instance) -> instance
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.config.TemplateFeatureConfig} instead
|
||||||
.group(
|
*/
|
||||||
ExtraCodecs.nonEmptyList(StructureWorldNBT.CODEC.listOf())
|
public class TemplateFeatureConfig extends org.betterx.bclib.api.v3.levelgen.features.config.TemplateFeatureConfig {
|
||||||
.fieldOf("structures")
|
|
||||||
.forGetter((TemplateFeatureConfig cfg) -> cfg.structures)
|
|
||||||
)
|
|
||||||
.apply(instance, TemplateFeatureConfig::new)
|
|
||||||
);
|
|
||||||
|
|
||||||
public final List<StructureWorldNBT> structures;
|
|
||||||
|
|
||||||
public static StructureWorldNBT cfg(
|
|
||||||
ResourceLocation location,
|
|
||||||
int offsetY,
|
|
||||||
StructurePlacementType type,
|
|
||||||
float chance
|
|
||||||
) {
|
|
||||||
return StructureWorldNBT.create(location, offsetY, type, chance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TemplateFeatureConfig(ResourceLocation location, int offsetY, StructurePlacementType type) {
|
public TemplateFeatureConfig(ResourceLocation location, int offsetY, StructurePlacementType type) {
|
||||||
this(List.of(cfg(location, offsetY, type, 1.0f)));
|
super(location, offsetY, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TemplateFeatureConfig(List<StructureWorldNBT> structures) {
|
public TemplateFeatureConfig(List<StructureWorldNBT> structures) {
|
||||||
this.structures = structures;
|
super(structures);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +1,8 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.features;
|
package org.betterx.bclib.api.v2.levelgen.features.features;
|
||||||
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.ConditionFeatureConfig;
|
/**
|
||||||
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.features.ConditionFeature} instead.
|
||||||
import net.minecraft.core.BlockPos;
|
*/
|
||||||
import net.minecraft.core.Holder;
|
@Deprecated(forRemoval = true)
|
||||||
import net.minecraft.util.RandomSource;
|
public class ConditionFeature extends org.betterx.bclib.api.v3.levelgen.features.features.ConditionFeature {
|
||||||
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 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,8 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.features;
|
package org.betterx.bclib.api.v2.levelgen.features.features;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
/**
|
||||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.features.MarkPostProcessingFeature} instead.
|
||||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
*/
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
@Deprecated(forRemoval = true)
|
||||||
|
public class MarkPostProcessingFeature extends org.betterx.bclib.api.v3.levelgen.features.features.MarkPostProcessingFeature {
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.features;
|
package org.betterx.bclib.api.v2.levelgen.features.features;
|
||||||
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.PlaceBlockFeatureConfig;
|
import org.betterx.bclib.api.v3.levelgen.features.config.PlaceBlockFeatureConfig;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
|
||||||
|
|
||||||
public class PlaceBlockFeature<FC extends PlaceBlockFeatureConfig> extends Feature<FC> {
|
/**
|
||||||
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.features.PlaceBlockFeature} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
public class PlaceBlockFeature<FC extends PlaceBlockFeatureConfig> extends org.betterx.bclib.api.v3.levelgen.features.features.PlaceBlockFeature<FC> {
|
||||||
|
|
||||||
public PlaceBlockFeature(Codec<FC> codec) {
|
public PlaceBlockFeature(Codec<FC> codec) {
|
||||||
super(codec);
|
super(codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean place(FeaturePlaceContext<FC> ctx) {
|
|
||||||
return ctx.config().place(ctx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.features;
|
package org.betterx.bclib.api.v2.levelgen.features.features;
|
||||||
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.UserGrowableFeature;
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.ScatterFeatureConfig;
|
import org.betterx.bclib.api.v2.levelgen.features.config.ScatterFeatureConfig;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.UserGrowableFeature;
|
||||||
import org.betterx.bclib.util.BlocksHelper;
|
import org.betterx.bclib.util.BlocksHelper;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
|
@ -17,6 +17,7 @@ import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public class ScatterFeature<FC extends ScatterFeatureConfig>
|
public class ScatterFeature<FC extends ScatterFeatureConfig>
|
||||||
extends Feature<FC> implements UserGrowableFeature<FC> {
|
extends Feature<FC> implements UserGrowableFeature<FC> {
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,9 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.features;
|
package org.betterx.bclib.api.v2.levelgen.features.features;
|
||||||
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.SequenceFeatureConfig;
|
/**
|
||||||
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.features.SequenceFeature} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
public class SequenceFeature extends org.betterx.bclib.api.v3.levelgen.features.features.SequenceFeature {
|
||||||
|
|
||||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
|
||||||
|
|
||||||
public class SequenceFeature extends Feature<SequenceFeatureConfig> {
|
|
||||||
public SequenceFeature() {
|
|
||||||
super(SequenceFeatureConfig.CODEC);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean place(FeaturePlaceContext<SequenceFeatureConfig> featurePlaceContext) {
|
|
||||||
return featurePlaceContext.config().placeAll(featurePlaceContext);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConf
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public abstract class SurfaceFeature<T extends FeatureConfiguration> extends Feature<T> {
|
public abstract class SurfaceFeature<T extends FeatureConfiguration> extends Feature<T> {
|
||||||
public static abstract class DefaultConfiguration extends SurfaceFeature<NoneFeatureConfiguration> {
|
public static abstract class DefaultConfiguration extends SurfaceFeature<NoneFeatureConfiguration> {
|
||||||
protected DefaultConfiguration() {
|
protected DefaultConfiguration() {
|
||||||
|
|
|
@ -1,87 +1,16 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.features;
|
package org.betterx.bclib.api.v2.levelgen.features.features;
|
||||||
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.BCLFeature;
|
import org.betterx.bclib.api.v3.levelgen.features.config.TemplateFeatureConfig;
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.BCLFeatureBuilder;
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.TemplateFeatureConfig;
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.structures.StructureNBT;
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.structures.StructureWorldNBT;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.util.RandomSource;
|
|
||||||
import net.minecraft.world.level.levelgen.GenerationStep;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
|
||||||
|
|
||||||
public class TemplateFeature<FC extends TemplateFeatureConfig> extends Feature<FC> {
|
/**
|
||||||
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.features.TemplateFeature} instead.
|
||||||
public static <T extends TemplateFeatureConfig> BCLFeature createAndRegisterRare(
|
*/
|
||||||
ResourceLocation location,
|
@Deprecated(forRemoval = true)
|
||||||
TemplateFeatureConfig configuration,
|
public class TemplateFeature<FC extends TemplateFeatureConfig> extends org.betterx.bclib.api.v3.levelgen.features.features.TemplateFeature<FC> {
|
||||||
int onceEveryChunk
|
|
||||||
) {
|
|
||||||
|
|
||||||
|
|
||||||
return BCLFeatureBuilder
|
|
||||||
.start(location, org.betterx.bclib.api.v3.levelgen.features.BCLFeature.TEMPLATE)
|
|
||||||
.decoration(GenerationStep.Decoration.SURFACE_STRUCTURES)
|
|
||||||
.onceEvery(onceEveryChunk) //discard neighboring chunks
|
|
||||||
.count(16) //try 16 placements in chunk
|
|
||||||
.squarePlacement() //randomize x/z in chunk
|
|
||||||
.randomHeight10FromFloorCeil() //randomize height 10 above and 10 below max vertical
|
|
||||||
.findSolidFloor(12) //cast downward ray to find solid surface
|
|
||||||
.isEmptyAbove4() //make sure we have 4 free blocks above
|
|
||||||
.onlyInBiome() //ensure that we still are in the correct biome
|
|
||||||
|
|
||||||
.buildAndRegister(configuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T extends TemplateFeatureConfig> BCLFeature createAndRegister(
|
|
||||||
ResourceLocation location,
|
|
||||||
TemplateFeatureConfig configuration,
|
|
||||||
int count
|
|
||||||
) {
|
|
||||||
return BCLFeatureBuilder
|
|
||||||
.start(location, org.betterx.bclib.api.v3.levelgen.features.BCLFeature.TEMPLATE)
|
|
||||||
.decoration(GenerationStep.Decoration.SURFACE_STRUCTURES)
|
|
||||||
.count(count)
|
|
||||||
.squarePlacement()
|
|
||||||
.randomHeight10FromFloorCeil()
|
|
||||||
.findSolidFloor(12) //cast downward ray to find solid surface
|
|
||||||
.isEmptyAbove4()
|
|
||||||
.onlyInBiome()
|
|
||||||
.buildAndRegister(configuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TemplateFeature(Codec<FC> codec) {
|
public TemplateFeature(Codec<FC> codec) {
|
||||||
super(codec);
|
super(codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected StructureWorldNBT randomStructure(TemplateFeatureConfig cfg, RandomSource random) {
|
|
||||||
|
|
||||||
if (cfg.structures.size() > 1) {
|
|
||||||
final float chanceSum = cfg.structures.parallelStream().map(c -> c.chance).reduce(0.0f, (p, c) -> p + c);
|
|
||||||
float rnd = random.nextFloat() * chanceSum;
|
|
||||||
|
|
||||||
for (StructureWorldNBT c : cfg.structures) {
|
|
||||||
rnd -= c.chance;
|
|
||||||
if (rnd <= 0) return c;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return cfg.structures.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean place(FeaturePlaceContext<FC> ctx) {
|
|
||||||
StructureWorldNBT structure = randomStructure(ctx.config(), ctx.random());
|
|
||||||
return structure.generateIfPlaceable(
|
|
||||||
ctx.level(),
|
|
||||||
ctx.origin(),
|
|
||||||
StructureNBT.getRandomRotation(ctx.random()),
|
|
||||||
StructureNBT.getRandomMirror(ctx.random())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ import net.minecraft.world.level.levelgen.feature.WeightedPlacedFeature;
|
||||||
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;
|
||||||
|
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public class WeightedRandomSelectorFeature extends Feature<RandomFeatureConfiguration> {
|
public class WeightedRandomSelectorFeature extends Feature<RandomFeatureConfiguration> {
|
||||||
public WeightedRandomSelectorFeature() {
|
public WeightedRandomSelectorFeature() {
|
||||||
super(RandomFeatureConfiguration.CODEC);
|
super(RandomFeatureConfiguration.CODEC);
|
||||||
|
|
|
@ -1,34 +1,9 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
/**
|
||||||
import net.minecraft.core.BlockPos;
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.All} instead.
|
||||||
import net.minecraft.util.RandomSource;
|
*/
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementContext;
|
@Deprecated(forRemoval = true)
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
public class All extends org.betterx.bclib.api.v3.levelgen.features.placement.All {
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,9 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
/**
|
||||||
import net.minecraft.core.BlockPos;
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.Debug} instead.
|
||||||
import net.minecraft.util.RandomSource;
|
*/
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementContext;
|
@Deprecated(forRemoval = true)
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
public class Debug extends org.betterx.bclib.api.v3.levelgen.features.placement.Debug {
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
|
||||||
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class Debug extends PlacementModifier {
|
|
||||||
public static final Debug INSTANCE = new Debug();
|
|
||||||
public static final Codec<Debug> CODEC = Codec.unit(Debug::new);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<BlockPos> getPositions(
|
|
||||||
PlacementContext placementContext,
|
|
||||||
RandomSource randomSource,
|
|
||||||
BlockPos blockPos
|
|
||||||
) {
|
|
||||||
return Stream.of(blockPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PlacementModifierType<?> type() {
|
|
||||||
return PlacementModifiers.DEBUG;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,57 +1,14 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.util.RandomSource;
|
|
||||||
import net.minecraft.util.valueproviders.IntProvider;
|
import net.minecraft.util.valueproviders.IntProvider;
|
||||||
import net.minecraft.util.valueproviders.UniformInt;
|
|
||||||
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 java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class Extend extends PlacementModifier {
|
|
||||||
public static final Codec<Extend> CODEC = RecordCodecBuilder.create((instance) -> instance
|
|
||||||
.group(
|
|
||||||
Direction.CODEC
|
|
||||||
.fieldOf("direction")
|
|
||||||
.orElse(Direction.DOWN)
|
|
||||||
.forGetter(cfg -> cfg.direction),
|
|
||||||
IntProvider.codec(0, 16)
|
|
||||||
.fieldOf("length")
|
|
||||||
.orElse(UniformInt.of(0, 3))
|
|
||||||
.forGetter(cfg -> cfg.length)
|
|
||||||
)
|
|
||||||
.apply(instance, Extend::new));
|
|
||||||
|
|
||||||
private final Direction direction;
|
|
||||||
private final IntProvider length;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.Extend} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
public class Extend extends org.betterx.bclib.api.v3.levelgen.features.placement.Extend {
|
||||||
public Extend(Direction direction, IntProvider length) {
|
public Extend(Direction direction, IntProvider length) {
|
||||||
this.direction = direction;
|
super(direction, length);
|
||||||
this.length = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<BlockPos> getPositions(
|
|
||||||
PlacementContext placementContext,
|
|
||||||
RandomSource random,
|
|
||||||
BlockPos blockPos
|
|
||||||
) {
|
|
||||||
var builder = Stream.<BlockPos>builder();
|
|
||||||
final int count = length.sample(random);
|
|
||||||
builder.add(blockPos);
|
|
||||||
for (int y = 1; y < count + 1; y++) {
|
|
||||||
builder.add(blockPos.relative(direction, y));
|
|
||||||
}
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PlacementModifierType<?> type() {
|
|
||||||
return PlacementModifiers.EXTEND;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,134 +1,25 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
||||||
|
|
||||||
import org.betterx.bclib.util.BlocksHelper;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.core.SectionPos;
|
|
||||||
import net.minecraft.util.ExtraCodecs;
|
|
||||||
import net.minecraft.util.RandomSource;
|
|
||||||
import net.minecraft.util.valueproviders.IntProvider;
|
|
||||||
import net.minecraft.util.valueproviders.UniformInt;
|
|
||||||
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 java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class FindSolidInDirection extends PlacementModifier {
|
/**
|
||||||
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.FindSolidInDirection} instead.
|
||||||
public static final Codec<FindSolidInDirection> CODEC = RecordCodecBuilder
|
*/
|
||||||
.create((instance) -> instance.group(
|
@Deprecated(forRemoval = true)
|
||||||
ExtraCodecs.nonEmptyList(Direction.CODEC.listOf())
|
public class FindSolidInDirection extends org.betterx.bclib.api.v3.levelgen.features.placement.FindSolidInDirection {
|
||||||
.fieldOf("dir")
|
|
||||||
.orElse(List.of(Direction.DOWN))
|
|
||||||
.forGetter(a -> a.direction),
|
|
||||||
Codec.intRange(1, 32).fieldOf("dist").orElse(12).forGetter((p) -> p.maxSearchDistance),
|
|
||||||
Codec.BOOL.fieldOf("random:select").orElse(true).forGetter(p -> p.randomSelect)
|
|
||||||
)
|
|
||||||
.apply(
|
|
||||||
instance,
|
|
||||||
FindSolidInDirection::new
|
|
||||||
));
|
|
||||||
protected static final FindSolidInDirection DOWN = new FindSolidInDirection(Direction.DOWN, 6);
|
|
||||||
protected static final FindSolidInDirection UP = new FindSolidInDirection(Direction.UP, 6);
|
|
||||||
private final List<Direction> direction;
|
|
||||||
private final int maxSearchDistance;
|
|
||||||
|
|
||||||
private final boolean randomSelect;
|
|
||||||
private final IntProvider provider;
|
|
||||||
|
|
||||||
|
|
||||||
public FindSolidInDirection(Direction direction, int maxSearchDistance) {
|
public FindSolidInDirection(Direction direction, int maxSearchDistance) {
|
||||||
this(List.of(direction), maxSearchDistance, false);
|
super(direction, maxSearchDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FindSolidInDirection(List<Direction> direction, int maxSearchDistance) {
|
public FindSolidInDirection(List<Direction> direction, int maxSearchDistance) {
|
||||||
this(direction, maxSearchDistance, direction.size() > 1);
|
super(direction, maxSearchDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FindSolidInDirection(List<Direction> direction, int maxSearchDistance, boolean randomSelect) {
|
public FindSolidInDirection(List<Direction> direction, int maxSearchDistance, boolean randomSelect) {
|
||||||
this.direction = direction;
|
super(direction, maxSearchDistance, randomSelect);
|
||||||
this.maxSearchDistance = maxSearchDistance;
|
|
||||||
this.provider = UniformInt.of(0, direction.size() - 1);
|
|
||||||
this.randomSelect = randomSelect;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PlacementModifier down() {
|
|
||||||
return DOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PlacementModifier up() {
|
|
||||||
return UP;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PlacementModifier down(int dist) {
|
|
||||||
if (dist == DOWN.maxSearchDistance) return DOWN;
|
|
||||||
return new FindSolidInDirection(Direction.DOWN, dist);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PlacementModifier up(int dist) {
|
|
||||||
if (dist == UP.maxSearchDistance) return UP;
|
|
||||||
return new FindSolidInDirection(Direction.UP, dist);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Direction randomDirection(RandomSource random) {
|
|
||||||
return direction.get(provider.sample(random));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<BlockPos> getPositions(
|
|
||||||
PlacementContext placementContext,
|
|
||||||
RandomSource randomSource,
|
|
||||||
BlockPos blockPos
|
|
||||||
) {
|
|
||||||
var builder = Stream.<BlockPos>builder();
|
|
||||||
if (randomSelect) {
|
|
||||||
submitSingle(placementContext, blockPos, builder, randomDirection(randomSource));
|
|
||||||
} else {
|
|
||||||
for (Direction d : direction) {
|
|
||||||
submitSingle(placementContext, blockPos, builder, d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void submitSingle(
|
|
||||||
PlacementContext placementContext,
|
|
||||||
BlockPos blockPos,
|
|
||||||
Stream.Builder<BlockPos> builder,
|
|
||||||
Direction d
|
|
||||||
) {
|
|
||||||
int searchDist;
|
|
||||||
BlockPos.MutableBlockPos POS = blockPos.mutable();
|
|
||||||
if (d == Direction.EAST) { //+x
|
|
||||||
searchDist = Math.min(maxSearchDistance, 15 - SectionPos.sectionRelative(blockPos.getX()));
|
|
||||||
} else if (d == Direction.WEST) { //-x
|
|
||||||
searchDist = Math.min(maxSearchDistance, SectionPos.sectionRelative(blockPos.getX()));
|
|
||||||
} else if (d == Direction.SOUTH) { //+z
|
|
||||||
searchDist = Math.min(maxSearchDistance, 15 - SectionPos.sectionRelative(blockPos.getZ()));
|
|
||||||
} else if (d == Direction.NORTH) { //-z
|
|
||||||
searchDist = Math.min(maxSearchDistance, SectionPos.sectionRelative(blockPos.getZ()));
|
|
||||||
} else {
|
|
||||||
searchDist = maxSearchDistance;
|
|
||||||
}
|
|
||||||
if (BlocksHelper.findOnSurroundingSurface(
|
|
||||||
placementContext.getLevel(),
|
|
||||||
POS,
|
|
||||||
d,
|
|
||||||
searchDist,
|
|
||||||
BlocksHelper::isTerrain
|
|
||||||
)) {
|
|
||||||
builder.add(POS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PlacementModifierType<?> type() {
|
|
||||||
return PlacementModifiers.SOLID_IN_DIR;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,47 +1,16 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.util.ExtraCodecs;
|
|
||||||
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.PlacementModifier;
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class ForAll extends PlacementModifier {
|
/**
|
||||||
public static final Codec<ForAll> CODEC = RecordCodecBuilder.create(instance -> instance
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.ForAll} instead.
|
||||||
.group(
|
*/
|
||||||
ExtraCodecs.nonEmptyList(PlacementModifier.CODEC.listOf())
|
@Deprecated(forRemoval = true)
|
||||||
.fieldOf("modifiers")
|
public class ForAll extends org.betterx.bclib.api.v3.levelgen.features.placement.ForAll {
|
||||||
.forGetter(a -> a.modifiers)
|
|
||||||
)
|
|
||||||
.apply(instance, ForAll::new));
|
|
||||||
|
|
||||||
private final List<PlacementModifier> modifiers;
|
|
||||||
|
|
||||||
public ForAll(List<PlacementModifier> modifiers) {
|
public ForAll(List<PlacementModifier> modifiers) {
|
||||||
this.modifiers = modifiers;
|
super(modifiers);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<BlockPos> getPositions(
|
|
||||||
PlacementContext placementContext,
|
|
||||||
RandomSource randomSource,
|
|
||||||
BlockPos blockPos
|
|
||||||
) {
|
|
||||||
Stream.Builder<BlockPos> stream = Stream.builder();
|
|
||||||
for (PlacementModifier p : modifiers) {
|
|
||||||
p.getPositions(placementContext, randomSource, blockPos).forEach(pp -> stream.add(pp));
|
|
||||||
}
|
|
||||||
return stream.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PlacementModifierType<?> type() {
|
|
||||||
return PlacementModifiers.FOR_ALL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,59 +1,17 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.core.Vec3i;
|
import net.minecraft.core.Vec3i;
|
||||||
import net.minecraft.util.RandomSource;
|
|
||||||
import net.minecraft.world.level.WorldGenLevel;
|
|
||||||
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementContext;
|
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementFilter;
|
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class Is extends PlacementFilter {
|
/**
|
||||||
public static final Codec<Is> CODEC = RecordCodecBuilder.create((instance) -> instance
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.Is} instead.
|
||||||
.group(
|
*/
|
||||||
BlockPredicate.CODEC
|
@Deprecated(forRemoval = true)
|
||||||
.fieldOf("predicate")
|
public class Is extends org.betterx.bclib.api.v3.levelgen.features.placement.Is {
|
||||||
.forGetter(cfg -> cfg.predicate),
|
|
||||||
Vec3i.CODEC
|
|
||||||
.optionalFieldOf("offset")
|
|
||||||
.forGetter(cfg -> cfg.offset)
|
|
||||||
)
|
|
||||||
.apply(instance, Is::new));
|
|
||||||
|
|
||||||
private final BlockPredicate predicate;
|
|
||||||
private final Optional<Vec3i> offset;
|
|
||||||
|
|
||||||
public Is(BlockPredicate predicate, Optional<Vec3i> offset) {
|
public Is(BlockPredicate predicate, Optional<Vec3i> offset) {
|
||||||
this.predicate = predicate;
|
super(predicate, offset);
|
||||||
this.offset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Is simple(BlockPredicate predicate) {
|
|
||||||
return new Is(predicate, Optional.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Is below(BlockPredicate predicate) {
|
|
||||||
return new Is(predicate, Optional.of(Direction.DOWN.getNormal()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Is above(BlockPredicate predicate) {
|
|
||||||
return new Is(predicate, Optional.of(Direction.UP.getNormal()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean shouldPlace(PlacementContext ctx, RandomSource random, BlockPos pos) {
|
|
||||||
WorldGenLevel level = ctx.getLevel();
|
|
||||||
return predicate.test(level, offset.map(v -> pos.offset(v.getX(), v.getY(), v.getZ())).orElse(pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PlacementModifierType<Is> type() {
|
|
||||||
return PlacementModifiers.IS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,64 +1,21 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.util.RandomSource;
|
|
||||||
import net.minecraft.world.level.WorldGenLevel;
|
|
||||||
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementContext;
|
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementFilter;
|
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class IsBasin extends PlacementFilter {
|
|
||||||
public static final Codec<IsBasin> CODEC = RecordCodecBuilder.create((instance) -> instance
|
|
||||||
.group(
|
|
||||||
BlockPredicate.CODEC
|
|
||||||
.fieldOf("predicate")
|
|
||||||
.forGetter(cfg -> cfg.predicate),
|
|
||||||
BlockPredicate.CODEC
|
|
||||||
.optionalFieldOf("top_predicate")
|
|
||||||
.orElse(Optional.empty())
|
|
||||||
.forGetter(cfg -> cfg.topPredicate)
|
|
||||||
)
|
|
||||||
.apply(instance, IsBasin::new));
|
|
||||||
|
|
||||||
private final BlockPredicate predicate;
|
/**
|
||||||
private final Optional<BlockPredicate> topPredicate;
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.IsBasin} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
public class IsBasin extends org.betterx.bclib.api.v3.levelgen.features.placement.IsBasin {
|
||||||
|
|
||||||
public IsBasin(BlockPredicate predicate) {
|
public IsBasin(BlockPredicate predicate) {
|
||||||
this(predicate, Optional.empty());
|
super(predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IsBasin(BlockPredicate predicate, Optional<BlockPredicate> topPredicate) {
|
public IsBasin(BlockPredicate predicate, Optional<BlockPredicate> topPredicate) {
|
||||||
this.predicate = predicate;
|
super(predicate, topPredicate);
|
||||||
this.topPredicate = topPredicate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PlacementFilter simple(BlockPredicate predicate) {
|
|
||||||
return new IsBasin(predicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IsBasin openTop(BlockPredicate predicate) {
|
|
||||||
return new IsBasin(predicate, Optional.of(BlockPredicate.ONLY_IN_AIR_PREDICATE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean shouldPlace(PlacementContext ctx, RandomSource random, BlockPos pos) {
|
|
||||||
WorldGenLevel level = ctx.getLevel();
|
|
||||||
if (topPredicate.isPresent() && !topPredicate.get().test(level, pos.above())) return false;
|
|
||||||
|
|
||||||
return predicate.test(level, pos.below())
|
|
||||||
&& predicate.test(level, pos.west())
|
|
||||||
&& predicate.test(level, pos.east())
|
|
||||||
&& predicate.test(level, pos.north())
|
|
||||||
&& predicate.test(level, pos.south());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PlacementModifierType<?> type() {
|
|
||||||
return PlacementModifiers.IS_BASIN;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
||||||
/**
|
/**
|
||||||
* Tests if there is air at two locations above the tested block position
|
* Tests if there is air at two locations above the tested block position
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
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);
|
||||||
|
|
|
@ -12,6 +12,7 @@ import net.minecraft.world.level.levelgen.placement.PlacementFilter;
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public class MinEmptyFilter extends PlacementFilter {
|
public class MinEmptyFilter extends PlacementFilter {
|
||||||
private static final MinEmptyFilter DOWN = new MinEmptyFilter(Direction.DOWN, 2);
|
private static final MinEmptyFilter DOWN = new MinEmptyFilter(Direction.DOWN, 2);
|
||||||
private static final MinEmptyFilter UP = new MinEmptyFilter(Direction.UP, 2);
|
private static final MinEmptyFilter UP = new MinEmptyFilter(Direction.UP, 2);
|
||||||
|
|
|
@ -1,56 +1,14 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.core.Vec3i;
|
import net.minecraft.core.Vec3i;
|
||||||
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.google.common.collect.Maps;
|
/**
|
||||||
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.Offset} instead.
|
||||||
import java.util.Map;
|
*/
|
||||||
import java.util.stream.Stream;
|
@Deprecated(forRemoval = true)
|
||||||
|
public class Offset extends org.betterx.bclib.api.v3.levelgen.features.placement.Offset {
|
||||||
public class Offset extends PlacementModifier {
|
|
||||||
private static final Map<Direction, Offset> DIRECTIONS = Maps.newHashMap();
|
|
||||||
public static final Codec<Offset> CODEC = RecordCodecBuilder.create((instance) -> instance
|
|
||||||
.group(
|
|
||||||
Vec3i.CODEC
|
|
||||||
.fieldOf("blocks")
|
|
||||||
.forGetter(cfg -> cfg.offset)
|
|
||||||
)
|
|
||||||
.apply(instance, Offset::new));
|
|
||||||
|
|
||||||
private final Vec3i offset;
|
|
||||||
|
|
||||||
public Offset(Vec3i offset) {
|
public Offset(Vec3i offset) {
|
||||||
this.offset = offset;
|
super(offset);
|
||||||
}
|
|
||||||
|
|
||||||
public static Offset inDirection(Direction dir) {
|
|
||||||
return DIRECTIONS.get(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<BlockPos> getPositions(
|
|
||||||
PlacementContext placementContext,
|
|
||||||
RandomSource randomSource,
|
|
||||||
BlockPos blockPos
|
|
||||||
) {
|
|
||||||
return Stream.of(blockPos.offset(offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PlacementModifierType<?> type() {
|
|
||||||
return PlacementModifiers.OFFSET;
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
for (Direction d : Direction.values())
|
|
||||||
DIRECTIONS.put(d, new Offset(d.getNormal()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,93 +1,14 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
||||||
|
|
||||||
import org.betterx.bclib.util.BlocksHelper;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.util.RandomSource;
|
|
||||||
import net.minecraft.world.level.block.Blocks;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
|
||||||
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 java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class OnEveryLayer
|
/**
|
||||||
extends PlacementModifier {
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.OnEveryLayer} instead
|
||||||
private static final OnEveryLayer INSTANCE = new OnEveryLayer(Optional.empty(), Optional.empty());
|
*/
|
||||||
private static final OnEveryLayer INSTANCE_MIN_4 = new OnEveryLayer(Optional.of(4), Optional.empty());
|
@Deprecated(forRemoval = true)
|
||||||
public static final Codec<OnEveryLayer> CODEC = RecordCodecBuilder.create(instance -> instance
|
public class OnEveryLayer extends org.betterx.bclib.api.v3.levelgen.features.placement.OnEveryLayer {
|
||||||
.group(
|
|
||||||
Codec.INT.optionalFieldOf("min").forGetter(o -> o.minHeight),
|
|
||||||
Codec.INT.optionalFieldOf("max").forGetter(o -> o.maxHeight)
|
|
||||||
).apply(instance, OnEveryLayer::new));
|
|
||||||
|
|
||||||
|
protected OnEveryLayer(Optional<Integer> minHeight, Optional<Integer> maxHeight) {
|
||||||
private final Optional<Integer> minHeight;
|
super(minHeight, maxHeight);
|
||||||
private final Optional<Integer> maxHeight;
|
|
||||||
|
|
||||||
private OnEveryLayer(Optional<Integer> minHeight, Optional<Integer> maxHeight) {
|
|
||||||
this.minHeight = minHeight;
|
|
||||||
|
|
||||||
this.maxHeight = maxHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static OnEveryLayer simple() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static OnEveryLayer min4() {
|
|
||||||
return INSTANCE_MIN_4;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<BlockPos> getPositions(
|
|
||||||
PlacementContext ctx,
|
|
||||||
RandomSource random,
|
|
||||||
BlockPos pos
|
|
||||||
) {
|
|
||||||
|
|
||||||
Stream.Builder<BlockPos> builder = Stream.builder();
|
|
||||||
|
|
||||||
final int z = pos.getZ();
|
|
||||||
final int x = pos.getX();
|
|
||||||
final int levelHeight = ctx.getHeight(Heightmap.Types.MOTION_BLOCKING, x, z);
|
|
||||||
final int minLevelHeight = ctx.getMinBuildHeight();
|
|
||||||
int y = maxHeight.map(h -> Math.min(levelHeight, h)).orElse(levelHeight);
|
|
||||||
final int minHeight = this.minHeight.map(h -> Math.max(minLevelHeight, h)).orElse(minLevelHeight);
|
|
||||||
|
|
||||||
int layerY;
|
|
||||||
do {
|
|
||||||
layerY = OnEveryLayer.findOnGroundYPosition(ctx, x, y, z, minHeight);
|
|
||||||
if (layerY != Integer.MAX_VALUE) {
|
|
||||||
builder.add(new BlockPos(x, layerY, z));
|
|
||||||
y = layerY - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (layerY != Integer.MAX_VALUE);
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PlacementModifierType<OnEveryLayer> type() {
|
|
||||||
return PlacementModifiers.ON_EVERY_LAYER;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int findOnGroundYPosition(PlacementContext ctx, int x, int startY, int z, int minHeight) {
|
|
||||||
BlockPos.MutableBlockPos mPos = new BlockPos.MutableBlockPos(x, startY, z);
|
|
||||||
BlockState nowState = ctx.getBlockState(mPos);
|
|
||||||
for (int y = startY; y >= minHeight + 1; --y) {
|
|
||||||
mPos.setY(y - 1);
|
|
||||||
BlockState belowState = ctx.getBlockState(mPos);
|
|
||||||
if (BlocksHelper.isTerrain(belowState) && BlocksHelper.isFreeOrFluid(nowState) && !belowState.is(Blocks.BEDROCK)) {
|
|
||||||
return mPos.getY() + 1;
|
|
||||||
}
|
|
||||||
nowState = belowState;
|
|
||||||
}
|
|
||||||
return Integer.MAX_VALUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,40 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
||||||
|
|
||||||
import org.betterx.bclib.BCLib;
|
import org.betterx.bclib.BCLib;
|
||||||
import org.betterx.bclib.api.v3.levelgen.features.placement.NoiseFilter;
|
import org.betterx.bclib.api.v3.levelgen.features.placement.All;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.placement.Debug;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.placement.Extend;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.placement.FindSolidInDirection;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.placement.ForAll;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.placement.Is;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.placement.IsBasin;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.placement.Offset;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.placement.OnEveryLayer;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.placement.Stencil;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.placement.UnderEveryLayer;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.placement.*;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import net.minecraft.core.Registry;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers} instead
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public class PlacementModifiers {
|
public class PlacementModifiers {
|
||||||
public static final PlacementModifierType<NoiseFilter> NOISE_FILTER = register(
|
/**
|
||||||
"noise_filter",
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers#NOISE_FILTER} instead
|
||||||
NoiseFilter.CODEC
|
*/
|
||||||
);
|
@Deprecated(forRemoval = true)
|
||||||
public static final PlacementModifierType<Debug> DEBUG = register(
|
public static final PlacementModifierType<NoiseFilter> NOISE_FILTER = org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers.NOISE_FILTER;
|
||||||
"debug",
|
/**
|
||||||
Debug.CODEC
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers#DEBUG} instead
|
||||||
);
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
public static final PlacementModifierType<Debug> DEBUG = org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers.DEBUG;
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public static final PlacementModifierType<IsEmptyAboveSampledFilter> IS_EMPTY_ABOVE_SAMPLED_FILTER = register(
|
public static final PlacementModifierType<IsEmptyAboveSampledFilter> IS_EMPTY_ABOVE_SAMPLED_FILTER = register(
|
||||||
"is_empty_above_sampled_filter",
|
"is_empty_above_sampled_filter",
|
||||||
IsEmptyAboveSampledFilter.CODEC
|
IsEmptyAboveSampledFilter.CODEC
|
||||||
|
@ -28,73 +45,87 @@ public class PlacementModifiers {
|
||||||
MinEmptyFilter.CODEC
|
MinEmptyFilter.CODEC
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final PlacementModifierType<ForAll> FOR_ALL = register(
|
/**
|
||||||
"for_all",
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers#FOR_ALL} instead
|
||||||
ForAll.CODEC
|
*/
|
||||||
);
|
@Deprecated(forRemoval = true)
|
||||||
|
public static final PlacementModifierType<ForAll> FOR_ALL = org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers.FOR_ALL;
|
||||||
|
|
||||||
public static final PlacementModifierType<FindSolidInDirection> SOLID_IN_DIR = register(
|
/**
|
||||||
"solid_in_dir",
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers#SOLID_IN_DIR} instead
|
||||||
FindSolidInDirection.CODEC
|
*/
|
||||||
);
|
@Deprecated(forRemoval = true)
|
||||||
|
public static final PlacementModifierType<FindSolidInDirection> SOLID_IN_DIR = org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers.SOLID_IN_DIR;
|
||||||
|
|
||||||
public static final PlacementModifierType<Stencil> STENCIL = register(
|
/**
|
||||||
"stencil",
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers#STENCIL} instead
|
||||||
Stencil.CODEC
|
*/
|
||||||
);
|
@Deprecated(forRemoval = true)
|
||||||
|
public static final PlacementModifierType<Stencil> STENCIL = org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers.STENCIL;
|
||||||
|
|
||||||
public static final PlacementModifierType<All> ALL = register(
|
/**
|
||||||
"all",
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers#ALL} instead
|
||||||
All.CODEC
|
*/
|
||||||
);
|
@Deprecated(forRemoval = true)
|
||||||
|
public static final PlacementModifierType<All> ALL = org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers.ALL;
|
||||||
|
|
||||||
public static final PlacementModifierType<IsBasin> IS_BASIN = register(
|
/**
|
||||||
"is_basin",
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers#IS_BASIN} instead
|
||||||
IsBasin.CODEC
|
*/
|
||||||
);
|
@Deprecated(forRemoval = true)
|
||||||
|
public static final PlacementModifierType<IsBasin> IS_BASIN = org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers.IS_BASIN;
|
||||||
|
|
||||||
public static final PlacementModifierType<IsNextTo> IS_NEXT_TO = register(
|
/**
|
||||||
"is_next_to",
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers#IS} instead
|
||||||
IsNextTo.CODEC
|
*/
|
||||||
);
|
@Deprecated(forRemoval = true)
|
||||||
|
public static final PlacementModifierType<Is> IS = org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers.IS;
|
||||||
|
|
||||||
public static final PlacementModifierType<Is> IS = register(
|
/**
|
||||||
"is",
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers#OFFSET} instead
|
||||||
Is.CODEC
|
*/
|
||||||
);
|
@Deprecated(forRemoval = true)
|
||||||
|
public static final PlacementModifierType<Offset> OFFSET = org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers.OFFSET;
|
||||||
|
|
||||||
public static final PlacementModifierType<Offset> OFFSET = register(
|
/**
|
||||||
"offset",
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers#EXTEND} instead
|
||||||
Offset.CODEC
|
*/
|
||||||
);
|
@Deprecated(forRemoval = true)
|
||||||
|
public static final PlacementModifierType<Extend> EXTEND = org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers.EXTEND;
|
||||||
|
|
||||||
public static final PlacementModifierType<Extend> EXTEND = register(
|
/**
|
||||||
"extend",
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers#ON_EVERY_LAYER} instead
|
||||||
Extend.CODEC
|
*/
|
||||||
);
|
@Deprecated(forRemoval = true)
|
||||||
|
public static final PlacementModifierType<OnEveryLayer> ON_EVERY_LAYER = org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers.ON_EVERY_LAYER;
|
||||||
public static final PlacementModifierType<OnEveryLayer> ON_EVERY_LAYER = register(
|
|
||||||
"on_every_layer",
|
|
||||||
OnEveryLayer.CODEC
|
|
||||||
);
|
|
||||||
|
|
||||||
public static final PlacementModifierType<UnderEveryLayer> UNDER_EVERY_LAYER = register(
|
|
||||||
"under_every_layer",
|
|
||||||
UnderEveryLayer.CODEC
|
|
||||||
);
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers#UNDER_EVERY_LAYER} instead
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
public static final PlacementModifierType<UnderEveryLayer> UNDER_EVERY_LAYER = org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers.UNDER_EVERY_LAYER;
|
||||||
|
|
||||||
private static <P extends PlacementModifier> PlacementModifierType<P> register(String path, Codec<P> codec) {
|
private static <P extends PlacementModifier> PlacementModifierType<P> register(String path, Codec<P> codec) {
|
||||||
return register(BCLib.makeID(path), codec);
|
return register(BCLib.makeID(path), codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param location
|
||||||
|
* @param codec
|
||||||
|
* @param <P>
|
||||||
|
* @return
|
||||||
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers#register(ResourceLocation, Codec)} instead
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public static <P extends PlacementModifier> PlacementModifierType<P> register(
|
public static <P extends PlacementModifier> PlacementModifierType<P> register(
|
||||||
ResourceLocation location,
|
ResourceLocation location,
|
||||||
Codec<P> codec
|
Codec<P> codec
|
||||||
) {
|
) {
|
||||||
return Registry.register(Registry.PLACEMENT_MODIFIERS, location, () -> codec);
|
return org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers.register(location, codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public static void ensureStaticInitialization() {
|
public static void ensureStaticInitialization() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,345 +1,19 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.util.ExtraCodecs;
|
|
||||||
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 java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class Stencil extends PlacementModifier {
|
|
||||||
public static final Codec<Stencil> CODEC;
|
|
||||||
private static final Boolean[] BN_STENCIL;
|
|
||||||
private final List<Boolean> stencil;
|
|
||||||
private static final Stencil DEFAULT;
|
|
||||||
private static final Stencil DEFAULT4;
|
|
||||||
private final int selectOneIn;
|
|
||||||
|
|
||||||
private static List<Boolean> convert(Boolean[] s) {
|
/**
|
||||||
return Arrays.stream(s).toList();
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.Stencil} instead
|
||||||
}
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
public class Stencil extends org.betterx.bclib.api.v3.levelgen.features.placement.Stencil {
|
||||||
|
|
||||||
public Stencil(Boolean[] stencil, int selectOneIn) {
|
public Stencil(Boolean[] stencil, int selectOneIn) {
|
||||||
this(convert(stencil), selectOneIn);
|
super(stencil, selectOneIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stencil(List<Boolean> stencil, int selectOneIn) {
|
public Stencil(List<Boolean> stencil, int selectOneIn) {
|
||||||
this.stencil = stencil;
|
super(stencil, selectOneIn);
|
||||||
this.selectOneIn = selectOneIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Stencil all() {
|
|
||||||
return DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Stencil oneIn4() {
|
|
||||||
return DEFAULT4;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<BlockPos> getPositions(
|
|
||||||
PlacementContext placementContext,
|
|
||||||
RandomSource randomSource,
|
|
||||||
BlockPos blockPos
|
|
||||||
) {
|
|
||||||
List<BlockPos> pos = new ArrayList<>(16 * 16);
|
|
||||||
for (int x = 0; x < 16; x++) {
|
|
||||||
for (int y = 0; y < 16; y++) {
|
|
||||||
if (stencil.get(x << 4 | y)) {
|
|
||||||
pos.add(blockPos.offset(x, 0, y));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pos.stream();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PlacementModifierType<?> type() {
|
|
||||||
return PlacementModifiers.STENCIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
BN_STENCIL = new Boolean[]{
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
DEFAULT = new Stencil(BN_STENCIL, 1);
|
|
||||||
DEFAULT4 = new Stencil(BN_STENCIL, 4);
|
|
||||||
CODEC = RecordCodecBuilder.create((instance) -> instance
|
|
||||||
.group(
|
|
||||||
ExtraCodecs.nonEmptyList(Codec.BOOL.listOf())
|
|
||||||
.fieldOf("structures")
|
|
||||||
.orElse(convert(BN_STENCIL))
|
|
||||||
.forGetter((Stencil a) -> a.stencil),
|
|
||||||
Codec.INT
|
|
||||||
.fieldOf("one_in")
|
|
||||||
.orElse(1)
|
|
||||||
.forGetter((Stencil a) -> a.selectOneIn)
|
|
||||||
)
|
|
||||||
.apply(instance, Stencil::new)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,93 +1,15 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
||||||
|
|
||||||
import org.betterx.bclib.util.BlocksHelper;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.util.RandomSource;
|
|
||||||
import net.minecraft.world.level.block.Blocks;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
|
||||||
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 java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.placement.UnderEveryLayer} instead
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public class UnderEveryLayer
|
public class UnderEveryLayer
|
||||||
extends PlacementModifier {
|
extends org.betterx.bclib.api.v3.levelgen.features.placement.UnderEveryLayer {
|
||||||
private static final UnderEveryLayer INSTANCE = new UnderEveryLayer(Optional.empty(), Optional.empty());
|
|
||||||
private static final UnderEveryLayer INSTANCE_MIN_4 = new UnderEveryLayer(Optional.of(4), Optional.empty());
|
|
||||||
public static final Codec<UnderEveryLayer> CODEC = RecordCodecBuilder.create(instance -> instance
|
|
||||||
.group(
|
|
||||||
Codec.INT.optionalFieldOf("min").forGetter(o -> o.minHeight),
|
|
||||||
Codec.INT.optionalFieldOf("max").forGetter(o -> o.maxHeight)
|
|
||||||
).apply(instance, UnderEveryLayer::new));
|
|
||||||
|
|
||||||
|
protected UnderEveryLayer(Optional<Integer> minHeight, Optional<Integer> maxHeight) {
|
||||||
private final Optional<Integer> minHeight;
|
super(minHeight, maxHeight);
|
||||||
private final Optional<Integer> maxHeight;
|
|
||||||
|
|
||||||
private UnderEveryLayer(Optional<Integer> minHeight, Optional<Integer> maxHeight) {
|
|
||||||
this.minHeight = minHeight;
|
|
||||||
|
|
||||||
this.maxHeight = maxHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UnderEveryLayer simple() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UnderEveryLayer min4() {
|
|
||||||
return INSTANCE_MIN_4;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<BlockPos> getPositions(
|
|
||||||
PlacementContext ctx,
|
|
||||||
RandomSource random,
|
|
||||||
BlockPos pos
|
|
||||||
) {
|
|
||||||
|
|
||||||
Stream.Builder<BlockPos> builder = Stream.builder();
|
|
||||||
|
|
||||||
final int z = pos.getZ();
|
|
||||||
final int x = pos.getX();
|
|
||||||
final int levelHeight = ctx.getHeight(Heightmap.Types.MOTION_BLOCKING, x, z);
|
|
||||||
final int minLevelHeight = ctx.getMinBuildHeight();
|
|
||||||
int y = maxHeight.map(h -> Math.min(levelHeight, h)).orElse(levelHeight);
|
|
||||||
final int minHeight = this.minHeight.map(h -> Math.max(minLevelHeight, h)).orElse(minLevelHeight);
|
|
||||||
|
|
||||||
int layerY;
|
|
||||||
do {
|
|
||||||
layerY = findUnderGroundYPosition(ctx, x, y, z, minHeight);
|
|
||||||
if (layerY != Integer.MAX_VALUE) {
|
|
||||||
builder.add(new BlockPos(x, layerY, z));
|
|
||||||
y = layerY - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (layerY != Integer.MAX_VALUE);
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PlacementModifierType<UnderEveryLayer> type() {
|
|
||||||
return PlacementModifiers.UNDER_EVERY_LAYER;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int findUnderGroundYPosition(PlacementContext ctx, int x, int startY, int z, int minHeight) {
|
|
||||||
BlockPos.MutableBlockPos mPos = new BlockPos.MutableBlockPos(x, startY, z);
|
|
||||||
BlockState nowState = ctx.getBlockState(mPos);
|
|
||||||
for (int y = startY; y >= minHeight + 1; --y) {
|
|
||||||
mPos.setY(y - 1);
|
|
||||||
BlockState belowState = ctx.getBlockState(mPos);
|
|
||||||
if (BlocksHelper.isTerrain(nowState) && BlocksHelper.isFreeOrFluid(belowState) && !nowState.is(Blocks.BEDROCK)) {
|
|
||||||
return mPos.getY();
|
|
||||||
}
|
|
||||||
nowState = belowState;
|
|
||||||
}
|
|
||||||
return Integer.MAX_VALUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package org.betterx.bclib.api.v3.levelgen.features;
|
package org.betterx.bclib.api.v3.levelgen.features;
|
||||||
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.UserGrowableFeature;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package org.betterx.bclib.api.v3.levelgen.features;
|
package org.betterx.bclib.api.v3.levelgen.features;
|
||||||
|
|
||||||
import org.betterx.bclib.BCLib;
|
import org.betterx.bclib.BCLib;
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.*;
|
import org.betterx.bclib.api.v3.levelgen.features.config.*;
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.features.*;
|
import org.betterx.bclib.api.v3.levelgen.features.features.*;
|
||||||
|
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
|
@ -11,7 +11,6 @@ import net.minecraft.world.level.levelgen.GenerationStep;
|
||||||
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.NoneFeatureConfiguration;
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.RandomFeatureConfiguration;
|
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||||
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
@ -21,25 +20,8 @@ public class BCLFeature<F extends Feature<FC>, FC extends FeatureConfiguration>
|
||||||
BCLib.makeID("place_block"),
|
BCLib.makeID("place_block"),
|
||||||
new PlaceBlockFeature<>(PlaceFacingBlockConfig.CODEC)
|
new PlaceBlockFeature<>(PlaceFacingBlockConfig.CODEC)
|
||||||
);
|
);
|
||||||
public static final Feature<ScatterFeatureConfig.OnSolid> SCATTER_ON_SOLID = register(
|
|
||||||
BCLib.makeID("scatter_on_solid"),
|
|
||||||
new ScatterFeature<>(ScatterFeatureConfig.OnSolid.CODEC)
|
|
||||||
);
|
|
||||||
|
|
||||||
public static final Feature<ScatterFeatureConfig.ExtendTop> SCATTER_EXTEND_TOP = register(
|
|
||||||
BCLib.makeID("scatter_extend_top"),
|
|
||||||
new ScatterFeature<>(ScatterFeatureConfig.ExtendTop.CODEC)
|
|
||||||
);
|
|
||||||
|
|
||||||
public static final Feature<ScatterFeatureConfig.ExtendBottom> SCATTER_EXTEND_BOTTOM = register(
|
|
||||||
BCLib.makeID("scatter_extend_bottom"),
|
|
||||||
new ScatterFeature<>(ScatterFeatureConfig.ExtendBottom.CODEC)
|
|
||||||
);
|
|
||||||
|
|
||||||
public static final Feature<RandomFeatureConfiguration> RANDOM_SELECTOR = register(
|
|
||||||
BCLib.makeID("random_select"),
|
|
||||||
new WeightedRandomSelectorFeature()
|
|
||||||
);
|
|
||||||
public static final Feature<TemplateFeatureConfig> TEMPLATE = register(
|
public static final Feature<TemplateFeatureConfig> TEMPLATE = register(
|
||||||
BCLib.makeID("template"),
|
BCLib.makeID("template"),
|
||||||
new TemplateFeature(
|
new TemplateFeature(
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
package org.betterx.bclib.api.v3.levelgen.features;
|
package org.betterx.bclib.api.v3.levelgen.features;
|
||||||
|
|
||||||
import org.betterx.bclib.BCLib;
|
import org.betterx.bclib.BCLib;
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.PillarFeatureConfig;
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.PlaceFacingBlockConfig;
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.SequenceFeatureConfig;
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.TemplateFeatureConfig;
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.features.PillarFeature;
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.features.PlaceBlockFeature;
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.features.SequenceFeature;
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.features.TemplateFeature;
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.structures.StructurePlacementType;
|
import org.betterx.bclib.api.v2.levelgen.structures.StructurePlacementType;
|
||||||
import org.betterx.bclib.api.v2.levelgen.structures.StructureWorldNBT;
|
import org.betterx.bclib.api.v2.levelgen.structures.StructureWorldNBT;
|
||||||
import org.betterx.bclib.api.v2.poi.BCLPoiType;
|
import org.betterx.bclib.api.v2.poi.BCLPoiType;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.config.PillarFeatureConfig;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.config.PlaceFacingBlockConfig;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.config.SequenceFeatureConfig;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.config.TemplateFeatureConfig;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.features.PillarFeature;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.features.PlaceBlockFeature;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.features.SequenceFeature;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.features.TemplateFeature;
|
||||||
import org.betterx.bclib.blocks.BlockProperties;
|
import org.betterx.bclib.blocks.BlockProperties;
|
||||||
import org.betterx.bclib.util.Triple;
|
import org.betterx.bclib.util.Triple;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package org.betterx.bclib.api.v3.levelgen.features;
|
package org.betterx.bclib.api.v3.levelgen.features;
|
||||||
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.PlaceFacingBlockConfig;
|
import org.betterx.bclib.api.v3.levelgen.features.blockpredicates.BlockPredicates;
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.placement.*;
|
import org.betterx.bclib.api.v3.levelgen.features.config.PlaceFacingBlockConfig;
|
||||||
import org.betterx.bclib.api.v3.levelgen.features.placement.NoiseFilter;
|
import org.betterx.bclib.api.v3.levelgen.features.placement.*;
|
||||||
import org.betterx.worlds.together.tag.v3.CommonBlockTags;
|
import org.betterx.worlds.together.tag.v3.CommonBlockTags;
|
||||||
|
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
|
@ -74,24 +74,6 @@ abstract class CommonPlacedFeatureBuilder<F extends Feature<FC>, FC extends Feat
|
||||||
return modifier(CountPlacement.of(UniformInt.of(min, max)));
|
return modifier(CountPlacement.of(UniformInt.of(min, max)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate points in a stencil pattern
|
|
||||||
*
|
|
||||||
* @return same {@link CommonPlacedFeatureBuilder} instance.
|
|
||||||
*/
|
|
||||||
public T stencil() {
|
|
||||||
return modifier(Stencil.all());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate points in a stencil pattern and selecting (on average) only every 4th
|
|
||||||
*
|
|
||||||
* @return same {@link CommonPlacedFeatureBuilder} instance.
|
|
||||||
*/
|
|
||||||
public T stencilOneIn4() {
|
|
||||||
return modifier(Stencil.oneIn4());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate points for every xz-Coordinate in a chunk. Be carefuller, this is quite expensive!
|
* Generate points for every xz-Coordinate in a chunk. Be carefuller, this is quite expensive!
|
||||||
*
|
*
|
||||||
|
@ -101,6 +83,15 @@ abstract class CommonPlacedFeatureBuilder<F extends Feature<FC>, FC extends Feat
|
||||||
return modifier(All.simple());
|
return modifier(All.simple());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T stencil() {
|
||||||
|
return modifier(Stencil.all());
|
||||||
|
}
|
||||||
|
|
||||||
|
public T stencilOneIn4() {
|
||||||
|
return modifier(Stencil.oneIn4());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate feature in certain iterations (per chunk).
|
* Generate feature in certain iterations (per chunk).
|
||||||
* Feature will be generated on all layers (example - Nether plants).
|
* Feature will be generated on all layers (example - Nether plants).
|
||||||
|
@ -218,34 +209,6 @@ abstract class CommonPlacedFeatureBuilder<F extends Feature<FC>, FC extends Feat
|
||||||
return modifier(PlacementUtils.FULL_RANGE);
|
return modifier(PlacementUtils.FULL_RANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T isEmptyAbove4() {
|
|
||||||
return modifier(IsEmptyAboveSampledFilter.emptyAbove4());
|
|
||||||
}
|
|
||||||
|
|
||||||
public T isEmptyAbove2() {
|
|
||||||
return modifier(IsEmptyAboveSampledFilter.emptyAbove2());
|
|
||||||
}
|
|
||||||
|
|
||||||
public T isEmptyAbove() {
|
|
||||||
return modifier(IsEmptyAboveSampledFilter.emptyAbove());
|
|
||||||
}
|
|
||||||
|
|
||||||
public T isEmptyBelow4() {
|
|
||||||
return modifier(IsEmptyAboveSampledFilter.emptyBelow4());
|
|
||||||
}
|
|
||||||
|
|
||||||
public T isEmptyBelow2() {
|
|
||||||
return modifier(IsEmptyAboveSampledFilter.emptyBelow2());
|
|
||||||
}
|
|
||||||
|
|
||||||
public T isEmptyBelow() {
|
|
||||||
return modifier(IsEmptyAboveSampledFilter.emptyBelow());
|
|
||||||
}
|
|
||||||
|
|
||||||
public T isEmptyAbove(int d1, int d2) {
|
|
||||||
return modifier(new IsEmptyAboveSampledFilter(d1, d2));
|
|
||||||
}
|
|
||||||
|
|
||||||
public T spreadHorizontal(IntProvider p) {
|
public T spreadHorizontal(IntProvider p) {
|
||||||
return modifier(RandomOffsetPlacement.horizontal(p));
|
return modifier(RandomOffsetPlacement.horizontal(p));
|
||||||
}
|
}
|
||||||
|
@ -309,15 +272,6 @@ abstract class CommonPlacedFeatureBuilder<F extends Feature<FC>, FC extends Feat
|
||||||
return modifier(FindSolidInDirection.up(distance));
|
return modifier(FindSolidInDirection.up(distance));
|
||||||
}
|
}
|
||||||
|
|
||||||
public T hasMinimumDownwardSpace() {
|
|
||||||
return modifier(MinEmptyFilter.down());
|
|
||||||
}
|
|
||||||
|
|
||||||
public T hasMinimumUpwardSpace() {
|
|
||||||
return modifier(MinEmptyFilter.up());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast a ray with max {@code distance} length to find the next solid Block. The ray will travel through replaceable
|
* Cast a ray with max {@code distance} length to find the next solid Block. The ray will travel through replaceable
|
||||||
* Blocks (see {@link Material#isReplaceable()}) and will be accepted if it hits a block with the
|
* Blocks (see {@link Material#isReplaceable()}) and will be accepted if it hits a block with the
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
package org.betterx.bclib.api.v3.levelgen.features;
|
package org.betterx.bclib.api.v3.levelgen.features;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.level.ServerLevelAccessor;
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||||
|
|
||||||
public interface UserGrowableFeature<FC extends FeatureConfiguration> extends org.betterx.bclib.api.v2.levelgen.features.UserGrowableFeature<FC> {
|
public interface UserGrowableFeature<FC extends FeatureConfiguration> {
|
||||||
|
boolean grow(
|
||||||
|
ServerLevelAccessor level,
|
||||||
|
BlockPos pos,
|
||||||
|
RandomSource random,
|
||||||
|
FC configuration
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
package org.betterx.bclib.api.v3.levelgen.features;
|
package org.betterx.bclib.api.v3.levelgen.features.blockpredicates;
|
||||||
|
|
||||||
|
import org.betterx.bclib.BCLib;
|
||||||
import org.betterx.worlds.together.tag.v3.CommonBlockTags;
|
import org.betterx.worlds.together.tag.v3.CommonBlockTags;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.tags.BlockTags;
|
import net.minecraft.tags.BlockTags;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
||||||
|
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicateType;
|
||||||
import net.minecraft.world.level.material.Fluids;
|
import net.minecraft.world.level.material.Fluids;
|
||||||
|
|
||||||
public class BlockPredicates {
|
public class BlockPredicates {
|
||||||
|
@ -24,4 +29,16 @@ public class BlockPredicates {
|
||||||
BlockPredicate.matchesTag(CommonBlockTags.TERRAIN),
|
BlockPredicate.matchesTag(CommonBlockTags.TERRAIN),
|
||||||
BlockPredicate.matchesFluids(Fluids.LAVA)
|
BlockPredicate.matchesFluids(Fluids.LAVA)
|
||||||
);
|
);
|
||||||
|
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() {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.blockpredicates;
|
package org.betterx.bclib.api.v3.levelgen.features.blockpredicates;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
@ -30,7 +30,7 @@ public class IsFullShape implements BlockPredicate {
|
||||||
|
|
||||||
|
|
||||||
public BlockPredicateType<IsFullShape> type() {
|
public BlockPredicateType<IsFullShape> type() {
|
||||||
return Types.FULL_SHAPE;
|
return BlockPredicates.FULL_SHAPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -0,0 +1,70 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.config;
|
||||||
|
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.features.BCLFeature;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.config;
|
package org.betterx.bclib.api.v3.levelgen.features.config;
|
||||||
|
|
||||||
import org.betterx.bclib.blocks.BlockProperties;
|
import org.betterx.bclib.blocks.BlockProperties;
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.config;
|
||||||
|
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.util.random.SimpleWeightedRandomList;
|
||||||
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.stateproviders.WeightedStateProvider;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public abstract class PlaceBlockFeatureConfig implements FeatureConfiguration {
|
||||||
|
|
||||||
|
protected static <T extends PlaceBlockFeatureConfig> RecordCodecBuilder<T, BlockStateProvider> blockStateCodec() {
|
||||||
|
return BlockStateProvider.CODEC
|
||||||
|
.fieldOf("entries")
|
||||||
|
.forGetter((T o) -> o.stateProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final BlockStateProvider stateProvider;
|
||||||
|
|
||||||
|
|
||||||
|
protected static SimpleWeightedRandomList<BlockState> buildWeightedList(List<BlockState> states) {
|
||||||
|
var builder = SimpleWeightedRandomList.<BlockState>builder();
|
||||||
|
for (BlockState s : states) builder.add(s, 1);
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static SimpleWeightedRandomList<BlockState> buildWeightedList(BlockState state) {
|
||||||
|
return SimpleWeightedRandomList
|
||||||
|
.<BlockState>builder()
|
||||||
|
.add(state, 1)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlaceBlockFeatureConfig(Block block) {
|
||||||
|
this(block.defaultBlockState());
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlaceBlockFeatureConfig(BlockState state) {
|
||||||
|
this(BlockStateProvider.simple(state));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public PlaceBlockFeatureConfig(List<BlockState> states) {
|
||||||
|
this(buildWeightedList(states));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlaceBlockFeatureConfig(SimpleWeightedRandomList<BlockState> blocks) {
|
||||||
|
this.stateProvider = new WeightedStateProvider(blocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlaceBlockFeatureConfig(BlockStateProvider blocks) {
|
||||||
|
this.stateProvider = blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockState getRandomBlock(RandomSource random, BlockPos pos) {
|
||||||
|
return this.stateProvider.getState(random, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean place(FeaturePlaceContext<? extends PlaceBlockFeatureConfig> ctx) {
|
||||||
|
BlockState state = getRandomBlock(ctx.random(), ctx.origin());
|
||||||
|
return placeBlock(ctx, ctx.level(), ctx.origin(), state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected abstract boolean placeBlock(
|
||||||
|
FeaturePlaceContext<? extends PlaceBlockFeatureConfig> ctx,
|
||||||
|
WorldGenLevel level,
|
||||||
|
BlockPos pos,
|
||||||
|
BlockState targetState
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.config;
|
||||||
|
|
||||||
|
import org.betterx.bclib.util.BlocksHelper;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.util.ExtraCodecs;
|
||||||
|
import net.minecraft.util.random.SimpleWeightedRandomList;
|
||||||
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.stateproviders.WeightedStateProvider;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PlaceFacingBlockConfig extends PlaceBlockFeatureConfig {
|
||||||
|
public static final Codec<PlaceFacingBlockConfig> CODEC = RecordCodecBuilder.create(instance -> instance
|
||||||
|
.group(
|
||||||
|
blockStateCodec(),
|
||||||
|
ExtraCodecs.nonEmptyList(Direction.CODEC.listOf())
|
||||||
|
.fieldOf("dir")
|
||||||
|
.orElse(List.of(Direction.NORTH))
|
||||||
|
.forGetter(a -> a.directions)
|
||||||
|
).apply(instance, PlaceFacingBlockConfig::new)
|
||||||
|
);
|
||||||
|
public static final List<Direction> HORIZONTAL = List.of(
|
||||||
|
Direction.NORTH,
|
||||||
|
Direction.EAST,
|
||||||
|
Direction.WEST,
|
||||||
|
Direction.SOUTH
|
||||||
|
);
|
||||||
|
public static final List<Direction> VERTICAL = List.of(Direction.UP, Direction.DOWN);
|
||||||
|
public static final List<Direction> ALL = List.of(
|
||||||
|
Direction.NORTH,
|
||||||
|
Direction.EAST,
|
||||||
|
Direction.SOUTH,
|
||||||
|
Direction.WEST,
|
||||||
|
Direction.UP,
|
||||||
|
Direction.DOWN
|
||||||
|
);
|
||||||
|
|
||||||
|
private final List<Direction> directions;
|
||||||
|
|
||||||
|
public PlaceFacingBlockConfig(Block block, List<Direction> dir) {
|
||||||
|
this(block.defaultBlockState(), dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlaceFacingBlockConfig(BlockState state, List<Direction> dir) {
|
||||||
|
this(BlockStateProvider.simple(state), dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlaceFacingBlockConfig(List<BlockState> states, List<Direction> dir) {
|
||||||
|
this(buildWeightedList(states), dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlaceFacingBlockConfig(SimpleWeightedRandomList<BlockState> blocks, List<Direction> dir) {
|
||||||
|
this(new WeightedStateProvider(blocks), dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlaceFacingBlockConfig(BlockStateProvider blocks, List<Direction> dir) {
|
||||||
|
super(blocks);
|
||||||
|
directions = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
|
||||||
|
public boolean placeBlock(
|
||||||
|
FeaturePlaceContext<? extends PlaceBlockFeatureConfig> ctx,
|
||||||
|
WorldGenLevel level,
|
||||||
|
BlockPos pos,
|
||||||
|
BlockState targetState
|
||||||
|
) {
|
||||||
|
BlockState lookupState;
|
||||||
|
BlockPos testPos;
|
||||||
|
for (Direction dir : directions) {
|
||||||
|
testPos = pos.relative(dir.getOpposite());
|
||||||
|
lookupState = targetState.setValue(HorizontalDirectionalBlock.FACING, dir);
|
||||||
|
if (lookupState.canSurvive(level, testPos) && level.getBlockState(testPos).isAir()) {
|
||||||
|
BlocksHelper.setWithoutUpdate(level, testPos, lookupState);
|
||||||
|
//BlocksHelper.setWithoutUpdate(level, pos, level.getBlockState(pos.relative(dir.getOpposite())));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.config;
|
||||||
|
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.features.BCLFeature;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
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 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 static SequenceFeatureConfig createSequence(List<org.betterx.bclib.api.v3.levelgen.features.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,42 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.config;
|
||||||
|
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.structures.StructurePlacementType;
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.structures.StructureWorldNBT;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.ExtraCodecs;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class TemplateFeatureConfig implements FeatureConfiguration {
|
||||||
|
public static final Codec<TemplateFeatureConfig> CODEC = RecordCodecBuilder.create((instance) -> instance
|
||||||
|
.group(
|
||||||
|
ExtraCodecs.nonEmptyList(StructureWorldNBT.CODEC.listOf())
|
||||||
|
.fieldOf("structures")
|
||||||
|
.forGetter((TemplateFeatureConfig cfg) -> cfg.structures)
|
||||||
|
)
|
||||||
|
.apply(instance, TemplateFeatureConfig::new)
|
||||||
|
);
|
||||||
|
|
||||||
|
public final List<StructureWorldNBT> structures;
|
||||||
|
|
||||||
|
public static StructureWorldNBT cfg(
|
||||||
|
ResourceLocation location,
|
||||||
|
int offsetY,
|
||||||
|
StructurePlacementType type,
|
||||||
|
float chance
|
||||||
|
) {
|
||||||
|
return StructureWorldNBT.create(location, offsetY, type, chance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TemplateFeatureConfig(ResourceLocation location, int offsetY, StructurePlacementType type) {
|
||||||
|
this(List.of(cfg(location, offsetY, type, 1.0f)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public TemplateFeatureConfig(List<StructureWorldNBT> structures) {
|
||||||
|
this.structures = structures;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.features;
|
||||||
|
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.config.ConditionFeatureConfig;
|
||||||
|
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.features;
|
package org.betterx.bclib.api.v3.levelgen.features.features;
|
||||||
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.config.PillarFeatureConfig;
|
import org.betterx.bclib.api.v3.levelgen.features.config.PillarFeatureConfig;
|
||||||
import org.betterx.bclib.util.BlocksHelper;
|
import org.betterx.bclib.util.BlocksHelper;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
|
@ -0,0 +1,18 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.features;
|
||||||
|
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.config.PlaceBlockFeatureConfig;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||||
|
|
||||||
|
public class PlaceBlockFeature<FC extends PlaceBlockFeatureConfig> extends Feature<FC> {
|
||||||
|
public PlaceBlockFeature(Codec<FC> codec) {
|
||||||
|
super(codec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean place(FeaturePlaceContext<FC> ctx) {
|
||||||
|
return ctx.config().place(ctx);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.features;
|
||||||
|
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.config.SequenceFeatureConfig;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||||
|
|
||||||
|
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,87 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.features;
|
||||||
|
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.features.BCLFeature;
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.features.BCLFeatureBuilder;
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.structures.StructureNBT;
|
||||||
|
import org.betterx.bclib.api.v2.levelgen.structures.StructureWorldNBT;
|
||||||
|
import org.betterx.bclib.api.v3.levelgen.features.config.TemplateFeatureConfig;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||||
|
|
||||||
|
public class TemplateFeature<FC extends TemplateFeatureConfig> extends Feature<FC> {
|
||||||
|
|
||||||
|
public static <T extends TemplateFeatureConfig> BCLFeature createAndRegisterRare(
|
||||||
|
ResourceLocation location,
|
||||||
|
TemplateFeatureConfig configuration,
|
||||||
|
int onceEveryChunk
|
||||||
|
) {
|
||||||
|
|
||||||
|
|
||||||
|
return BCLFeatureBuilder
|
||||||
|
.start(location, org.betterx.bclib.api.v3.levelgen.features.BCLFeature.TEMPLATE)
|
||||||
|
.decoration(GenerationStep.Decoration.SURFACE_STRUCTURES)
|
||||||
|
.onceEvery(onceEveryChunk) //discard neighboring chunks
|
||||||
|
.count(16) //try 16 placements in chunk
|
||||||
|
.squarePlacement() //randomize x/z in chunk
|
||||||
|
.randomHeight10FromFloorCeil() //randomize height 10 above and 10 below max vertical
|
||||||
|
.findSolidFloor(12) //cast downward ray to find solid surface
|
||||||
|
.isEmptyAbove4() //make sure we have 4 free blocks above
|
||||||
|
.onlyInBiome() //ensure that we still are in the correct biome
|
||||||
|
|
||||||
|
.buildAndRegister(configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends TemplateFeatureConfig> BCLFeature createAndRegister(
|
||||||
|
ResourceLocation location,
|
||||||
|
TemplateFeatureConfig configuration,
|
||||||
|
int count
|
||||||
|
) {
|
||||||
|
return BCLFeatureBuilder
|
||||||
|
.start(location, org.betterx.bclib.api.v3.levelgen.features.BCLFeature.TEMPLATE)
|
||||||
|
.decoration(GenerationStep.Decoration.SURFACE_STRUCTURES)
|
||||||
|
.count(count)
|
||||||
|
.squarePlacement()
|
||||||
|
.randomHeight10FromFloorCeil()
|
||||||
|
.findSolidFloor(12) //cast downward ray to find solid surface
|
||||||
|
.isEmptyAbove4()
|
||||||
|
.onlyInBiome()
|
||||||
|
.buildAndRegister(configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TemplateFeature(Codec<FC> codec) {
|
||||||
|
super(codec);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected StructureWorldNBT randomStructure(TemplateFeatureConfig cfg, RandomSource random) {
|
||||||
|
|
||||||
|
if (cfg.structures.size() > 1) {
|
||||||
|
final float chanceSum = cfg.structures.parallelStream().map(c -> c.chance).reduce(0.0f, (p, c) -> p + c);
|
||||||
|
float rnd = random.nextFloat() * chanceSum;
|
||||||
|
|
||||||
|
for (StructureWorldNBT c : cfg.structures) {
|
||||||
|
rnd -= c.chance;
|
||||||
|
if (rnd <= 0) return c;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return cfg.structures.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean place(FeaturePlaceContext<FC> ctx) {
|
||||||
|
StructureWorldNBT structure = randomStructure(ctx.config(), ctx.random());
|
||||||
|
return structure.generateIfPlaceable(
|
||||||
|
ctx.level(),
|
||||||
|
ctx.origin(),
|
||||||
|
StructureNBT.getRandomRotation(ctx.random()),
|
||||||
|
StructureNBT.getRandomMirror(ctx.random())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.placement;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.placement;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
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 java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class Debug extends PlacementModifier {
|
||||||
|
public static final Debug INSTANCE = new Debug();
|
||||||
|
public static final Codec<Debug> CODEC = Codec.unit(Debug::new);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<BlockPos> getPositions(
|
||||||
|
PlacementContext placementContext,
|
||||||
|
RandomSource randomSource,
|
||||||
|
BlockPos blockPos
|
||||||
|
) {
|
||||||
|
return Stream.of(blockPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlacementModifierType<?> type() {
|
||||||
|
return PlacementModifiers.DEBUG;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.placement;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.util.valueproviders.IntProvider;
|
||||||
|
import net.minecraft.util.valueproviders.UniformInt;
|
||||||
|
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 java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class Extend extends PlacementModifier {
|
||||||
|
public static final Codec<Extend> CODEC = RecordCodecBuilder.create((instance) -> instance
|
||||||
|
.group(
|
||||||
|
Direction.CODEC
|
||||||
|
.fieldOf("direction")
|
||||||
|
.orElse(Direction.DOWN)
|
||||||
|
.forGetter(cfg -> cfg.direction),
|
||||||
|
IntProvider.codec(0, 16)
|
||||||
|
.fieldOf("length")
|
||||||
|
.orElse(UniformInt.of(0, 3))
|
||||||
|
.forGetter(cfg -> cfg.length)
|
||||||
|
)
|
||||||
|
.apply(instance, Extend::new));
|
||||||
|
|
||||||
|
private final Direction direction;
|
||||||
|
private final IntProvider length;
|
||||||
|
|
||||||
|
public Extend(Direction direction, IntProvider length) {
|
||||||
|
this.direction = direction;
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<BlockPos> getPositions(
|
||||||
|
PlacementContext placementContext,
|
||||||
|
RandomSource random,
|
||||||
|
BlockPos blockPos
|
||||||
|
) {
|
||||||
|
var builder = Stream.<BlockPos>builder();
|
||||||
|
final int count = length.sample(random);
|
||||||
|
builder.add(blockPos);
|
||||||
|
for (int y = 1; y < count + 1; y++) {
|
||||||
|
builder.add(blockPos.relative(direction, y));
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlacementModifierType<?> type() {
|
||||||
|
return PlacementModifiers.EXTEND;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.placement;
|
||||||
|
|
||||||
|
import org.betterx.bclib.util.BlocksHelper;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.core.SectionPos;
|
||||||
|
import net.minecraft.util.ExtraCodecs;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.util.valueproviders.IntProvider;
|
||||||
|
import net.minecraft.util.valueproviders.UniformInt;
|
||||||
|
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 java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
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),
|
||||||
|
Codec.BOOL.fieldOf("random:select").orElse(true).forGetter(p -> p.randomSelect)
|
||||||
|
)
|
||||||
|
.apply(
|
||||||
|
instance,
|
||||||
|
FindSolidInDirection::new
|
||||||
|
));
|
||||||
|
protected static final FindSolidInDirection DOWN = new FindSolidInDirection(Direction.DOWN, 6);
|
||||||
|
protected static final FindSolidInDirection UP = new FindSolidInDirection(Direction.UP, 6);
|
||||||
|
private final List<Direction> direction;
|
||||||
|
private final int maxSearchDistance;
|
||||||
|
|
||||||
|
private final boolean randomSelect;
|
||||||
|
private final IntProvider provider;
|
||||||
|
|
||||||
|
|
||||||
|
public FindSolidInDirection(Direction direction, int maxSearchDistance) {
|
||||||
|
this(List.of(direction), maxSearchDistance, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FindSolidInDirection(List<Direction> direction, int maxSearchDistance) {
|
||||||
|
this(direction, maxSearchDistance, direction.size() > 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FindSolidInDirection(List<Direction> direction, int maxSearchDistance, boolean randomSelect) {
|
||||||
|
this.direction = direction;
|
||||||
|
this.maxSearchDistance = maxSearchDistance;
|
||||||
|
this.provider = UniformInt.of(0, direction.size() - 1);
|
||||||
|
this.randomSelect = randomSelect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlacementModifier down() {
|
||||||
|
return DOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlacementModifier up() {
|
||||||
|
return UP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlacementModifier down(int dist) {
|
||||||
|
if (dist == DOWN.maxSearchDistance) return DOWN;
|
||||||
|
return new FindSolidInDirection(Direction.DOWN, dist);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlacementModifier up(int dist) {
|
||||||
|
if (dist == UP.maxSearchDistance) return UP;
|
||||||
|
return new FindSolidInDirection(Direction.UP, dist);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Direction randomDirection(RandomSource random) {
|
||||||
|
return direction.get(provider.sample(random));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<BlockPos> getPositions(
|
||||||
|
PlacementContext placementContext,
|
||||||
|
RandomSource randomSource,
|
||||||
|
BlockPos blockPos
|
||||||
|
) {
|
||||||
|
var builder = Stream.<BlockPos>builder();
|
||||||
|
if (randomSelect) {
|
||||||
|
submitSingle(placementContext, blockPos, builder, randomDirection(randomSource));
|
||||||
|
} else {
|
||||||
|
for (Direction d : direction) {
|
||||||
|
submitSingle(placementContext, blockPos, builder, d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void submitSingle(
|
||||||
|
PlacementContext placementContext,
|
||||||
|
BlockPos blockPos,
|
||||||
|
Stream.Builder<BlockPos> builder,
|
||||||
|
Direction d
|
||||||
|
) {
|
||||||
|
int searchDist;
|
||||||
|
BlockPos.MutableBlockPos POS = blockPos.mutable();
|
||||||
|
if (d == Direction.EAST) { //+x
|
||||||
|
searchDist = Math.min(maxSearchDistance, 15 - SectionPos.sectionRelative(blockPos.getX()));
|
||||||
|
} else if (d == Direction.WEST) { //-x
|
||||||
|
searchDist = Math.min(maxSearchDistance, SectionPos.sectionRelative(blockPos.getX()));
|
||||||
|
} else if (d == Direction.SOUTH) { //+z
|
||||||
|
searchDist = Math.min(maxSearchDistance, 15 - SectionPos.sectionRelative(blockPos.getZ()));
|
||||||
|
} else if (d == Direction.NORTH) { //-z
|
||||||
|
searchDist = Math.min(maxSearchDistance, SectionPos.sectionRelative(blockPos.getZ()));
|
||||||
|
} else {
|
||||||
|
searchDist = maxSearchDistance;
|
||||||
|
}
|
||||||
|
if (BlocksHelper.findOnSurroundingSurface(
|
||||||
|
placementContext.getLevel(),
|
||||||
|
POS,
|
||||||
|
d,
|
||||||
|
searchDist,
|
||||||
|
BlocksHelper::isTerrain
|
||||||
|
)) {
|
||||||
|
builder.add(POS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlacementModifierType<?> type() {
|
||||||
|
return PlacementModifiers.SOLID_IN_DIR;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.placement;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.util.ExtraCodecs;
|
||||||
|
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 java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class ForAll extends PlacementModifier {
|
||||||
|
public static final Codec<ForAll> CODEC = RecordCodecBuilder.create(instance -> instance
|
||||||
|
.group(
|
||||||
|
ExtraCodecs.nonEmptyList(PlacementModifier.CODEC.listOf())
|
||||||
|
.fieldOf("modifiers")
|
||||||
|
.forGetter(a -> a.modifiers)
|
||||||
|
)
|
||||||
|
.apply(instance, ForAll::new));
|
||||||
|
|
||||||
|
private final List<PlacementModifier> modifiers;
|
||||||
|
|
||||||
|
public ForAll(List<PlacementModifier> modifiers) {
|
||||||
|
this.modifiers = modifiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<BlockPos> getPositions(
|
||||||
|
PlacementContext placementContext,
|
||||||
|
RandomSource randomSource,
|
||||||
|
BlockPos blockPos
|
||||||
|
) {
|
||||||
|
Stream.Builder<BlockPos> stream = Stream.builder();
|
||||||
|
for (PlacementModifier p : modifiers) {
|
||||||
|
p.getPositions(placementContext, randomSource, blockPos).forEach(pp -> stream.add(pp));
|
||||||
|
}
|
||||||
|
return stream.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlacementModifierType<?> type() {
|
||||||
|
return PlacementModifiers.FOR_ALL;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.placement;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.core.Vec3i;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
|
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
||||||
|
import net.minecraft.world.level.levelgen.placement.PlacementContext;
|
||||||
|
import net.minecraft.world.level.levelgen.placement.PlacementFilter;
|
||||||
|
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class Is extends PlacementFilter {
|
||||||
|
public static final Codec<Is> CODEC = RecordCodecBuilder.create((instance) -> instance
|
||||||
|
.group(
|
||||||
|
BlockPredicate.CODEC
|
||||||
|
.fieldOf("predicate")
|
||||||
|
.forGetter(cfg -> cfg.predicate),
|
||||||
|
Vec3i.CODEC
|
||||||
|
.optionalFieldOf("offset")
|
||||||
|
.forGetter(cfg -> cfg.offset)
|
||||||
|
)
|
||||||
|
.apply(instance, Is::new));
|
||||||
|
|
||||||
|
private final BlockPredicate predicate;
|
||||||
|
private final Optional<Vec3i> offset;
|
||||||
|
|
||||||
|
public Is(BlockPredicate predicate, Optional<Vec3i> offset) {
|
||||||
|
this.predicate = predicate;
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Is simple(BlockPredicate predicate) {
|
||||||
|
return new Is(predicate, Optional.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Is below(BlockPredicate predicate) {
|
||||||
|
return new Is(predicate, Optional.of(Direction.DOWN.getNormal()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Is above(BlockPredicate predicate) {
|
||||||
|
return new Is(predicate, Optional.of(Direction.UP.getNormal()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldPlace(PlacementContext ctx, RandomSource random, BlockPos pos) {
|
||||||
|
WorldGenLevel level = ctx.getLevel();
|
||||||
|
return predicate.test(level, offset.map(v -> pos.offset(v.getX(), v.getY(), v.getZ())).orElse(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlacementModifierType<Is> type() {
|
||||||
|
return PlacementModifiers.IS;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.placement;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
|
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
||||||
|
import net.minecraft.world.level.levelgen.placement.PlacementContext;
|
||||||
|
import net.minecraft.world.level.levelgen.placement.PlacementFilter;
|
||||||
|
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class IsBasin extends PlacementFilter {
|
||||||
|
public static final Codec<IsBasin> CODEC = RecordCodecBuilder.create((instance) -> instance
|
||||||
|
.group(
|
||||||
|
BlockPredicate.CODEC
|
||||||
|
.fieldOf("predicate")
|
||||||
|
.forGetter(cfg -> cfg.predicate),
|
||||||
|
BlockPredicate.CODEC
|
||||||
|
.optionalFieldOf("top_predicate")
|
||||||
|
.orElse(Optional.empty())
|
||||||
|
.forGetter(cfg -> cfg.topPredicate)
|
||||||
|
)
|
||||||
|
.apply(instance, IsBasin::new));
|
||||||
|
|
||||||
|
private final BlockPredicate predicate;
|
||||||
|
private final Optional<BlockPredicate> topPredicate;
|
||||||
|
|
||||||
|
public IsBasin(BlockPredicate predicate) {
|
||||||
|
this(predicate, Optional.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IsBasin(BlockPredicate predicate, Optional<BlockPredicate> topPredicate) {
|
||||||
|
this.predicate = predicate;
|
||||||
|
this.topPredicate = topPredicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlacementFilter simple(BlockPredicate predicate) {
|
||||||
|
return new IsBasin(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IsBasin openTop(BlockPredicate predicate) {
|
||||||
|
return new IsBasin(predicate, Optional.of(BlockPredicate.ONLY_IN_AIR_PREDICATE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldPlace(PlacementContext ctx, RandomSource random, BlockPos pos) {
|
||||||
|
WorldGenLevel level = ctx.getLevel();
|
||||||
|
if (topPredicate.isPresent() && !topPredicate.get().test(level, pos.above())) return false;
|
||||||
|
|
||||||
|
return predicate.test(level, pos.below())
|
||||||
|
&& predicate.test(level, pos.west())
|
||||||
|
&& predicate.test(level, pos.east())
|
||||||
|
&& predicate.test(level, pos.north())
|
||||||
|
&& predicate.test(level, pos.south());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlacementModifierType<?> type() {
|
||||||
|
return PlacementModifiers.IS_BASIN;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package org.betterx.bclib.api.v2.levelgen.features.placement;
|
package org.betterx.bclib.api.v3.levelgen.features.placement;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
@ -1,6 +1,5 @@
|
||||||
package org.betterx.bclib.api.v3.levelgen.features.placement;
|
package org.betterx.bclib.api.v3.levelgen.features.placement;
|
||||||
|
|
||||||
import org.betterx.bclib.api.v2.levelgen.features.placement.PlacementModifiers;
|
|
||||||
import org.betterx.bclib.noise.Noises;
|
import org.betterx.bclib.noise.Noises;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.placement;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.core.Vec3i;
|
||||||
|
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.google.common.collect.Maps;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class Offset extends PlacementModifier {
|
||||||
|
private static final Map<Direction, Offset> DIRECTIONS = Maps.newHashMap();
|
||||||
|
public static final Codec<Offset> CODEC = RecordCodecBuilder.create((instance) -> instance
|
||||||
|
.group(
|
||||||
|
Vec3i.CODEC
|
||||||
|
.fieldOf("blocks")
|
||||||
|
.forGetter(cfg -> cfg.offset)
|
||||||
|
)
|
||||||
|
.apply(instance, Offset::new));
|
||||||
|
|
||||||
|
private final Vec3i offset;
|
||||||
|
|
||||||
|
public Offset(Vec3i offset) {
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Offset inDirection(Direction dir) {
|
||||||
|
return DIRECTIONS.get(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<BlockPos> getPositions(
|
||||||
|
PlacementContext placementContext,
|
||||||
|
RandomSource randomSource,
|
||||||
|
BlockPos blockPos
|
||||||
|
) {
|
||||||
|
return Stream.of(blockPos.offset(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlacementModifierType<?> type() {
|
||||||
|
return PlacementModifiers.OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (Direction d : Direction.values())
|
||||||
|
DIRECTIONS.put(d, new Offset(d.getNormal()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.placement;
|
||||||
|
|
||||||
|
import org.betterx.bclib.util.BlocksHelper;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
|
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 java.util.Optional;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class OnEveryLayer
|
||||||
|
extends PlacementModifier {
|
||||||
|
private static final OnEveryLayer INSTANCE = new OnEveryLayer(Optional.empty(), Optional.empty());
|
||||||
|
private static final OnEveryLayer INSTANCE_MIN_4 = new OnEveryLayer(Optional.of(4), Optional.empty());
|
||||||
|
public static final Codec<OnEveryLayer> CODEC = RecordCodecBuilder.create(instance -> instance
|
||||||
|
.group(
|
||||||
|
Codec.INT.optionalFieldOf("min").forGetter(o -> o.minHeight),
|
||||||
|
Codec.INT.optionalFieldOf("max").forGetter(o -> o.maxHeight)
|
||||||
|
).apply(instance, OnEveryLayer::new));
|
||||||
|
|
||||||
|
|
||||||
|
private final Optional<Integer> minHeight;
|
||||||
|
private final Optional<Integer> maxHeight;
|
||||||
|
|
||||||
|
protected OnEveryLayer(Optional<Integer> minHeight, Optional<Integer> maxHeight) {
|
||||||
|
this.minHeight = minHeight;
|
||||||
|
|
||||||
|
this.maxHeight = maxHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OnEveryLayer simple() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OnEveryLayer min4() {
|
||||||
|
return INSTANCE_MIN_4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<BlockPos> getPositions(
|
||||||
|
PlacementContext ctx,
|
||||||
|
RandomSource random,
|
||||||
|
BlockPos pos
|
||||||
|
) {
|
||||||
|
|
||||||
|
Stream.Builder<BlockPos> builder = Stream.builder();
|
||||||
|
|
||||||
|
final int z = pos.getZ();
|
||||||
|
final int x = pos.getX();
|
||||||
|
final int levelHeight = ctx.getHeight(Heightmap.Types.MOTION_BLOCKING, x, z);
|
||||||
|
final int minLevelHeight = ctx.getMinBuildHeight();
|
||||||
|
int y = maxHeight.map(h -> Math.min(levelHeight, h)).orElse(levelHeight);
|
||||||
|
final int minHeight = this.minHeight.map(h -> Math.max(minLevelHeight, h)).orElse(minLevelHeight);
|
||||||
|
|
||||||
|
int layerY;
|
||||||
|
do {
|
||||||
|
layerY = OnEveryLayer.findOnGroundYPosition(ctx, x, y, z, minHeight);
|
||||||
|
if (layerY != Integer.MAX_VALUE) {
|
||||||
|
builder.add(new BlockPos(x, layerY, z));
|
||||||
|
y = layerY - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (layerY != Integer.MAX_VALUE);
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlacementModifierType<OnEveryLayer> type() {
|
||||||
|
return PlacementModifiers.ON_EVERY_LAYER;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int findOnGroundYPosition(PlacementContext ctx, int x, int startY, int z, int minHeight) {
|
||||||
|
BlockPos.MutableBlockPos mPos = new BlockPos.MutableBlockPos(x, startY, z);
|
||||||
|
BlockState nowState = ctx.getBlockState(mPos);
|
||||||
|
for (int y = startY; y >= minHeight + 1; --y) {
|
||||||
|
mPos.setY(y - 1);
|
||||||
|
BlockState belowState = ctx.getBlockState(mPos);
|
||||||
|
if (BlocksHelper.isTerrain(belowState) && BlocksHelper.isFreeOrFluid(nowState) && !belowState.is(Blocks.BEDROCK)) {
|
||||||
|
return mPos.getY() + 1;
|
||||||
|
}
|
||||||
|
nowState = belowState;
|
||||||
|
}
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.placement;
|
||||||
|
|
||||||
|
import org.betterx.bclib.BCLib;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||||
|
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
||||||
|
|
||||||
|
public class PlacementModifiers {
|
||||||
|
public static final PlacementModifierType<Stencil> STENCIL = register(
|
||||||
|
"stencil",
|
||||||
|
Stencil.CODEC
|
||||||
|
);
|
||||||
|
public static final PlacementModifierType<IsNextTo> IS_NEXT_TO = register(
|
||||||
|
"is_next_to",
|
||||||
|
IsNextTo.CODEC
|
||||||
|
);
|
||||||
|
public static final PlacementModifierType<NoiseFilter> NOISE_FILTER = register(
|
||||||
|
"noise_filter",
|
||||||
|
NoiseFilter.CODEC
|
||||||
|
);
|
||||||
|
public static final PlacementModifierType<Debug> DEBUG = register(
|
||||||
|
"debug",
|
||||||
|
Debug.CODEC
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final PlacementModifierType<ForAll> FOR_ALL = register(
|
||||||
|
"for_all",
|
||||||
|
ForAll.CODEC
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final PlacementModifierType<FindSolidInDirection> SOLID_IN_DIR = register(
|
||||||
|
"solid_in_dir",
|
||||||
|
FindSolidInDirection.CODEC
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final PlacementModifierType<All> ALL = register(
|
||||||
|
"all",
|
||||||
|
All.CODEC
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final PlacementModifierType<IsBasin> IS_BASIN = register(
|
||||||
|
"is_basin",
|
||||||
|
IsBasin.CODEC
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final PlacementModifierType<Is> IS = register(
|
||||||
|
"is",
|
||||||
|
Is.CODEC
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final PlacementModifierType<Offset> OFFSET = register(
|
||||||
|
"offset",
|
||||||
|
Offset.CODEC
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final PlacementModifierType<Extend> EXTEND = register(
|
||||||
|
"extend",
|
||||||
|
Extend.CODEC
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final PlacementModifierType<OnEveryLayer> ON_EVERY_LAYER = register(
|
||||||
|
"on_every_layer",
|
||||||
|
OnEveryLayer.CODEC
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final PlacementModifierType<UnderEveryLayer> UNDER_EVERY_LAYER = register(
|
||||||
|
"under_every_layer",
|
||||||
|
UnderEveryLayer.CODEC
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
private static <P extends PlacementModifier> PlacementModifierType<P> register(String path, Codec<P> codec) {
|
||||||
|
return register(BCLib.makeID(path), codec);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <P extends PlacementModifier> PlacementModifierType<P> register(
|
||||||
|
ResourceLocation location,
|
||||||
|
Codec<P> codec
|
||||||
|
) {
|
||||||
|
return Registry.register(Registry.PLACEMENT_MODIFIERS, location, () -> codec);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ensureStaticInitialization() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,345 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.placement;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.util.ExtraCodecs;
|
||||||
|
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 java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class Stencil extends PlacementModifier {
|
||||||
|
public static final Codec<Stencil> CODEC;
|
||||||
|
private static final Boolean[] BN_STENCIL;
|
||||||
|
private final List<Boolean> stencil;
|
||||||
|
private static final Stencil DEFAULT;
|
||||||
|
private static final Stencil DEFAULT4;
|
||||||
|
private final int selectOneIn;
|
||||||
|
|
||||||
|
private static List<Boolean> convert(Boolean[] s) {
|
||||||
|
return Arrays.stream(s).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stencil(Boolean[] stencil, int selectOneIn) {
|
||||||
|
this(convert(stencil), selectOneIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stencil(List<Boolean> stencil, int selectOneIn) {
|
||||||
|
this.stencil = stencil;
|
||||||
|
this.selectOneIn = selectOneIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stencil all() {
|
||||||
|
return DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stencil oneIn4() {
|
||||||
|
return DEFAULT4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<BlockPos> getPositions(
|
||||||
|
PlacementContext placementContext,
|
||||||
|
RandomSource randomSource,
|
||||||
|
BlockPos blockPos
|
||||||
|
) {
|
||||||
|
List<BlockPos> pos = new ArrayList<>(16 * 16);
|
||||||
|
for (int x = 0; x < 16; x++) {
|
||||||
|
for (int y = 0; y < 16; y++) {
|
||||||
|
if (stencil.get(x << 4 | y)) {
|
||||||
|
pos.add(blockPos.offset(x, 0, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos.stream();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlacementModifierType<?> type() {
|
||||||
|
return PlacementModifiers.STENCIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
BN_STENCIL = new Boolean[]{
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFAULT = new Stencil(BN_STENCIL, 1);
|
||||||
|
DEFAULT4 = new Stencil(BN_STENCIL, 4);
|
||||||
|
CODEC = RecordCodecBuilder.create((instance) -> instance
|
||||||
|
.group(
|
||||||
|
ExtraCodecs.nonEmptyList(Codec.BOOL.listOf())
|
||||||
|
.fieldOf("structures")
|
||||||
|
.orElse(convert(BN_STENCIL))
|
||||||
|
.forGetter((Stencil a) -> a.stencil),
|
||||||
|
Codec.INT
|
||||||
|
.fieldOf("one_in")
|
||||||
|
.orElse(1)
|
||||||
|
.forGetter((Stencil a) -> a.selectOneIn)
|
||||||
|
)
|
||||||
|
.apply(instance, Stencil::new)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
package org.betterx.bclib.api.v3.levelgen.features.placement;
|
||||||
|
|
||||||
|
import org.betterx.bclib.util.BlocksHelper;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
|
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 java.util.Optional;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class UnderEveryLayer
|
||||||
|
extends PlacementModifier {
|
||||||
|
private static final UnderEveryLayer INSTANCE = new UnderEveryLayer(Optional.empty(), Optional.empty());
|
||||||
|
private static final UnderEveryLayer INSTANCE_MIN_4 = new UnderEveryLayer(Optional.of(4), Optional.empty());
|
||||||
|
public static final Codec<UnderEveryLayer> CODEC = RecordCodecBuilder.create(instance -> instance
|
||||||
|
.group(
|
||||||
|
Codec.INT.optionalFieldOf("min").forGetter(o -> o.minHeight),
|
||||||
|
Codec.INT.optionalFieldOf("max").forGetter(o -> o.maxHeight)
|
||||||
|
).apply(instance, UnderEveryLayer::new));
|
||||||
|
|
||||||
|
|
||||||
|
private final Optional<Integer> minHeight;
|
||||||
|
private final Optional<Integer> maxHeight;
|
||||||
|
|
||||||
|
protected UnderEveryLayer(Optional<Integer> minHeight, Optional<Integer> maxHeight) {
|
||||||
|
this.minHeight = minHeight;
|
||||||
|
|
||||||
|
this.maxHeight = maxHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UnderEveryLayer simple() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UnderEveryLayer min4() {
|
||||||
|
return INSTANCE_MIN_4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<BlockPos> getPositions(
|
||||||
|
PlacementContext ctx,
|
||||||
|
RandomSource random,
|
||||||
|
BlockPos pos
|
||||||
|
) {
|
||||||
|
|
||||||
|
Stream.Builder<BlockPos> builder = Stream.builder();
|
||||||
|
|
||||||
|
final int z = pos.getZ();
|
||||||
|
final int x = pos.getX();
|
||||||
|
final int levelHeight = ctx.getHeight(Heightmap.Types.MOTION_BLOCKING, x, z);
|
||||||
|
final int minLevelHeight = ctx.getMinBuildHeight();
|
||||||
|
int y = maxHeight.map(h -> Math.min(levelHeight, h)).orElse(levelHeight);
|
||||||
|
final int minHeight = this.minHeight.map(h -> Math.max(minLevelHeight, h)).orElse(minLevelHeight);
|
||||||
|
|
||||||
|
int layerY;
|
||||||
|
do {
|
||||||
|
layerY = findUnderGroundYPosition(ctx, x, y, z, minHeight);
|
||||||
|
if (layerY != Integer.MAX_VALUE) {
|
||||||
|
builder.add(new BlockPos(x, layerY, z));
|
||||||
|
y = layerY - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (layerY != Integer.MAX_VALUE);
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlacementModifierType<UnderEveryLayer> type() {
|
||||||
|
return PlacementModifiers.UNDER_EVERY_LAYER;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int findUnderGroundYPosition(PlacementContext ctx, int x, int startY, int z, int minHeight) {
|
||||||
|
BlockPos.MutableBlockPos mPos = new BlockPos.MutableBlockPos(x, startY, z);
|
||||||
|
BlockState nowState = ctx.getBlockState(mPos);
|
||||||
|
for (int y = startY; y >= minHeight + 1; --y) {
|
||||||
|
mPos.setY(y - 1);
|
||||||
|
BlockState belowState = ctx.getBlockState(mPos);
|
||||||
|
if (BlocksHelper.isTerrain(nowState) && BlocksHelper.isFreeOrFluid(belowState) && !nowState.is(Blocks.BEDROCK)) {
|
||||||
|
return mPos.getY();
|
||||||
|
}
|
||||||
|
nowState = belowState;
|
||||||
|
}
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue