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
47
build.gradle
47
build.gradle
|
@ -4,6 +4,7 @@ plugins {
|
|||
id 'fabric-loom' version "${loom_version}"
|
||||
id 'maven-publish'
|
||||
id "com.modrinth.minotaur" version "2.+"
|
||||
id "com.matthewprenger.cursegradle" version "1.4.0"
|
||||
}
|
||||
|
||||
apply from: "bclib.gradle"
|
||||
|
@ -99,4 +100,50 @@ modrinth {
|
|||
required.project "fabric-api"
|
||||
}
|
||||
debugMode = false
|
||||
}
|
||||
|
||||
curseforge {
|
||||
def slurper = new groovy.json.JsonSlurper()
|
||||
apiKey = new File(projectDir, "../CURSEFORGE_TOKEN")
|
||||
if (apiKey.exists()) {
|
||||
apiKey = apiKey.text
|
||||
} else {
|
||||
apiKey = ""
|
||||
}
|
||||
|
||||
def changes = new File(projectDir, "CHANGES.md")
|
||||
if (changes.exists()) {
|
||||
changes = changes.getText('UTF-8')
|
||||
} else {
|
||||
changes = ""
|
||||
}
|
||||
|
||||
project {
|
||||
id = '495191'
|
||||
changelogType = 'markdown'
|
||||
changelog = changes
|
||||
releaseType = project.release_channel
|
||||
def versions = slurper.parseText(project.modrinth_versions);
|
||||
def latestVersion = ''
|
||||
for (v in versions) {
|
||||
addGameVersion v
|
||||
latestVersion = "[$v]"
|
||||
}
|
||||
addGameVersion 'Fabric'
|
||||
addGameVersion 'Java 17'
|
||||
relations {
|
||||
requiredDependency 'fabric-api'
|
||||
}
|
||||
mainArtifact(remapJar) {
|
||||
displayName = "$project.archives_base_name-$project.version $latestVersion"
|
||||
}
|
||||
afterEvaluate {
|
||||
mainArtifact(remapJar.outputs)
|
||||
}
|
||||
}
|
||||
|
||||
options {
|
||||
debug = false
|
||||
forgeGradleIntegration = false
|
||||
}
|
||||
}
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
"title.bclib.datafixer.error.continue": "Continue and Mark as Fixed",
|
||||
"tooltip.bclib.place_on": "Lebt auf: %s",
|
||||
"generator.bclib.normal": "BetterX",
|
||||
"generator.bclib.large": "Groß & BetterX",
|
||||
"generator.bclib.amplified": "Ampl. & BetterX",
|
||||
"title.screen.bclib.worldgen.main": "Welt-Generator Eigenschaften",
|
||||
"title.bclib.the_nether": "Nether",
|
||||
"title.bclib.the_end": "Das Ende",
|
||||
|
@ -59,6 +61,10 @@
|
|||
"title.screen.bclib.worldgen.end_void": "Kleine End-Inseln erzeugen",
|
||||
"title.screen.bclib.worldgen.avg_biome_size": "Durchschnittl. Biome Größe (in Chunks)",
|
||||
"title.screen.bclib.worldgen.other": "Sonstiges",
|
||||
"title.screen.bclib.worldgen.nether_biome_size": "Größe",
|
||||
"title.screen.bclib.worldgen.nether_vertical_biome_size": "Biomhöhe",
|
||||
"title.screen.bclib.worldgen.nether_vertical": "Biome auch vertikal verteilen",
|
||||
"title.screen.bclib.worldgen.nether_amplified": "Doppelte Netherhöhe (Amplified)",
|
||||
"title.screen.bclib.worldgen.land_biome_size": "Land-Biome",
|
||||
"title.screen.bclib.worldgen.void_biome_size": "Kleine Inseln",
|
||||
"title.screen.bclib.worldgen.center_biome_size": "Zentralbiome",
|
||||
|
@ -67,6 +73,8 @@
|
|||
"title.config.bclib.client.rendering.customFogRendering": "Angepasster Nebel",
|
||||
"title.config.bclib.client.rendering.netherThickFog": "Dicker Nether-Nebel",
|
||||
"bclib.updates.curseforge_link": "[CurseForge]",
|
||||
"bclib.updates.modrinth_link": "[Modrinth]",
|
||||
"bclib.updates.download_link": "Herunterladen",
|
||||
"bclib.updates.title": "Mod Aktualisierungen",
|
||||
"bclib.updates.disable_check": "Nicht Prüfen",
|
||||
"bclib.updates.donate_pre": "Gefallen Dir unsere Inhalte?\nDann erwäge eine kleine Spende :)",
|
||||
|
@ -82,6 +90,7 @@
|
|||
"title.config.bclib.main.infos.verbose": "Ausführliche Logs",
|
||||
"title.config.bclib.client.infos.survives_on_hint": "Zeige 'Überlebt auf' Tooltip",
|
||||
"description.config.bclib.client.ui.suppressExperimentalDialogOnLoad": "Der Warnbildschirm wird immer dann angezeigt, wenn Deine Welt nicht die Einstellungen der Vanilla-Version verwendet. Dies kann passieren, wenn Du eine Welt in einer Vorschauversion startest, aber auch wenn Du Mods verwendest, um die Welterzeugung zu verändern. Wenn diese Option aktiviert ist, wird die Warnung übersprungen, wenn Du eine bestehende Welt lädst. Sie wird weiterhin angezeigt (als Erinnerung), wenn eine neue Welt erstellt wird.",
|
||||
"title.config.bclib.client.ui.preferModrinthForUpdates": "Bevorzuge Updates über Modrinth",
|
||||
"title.config.bclib.client.ui.forceBetterXPreset": "BetterX als Standard-Welt-Typ verwenden",
|
||||
"description.config.bclib.client.ui.forceBetterXPreset": "Der Welt-Typ bestimmt, wie eine Welt generiert wird. In den meisten Fällen solltet BetterX als Standardeinstellung beibehalten werden (Du kannst den Typ jederzeit im Welt-Erstellen-Bildschirm ändern). Dieser Typ ist für maximale Kompatibilität zwischen DataPacks, unserer Mod und anderen Fabric-Mods optimiert. Außerdem bietet er einige einzigartige Funktionen für BetterNether und BetterEnd. Du solltest diese Option nur deaktivieren, wenn Du einen Grund dazu hast!",
|
||||
"warning.config.bclib.client.ui.forceBetterXPreset": "IN DEN MEISTEN FÄLLEN SOLLTE DIESE OPTION AKTIVIERT BLEIBEN.\n",
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
"title.config.bclib.main.patches.applyPatches": "Automatically apply patches when loading level",
|
||||
"title.config.bclib.main.patches.repairBiomesOnLoad": "Fix Biomesource on level load",
|
||||
"title.config.bclib.client.ui.suppressExperimentalDialogOnLoad": "Disable Experimental Warning Screen on Load",
|
||||
"title.config.bclib.client.ui.preferModrinthForUpdates": "Prefere Modrinth for Updates",
|
||||
"title.bclib.syncfiles.modInfo": "Mod Info",
|
||||
"title.bclib.syncfiles.modlist": "Mod Information",
|
||||
"message.bclib.syncfiles.modlist": "The following shows the state of your installed Mods.\n\nAll Mods that do not exist locally, or have a different version on the Server will be synchronized.",
|
||||
|
@ -54,6 +55,8 @@
|
|||
"title.config.bclib.client.infos.survives_on_hint": "Show 'Survives On' hint as Tooltip",
|
||||
"tooltip.bclib.place_on": "Survives on: %s",
|
||||
"generator.bclib.normal": "BetterX",
|
||||
"generator.bclib.large": "Large & BetterX",
|
||||
"generator.bclib.amplified": "Ampl. & BetterX",
|
||||
"title.screen.bclib.worldgen.main": "World Generator Settings",
|
||||
"title.bclib.the_nether": "The Nether",
|
||||
"title.bclib.the_end": "The End",
|
||||
|
@ -62,6 +65,10 @@
|
|||
"title.screen.bclib.worldgen.custom_end_terrain": "Custom End Terrain Generator",
|
||||
"title.screen.bclib.worldgen.avg_biome_size": "Average Biome Size (in Chunks)",
|
||||
"title.screen.bclib.worldgen.other": "Other Settings",
|
||||
"title.screen.bclib.worldgen.nether_biome_size": "Biome Size",
|
||||
"title.screen.bclib.worldgen.nether_vertical_biome_size": "Biome Height",
|
||||
"title.screen.bclib.worldgen.nether_vertical": "Generate vertical Biomes",
|
||||
"title.screen.bclib.worldgen.nether_amplified": "Double the Nether Height (Amplified)",
|
||||
"title.screen.bclib.worldgen.land_biome_size": "Land Biomes",
|
||||
"title.screen.bclib.worldgen.void_biome_size": "Small Island Biomes",
|
||||
"title.screen.bclib.worldgen.center_biome_size": "Central Biomes",
|
||||
|
@ -69,6 +76,8 @@
|
|||
"title.screen.bclib.worldgen.central_radius": "Central Void Radius (in Chunks)",
|
||||
"title.screen.bclib.worldgen.end_void": "Generate Small Islands",
|
||||
"bclib.updates.curseforge_link": "[CurseForge]",
|
||||
"bclib.updates.modrinth_link": "[Modrinth]",
|
||||
"bclib.updates.download_link": "Download",
|
||||
"bclib.updates.title": "Mod Updates",
|
||||
"bclib.updates.disable_check": "Disable Check",
|
||||
"bclib.updates.donate_pre": "Like our Content?\nPlease consider a small Donation :)",
|
||||
|
|
103
src/main/resources/assets/bclib/lang/pt_br.json
Normal file
103
src/main/resources/assets/bclib/lang/pt_br.json
Normal file
|
@ -0,0 +1,103 @@
|
|||
{
|
||||
"message.bclib.anvil_damage": "§cDano",
|
||||
"bclib.datafixer.backupWarning.title": "Guardian detectou um mundo incompatível",
|
||||
"bclib.datafixer.backupWarning.message": "O Guardian detectou, que os internos alguns mods instalados mudaram desde que este mundo foi jogado pela última vez.\n\nPodemos mudar automaticamente o mundo para você.Se você continuar sem aplicar as alterações, o mundo pode não carregar correto.Antes de continuar, você deve criar um backup.",
|
||||
"bclib.datafixer.backupWarning.backup": "Crie backup antes de aplicar correções",
|
||||
"bclib.datafixer.backupWarning.nofixes": "Continue sem correções",
|
||||
"bclib.datafixer.backupWarning.fix": "Aplique correções",
|
||||
"title.bclib.bclibmissmatch": "Incompatibilidade de versão",
|
||||
"message.bclib.bclibmissmatch": "A versão do BCLIB no servidor e esse cliente não corresponde.Isso causará problemas ao jogar.\n\nVocê deseja baixar automaticamente a versão bclib do servidor? \n\nO BCLIB moverá a versão antiga para um subdiretório do seu mods-dobrador e antes de instalar o novo.",
|
||||
"title.bclib.syncfiles": "Dados incompatíveis",
|
||||
"message.bclib.syncfiles": "Algum conteúdo no servidor não corresponde às versões do cliente.\nDeseja substituir o conteúdo selecionado pelos dados do servidor?",
|
||||
"message.bclib.syncfiles.mods": "Sincronize mods",
|
||||
"message.bclib.syncfiles.configs": "Sincronize as configurações",
|
||||
"message.bclib.syncfiles.folders": "Sincronize pastas e arquivos",
|
||||
"message.bclib.syncfiles.delete": "Exclua desnecessário",
|
||||
"title.bclib.confirmrestart": "É necessário reiniciar",
|
||||
"message.bclib.confirmrestart": "O conteúdo solicitado foi sincronizado.Você precisa reiniciar o minecraft agora.",
|
||||
"title.link.bclib.discord": "Discórdia",
|
||||
"title.bclib.modmenu.main": "Configurações do BCLIB",
|
||||
"title.bclib.progress": "Progresso",
|
||||
"title.bclib.filesync.progress": "Transferência de arquivo",
|
||||
"message.bclib.filesync.progress": "Sincronizar o conteúdo do arquivo com o servidor",
|
||||
"message.bclib.filesync.progress.stage.empty": "",
|
||||
"title.config.bclib.client.auto_sync.enabled": "Ativar sincronização automática",
|
||||
"title.config.bclib.client.auto_sync.acceptConfigs": "Accept incoming Config Files",
|
||||
"title.config.bclib.client.auto_sync.acceptFiles": "Aceitar arquivos de entrada",
|
||||
"title.config.bclib.client.auto_sync.acceptMods": "Aceitar mods de entrada",
|
||||
"title.config.bclib.client.auto_sync.displayModInfo": "Exibir aviso quando os mods do servidor diferem do cliente",
|
||||
"title.config.bclib.client.auto_sync.debugHashes": "Imprima-se-hashes de depuração de sincronização automática para registrar",
|
||||
"title.config.bclib.generator.options.useOldBiomeGenerator": "Use Legacy 1.17 Biome Gerator",
|
||||
"title.config.bclib.main.patches.applyPatches": "Aplique automaticamente patches ao carregar o nível",
|
||||
"title.config.bclib.main.patches.repairBiomesOnLoad": "Corrija o Biomesource na carga nivelada",
|
||||
"title.config.bclib.client.ui.suppressExperimentalDialogOnLoad": "Desative a tela de aviso experimental na carga",
|
||||
"title.bclib.syncfiles.modInfo": "modInfo",
|
||||
"title.bclib.syncfiles.modlist": "Informação mod",
|
||||
"message.bclib.syncfiles.modlist": "A seguir, mostra o estado de seus mods instalados.\n\nTodos os mods que não existem localmente ou têm uma versão diferente no servidor serão sincronizados.",
|
||||
"title.bclib.modmissmatch": "Conflito da versão mod",
|
||||
"message.bclib.modmissmatch": "Alguns mods neste cliente não correspondem à versão dos mods no servidor.\n\nMods incompatíveis podem resultar em comportamento ou falha de jogo estranho.Por favor, faça Sue que você use os mesmos mods que o servidor.",
|
||||
"message.bclib.datafixer.progress.waitbackup": "Esperando o backup terminar.Isso pode demorar um pouco!",
|
||||
"message.bclib.datafixer.progress.reading": "Reading Data",
|
||||
"message.bclib.datafixer.progress.players": "Consertando jogadores",
|
||||
"message.bclib.datafixer.progress.level": "Aplicando patches ao nível.dat",
|
||||
"message.bclib.datafixer.progress.worlddata": "Patching de dados mundiais personalizados",
|
||||
"message.bclib.datafixer.progress.regions": "Reparando todas as regiões",
|
||||
"message.bclib.datafixer.progress.saving": "Salvando o estado do patch",
|
||||
"title.bclib.datafixer.progress": "fixingWorld",
|
||||
"message.bclib.datafixer.progress": "Aplicando todos os patches ao seu mundo.",
|
||||
"title.bclib.datafixer.error": "Erros enquanto corrige o mundo",
|
||||
"message.bclib.datafixer.error": "Houve erros enquanto reparava o mundo.Isso significa que esse nível provavelmente está em um estado inconsistente e você não deve jogar.Restaure seu backup e corrija os erros abaixo antes de tentar novamente.",
|
||||
"title.bclib.datafixer.error.continue": "Prossiga e marque como fixo",
|
||||
"title.config.bclib.client.rendering.customFogRendering": "Renderização de nevoeiro personalizada",
|
||||
"title.config.bclib.client.rendering.netherThickFog": "Nether de névoa espessa",
|
||||
"title.config.bclib.main.infos.verbose": "Registro detalhado",
|
||||
"title.config.bclib.client.infos.survives_on_hint": "Mostrar dica 'Sobrevive em' como dica de ferramenta",
|
||||
"tooltip.bclib.place_on": "Sobrevive: %s",
|
||||
"generator.bclib.normal": "BetterX",
|
||||
"title.screen.bclib.worldgen.main": "Configurações mundiais do gerador",
|
||||
"title.bclib.the_nether": "The Nether",
|
||||
"title.bclib.the_end": "The End",
|
||||
"title.screen.bclib.worldgen.custom_biome_source": "Use fonte de bioma personalizado",
|
||||
"title.screen.bclib.worldgen.legacy_square": "Use mapa herdado (1.17)",
|
||||
"title.screen.bclib.worldgen.custom_end_terrain": "Gerador de terreno final personalizado",
|
||||
"title.screen.bclib.worldgen.avg_biome_size": "Tamanho médio do bioma (em pedaços)",
|
||||
"title.screen.bclib.worldgen.other": "Other Settings",
|
||||
"title.screen.bclib.worldgen.land_biome_size": "Biomas terrestres",
|
||||
"title.screen.bclib.worldgen.void_biome_size": "Pequenos biomas da ilha",
|
||||
"title.screen.bclib.worldgen.center_biome_size": "Biomas Centrais",
|
||||
"title.screen.bclib.worldgen.barrens_biome_size": "barrens",
|
||||
"title.screen.bclib.worldgen.central_radius": "Raio do vazio central (em pedaços)",
|
||||
"title.screen.bclib.worldgen.end_void": "Gerar pequenas ilhas",
|
||||
"bclib.updates.curseforge_link": "[CurseForge]",
|
||||
"bclib.updates.title": "Moda atualizações",
|
||||
"bclib.updates.disable_check": "Desative a verificação",
|
||||
"bclib.updates.donate_pre": "Como nosso conteúdo?\nPor favor, considere uma pequena doação :)",
|
||||
"bclib.updates.donate": "Doar",
|
||||
"bclib.updates.description": "Alguns dos mods instalados estão desatualizados.Melhoramos e estendemos continuamente nosso conteúdo, bem como fornecemos importantes fixos de insetos.\nConsidere atualizar seus mods usando os links fornecidos abaixo.",
|
||||
"bclib.welcome.title": "Bem-vindo ao ",
|
||||
"bclib.welcome.description": "... E um enorme saudável ** Obrigado ** por baixar e reproduzir nossos mods.Esperamos que você os aprecie tanto quanto nós.\n\nAntes de começarmos, há algumas coisas que precisamos configurar; portanto, continue lendo a seguinte parte chata.",
|
||||
"bclib.welcome.donation": "Se você gosta de nossos mods tanto quanto esperamos que faça, considere uma pequena doação :)",
|
||||
"description.config.bclib.client.version.check": "O BCLIB inclui um verificador de versão simples que pode notificá -lo quando novas atualizações de nossos mods estiverem disponíveis.Para fazer isso, precisamos ler um recurso de um de nossos servidores da Web.Para processar a solicitação, juntamente com seu endereço IP (precisamos saber para onde enviar a resposta), também enviamos sua versão do Minecraft (para que possamos escolher a versão Mod certa).Os dados transmitidos nunca serão usados ou processados por nós para outros fins, mas devem ser armazenados em nossos arquivos de log por 4 semanas por razões legais.",
|
||||
"title.config.bclib.client.version.check": "Habilitar Verificação da versão",
|
||||
"title.config.bclib.client.ui.showUpdateInfo": "Permitir a tela de lembrete de atualização",
|
||||
"title.config.bclib.client.rendering.FogDensity": "Densidade de nevoeiro",
|
||||
"description.config.bclib.client.ui.suppressExperimentalDialogOnLoad": "A tela de aviso aparece sempre que seu mundo não usa as configurações da versão de baunilha.Isso pode acontecer quando você inicia um mundo em uma versão de visualização, mas também quando você usa mods para mudar a criação do mundo.Se essa opção estiver ativada, o aviso será ignorado quando você carregar um mundo existente.Ele ainda será exibido (como um lembrete) quando um novo mundo for criado.",
|
||||
"title.config.bclib.client.ui.forceBetterXPreset": "Use melhorx como o tipo mundial padrão",
|
||||
"warning.config.bclib.client.ui.forceBetterXPreset": "Provavelmente, você desejará manter esta opção ativada.\n",
|
||||
"description.config.bclib.client.ui.forceBetterXPreset": "O tipo de mundo determina como um mundo é gerado.Na maioria dos casos, o melhorx deve ser mantido como padrão (você pode alterar o tipo a qualquer momento na tela de criação mundial).Esse tipo é otimizado para máxima compatibilidade entre os dados, nosso mod e outros mods de tecido.Ele também fornece alguns recursos exclusivos para melhor e melhor.Você só deve desativar essa opção se tiver um motivo para fazê -lo! ",
|
||||
"emi.category.bclib.alloying": "Liga",
|
||||
"emi.category.bclib.anvil_0": "Bigorna (Nível 0)",
|
||||
"emi.category.bclib.anvil_1": "Bigorna (Nível I)",
|
||||
"emi.category.bclib.anvil_2": "Bigorna (Nível II)",
|
||||
"emi.category.bclib.anvil_3": "Bigorna (Nível III)",
|
||||
"emi.category.bclib.anvil_4": "Bigorna (Nível IV)",
|
||||
"emi.category.bclib.anvil_5": "Bigorna (Nível V)",
|
||||
"tag.c.barrel": "Barris",
|
||||
"tag.c.wooden_barrels": "Barris de madeira",
|
||||
"tag.c.workbench": "Tabelas de criação",
|
||||
"tag.c.furnaces": "Fornos",
|
||||
"tag.c.saplings": "Mudas",
|
||||
"tag.c.hammers": "Martelos",
|
||||
"tag.c.leaves": "Folhas",
|
||||
"tag.c.soul_ground": "Solo da Alma"
|
||||
}
|
|
@ -23,5 +23,8 @@ accessible method net/minecraft/world/level/levelgen/SurfaceRules$SequenceRuleSo
|
|||
accessible method net/minecraft/core/Registry registerSimple (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/core/Registry$RegistryBootstrap;)Lnet/minecraft/core/Registry;
|
||||
accessible method net/minecraft/world/entity/SpawnPlacements register (Lnet/minecraft/world/entity/EntityType;Lnet/minecraft/world/entity/SpawnPlacements$Type;Lnet/minecraft/world/level/levelgen/Heightmap$Types;Lnet/minecraft/world/entity/SpawnPlacements$SpawnPredicate;)V
|
||||
accessible method net/minecraft/world/level/block/state/properties/WoodType register (Lnet/minecraft/world/level/block/state/properties/WoodType;)Lnet/minecraft/world/level/block/state/properties/WoodType;
|
||||
accessible method net/minecraft/world/level/levelgen/NoiseRouterData nether (Lnet/minecraft/core/Registry;)Lnet/minecraft/world/level/levelgen/NoiseRouter;
|
||||
accessible method net/minecraft/world/level/levelgen/NoiseRouterData noNewCaves (Lnet/minecraft/core/Registry;Lnet/minecraft/world/level/levelgen/DensityFunction;)Lnet/minecraft/world/level/levelgen/NoiseRouter;
|
||||
accessible method net/minecraft/world/level/levelgen/NoiseRouterData slideNetherLike (Lnet/minecraft/core/Registry;II)Lnet/minecraft/world/level/levelgen/DensityFunction;
|
||||
#Fields
|
||||
accessible field net/minecraft/world/entity/ai/village/poi/PoiTypes TYPE_BY_STATE Ljava/util/Map;
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "bclib",
|
||||
"version": "2.1.3",
|
||||
"version": "2.1.5",
|
||||
"name": "BCLib",
|
||||
"description": "A library for BetterX team mods",
|
||||
"authors": [
|
||||
|
@ -10,7 +10,7 @@
|
|||
"Bulldog83"
|
||||
],
|
||||
"contact": {
|
||||
"homepage": "https://www.curseforge.com/minecraft/mc-mods/bclib",
|
||||
"homepage": "https://modrinth.com/mod/bclib",
|
||||
"issues": "https://github.com/quiqueck/bclib/issues",
|
||||
"sources": "https://github.com/quiqueck/bclib"
|
||||
},
|
||||
|
@ -56,6 +56,12 @@
|
|||
]
|
||||
},
|
||||
"custom": {
|
||||
"bclib": {
|
||||
"downloads": {
|
||||
"modrinth": "https://modrinth.com/mod/bclib",
|
||||
"curseforge": "https://www.curseforge.com/minecraft/mc-mods/bclib"
|
||||
}
|
||||
},
|
||||
"modmenu": {
|
||||
"links": {
|
||||
"title.link.bclib.discord": "https://discord.gg/kYuATbYbKW"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue