Merge branch '1.19' into 1.19.3
# Conflicts: # gradle.properties # src/main/java/org/betterx/bclib/BCLib.java # src/main/java/org/betterx/bclib/api/v2/generator/BCLChunkGenerator.java # src/main/java/org/betterx/worlds/together/mixin/common/WorldPresetsBootstrapMixin.java # src/main/java/org/betterx/worlds/together/worldPreset/WorldPresets.java # src/main/resources/bclib.accesswidener
This commit is contained in:
commit
0dcb7809b8
41 changed files with 1586 additions and 75 deletions
|
@ -15,6 +15,7 @@ import org.betterx.bclib.api.v2.levelgen.surface.rules.Conditions;
|
|||
import org.betterx.bclib.api.v2.poi.PoiManager;
|
||||
import org.betterx.bclib.api.v3.levelgen.features.blockpredicates.BlockPredicates;
|
||||
import org.betterx.bclib.api.v3.levelgen.features.placement.PlacementModifiers;
|
||||
import org.betterx.bclib.api.v3.tag.BCLBlockTags;
|
||||
import org.betterx.bclib.commands.CommandRegistry;
|
||||
import org.betterx.bclib.config.Configs;
|
||||
import org.betterx.bclib.networking.VersionChecker;
|
||||
|
@ -139,6 +140,7 @@ public class BCLib implements ModInitializer {
|
|||
AnvilRecipe.register();
|
||||
Conditions.registerAll();
|
||||
CommandRegistry.register();
|
||||
BCLBlockTags.ensureStaticallyLoaded();
|
||||
PoiManager.registerAll();
|
||||
|
||||
DataExchangeAPI.registerDescriptors(List.of(
|
||||
|
|
|
@ -25,6 +25,7 @@ public class BonemealAPI {
|
|||
private static final Set<Block> TERRAIN_TO_SPREAD = Sets.newHashSet();
|
||||
private static final Set<Block> TERRAIN = Sets.newHashSet();
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void addSpreadableBlock(Block spreadableBlock, Block surfaceForSpread) {
|
||||
SPREADABLE_BLOCKS.put(spreadableBlock, surfaceForSpread);
|
||||
TERRAIN_TO_SPREAD.add(surfaceForSpread);
|
||||
|
@ -35,38 +36,53 @@ public class BonemealAPI {
|
|||
return TERRAIN.contains(block);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static boolean isSpreadableTerrain(Block block) {
|
||||
return TERRAIN_TO_SPREAD.contains(block);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static Block getSpreadable(Block block) {
|
||||
return SPREADABLE_BLOCKS.get(block);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void addLandGrass(Block plant, Block... terrain) {
|
||||
addLandGrass(makeConsumer(plant), terrain);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void addLandGrass(BiConsumer<Level, BlockPos> plant, Block... terrain) {
|
||||
for (Block block : terrain) {
|
||||
addLandGrass(plant, block, 1F);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This API is deprecated, please use the new {@link org.betterx.bclib.api.v3.bonemeal.BonemealAPI}.
|
||||
*
|
||||
* @param biome
|
||||
* @param plant
|
||||
* @param terrain
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void addLandGrass(ResourceLocation biome, Block plant, Block... terrain) {
|
||||
addLandGrass(biome, makeConsumer(plant), terrain);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void addLandGrass(ResourceLocation biome, BiConsumer<Level, BlockPos> plant, Block... terrain) {
|
||||
for (Block block : terrain) {
|
||||
addLandGrass(biome, plant, block, 1F);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void addLandGrass(Block plant, Block terrain, float chance) {
|
||||
addLandGrass(makeConsumer(plant), terrain, chance);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void addLandGrass(BiConsumer<Level, BlockPos> plant, Block terrain, float chance) {
|
||||
WeightedList<BiConsumer<Level, BlockPos>> list = LAND_GRASS_TYPES.get(terrain);
|
||||
if (list == null) {
|
||||
|
@ -77,10 +93,12 @@ public class BonemealAPI {
|
|||
list.add(plant, chance);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void addLandGrass(ResourceLocation biome, Block plant, Block terrain, float chance) {
|
||||
addLandGrass(biome, makeConsumer(plant), terrain, chance);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void addLandGrass(
|
||||
ResourceLocation biome,
|
||||
BiConsumer<Level, BlockPos> plant,
|
||||
|
@ -159,6 +177,7 @@ public class BonemealAPI {
|
|||
list.add(plant, chance);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BiConsumer<Level, BlockPos> getLandGrass(
|
||||
ResourceLocation biomeID,
|
||||
Block terrain,
|
||||
|
|
|
@ -17,6 +17,8 @@ import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.data.worldgen.SurfaceRuleData;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
|
@ -24,12 +26,11 @@ import net.minecraft.world.level.biome.Biome;
|
|||
import net.minecraft.world.level.biome.BiomeGenerationSettings;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.biome.FeatureSorter;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
import net.minecraft.world.level.levelgen.RandomState;
|
||||
import net.minecraft.world.level.levelgen.*;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureSet;
|
||||
import net.minecraft.world.level.levelgen.synth.NormalNoise;
|
||||
|
||||
|
@ -62,6 +63,12 @@ public class BCLChunkGenerator extends NoiseBasedChunkGenerator implements Resto
|
|||
.and(builderInstance.group(noiseGetter, biomeSourceCodec, settingsCodec))
|
||||
.apply(builderInstance, builderInstance.stable(BCLChunkGenerator::new));
|
||||
});
|
||||
protected static final NoiseSettings NETHER_NOISE_SETTINGS_AMPLIFIED = NoiseSettings.create(0, 256, 1, 4);
|
||||
public static final ResourceKey<NoiseGeneratorSettings> AMPLIFIED_NETHER = ResourceKey.create(
|
||||
Registry.NOISE_GENERATOR_SETTINGS_REGISTRY,
|
||||
BCLib.makeID("amplified_nether")
|
||||
);
|
||||
|
||||
public final BiomeSource initialBiomeSource;
|
||||
|
||||
public BCLChunkGenerator(
|
||||
|
@ -225,4 +232,24 @@ public class BCLChunkGenerator extends NoiseBasedChunkGenerator implements Resto
|
|||
//
|
||||
// return Holder.direct(noise);
|
||||
}
|
||||
|
||||
|
||||
public static NoiseGeneratorSettings amplifiedNether() {
|
||||
return new NoiseGeneratorSettings(
|
||||
NETHER_NOISE_SETTINGS_AMPLIFIED,
|
||||
Blocks.NETHERRACK.defaultBlockState(),
|
||||
Blocks.LAVA.defaultBlockState(),
|
||||
NoiseRouterData.noNewCaves(
|
||||
BuiltinRegistries.DENSITY_FUNCTION,
|
||||
NoiseRouterData.slideNetherLike(BuiltinRegistries.DENSITY_FUNCTION, 0, 256)
|
||||
),
|
||||
SurfaceRuleData.nether(),
|
||||
List.of(),
|
||||
32,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,28 @@ public class BCLEndBiomeSourceConfig implements BiomeSourceConfig<BCLibEndBiomeS
|
|||
MINECRAFT_17.landBiomesSize,
|
||||
MINECRAFT_17.barrensBiomesSize
|
||||
);
|
||||
|
||||
public static final BCLEndBiomeSourceConfig MINECRAFT_18_LARGE = new BCLEndBiomeSourceConfig(
|
||||
EndBiomeMapType.HEX,
|
||||
BCLib.RUNS_NULLSCAPE ? EndBiomeGeneratorType.VANILLA : EndBiomeGeneratorType.PAULEVS,
|
||||
BCLib.RUNS_NULLSCAPE ? false : true,
|
||||
MINECRAFT_18.innerVoidRadiusSquared,
|
||||
MINECRAFT_18.centerBiomesSize,
|
||||
MINECRAFT_18.voidBiomesSize * 2,
|
||||
MINECRAFT_18.landBiomesSize * 4,
|
||||
MINECRAFT_18.barrensBiomesSize * 2
|
||||
);
|
||||
|
||||
public static final BCLEndBiomeSourceConfig MINECRAFT_18_AMPLIFIED = new BCLEndBiomeSourceConfig(
|
||||
EndBiomeMapType.HEX,
|
||||
EndBiomeGeneratorType.PAULEVS,
|
||||
true,
|
||||
MINECRAFT_18.innerVoidRadiusSquared,
|
||||
MINECRAFT_18.centerBiomesSize,
|
||||
MINECRAFT_18.voidBiomesSize,
|
||||
MINECRAFT_18.landBiomesSize,
|
||||
MINECRAFT_18.barrensBiomesSize
|
||||
);
|
||||
public static final BCLEndBiomeSourceConfig DEFAULT = MINECRAFT_18;
|
||||
|
||||
public static final Codec<BCLEndBiomeSourceConfig> CODEC = RecordCodecBuilder.create(instance -> instance
|
||||
|
|
|
@ -18,20 +18,40 @@ public class BCLNetherBiomeSourceConfig implements BiomeSourceConfig<BCLibNether
|
|||
NetherBiomeMapType.VANILLA,
|
||||
256,
|
||||
86,
|
||||
false,
|
||||
false
|
||||
);
|
||||
public static final BCLNetherBiomeSourceConfig MINECRAFT_17 = new BCLNetherBiomeSourceConfig(
|
||||
NetherBiomeMapType.SQUARE,
|
||||
256,
|
||||
86,
|
||||
true
|
||||
true,
|
||||
false
|
||||
);
|
||||
public static final BCLNetherBiomeSourceConfig MINECRAFT_18 = new BCLNetherBiomeSourceConfig(
|
||||
NetherBiomeMapType.HEX,
|
||||
MINECRAFT_17.biomeSize,
|
||||
MINECRAFT_17.biomeSizeVertical,
|
||||
MINECRAFT_17.useVerticalBiomes
|
||||
MINECRAFT_17.useVerticalBiomes,
|
||||
MINECRAFT_17.amplified
|
||||
);
|
||||
|
||||
public static final BCLNetherBiomeSourceConfig MINECRAFT_18_LARGE = new BCLNetherBiomeSourceConfig(
|
||||
NetherBiomeMapType.HEX,
|
||||
MINECRAFT_18.biomeSize * 4,
|
||||
MINECRAFT_18.biomeSizeVertical * 2,
|
||||
MINECRAFT_18.useVerticalBiomes,
|
||||
MINECRAFT_17.amplified
|
||||
);
|
||||
|
||||
public static final BCLNetherBiomeSourceConfig MINECRAFT_18_AMPLIFIED = new BCLNetherBiomeSourceConfig(
|
||||
NetherBiomeMapType.HEX,
|
||||
MINECRAFT_18.biomeSize,
|
||||
128,
|
||||
true,
|
||||
true
|
||||
);
|
||||
|
||||
public static final BCLNetherBiomeSourceConfig DEFAULT = MINECRAFT_18;
|
||||
|
||||
public static final Codec<BCLNetherBiomeSourceConfig> CODEC = RecordCodecBuilder.create(instance -> instance
|
||||
|
@ -46,7 +66,10 @@ public class BCLNetherBiomeSourceConfig implements BiomeSourceConfig<BCLibNether
|
|||
.forGetter(o -> o.biomeSizeVertical),
|
||||
Codec.BOOL.fieldOf("use_vertical_biomes")
|
||||
.orElse(DEFAULT.useVerticalBiomes)
|
||||
.forGetter(o -> o.useVerticalBiomes)
|
||||
.forGetter(o -> o.useVerticalBiomes),
|
||||
Codec.BOOL.fieldOf("amplified")
|
||||
.orElse(DEFAULT.amplified)
|
||||
.forGetter(o -> o.amplified)
|
||||
)
|
||||
.apply(instance, BCLNetherBiomeSourceConfig::new));
|
||||
public final @NotNull NetherBiomeMapType mapVersion;
|
||||
|
@ -54,23 +77,30 @@ public class BCLNetherBiomeSourceConfig implements BiomeSourceConfig<BCLibNether
|
|||
public final int biomeSizeVertical;
|
||||
|
||||
public final boolean useVerticalBiomes;
|
||||
public final boolean amplified;
|
||||
|
||||
public BCLNetherBiomeSourceConfig(
|
||||
@NotNull NetherBiomeMapType mapVersion,
|
||||
int biomeSize,
|
||||
int biomeSizeVertical,
|
||||
boolean useVerticalBiomes
|
||||
boolean useVerticalBiomes,
|
||||
boolean amplified
|
||||
) {
|
||||
this.mapVersion = mapVersion;
|
||||
this.biomeSize = Mth.clamp(biomeSize, 1, 8192);
|
||||
this.biomeSizeVertical = Mth.clamp(biomeSizeVertical, 1, 8192);
|
||||
this.useVerticalBiomes = useVerticalBiomes;
|
||||
this.amplified = amplified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BCLibNetherBiomeSourceConfig{" +
|
||||
"mapVersion=" + mapVersion +
|
||||
", useVerticalBiomes=" + useVerticalBiomes +
|
||||
", amplified=" + amplified +
|
||||
", biomeSize=" + biomeSize +
|
||||
", biomeSizeVertical=" + biomeSizeVertical +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
package org.betterx.bclib.api.v3.bonemeal;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.util.random.SimpleWeightedRandomList;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.feature.stateproviders.WeightedStateProvider;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
abstract class BlockSpreader implements BonemealBlockSpreader {
|
||||
protected abstract boolean isValidSource(BlockState state);
|
||||
protected abstract boolean hasCustomBehaviour(BlockState state);
|
||||
|
||||
public boolean isValidBonemealSpreadTarget(
|
||||
BlockGetter blockGetter,
|
||||
BlockPos blockPos,
|
||||
BlockState blockState,
|
||||
boolean bl
|
||||
) {
|
||||
if (!blockGetter.getBlockState(blockPos.above()).propagatesSkylightDown(blockGetter, blockPos)) {
|
||||
return false;
|
||||
} else {
|
||||
for (BlockPos testPos : BlockPos.betweenClosed(
|
||||
blockPos.offset(-1, -1, -1),
|
||||
blockPos.offset(1, 1, 1)
|
||||
)) {
|
||||
BlockState state = blockGetter.getBlockState(testPos);
|
||||
if (isValidSource(state))
|
||||
if (hasCustomBehaviour(state))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean performBonemealSpread(
|
||||
ServerLevel serverLevel,
|
||||
RandomSource randomSource,
|
||||
BlockPos blockPos,
|
||||
BlockState blockState
|
||||
) {
|
||||
final Map<BlockState, Integer> sourceBlocks = new HashMap<>();
|
||||
|
||||
for (BlockPos testPos : BlockPos.betweenClosed(
|
||||
blockPos.offset(-1, -1, -1),
|
||||
blockPos.offset(1, 1, 1)
|
||||
)) {
|
||||
BlockState state = serverLevel.getBlockState(testPos);
|
||||
if (isValidSource(state)) {
|
||||
sourceBlocks.compute(state, (k, v) -> {
|
||||
if (v == null) return 1;
|
||||
return v + 1;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
SimpleWeightedRandomList.Builder<BlockState> builder = new SimpleWeightedRandomList.Builder<>();
|
||||
for (Map.Entry<BlockState, Integer> e : sourceBlocks.entrySet()) {
|
||||
builder.add(e.getKey(), e.getValue());
|
||||
}
|
||||
WeightedStateProvider provider = new WeightedStateProvider(builder.build());
|
||||
|
||||
BlockState bl = provider.getState(randomSource, blockPos);
|
||||
if (bl != null) {
|
||||
serverLevel.setBlock(blockPos, bl, 3);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
144
src/main/java/org/betterx/bclib/api/v3/bonemeal/BonemealAPI.java
Normal file
144
src/main/java/org/betterx/bclib/api/v3/bonemeal/BonemealAPI.java
Normal file
|
@ -0,0 +1,144 @@
|
|||
package org.betterx.bclib.api.v3.bonemeal;
|
||||
|
||||
import org.betterx.bclib.api.v3.levelgen.features.BCLConfigureFeature;
|
||||
import org.betterx.bclib.api.v3.tag.BCLBlockTags;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BonemealAPI {
|
||||
public static BonemealAPI INSTANCE = new BonemealAPI();
|
||||
private final Map<TagKey<Block>, BonemealBlockSpreader> taggedSpreaders;
|
||||
private final Map<Block, FeatureSpreader> featureSpreaders;
|
||||
|
||||
private BonemealAPI() {
|
||||
taggedSpreaders = new HashMap<>();
|
||||
featureSpreaders = new HashMap<>();
|
||||
|
||||
addSpreadableBlocks(BCLBlockTags.BONEMEAL_TARGET_NETHERRACK, NetherrackSpreader.INSTANCE);
|
||||
addSpreadableBlocks(BCLBlockTags.BONEMEAL_TARGET_END_STONE, EndStoneSpreader.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bonemeal can be used to spread vegetation to neighbouring blocks.
|
||||
* <p>
|
||||
* This method allows you to register a block (the type that was clicked with bonemeal) with
|
||||
* a {@link BCLConfigureFeature} that will be placed on the bonemeald block
|
||||
* <p>
|
||||
* You can achieve the same behaviour by implementing {@link BonemealNyliumLike} on your custom
|
||||
* BlockClass. This is mainly intended for vanilla Blocks where you need to add bonemeal
|
||||
* behaviour
|
||||
*
|
||||
* @param target The block-type
|
||||
* @param spreadableFeature the feature to place
|
||||
*/
|
||||
public void addSpreadableFeatures(
|
||||
Block target,
|
||||
@NotNull BCLConfigureFeature<? extends Feature<?>, ?> spreadableFeature
|
||||
) {
|
||||
featureSpreaders.put(target, new FeatureSpreader(target, spreadableFeature));
|
||||
}
|
||||
|
||||
/**
|
||||
* Bonemeal can be used to spread for example Nylium to Netherrack.
|
||||
* <p>
|
||||
* In this example, Netherrack is the target block which will get replaced by one of the source blocks (like
|
||||
* Warped or Crimson Nylium. You can register Tag-Combinations to easily add your own behaviour for custom
|
||||
* blocks.
|
||||
* <p>
|
||||
* When a Block with the Target-Tag
|
||||
*
|
||||
* @param targetTag If you click a Block with the given Tag using Bonemeal, you will replace it with
|
||||
* a block from the sourceTag
|
||||
* @param sourceTag Blocks with this Tag can replace the Target block if they are in a 3x3 Neighborhood
|
||||
* centered around the target Block.
|
||||
*/
|
||||
public void addSpreadableBlocks(@NotNull TagKey<Block> targetTag, @NotNull TagKey<Block> sourceTag) {
|
||||
taggedSpreaders.put(targetTag, new TaggedBonemealBlockSpreader(sourceTag));
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #addSpreadableBlocks(TagKey, TagKey)} for Details.
|
||||
*
|
||||
* @param targetTag If you click a Block with the given Tag using Bonemeal, you will replace it with
|
||||
* * a block from the sourceTag
|
||||
* @param spreader The {@link BonemealBlockSpreader}-Object that is called when a corresponding target-Block
|
||||
* is clicked with Bone-Meal
|
||||
*/
|
||||
public void addSpreadableBlocks(@NotNull TagKey<Block> targetTag, @NotNull BonemealBlockSpreader spreader) {
|
||||
taggedSpreaders.put(targetTag, spreader);
|
||||
}
|
||||
|
||||
/**
|
||||
* When a block is clicked with Bonemeal, this method will be called with the state of the given Block.
|
||||
* <p>
|
||||
* If the Method returs a valid {@link BonemealBlockSpreader}-Instance, it will override the default behaviour
|
||||
* for the BoneMeal, otherwise the vanilla action will be performed.
|
||||
*
|
||||
* @param state The {@link BlockState} you need to test
|
||||
* @return A valid spreader instance, or {@code null}
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public BonemealBlockSpreader blockSpreaderForState(@NotNull BlockState state) {
|
||||
for (var e : taggedSpreaders.entrySet()) {
|
||||
if (state.is(e.getKey())) {
|
||||
return e.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public FeatureSpreader featureSpreaderForState(@NotNull BlockState state) {
|
||||
return featureSpreaders.get(state.getBlock());
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public boolean runSpreaders(ItemStack itemStack, Level level, BlockPos blockPos) {
|
||||
BlockState blockState = level.getBlockState(blockPos);
|
||||
BonemealBlockSpreader spreader = org.betterx.bclib.api.v3.bonemeal.BonemealAPI
|
||||
.INSTANCE
|
||||
.blockSpreaderForState(blockState);
|
||||
|
||||
if (spreader != null) {
|
||||
if (spreader.isValidBonemealSpreadTarget(level, blockPos, blockState, level.isClientSide)) {
|
||||
if (level instanceof ServerLevel) {
|
||||
if (spreader.performBonemealSpread((ServerLevel) level, level.random, blockPos, blockState)) {
|
||||
itemStack.shrink(1);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
FeatureSpreader fSpreader = org.betterx.bclib.api.v3.bonemeal.BonemealAPI
|
||||
.INSTANCE
|
||||
.featureSpreaderForState(blockState);
|
||||
|
||||
if (fSpreader != null) {
|
||||
if (fSpreader.isValidBonemealTarget(level, blockPos, blockState, level.isClientSide)) {
|
||||
if (level instanceof ServerLevel) {
|
||||
if (fSpreader.isBonemealSuccess(level, level.random, blockPos, blockState)) {
|
||||
fSpreader.performBonemeal((ServerLevel) level, level.random, blockPos, blockState);
|
||||
}
|
||||
itemStack.shrink(1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package org.betterx.bclib.api.v3.bonemeal;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public interface BonemealBlockSpreader {
|
||||
boolean isValidBonemealSpreadTarget(BlockGetter blockGetter, BlockPos blockPos, BlockState blockState, boolean bl);
|
||||
|
||||
|
||||
boolean performBonemealSpread(
|
||||
ServerLevel serverLevel,
|
||||
RandomSource randomSource,
|
||||
BlockPos blockPos,
|
||||
BlockState blockState
|
||||
);
|
||||
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
package org.betterx.bclib.api.v3.bonemeal;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.BonemealableBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.RandomPatchConfiguration;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface BonemealGrassLike extends BonemealableBlock {
|
||||
BlockState getGrowableCoverState(); //Blocks.GRASS.defaultBlockState();
|
||||
Block getHostBlock(); //this
|
||||
|
||||
Holder<PlacedFeature> getCoverFeature(); //VegetationPlacements.GRASS_BONEMEAL
|
||||
List<ConfiguredFeature<?, ?>> getFlowerFeatures(); /*serverLevel.getBiome(currentPos)
|
||||
.value()
|
||||
.getGenerationSettings()
|
||||
.getFlowerFeatures();*/
|
||||
|
||||
default boolean canGrowFlower(RandomSource random) {
|
||||
return random.nextInt(8) == 0;
|
||||
}
|
||||
default boolean canGrowCover(RandomSource random) {
|
||||
return random.nextInt(10) == 0;
|
||||
}
|
||||
|
||||
default boolean isValidBonemealTarget(
|
||||
BlockGetter blockGetter,
|
||||
BlockPos blockPos,
|
||||
BlockState blockState,
|
||||
boolean bl
|
||||
) {
|
||||
return blockGetter.getBlockState(blockPos.above()).isAir();
|
||||
}
|
||||
|
||||
default boolean isBonemealSuccess(
|
||||
Level level,
|
||||
RandomSource randomSource,
|
||||
BlockPos blockPos,
|
||||
BlockState blockState
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
default void performBonemeal(ServerLevel serverLevel, RandomSource random, BlockPos pos, BlockState state) {
|
||||
final BlockPos above = pos.above();
|
||||
final BlockState growableState = getGrowableCoverState();
|
||||
|
||||
outerLoop:
|
||||
for (int bonemealAttempt = 0; bonemealAttempt < 128; ++bonemealAttempt) {
|
||||
BlockPos currentPos = above;
|
||||
|
||||
for (int j = 0; j < bonemealAttempt / 16; ++j) {
|
||||
currentPos = currentPos.offset(
|
||||
random.nextInt(3) - 1,
|
||||
(random.nextInt(3) - 1) * random.nextInt(3) / 2,
|
||||
random.nextInt(3) - 1
|
||||
);
|
||||
if (!serverLevel.getBlockState(currentPos.below()).is(getHostBlock())
|
||||
|| serverLevel.getBlockState(currentPos)
|
||||
.isCollisionShapeFullBlock(serverLevel, currentPos)) {
|
||||
continue outerLoop;
|
||||
}
|
||||
}
|
||||
|
||||
BlockState currentState = serverLevel.getBlockState(currentPos);
|
||||
if (currentState.is(growableState.getBlock()) && canGrowCover(random)) {
|
||||
((BonemealableBlock) growableState.getBlock()).performBonemeal(
|
||||
serverLevel,
|
||||
random,
|
||||
currentPos,
|
||||
currentState
|
||||
);
|
||||
}
|
||||
|
||||
if (currentState.isAir()) {
|
||||
Holder<PlacedFeature> boneFeature;
|
||||
if (canGrowFlower(random)) {
|
||||
List<ConfiguredFeature<?, ?>> list = getFlowerFeatures();
|
||||
if (list.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boneFeature = ((RandomPatchConfiguration) list.get(0).config()).feature();
|
||||
} else {
|
||||
boneFeature = getCoverFeature();
|
||||
}
|
||||
|
||||
boneFeature.value()
|
||||
.place(serverLevel, serverLevel.getChunkSource().getGenerator(), random, currentPos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package org.betterx.bclib.api.v3.bonemeal;
|
||||
|
||||
import org.betterx.bclib.api.v3.levelgen.features.BCLConfigureFeature;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.BonemealableBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
|
||||
//adapted from NyliumBlock
|
||||
public interface BonemealNyliumLike extends BonemealableBlock {
|
||||
Block getHostBlock(); //this
|
||||
BCLConfigureFeature<? extends Feature<?>, ?> getCoverFeature();
|
||||
|
||||
default boolean isValidBonemealTarget(
|
||||
BlockGetter blockGetter,
|
||||
BlockPos blockPos,
|
||||
BlockState blockState,
|
||||
boolean bl
|
||||
) {
|
||||
return blockGetter.getBlockState(blockPos.above()).isAir();
|
||||
}
|
||||
|
||||
default boolean isBonemealSuccess(
|
||||
Level level,
|
||||
RandomSource randomSource,
|
||||
BlockPos blockPos,
|
||||
BlockState blockState
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
default void performBonemeal(
|
||||
ServerLevel serverLevel,
|
||||
RandomSource randomSource,
|
||||
BlockPos blockPos,
|
||||
BlockState blockState
|
||||
) {
|
||||
final BlockState currentState = serverLevel.getBlockState(blockPos);
|
||||
if (currentState.is(getHostBlock())) {
|
||||
BCLConfigureFeature<? extends Feature<?>, ?> feature = getCoverFeature();
|
||||
if (feature != null) {
|
||||
feature.placeInWorld(serverLevel, blockPos.above(), randomSource, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.betterx.bclib.api.v3.bonemeal;
|
||||
|
||||
import org.betterx.bclib.api.v3.tag.BCLBlockTags;
|
||||
|
||||
public class EndStoneSpreader extends TaggedBonemealBlockSpreader {
|
||||
static final EndStoneSpreader INSTANCE = new EndStoneSpreader();
|
||||
|
||||
protected EndStoneSpreader() {
|
||||
super(BCLBlockTags.BONEMEAL_SOURCE_END_STONE);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package org.betterx.bclib.api.v3.bonemeal;
|
||||
|
||||
import org.betterx.bclib.api.v3.levelgen.features.BCLConfigureFeature;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
|
||||
public class FeatureSpreader implements BonemealNyliumLike {
|
||||
public final BCLConfigureFeature<? extends Feature<?>, ?> spreadableFeature;
|
||||
public final Block hostBlock;
|
||||
|
||||
public FeatureSpreader(Block hostBlock, BCLConfigureFeature<? extends Feature<?>, ?> spreadableFeature) {
|
||||
this.spreadableFeature = spreadableFeature;
|
||||
this.hostBlock = hostBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidBonemealTarget(
|
||||
BlockGetter blockGetter,
|
||||
BlockPos blockPos,
|
||||
BlockState blockState,
|
||||
boolean bl
|
||||
) {
|
||||
return spreadableFeature != null
|
||||
&& BonemealNyliumLike.super.isValidBonemealTarget(blockGetter, blockPos, blockState, bl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getHostBlock() {
|
||||
return hostBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BCLConfigureFeature<? extends Feature<?>, ?> getCoverFeature() {
|
||||
return spreadableFeature;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package org.betterx.bclib.api.v3.bonemeal;
|
||||
|
||||
import org.betterx.bclib.api.v3.tag.BCLBlockTags;
|
||||
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class NetherrackSpreader extends TaggedBonemealBlockSpreader {
|
||||
public static final NetherrackSpreader INSTANCE = new NetherrackSpreader();
|
||||
|
||||
protected NetherrackSpreader() {
|
||||
super(BCLBlockTags.BONEMEAL_SOURCE_NETHERRACK);
|
||||
}
|
||||
|
||||
protected boolean hasCustomBehaviour(BlockState state) {
|
||||
return !state.is(Blocks.WARPED_NYLIUM) && !state.is(Blocks.CRIMSON_NYLIUM);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package org.betterx.bclib.api.v3.bonemeal;
|
||||
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
class TaggedBonemealBlockSpreader extends BlockSpreader {
|
||||
public final TagKey<Block> blockTag;
|
||||
|
||||
public TaggedBonemealBlockSpreader(TagKey<Block> blockTag) {
|
||||
this.blockTag = blockTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isValidSource(BlockState state) {
|
||||
return state.is(blockTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasCustomBehaviour(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -55,7 +55,11 @@ public class BCLConfigureFeature<F extends Feature<FC>, FC extends FeatureConfig
|
|||
}
|
||||
|
||||
public boolean placeInWorld(ServerLevel level, BlockPos pos, RandomSource random) {
|
||||
return placeInWorld(getFeature(), getConfiguration(), level, pos, random);
|
||||
return placeInWorld(level, pos, random, false);
|
||||
}
|
||||
|
||||
public boolean placeInWorld(ServerLevel level, BlockPos pos, RandomSource random, boolean unchanged) {
|
||||
return placeUnboundInWorld(getFeature(), getConfiguration(), level, pos, random, unchanged);
|
||||
}
|
||||
|
||||
private static boolean placeUnboundInWorld(
|
||||
|
@ -63,16 +67,19 @@ public class BCLConfigureFeature<F extends Feature<FC>, FC extends FeatureConfig
|
|||
FeatureConfiguration config,
|
||||
ServerLevel level,
|
||||
BlockPos pos,
|
||||
RandomSource random
|
||||
RandomSource random,
|
||||
boolean asIs
|
||||
) {
|
||||
if (config instanceof RandomPatchConfiguration rnd) {
|
||||
var configured = rnd.feature().value().feature().value();
|
||||
feature = configured.feature();
|
||||
config = configured.config();
|
||||
}
|
||||
if (!asIs) {
|
||||
if (config instanceof RandomPatchConfiguration rnd) {
|
||||
var configured = rnd.feature().value().feature().value();
|
||||
feature = configured.feature();
|
||||
config = configured.config();
|
||||
}
|
||||
|
||||
if (feature instanceof UserGrowableFeature growable) {
|
||||
return growable.grow(level, pos, random, config);
|
||||
if (feature instanceof UserGrowableFeature growable) {
|
||||
return growable.grow(level, pos, random, config);
|
||||
}
|
||||
}
|
||||
|
||||
FeaturePlaceContext context = new FeaturePlaceContext(
|
||||
|
@ -92,7 +99,7 @@ public class BCLConfigureFeature<F extends Feature<FC>, FC extends FeatureConfig
|
|||
BlockPos pos,
|
||||
RandomSource random
|
||||
) {
|
||||
return placeUnboundInWorld(feature, FeatureConfiguration.NONE, level, pos, random);
|
||||
return placeUnboundInWorld(feature, FeatureConfiguration.NONE, level, pos, random, true);
|
||||
}
|
||||
|
||||
public static <FC extends FeatureConfiguration> boolean placeInWorld(
|
||||
|
@ -102,6 +109,6 @@ public class BCLConfigureFeature<F extends Feature<FC>, FC extends FeatureConfig
|
|||
BlockPos pos,
|
||||
RandomSource random
|
||||
) {
|
||||
return placeUnboundInWorld(feature, config, level, pos, random);
|
||||
return placeUnboundInWorld(feature, config, level, pos, random, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ import org.jetbrains.annotations.NotNull;
|
|||
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends FeatureConfiguration> {
|
||||
private final ResourceLocation featureID;
|
||||
protected final ResourceLocation featureID;
|
||||
private final F feature;
|
||||
|
||||
private BCLFeatureBuilder(ResourceLocation featureID, F feature) {
|
||||
|
@ -100,6 +100,22 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
|
|||
);
|
||||
}
|
||||
|
||||
public static WeightedBlockPatch startWeightedRandomPatch(
|
||||
ResourceLocation featureID
|
||||
) {
|
||||
return new WeightedBlockPatch(
|
||||
featureID,
|
||||
(RandomPatchFeature) Feature.RANDOM_PATCH
|
||||
);
|
||||
}
|
||||
|
||||
public static WeightedBlockPatch startBonemealPatch(
|
||||
ResourceLocation featureID
|
||||
) {
|
||||
return startWeightedRandomPatch(featureID).likeDefaultBonemeal();
|
||||
}
|
||||
|
||||
|
||||
public static RandomPatch startRandomPatch(
|
||||
ResourceLocation featureID,
|
||||
Holder<PlacedFeature> featureToPlace
|
||||
|
@ -140,6 +156,15 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
|
|||
);
|
||||
}
|
||||
|
||||
public static NetherForrestVegetation startBonemealNetherVegetation(
|
||||
ResourceLocation featureID
|
||||
) {
|
||||
return new NetherForrestVegetation(
|
||||
featureID,
|
||||
(NetherForestVegetationFeature) Feature.NETHER_FOREST_VEGETATION
|
||||
).spreadHeight(1).spreadWidth(3);
|
||||
}
|
||||
|
||||
|
||||
public static WithTemplates startWithTemplates(
|
||||
ResourceLocation featureID
|
||||
|
@ -773,9 +798,86 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
|
|||
}
|
||||
}
|
||||
|
||||
public static class WeightedBlock extends BCLFeatureBuilder<SimpleBlockFeature, SimpleBlockConfiguration> {
|
||||
SimpleWeightedRandomList.Builder<BlockState> stateBuilder = SimpleWeightedRandomList.builder();
|
||||
public static class WeightedBlockPatch extends WeightedBaseBlock<RandomPatchFeature, RandomPatchConfiguration, WeightedBlockPatch> {
|
||||
|
||||
private BlockPredicate groundType = null;
|
||||
private boolean isEmpty = true;
|
||||
private int tries = 96;
|
||||
private int xzSpread = 7;
|
||||
private int ySpread = 3;
|
||||
|
||||
protected WeightedBlockPatch(@NotNull ResourceLocation featureID, @NotNull RandomPatchFeature feature) {
|
||||
super(featureID, feature);
|
||||
}
|
||||
|
||||
public WeightedBlockPatch isEmpty() {
|
||||
return this.isEmpty(true);
|
||||
}
|
||||
|
||||
public WeightedBlockPatch isEmpty(boolean value) {
|
||||
this.isEmpty = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public WeightedBlockPatch isOn(BlockPredicate predicate) {
|
||||
this.groundType = predicate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public WeightedBlockPatch isEmptyAndOn(BlockPredicate predicate) {
|
||||
return this.isEmpty().isOn(predicate);
|
||||
}
|
||||
|
||||
public WeightedBlockPatch likeDefaultNetherVegetation() {
|
||||
return likeDefaultNetherVegetation(8, 4);
|
||||
}
|
||||
|
||||
public WeightedBlockPatch likeDefaultNetherVegetation(int xzSpread, int ySpread) {
|
||||
this.xzSpread = xzSpread;
|
||||
this.ySpread = ySpread;
|
||||
tries = xzSpread * xzSpread;
|
||||
return this;
|
||||
}
|
||||
|
||||
public WeightedBlockPatch likeDefaultBonemeal() {
|
||||
return this.tries(9)
|
||||
.spreadXZ(3)
|
||||
.spreadY(1);
|
||||
}
|
||||
|
||||
public WeightedBlockPatch tries(int v) {
|
||||
tries = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
public WeightedBlockPatch spreadXZ(int v) {
|
||||
xzSpread = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
public WeightedBlockPatch spreadY(int v) {
|
||||
ySpread = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RandomPatchConfiguration createConfiguration() {
|
||||
BCLInlinePlacedBuilder<Feature<SimpleBlockConfiguration>, SimpleBlockConfiguration> blockFeature = BCLFeatureBuilder
|
||||
.start(
|
||||
new ResourceLocation(featureID.getNamespace(), "tmp_" + featureID.getPath()),
|
||||
Feature.SIMPLE_BLOCK
|
||||
)
|
||||
.configuration(new SimpleBlockConfiguration(new WeightedStateProvider(stateBuilder.build())))
|
||||
.inlinePlace();
|
||||
|
||||
if (isEmpty) blockFeature.isEmpty();
|
||||
if (groundType != null) blockFeature.isOn(groundType);
|
||||
|
||||
return new RandomPatchConfiguration(tries, xzSpread, ySpread, blockFeature.build());
|
||||
}
|
||||
}
|
||||
|
||||
public static class WeightedBlock extends WeightedBaseBlock<SimpleBlockFeature, SimpleBlockConfiguration, WeightedBlock> {
|
||||
private WeightedBlock(
|
||||
@NotNull ResourceLocation featureID,
|
||||
@NotNull SimpleBlockFeature feature
|
||||
|
@ -783,31 +885,70 @@ public abstract class BCLFeatureBuilder<F extends Feature<FC>, FC extends Featur
|
|||
super(featureID, feature);
|
||||
}
|
||||
|
||||
public WeightedBlock add(Block block, int weight) {
|
||||
return add(block.defaultBlockState(), weight);
|
||||
}
|
||||
|
||||
public WeightedBlock add(BlockState state, int weight) {
|
||||
stateBuilder.add(state, weight);
|
||||
return this;
|
||||
}
|
||||
|
||||
public WeightedBlock addAllStates(Block block, int weight) {
|
||||
Set<BlockState> states = BCLPoiType.getBlockStates(block);
|
||||
states.forEach(s -> add(block.defaultBlockState(), Math.max(1, weight / states.size())));
|
||||
return this;
|
||||
}
|
||||
|
||||
public WeightedBlock addAllStatesFor(IntegerProperty prop, Block block, int weight) {
|
||||
Collection<Integer> values = prop.getPossibleValues();
|
||||
values.forEach(s -> add(block.defaultBlockState().setValue(prop, s), Math.max(1, weight / values.size())));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleBlockConfiguration createConfiguration() {
|
||||
return new SimpleBlockConfiguration(new WeightedStateProvider(stateBuilder.build()));
|
||||
}
|
||||
|
||||
//TODO: Remove in the next Minor Update. This method is just for backward compatibility.
|
||||
|
||||
@Override
|
||||
public WeightedBlock add(Block block, int weight) {
|
||||
return super.add(block, weight);
|
||||
}
|
||||
|
||||
//TODO: Remove in the next Minor Update. This method is just for backward compatibility.
|
||||
@Override
|
||||
public WeightedBlock add(BlockState state, int weight) {
|
||||
return super.add(state, weight);
|
||||
}
|
||||
|
||||
//TODO: Remove in the next Minor Update. This method is just for backward compatibility.
|
||||
|
||||
@Override
|
||||
public WeightedBlock addAllStates(Block block, int weight) {
|
||||
return super.addAllStates(block, weight);
|
||||
}
|
||||
|
||||
//TODO: Remove in the next Minor Update. This method is just for backward compatibility.
|
||||
|
||||
@Override
|
||||
public WeightedBlock addAllStatesFor(IntegerProperty prop, Block block, int weight) {
|
||||
return super.addAllStatesFor(prop, block, weight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private abstract static class WeightedBaseBlock<F extends Feature<FC>, FC extends FeatureConfiguration, W extends WeightedBaseBlock> extends BCLFeatureBuilder<F, FC> {
|
||||
SimpleWeightedRandomList.Builder<BlockState> stateBuilder = SimpleWeightedRandomList.builder();
|
||||
|
||||
protected WeightedBaseBlock(
|
||||
@NotNull ResourceLocation featureID,
|
||||
@NotNull F feature
|
||||
) {
|
||||
super(featureID, feature);
|
||||
}
|
||||
|
||||
public W add(Block block, int weight) {
|
||||
return add(block.defaultBlockState(), weight);
|
||||
}
|
||||
|
||||
public W add(BlockState state, int weight) {
|
||||
stateBuilder.add(state, weight);
|
||||
return (W) this;
|
||||
}
|
||||
|
||||
public W addAllStates(Block block, int weight) {
|
||||
Set<BlockState> states = BCLPoiType.getBlockStates(block);
|
||||
states.forEach(s -> add(block.defaultBlockState(), Math.max(1, weight / states.size())));
|
||||
return (W) this;
|
||||
}
|
||||
|
||||
public W addAllStatesFor(IntegerProperty prop, Block block, int weight) {
|
||||
Collection<Integer> values = prop.getPossibleValues();
|
||||
values.forEach(s -> add(block.defaultBlockState().setValue(prop, s), Math.max(1, weight / values.size())));
|
||||
return (W) this;
|
||||
}
|
||||
}
|
||||
|
||||
public static class AsRandomSelect extends BCLFeatureBuilder<RandomSelectorFeature, RandomFeatureConfiguration> {
|
||||
|
|
|
@ -354,6 +354,15 @@ abstract class CommonPlacedFeatureBuilder<F extends Feature<FC>, FC extends Feat
|
|||
return modifier(Is.below(predicate));
|
||||
}
|
||||
|
||||
|
||||
public T inBiomes(ResourceLocation... biomeID) {
|
||||
return modifier(InBiome.matchingID(biomeID));
|
||||
}
|
||||
|
||||
public T notInBiomes(ResourceLocation... biomeID) {
|
||||
return modifier(InBiome.notMatchingID(biomeID));
|
||||
}
|
||||
|
||||
public T isEmptyAndOn(BlockPredicate predicate) {
|
||||
return (T) this.isEmpty().isOn(predicate);
|
||||
}
|
||||
|
@ -420,4 +429,11 @@ abstract class CommonPlacedFeatureBuilder<F extends Feature<FC>, FC extends Feat
|
|||
public BCLFeatureBuilder.RandomPatch inRandomPatch(ResourceLocation id) {
|
||||
return BCLFeatureBuilder.startRandomPatch(id, build());
|
||||
}
|
||||
|
||||
public BCLFeatureBuilder.RandomPatch randomBonemealDistribution(ResourceLocation id) {
|
||||
return inRandomPatch(id)
|
||||
.tries(9)
|
||||
.spreadXZ(3)
|
||||
.spreadY(1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
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.Holder;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
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.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class InBiome extends PlacementFilter {
|
||||
public static final Codec<InBiome> CODEC = RecordCodecBuilder.create((instance) -> instance
|
||||
.group(
|
||||
Codec.BOOL
|
||||
.fieldOf("negate")
|
||||
.orElse(false)
|
||||
.forGetter(cfg -> cfg.negate),
|
||||
Codec.list(ResourceLocation.CODEC)
|
||||
.fieldOf("biomes")
|
||||
.forGetter(cfg -> cfg.biomeIDs)
|
||||
)
|
||||
.apply(instance, InBiome::new));
|
||||
|
||||
public final List<ResourceLocation> biomeIDs;
|
||||
public final boolean negate;
|
||||
|
||||
protected InBiome(boolean negate, List<ResourceLocation> biomeIDs) {
|
||||
this.biomeIDs = biomeIDs;
|
||||
this.negate = negate;
|
||||
}
|
||||
|
||||
public static InBiome matchingID(ResourceLocation... id) {
|
||||
return new InBiome(false, List.of(id));
|
||||
}
|
||||
|
||||
public static InBiome matchingID(List<ResourceLocation> ids) {
|
||||
return new InBiome(false, ids);
|
||||
}
|
||||
|
||||
public static InBiome notMatchingID(ResourceLocation... id) {
|
||||
return new InBiome(true, List.of(id));
|
||||
}
|
||||
|
||||
public static InBiome notMatchingID(List<ResourceLocation> ids) {
|
||||
return new InBiome(true, ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldPlace(PlacementContext ctx, RandomSource random, BlockPos pos) {
|
||||
Holder<Biome> holder = ctx.getLevel().getBiome(pos);
|
||||
Optional<ResourceLocation> biomeLocation = holder.unwrapKey().map(key -> key.location());
|
||||
if (biomeLocation.isPresent()) {
|
||||
boolean contains = biomeIDs.contains(biomeLocation.get());
|
||||
return negate != contains;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlacementModifierType<InBiome> type() {
|
||||
return PlacementModifiers.IN_BIOME;
|
||||
}
|
||||
}
|
|
@ -71,6 +71,11 @@ public class PlacementModifiers {
|
|||
UnderEveryLayer.CODEC
|
||||
);
|
||||
|
||||
public static final PlacementModifierType<InBiome> IN_BIOME = register(
|
||||
"in_biome",
|
||||
InBiome.CODEC
|
||||
);
|
||||
|
||||
|
||||
private static <P extends PlacementModifier> PlacementModifierType<P> register(String path, Codec<P> codec) {
|
||||
return register(BCLib.makeID(path), codec);
|
||||
|
|
38
src/main/java/org/betterx/bclib/api/v3/tag/BCLBlockTags.java
Normal file
38
src/main/java/org/betterx/bclib/api/v3/tag/BCLBlockTags.java
Normal file
|
@ -0,0 +1,38 @@
|
|||
package org.betterx.bclib.api.v3.tag;
|
||||
|
||||
import org.betterx.worlds.together.tag.v3.TagManager;
|
||||
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
public class BCLBlockTags {
|
||||
public static final TagKey<Block> BONEMEAL_SOURCE_NETHERRACK = TagManager.BLOCKS.makeTogetherTag(
|
||||
"bonemeal/source/netherrack"
|
||||
);
|
||||
public static final TagKey<Block> BONEMEAL_TARGET_NETHERRACK = TagManager.BLOCKS.makeTogetherTag(
|
||||
"bonemeal/target/netherrack"
|
||||
);
|
||||
public static final TagKey<Block> BONEMEAL_SOURCE_END_STONE = TagManager.BLOCKS.makeTogetherTag(
|
||||
"bonemeal/source/end_stone"
|
||||
);
|
||||
public static final TagKey<Block> BONEMEAL_TARGET_END_STONE = TagManager.BLOCKS.makeTogetherTag(
|
||||
"bonemeal/target/end_stone"
|
||||
);
|
||||
public static final TagKey<Block> BONEMEAL_SOURCE_OBSIDIAN = TagManager.BLOCKS.makeTogetherTag(
|
||||
"bonemeal/source/obsidian"
|
||||
);
|
||||
public static final TagKey<Block> BONEMEAL_TARGET_OBSIDIAN = TagManager.BLOCKS.makeTogetherTag(
|
||||
"bonemeal/target/obsidian"
|
||||
);
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void ensureStaticallyLoaded() {
|
||||
TagManager.BLOCKS.add(BONEMEAL_SOURCE_NETHERRACK, Blocks.WARPED_NYLIUM, Blocks.CRIMSON_NYLIUM);
|
||||
TagManager.BLOCKS.add(BONEMEAL_TARGET_NETHERRACK, Blocks.NETHERRACK);
|
||||
TagManager.BLOCKS.add(BONEMEAL_TARGET_END_STONE, Blocks.END_STONE);
|
||||
TagManager.BLOCKS.add(BONEMEAL_TARGET_OBSIDIAN, Blocks.OBSIDIAN);
|
||||
}
|
||||
}
|
|
@ -109,8 +109,37 @@ public class FeatureSaplingBlock<F extends Feature<FC>, FC extends FeatureConfig
|
|||
|
||||
@Override
|
||||
public void advanceTree(ServerLevel world, BlockPos pos, BlockState blockState, RandomSource random) {
|
||||
BCLConfigureFeature<F, FC> conf = getConfiguredFeature(blockState);
|
||||
conf.placeInWorld(world, pos, random);
|
||||
if (blockState.getValue(STAGE) == 0) {
|
||||
world.setBlock(pos, blockState.cycle(STAGE), 4);
|
||||
} else {
|
||||
BCLConfigureFeature<F, FC> conf = getConfiguredFeature(blockState);
|
||||
growFeature(conf, world, pos, blockState, random);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean growFeature(
|
||||
BCLConfigureFeature<F, FC> feature,
|
||||
ServerLevel serverLevel,
|
||||
BlockPos blockPos,
|
||||
BlockState originalBlockState,
|
||||
RandomSource randomSource
|
||||
) {
|
||||
if (feature == null) {
|
||||
return false;
|
||||
} else {
|
||||
BlockState emptyState = serverLevel.getFluidState(blockPos).createLegacyBlock();
|
||||
serverLevel.setBlock(blockPos, emptyState, 4);
|
||||
if (feature.placeInWorld(serverLevel, blockPos, randomSource)) {
|
||||
if (serverLevel.getBlockState(blockPos) == emptyState) {
|
||||
serverLevel.sendBlockUpdated(blockPos, originalBlockState, emptyState, 2);
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
serverLevel.setBlock(blockPos, originalBlockState, 4);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -81,8 +81,47 @@ public class UpdatesScreen extends BCLibLayoutScreen {
|
|||
row.addText(fit(), fit(), Component.literal(" -> "));
|
||||
row.addText(fit(), fit(), Component.literal(updated)).setColor(ColorHelper.GREEN);
|
||||
row.addFiller();
|
||||
if (nfo != null && nfo.getMetadata().getContact().get("homepage").isPresent()) {
|
||||
row.addButton(fit(), fit(), Component.translatable("bclib.updates.curseforge_link"))
|
||||
boolean createdDownloadLink = false;
|
||||
if (nfo != null
|
||||
&& nfo.getMetadata().getCustomValue("bclib") != null
|
||||
&& nfo.getMetadata().getCustomValue("bclib").getAsObject().get("downloads") != null) {
|
||||
CustomValue.CvObject downloadLinks = nfo.getMetadata()
|
||||
.getCustomValue("bclib")
|
||||
.getAsObject()
|
||||
.get("downloads")
|
||||
.getAsObject();
|
||||
String link = null;
|
||||
Component name = null;
|
||||
if (Configs.CLIENT_CONFIG.preferModrinthForUpdates() && downloadLinks.get("modrinth") != null) {
|
||||
link = downloadLinks.get("modrinth").getAsString();
|
||||
name = Component.translatable("bclib.updates.modrinth_link");
|
||||
// row.addButton(fit(), fit(), Component.translatable("bclib.updates.modrinth_link"))
|
||||
// .onPress((bt) -> {
|
||||
// this.openLink(downloadLinks.get("modrinth").getAsString());
|
||||
// }).centerVertical();
|
||||
// createdDownloadLink = true;
|
||||
} else if (downloadLinks.get("curseforge") != null) {
|
||||
link = downloadLinks.get("curseforge").getAsString();
|
||||
name = Component.translatable("bclib.updates.curseforge_link");
|
||||
// row.addButton(fit(), fit(), Component.translatable("bclib.updates.curseforge_link"))
|
||||
// .onPress((bt) -> {
|
||||
// this.openLink(downloadLinks.get("curseforge").getAsString());
|
||||
// }).centerVertical();
|
||||
// createdDownloadLink = true;
|
||||
}
|
||||
|
||||
if (link != null) {
|
||||
createdDownloadLink = true;
|
||||
final String finalLink = link;
|
||||
row.addButton(fit(), fit(), name)
|
||||
.onPress((bt) -> {
|
||||
this.openLink(finalLink);
|
||||
}).centerVertical();
|
||||
}
|
||||
}
|
||||
|
||||
if (!createdDownloadLink && nfo != null && nfo.getMetadata().getContact().get("homepage").isPresent()) {
|
||||
row.addButton(fit(), fit(), Component.translatable("bclib.updates.download_link"))
|
||||
.onPress((bt) -> {
|
||||
this.openLink(nfo.getMetadata().getContact().get("homepage").get());
|
||||
}).centerVertical();
|
||||
|
|
|
@ -41,6 +41,8 @@ import org.jetbrains.annotations.Nullable;
|
|||
public class WorldSetupScreen extends LayoutScreen {
|
||||
private final WorldCreationContext context;
|
||||
private final CreateWorldScreen createWorldScreen;
|
||||
private Range<Integer> netherBiomeSize;
|
||||
private Range<Integer> netherVerticalBiomeSize;
|
||||
private Range<Integer> landBiomeSize;
|
||||
private Range<Integer> voidBiomeSize;
|
||||
private Range<Integer> centerBiomeSize;
|
||||
|
@ -60,6 +62,8 @@ public class WorldSetupScreen extends LayoutScreen {
|
|||
Checkbox endCustomTerrain;
|
||||
Checkbox generateEndVoid;
|
||||
Checkbox netherLegacy;
|
||||
Checkbox netherVertical;
|
||||
Checkbox netherAmplified;
|
||||
|
||||
public LayoutComponent<?, ?> netherPage(BCLNetherBiomeSourceConfig netherConfig) {
|
||||
VerticalStack content = new VerticalStack(fill(), fit()).centerHorizontal();
|
||||
|
@ -77,9 +81,51 @@ public class WorldSetupScreen extends LayoutScreen {
|
|||
netherConfig.mapVersion == BCLNetherBiomeSourceConfig.NetherBiomeMapType.SQUARE
|
||||
);
|
||||
|
||||
netherAmplified = content.indent(20).addCheckbox(
|
||||
fit(), fit(),
|
||||
Component.translatable("title.screen.bclib.worldgen.nether_amplified"),
|
||||
netherConfig.amplified
|
||||
);
|
||||
|
||||
netherVertical = content.indent(20).addCheckbox(
|
||||
fit(), fit(),
|
||||
Component.translatable("title.screen.bclib.worldgen.nether_vertical"),
|
||||
netherConfig.useVerticalBiomes
|
||||
);
|
||||
|
||||
content.addSpacer(12);
|
||||
content.addText(fit(), fit(), Component.translatable("title.screen.bclib.worldgen.avg_biome_size"))
|
||||
.centerHorizontal();
|
||||
content.addHorizontalSeparator(8).alignTop();
|
||||
|
||||
netherBiomeSize = content.addRange(
|
||||
fixed(200),
|
||||
fit(),
|
||||
Component.translatable("title.screen.bclib.worldgen.nether_biome_size"),
|
||||
1,
|
||||
512,
|
||||
netherConfig.biomeSize / 16
|
||||
);
|
||||
|
||||
netherVerticalBiomeSize = content.addRange(
|
||||
fixed(200),
|
||||
fit(),
|
||||
Component.translatable("title.screen.bclib.worldgen.nether_vertical_biome_size"),
|
||||
1,
|
||||
32,
|
||||
netherConfig.biomeSizeVertical / 16
|
||||
);
|
||||
|
||||
bclibNether.onChange((cb, state) -> {
|
||||
netherLegacy.setEnabled(state);
|
||||
netherAmplified.setEnabled(state);
|
||||
netherVertical.setEnabled(state);
|
||||
netherBiomeSize.setEnabled(state);
|
||||
netherVerticalBiomeSize.setEnabled(state && netherVertical.isChecked());
|
||||
});
|
||||
|
||||
netherVertical.onChange((cb, state) -> {
|
||||
netherVerticalBiomeSize.setEnabled(state && bclibNether.isChecked());
|
||||
});
|
||||
|
||||
content.addSpacer(8);
|
||||
|
@ -198,6 +244,8 @@ public class WorldSetupScreen extends LayoutScreen {
|
|||
private void updateSettings() {
|
||||
Map<ResourceKey<LevelStem>, ChunkGenerator> betterxDimensions = TogetherWorldPreset.getDimensionsMap(
|
||||
PresetsRegistry.BCL_WORLD);
|
||||
Map<ResourceKey<LevelStem>, ChunkGenerator> betterxAmplifiedDimensions = TogetherWorldPreset.getDimensionsMap(
|
||||
PresetsRegistry.BCL_WORLD_AMPLIFIED);
|
||||
Map<ResourceKey<LevelStem>, ChunkGenerator> vanillaDimensions = TogetherWorldPreset.getDimensionsMap(
|
||||
WorldPresets.NORMAL);
|
||||
BCLEndBiomeSourceConfig.EndBiomeMapType endVersion = BCLEndBiomeSourceConfig.DEFAULT.mapVersion;
|
||||
|
@ -233,12 +281,17 @@ public class WorldSetupScreen extends LayoutScreen {
|
|||
netherLegacy.isChecked()
|
||||
? BCLNetherBiomeSourceConfig.NetherBiomeMapType.SQUARE
|
||||
: BCLNetherBiomeSourceConfig.NetherBiomeMapType.HEX,
|
||||
BCLNetherBiomeSourceConfig.DEFAULT.biomeSize,
|
||||
BCLNetherBiomeSourceConfig.DEFAULT.biomeSizeVertical,
|
||||
BCLNetherBiomeSourceConfig.DEFAULT.useVerticalBiomes
|
||||
netherBiomeSize.getValue() * 16,
|
||||
netherVerticalBiomeSize.getValue() * 16,
|
||||
netherVertical.isChecked(),
|
||||
netherAmplified.isChecked()
|
||||
);
|
||||
|
||||
ChunkGenerator netherGenerator = betterxDimensions.get(LevelStem.NETHER);
|
||||
ChunkGenerator netherGenerator = (
|
||||
netherAmplified.isChecked()
|
||||
? betterxAmplifiedDimensions
|
||||
: betterxDimensions
|
||||
).get(LevelStem.NETHER);
|
||||
((BCLibNetherBiomeSource) netherGenerator.getBiomeSource()).setTogetherConfig(netherConfig);
|
||||
|
||||
updateConfiguration(LevelStem.NETHER, BuiltinDimensionTypes.NETHER, netherGenerator);
|
||||
|
|
|
@ -11,7 +11,6 @@ public class ClientConfig extends NamedPathConfig {
|
|||
"didShowWelcome",
|
||||
"version"
|
||||
);
|
||||
@ConfigUI(topPadding = 12)
|
||||
public static final ConfigToken<Boolean> CHECK_VERSIONS = ConfigToken.Boolean(
|
||||
true,
|
||||
"check",
|
||||
|
@ -24,12 +23,20 @@ public class ClientConfig extends NamedPathConfig {
|
|||
"ui"
|
||||
);
|
||||
|
||||
@ConfigUI(leftPadding = 8)
|
||||
public static final ConfigToken<Boolean> PREFER_MODRINTH_FOR_UPDATES = ConfigToken.Boolean(
|
||||
true,
|
||||
"preferModrinthForUpdates",
|
||||
"ui"
|
||||
);
|
||||
|
||||
@ConfigUI(hide = true)
|
||||
public static final ConfigToken<Boolean> FORCE_BETTERX_PRESET = ConfigToken.Boolean(
|
||||
true,
|
||||
"forceBetterXPreset",
|
||||
"ui"
|
||||
);
|
||||
@ConfigUI(topPadding = 12)
|
||||
public static final ConfigToken<Boolean> SUPPRESS_EXPERIMENTAL_DIALOG = ConfigToken.Boolean(
|
||||
false,
|
||||
"suppressExperimentalDialogOnLoad",
|
||||
|
@ -107,6 +114,8 @@ public class ClientConfig extends NamedPathConfig {
|
|||
"rendering",
|
||||
(config) -> config.get(CUSTOM_FOG_RENDERING)
|
||||
);
|
||||
|
||||
@ConfigUI(topPadding = 12)
|
||||
public static final ConfigToken<Boolean> SURVIES_ON_HINT = ConfigToken.Boolean(
|
||||
true,
|
||||
"survives_on_hint",
|
||||
|
@ -194,8 +203,12 @@ public class ClientConfig extends NamedPathConfig {
|
|||
public void setForceBetterXPreset(boolean v) {
|
||||
set(FORCE_BETTERX_PRESET, v);
|
||||
}
|
||||
|
||||
|
||||
public boolean survivesOnHint() {
|
||||
return get(ClientConfig.SURVIES_ON_HINT);
|
||||
}
|
||||
|
||||
public boolean preferModrinthForUpdates() {
|
||||
return get(ClientConfig.PREFER_MODRINTH_FOR_UPDATES);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,7 @@ package org.betterx.bclib.config;
|
|||
import org.betterx.bclib.BCLib;
|
||||
|
||||
public class MainConfig extends NamedPathConfig {
|
||||
public static final ConfigToken<Boolean> VERBOSE_LOGGING = ConfigToken.Boolean(
|
||||
true,
|
||||
"verbose",
|
||||
Configs.MAIN_INFO_CATEGORY
|
||||
);
|
||||
|
||||
|
||||
public static final ConfigToken<Boolean> APPLY_PATCHES = ConfigToken.Boolean(
|
||||
true,
|
||||
|
@ -15,7 +11,7 @@ public class MainConfig extends NamedPathConfig {
|
|||
Configs.MAIN_PATCH_CATEGORY
|
||||
);
|
||||
|
||||
@ConfigUI(leftPadding = 8, topPadding = 8)
|
||||
@ConfigUI(leftPadding = 8)
|
||||
public static final ConfigToken<Boolean> REPAIR_BIOMES = DependendConfigToken.Boolean(
|
||||
false,
|
||||
"repairBiomesOnLoad",
|
||||
|
@ -24,6 +20,13 @@ public class MainConfig extends NamedPathConfig {
|
|||
APPLY_PATCHES)
|
||||
);
|
||||
|
||||
@ConfigUI(topPadding = 8)
|
||||
public static final ConfigToken<Boolean> VERBOSE_LOGGING = ConfigToken.Boolean(
|
||||
true,
|
||||
"verbose",
|
||||
Configs.MAIN_INFO_CATEGORY
|
||||
);
|
||||
|
||||
|
||||
public MainConfig() {
|
||||
super(BCLib.MOD_ID, "main", true, true);
|
||||
|
|
|
@ -9,9 +9,147 @@ import net.minecraft.world.level.ItemLike;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class EquipmentSet {
|
||||
public static class AttackDamage {
|
||||
public static SetValues WOOD_LEVEL = EquipmentSet.SetValues
|
||||
.create()
|
||||
.add(EquipmentSet.SWORD_SLOT, 3)
|
||||
.add(EquipmentSet.SHOVEL_SLOT, 1.5f)
|
||||
.add(EquipmentSet.PICKAXE_SLOT, 1)
|
||||
.add(EquipmentSet.AXE_SLOT, 6)
|
||||
.add(EquipmentSet.HOE_SLOT, 0);
|
||||
|
||||
public static SetValues STONE_LEVEL = EquipmentSet.SetValues
|
||||
.create()
|
||||
.add(EquipmentSet.SWORD_SLOT, 3)
|
||||
.add(EquipmentSet.SHOVEL_SLOT, 1.5f)
|
||||
.add(EquipmentSet.PICKAXE_SLOT, 1)
|
||||
.add(EquipmentSet.AXE_SLOT, 7)
|
||||
.add(EquipmentSet.HOE_SLOT, -1);
|
||||
|
||||
public static SetValues GOLDEN_LEVEL = EquipmentSet.SetValues
|
||||
.create()
|
||||
.add(EquipmentSet.SWORD_SLOT, 3)
|
||||
.add(EquipmentSet.SHOVEL_SLOT, 1.5f)
|
||||
.add(EquipmentSet.PICKAXE_SLOT, 1)
|
||||
.add(EquipmentSet.AXE_SLOT, 6)
|
||||
.add(EquipmentSet.HOE_SLOT, 0);
|
||||
public static SetValues IRON_LEVEL = EquipmentSet.SetValues
|
||||
.create()
|
||||
.add(EquipmentSet.SWORD_SLOT, 3)
|
||||
.add(EquipmentSet.SHOVEL_SLOT, 1.5f)
|
||||
.add(EquipmentSet.PICKAXE_SLOT, 1)
|
||||
.add(EquipmentSet.AXE_SLOT, 6)
|
||||
.add(EquipmentSet.HOE_SLOT, -2);
|
||||
|
||||
public static SetValues DIAMOND_LEVEL = EquipmentSet.SetValues
|
||||
.create()
|
||||
.add(EquipmentSet.SWORD_SLOT, 3)
|
||||
.add(EquipmentSet.SHOVEL_SLOT, 1.5f)
|
||||
.add(EquipmentSet.PICKAXE_SLOT, 1)
|
||||
.add(EquipmentSet.AXE_SLOT, 5)
|
||||
.add(EquipmentSet.HOE_SLOT, -3);
|
||||
|
||||
public static SetValues NETHERITE_LEVEL = EquipmentSet.SetValues
|
||||
.create()
|
||||
.add(EquipmentSet.SWORD_SLOT, 3)
|
||||
.add(EquipmentSet.SHOVEL_SLOT, 1.5f)
|
||||
.add(EquipmentSet.PICKAXE_SLOT, 1)
|
||||
.add(EquipmentSet.AXE_SLOT, 5)
|
||||
.add(EquipmentSet.HOE_SLOT, -4);
|
||||
}
|
||||
|
||||
public static class AttackSpeed {
|
||||
public static SetValues WOOD_LEVEL = EquipmentSet.SetValues
|
||||
.create()
|
||||
.add(EquipmentSet.SWORD_SLOT, -2.4f)
|
||||
.add(EquipmentSet.SHOVEL_SLOT, -3.0f)
|
||||
.add(EquipmentSet.PICKAXE_SLOT, -2.8f)
|
||||
.add(EquipmentSet.AXE_SLOT, -3.2f)
|
||||
.add(EquipmentSet.HOE_SLOT, -3.0f);
|
||||
|
||||
public static SetValues STONE_LEVEL = EquipmentSet.SetValues
|
||||
.create()
|
||||
.add(EquipmentSet.SWORD_SLOT, -2.4f)
|
||||
.add(EquipmentSet.SHOVEL_SLOT, -3.0f)
|
||||
.add(EquipmentSet.PICKAXE_SLOT, -2.8f)
|
||||
.add(EquipmentSet.AXE_SLOT, -3.2f)
|
||||
.add(EquipmentSet.HOE_SLOT, -2.0f);
|
||||
|
||||
public static SetValues GOLDEN_LEVEL = EquipmentSet.SetValues
|
||||
.create()
|
||||
.add(EquipmentSet.SWORD_SLOT, -2.4f)
|
||||
.add(EquipmentSet.SHOVEL_SLOT, -3.0f)
|
||||
.add(EquipmentSet.PICKAXE_SLOT, -2.8f)
|
||||
.add(EquipmentSet.AXE_SLOT, -3.0f)
|
||||
.add(EquipmentSet.HOE_SLOT, -3.0f);
|
||||
public static SetValues IRON_LEVEL = EquipmentSet.SetValues
|
||||
.create()
|
||||
.add(EquipmentSet.SWORD_SLOT, -2.4f)
|
||||
.add(EquipmentSet.SHOVEL_SLOT, -3.0f)
|
||||
.add(EquipmentSet.PICKAXE_SLOT, -2.8f)
|
||||
.add(EquipmentSet.AXE_SLOT, -3.1f)
|
||||
.add(EquipmentSet.HOE_SLOT, -1.0f);
|
||||
|
||||
public static SetValues DIAMOND_LEVEL = EquipmentSet.SetValues
|
||||
.create()
|
||||
.add(EquipmentSet.SWORD_SLOT, -2.4f)
|
||||
.add(EquipmentSet.SHOVEL_SLOT, -3.0f)
|
||||
.add(EquipmentSet.PICKAXE_SLOT, -2.8f)
|
||||
.add(EquipmentSet.AXE_SLOT, -3.0f)
|
||||
.add(EquipmentSet.HOE_SLOT, 0.0f);
|
||||
|
||||
public static SetValues NETHERITE_LEVEL = DIAMOND_LEVEL;
|
||||
}
|
||||
|
||||
public interface ItemDescriptorCreator<I extends Item> {
|
||||
EquipmentDescription<I> build(Item base, Function<Tier, I> creator);
|
||||
}
|
||||
|
||||
public interface DescriptorCreator<I extends Item> {
|
||||
EquipmentDescription<I> build(Function<Tier, I> creator);
|
||||
}
|
||||
|
||||
public interface ItemCreator<I extends Item> {
|
||||
I build(Tier t, float attackDamage, float attackSpeed);
|
||||
}
|
||||
|
||||
public static class SetValues {
|
||||
private final Map<String, Float> values;
|
||||
|
||||
private SetValues() {
|
||||
values = new HashMap<>();
|
||||
}
|
||||
|
||||
public static SetValues create() {
|
||||
return new SetValues();
|
||||
}
|
||||
|
||||
public static SetValues copy(SetValues source, float offset) {
|
||||
SetValues v = create();
|
||||
for (var e : source.values.entrySet())
|
||||
v.add(e.getKey(), e.getValue() + offset);
|
||||
return v;
|
||||
}
|
||||
|
||||
public SetValues add(String slot, float value) {
|
||||
values.put(slot, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SetValues offset(String slot, float offset) {
|
||||
values.put(slot, get(slot) + offset);
|
||||
return this;
|
||||
}
|
||||
|
||||
public float get(String slot) {
|
||||
return values.getOrDefault(slot, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public final Tier material;
|
||||
public final String baseName;
|
||||
public final String modID;
|
||||
|
@ -28,19 +166,62 @@ public abstract class EquipmentSet {
|
|||
public static final String LEGGINGS_SLOT = "leggings";
|
||||
public static final String BOOTS_SLOT = "boots";
|
||||
|
||||
public final SetValues attackDamage;
|
||||
public final SetValues attackSpeed;
|
||||
|
||||
private final Map<String, EquipmentDescription<?>> descriptions = new HashMap<>();
|
||||
|
||||
public EquipmentSet(Tier material, String modID, String baseName, ItemLike stick) {
|
||||
@Deprecated(forRemoval = true)
|
||||
public EquipmentSet(
|
||||
Tier material,
|
||||
String modID,
|
||||
String baseName,
|
||||
ItemLike stick
|
||||
) {
|
||||
this(material, modID, baseName, stick, AttackDamage.IRON_LEVEL, AttackSpeed.IRON_LEVEL);
|
||||
}
|
||||
|
||||
public EquipmentSet(
|
||||
Tier material,
|
||||
String modID,
|
||||
String baseName,
|
||||
ItemLike stick,
|
||||
SetValues attackDamage,
|
||||
SetValues attackSpeed
|
||||
) {
|
||||
this.material = material;
|
||||
this.baseName = baseName;
|
||||
this.modID = modID;
|
||||
this.stick = stick;
|
||||
this.attackDamage = attackDamage;
|
||||
this.attackSpeed = attackSpeed;
|
||||
}
|
||||
|
||||
protected <I extends Item> void add(String slot, EquipmentDescription<I> desc) {
|
||||
descriptions.put(slot, desc);
|
||||
}
|
||||
|
||||
protected <I extends Item> void add(
|
||||
String slot,
|
||||
EquipmentSet baseSet,
|
||||
ItemDescriptorCreator<I> descriptor,
|
||||
ItemCreator<I> item
|
||||
) {
|
||||
EquipmentDescription<I> desc = descriptor.build(
|
||||
baseSet.getSlot(slot),
|
||||
(tier) -> item.build(tier, this.attackDamage.get(slot), this.attackSpeed.get(slot))
|
||||
);
|
||||
descriptions.put(slot, desc);
|
||||
}
|
||||
|
||||
protected <I extends Item> void add(String slot, DescriptorCreator<I> descriptor, ItemCreator<I> item) {
|
||||
EquipmentDescription<I> desc = descriptor.build(
|
||||
(tier) -> item.build(tier, this.attackDamage.get(slot), this.attackSpeed.get(slot))
|
||||
);
|
||||
descriptions.put(slot, desc);
|
||||
}
|
||||
|
||||
|
||||
public EquipmentSet init(ItemRegistry itemsRegistry) {
|
||||
for (var desc : descriptions.entrySet()) {
|
||||
desc.getValue()
|
||||
|
|
|
@ -10,6 +10,7 @@ import net.minecraft.core.BlockPos.MutableBlockPos;
|
|||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.item.BoneMealItem;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
@ -33,7 +34,7 @@ public class BoneMealItemMixin {
|
|||
@Inject(method = "useOn", at = @At("HEAD"), cancellable = true)
|
||||
private void bclib_onUse(UseOnContext context, CallbackInfoReturnable<InteractionResult> info) {
|
||||
Level world = context.getLevel();
|
||||
BlockPos blockPos = context.getClickedPos();
|
||||
final BlockPos blockPos = context.getClickedPos();
|
||||
if (!world.isClientSide()) {
|
||||
if (BonemealAPI.isTerrain(world.getBlockState(blockPos).getBlock())) {
|
||||
boolean consume = false;
|
||||
|
@ -65,6 +66,21 @@ public class BoneMealItemMixin {
|
|||
}
|
||||
}
|
||||
|
||||
@Inject(method = "growCrop", at = @At("HEAD"), cancellable = true)
|
||||
private static void bcl_growCrop(
|
||||
ItemStack itemStack,
|
||||
Level level,
|
||||
BlockPos blockPos,
|
||||
CallbackInfoReturnable<Boolean> cir
|
||||
) {
|
||||
if (org.betterx.bclib.api.v3.bonemeal.BonemealAPI
|
||||
.INSTANCE
|
||||
.runSpreaders(itemStack, level, blockPos)
|
||||
) {
|
||||
cir.setReturnValue(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private boolean bclib_growLandGrass(Level level, BlockPos pos) {
|
||||
int y1 = pos.getY() + 3;
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import org.betterx.bclib.api.v2.generator.BCLChunkGenerator;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(NoiseGeneratorSettings.class)
|
||||
public abstract class NoiseGeneratorSettingsMixin {
|
||||
@Shadow
|
||||
static protected Holder<NoiseGeneratorSettings> register(
|
||||
Registry<NoiseGeneratorSettings> registry,
|
||||
ResourceKey<NoiseGeneratorSettings> resourceKey,
|
||||
NoiseGeneratorSettings noiseGeneratorSettings
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
@Inject(method = "bootstrap", at = @At("HEAD"))
|
||||
private static void bcl_addNoiseGenerators(
|
||||
Registry<NoiseGeneratorSettings> registry,
|
||||
CallbackInfoReturnable<Holder<NoiseGeneratorSettings>> cir
|
||||
) {
|
||||
register(registry, BCLChunkGenerator.AMPLIFIED_NETHER, BCLChunkGenerator.amplifiedNether());
|
||||
}
|
||||
}
|
|
@ -131,8 +131,8 @@ public class VersionChecker implements Runnable {
|
|||
}
|
||||
if (mod.n != null && mod.v != null && KNOWN_MODS.contains(mod.n)) {
|
||||
String installedVersion = ModUtil.getModVersion(mod.n);
|
||||
boolean isNew = ModUtil.isLargerVersion(mod.v, installedVersion) && !installedVersion.equals(
|
||||
"0.0.0");
|
||||
boolean isNew = ModUtil.isLargerVersion(mod.v, installedVersion)
|
||||
&& !installedVersion.equals("0.0.0");
|
||||
BCLib.LOGGER.info(" - " + mod.n + ":" + mod.v + (isNew ? " (update available)" : ""));
|
||||
if (isNew)
|
||||
NEW_VERSIONS.add(mod);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.betterx.bclib.registry;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.v2.generator.BCLChunkGenerator;
|
||||
import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig;
|
||||
import org.betterx.bclib.api.v2.generator.config.BCLNetherBiomeSourceConfig;
|
||||
import org.betterx.bclib.api.v2.levelgen.LevelGenUtil;
|
||||
|
@ -10,33 +11,81 @@ import org.betterx.worlds.together.levelgen.WorldGenUtil;
|
|||
import org.betterx.worlds.together.worldPreset.TogetherWorldPreset;
|
||||
import org.betterx.worlds.together.worldPreset.WorldPresets;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
import net.minecraft.world.level.levelgen.presets.WorldPreset;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class PresetsRegistry implements WorldPresetBootstrap {
|
||||
|
||||
public static ResourceKey<WorldPreset> BCL_WORLD;
|
||||
public static ResourceKey<WorldPreset> BCL_WORLD_LARGE;
|
||||
public static ResourceKey<WorldPreset> BCL_WORLD_AMPLIFIED;
|
||||
public static ResourceKey<WorldPreset> BCL_WORLD_17;
|
||||
|
||||
public void bootstrapWorldPresets() {
|
||||
BCL_WORLD =
|
||||
WorldPresets.register(
|
||||
BCLib.makeID("normal"),
|
||||
(overworldStem, netherContext, endContext) ->
|
||||
(overworldStem, netherContext, endContext, noiseSettings, noiseBasedOverworld) ->
|
||||
buildPreset(
|
||||
overworldStem,
|
||||
netherContext,
|
||||
BCLNetherBiomeSourceConfig.DEFAULT, endContext,
|
||||
BCLEndBiomeSourceConfig.DEFAULT
|
||||
netherContext, BCLNetherBiomeSourceConfig.DEFAULT,
|
||||
endContext, BCLEndBiomeSourceConfig.DEFAULT
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
BCL_WORLD_LARGE =
|
||||
WorldPresets.register(
|
||||
BCLib.makeID("large"),
|
||||
(overworldStem, netherContext, endContext, noiseSettings, noiseBasedOverworld) -> {
|
||||
Holder<NoiseGeneratorSettings> largeBiomeGenerator = noiseSettings
|
||||
.getOrCreateHolderOrThrow(NoiseGeneratorSettings.LARGE_BIOMES);
|
||||
return buildPreset(
|
||||
noiseBasedOverworld.make(
|
||||
overworldStem.generator().getBiomeSource(),
|
||||
largeBiomeGenerator
|
||||
),
|
||||
netherContext, BCLNetherBiomeSourceConfig.MINECRAFT_18_LARGE,
|
||||
endContext, BCLEndBiomeSourceConfig.MINECRAFT_18_LARGE
|
||||
);
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
BCL_WORLD_AMPLIFIED = WorldPresets.register(
|
||||
BCLib.makeID("amplified"),
|
||||
(overworldStem, netherContext, endContext, noiseSettings, noiseBasedOverworld) -> {
|
||||
Holder<NoiseGeneratorSettings> amplifiedBiomeGenerator = noiseSettings
|
||||
.getOrCreateHolderOrThrow(NoiseGeneratorSettings.AMPLIFIED);
|
||||
|
||||
WorldGenUtil.Context amplifiedNetherContext = new WorldGenUtil.Context(
|
||||
netherContext.biomes,
|
||||
netherContext.dimension,
|
||||
netherContext.structureSets,
|
||||
netherContext.noiseParameters,
|
||||
Holder.direct(BCLChunkGenerator.amplifiedNether())
|
||||
);
|
||||
|
||||
return buildPreset(
|
||||
noiseBasedOverworld.make(
|
||||
overworldStem.generator().getBiomeSource(),
|
||||
amplifiedBiomeGenerator
|
||||
),
|
||||
amplifiedNetherContext, BCLNetherBiomeSourceConfig.MINECRAFT_18_AMPLIFIED,
|
||||
endContext, BCLEndBiomeSourceConfig.MINECRAFT_18_AMPLIFIED
|
||||
);
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
BCL_WORLD_17 = WorldPresets.register(
|
||||
BCLib.makeID("legacy_17"),
|
||||
(overworldStem, netherContext, endContext) ->
|
||||
(overworldStem, netherContext, endContext, noiseSettings, noiseBasedOverworld) ->
|
||||
buildPreset(
|
||||
overworldStem,
|
||||
netherContext,
|
||||
|
|
|
@ -12,5 +12,19 @@ public class PresetsRegistryClient {
|
|||
WorldPresetsClient.registerCustomizeUI(PresetsRegistry.BCL_WORLD, (createWorldScreen, worldCreationContext) -> {
|
||||
return new WorldSetupScreen(createWorldScreen, worldCreationContext);
|
||||
});
|
||||
|
||||
WorldPresetsClient.registerCustomizeUI(
|
||||
PresetsRegistry.BCL_WORLD_LARGE,
|
||||
(createWorldScreen, worldCreationContext) -> {
|
||||
return new WorldSetupScreen(createWorldScreen, worldCreationContext);
|
||||
}
|
||||
);
|
||||
|
||||
WorldPresetsClient.registerCustomizeUI(
|
||||
PresetsRegistry.BCL_WORLD_AMPLIFIED,
|
||||
(createWorldScreen, worldCreationContext) -> {
|
||||
return new WorldSetupScreen(createWorldScreen, worldCreationContext);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import org.betterx.worlds.together.worldPreset.WorldPresets;
|
|||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
|
@ -47,7 +48,17 @@ public abstract class WorldPresetsBootstrapMixin {
|
|||
private Holder<NoiseGeneratorSettings> endNoiseSettings;
|
||||
|
||||
//see WorldPresets.register
|
||||
|
||||
|
||||
@Shadow
|
||||
protected abstract LevelStem makeNoiseBasedOverworld(
|
||||
BiomeSource biomeSource,
|
||||
Holder<NoiseGeneratorSettings> holder
|
||||
);
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private Registry<NoiseGeneratorSettings> noiseSettings;
|
||||
|
||||
@ModifyArg(method = "run", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/level/levelgen/presets/WorldPresets$Bootstrap;registerCustomOverworldPreset(Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/level/dimension/LevelStem;)Lnet/minecraft/core/Holder;"))
|
||||
private LevelStem bcl_getOverworldStem(LevelStem overworldStem) {
|
||||
WorldGenUtil.Context netherContext = new WorldGenUtil.Context(
|
||||
|
@ -65,7 +76,14 @@ public abstract class WorldPresetsBootstrapMixin {
|
|||
this.endNoiseSettings
|
||||
);
|
||||
|
||||
WorldPresets.bootstrapPresets(presets, overworldStem, netherContext, endContext);
|
||||
WorldPresets.bootstrapPresets(
|
||||
presets,
|
||||
overworldStem,
|
||||
netherContext,
|
||||
endContext,
|
||||
noiseSettings,
|
||||
this::makeNoiseBasedOverworld
|
||||
);
|
||||
|
||||
return overworldStem;
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ public class TagManager {
|
|||
|
||||
public static boolean isToolWithMineableTag(ItemStack stack, TagKey<Block> tag) {
|
||||
if (stack.getItem() instanceof DiggerItemAccessor dig) {
|
||||
return dig.bclib_getBlockTag().equals(tag);
|
||||
return dig.bclib_getBlockTag() == tag;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -207,6 +207,10 @@ public class TagRegistry<T> {
|
|||
return creatTagKey(new ResourceLocation("c", name));
|
||||
}
|
||||
|
||||
public TagKey<T> makeTogetherTag(String name) {
|
||||
return creatTagKey(WorldsTogether.makeID(name));
|
||||
}
|
||||
|
||||
public void addUntyped(TagKey<T> tagID, ResourceLocation... elements) {
|
||||
if (isFrozen) WorldsTogether.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen.");
|
||||
Set<TagEntry> set = getSetForTag(tagID);
|
||||
|
|
|
@ -16,7 +16,9 @@ import net.minecraft.core.registries.Registries;
|
|||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.WorldPresetTags;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
import net.minecraft.world.level.levelgen.presets.WorldPreset;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
@ -25,6 +27,10 @@ import java.util.Map;
|
|||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
public class WorldPresets {
|
||||
@FunctionalInterface
|
||||
public interface OverworldBuilder {
|
||||
LevelStem make(BiomeSource biomeSource, Holder<NoiseGeneratorSettings> noiseGeneratorSettings);
|
||||
}
|
||||
|
||||
public static final TagRegistry.Simple<WorldPreset> WORLD_PRESETS =
|
||||
TagManager.registerType(BuiltInRegistries.WORLD_PRESET, "tags/worldgen/world_preset");
|
||||
|
@ -79,17 +85,24 @@ public class WorldPresets {
|
|||
return key;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void bootstrapPresets(
|
||||
Registry<WorldPreset> presets,
|
||||
LevelStem overworldStem,
|
||||
WorldGenUtil.Context netherContext,
|
||||
WorldGenUtil.Context endContext
|
||||
WorldGenUtil.Context endContext,
|
||||
Registry<NoiseGeneratorSettings> noiseSettings,
|
||||
OverworldBuilder noiseBasedOverworld
|
||||
) {
|
||||
EntrypointUtil.getCommon(WorldPresetBootstrap.class)
|
||||
.forEach(e -> e.bootstrapWorldPresets());
|
||||
|
||||
for (Map.Entry<ResourceKey<WorldPreset>, PresetBuilder> e : BUILDERS.entrySet()) {
|
||||
TogetherWorldPreset preset = e.getValue().create(overworldStem, netherContext, endContext);
|
||||
TogetherWorldPreset preset = e.getValue()
|
||||
.create(
|
||||
overworldStem, netherContext, endContext,
|
||||
noiseSettings, noiseBasedOverworld
|
||||
);
|
||||
BuiltInRegistries.register(presets, e.getKey(), preset);
|
||||
}
|
||||
BUILDERS = null;
|
||||
|
@ -113,7 +126,9 @@ public class WorldPresets {
|
|||
TogetherWorldPreset create(
|
||||
LevelStem overworldStem,
|
||||
WorldGenUtil.Context netherContext,
|
||||
WorldGenUtil.Context endContext
|
||||
WorldGenUtil.Context endContext,
|
||||
Registry<NoiseGeneratorSettings> noiseSettings,
|
||||
OverworldBuilder noiseBasedOverworld
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue