Migrated Vegetation Features

This commit is contained in:
Frank 2023-12-22 17:40:39 +01:00
parent dfd3621af9
commit 9b6a47b211
4 changed files with 57 additions and 12 deletions

View file

@ -4,6 +4,7 @@ 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.core.Holder;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.ItemStack;
@ -11,14 +12,21 @@ 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.state.BlockState;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import java.util.HashMap;
import java.util.Map;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class BonemealAPI {
@FunctionalInterface
public interface FeatureProvider {
@Nullable
Holder<? extends ConfiguredFeature<?, ?>> getFeature();
}
public static BonemealAPI INSTANCE = new BonemealAPI();
private final Map<TagKey<Block>, BonemealBlockSpreader> taggedSpreaders;
private final Map<Block, FeatureSpreader> featureSpreaders;
@ -47,7 +55,27 @@ public class BonemealAPI {
*/
public void addSpreadableFeatures(
Block target,
@NotNull BCLConfigureFeature<? extends Feature<?>, ?> spreadableFeature
@NotNull BCLConfigureFeature<?, ?> spreadableFeature
) {
featureSpreaders.put(target, new FeatureSpreader(target, () -> spreadableFeature.configuredFeature));
}
/**
* 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 FeatureProvider spreadableFeature
) {
featureSpreaders.put(target, new FeatureSpreader(target, spreadableFeature));
}

View file

@ -3,6 +3,7 @@ package org.betterx.bclib.api.v3.bonemeal;
import org.betterx.bclib.api.v3.levelgen.features.BCLConfigureFeature;
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.Level;
@ -10,12 +11,15 @@ import net.minecraft.world.level.LevelReader;
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.Feature;
import org.jetbrains.annotations.Nullable;
//adapted from NyliumBlock
public interface BonemealNyliumLike extends BonemealableBlock {
Block getHostBlock(); //this
BCLConfigureFeature<? extends Feature<?>, ?> getCoverFeature();
@Nullable Holder<? extends ConfiguredFeature<?, ? extends Feature<?>>> getCoverFeature();
default boolean isValidBonemealTarget(
LevelReader blockGetter,
@ -42,9 +46,9 @@ public interface BonemealNyliumLike extends BonemealableBlock {
) {
final BlockState currentState = serverLevel.getBlockState(blockPos);
if (currentState.is(getHostBlock())) {
BCLConfigureFeature<? extends Feature<?>, ?> feature = getCoverFeature();
Holder<? extends ConfiguredFeature<?, ?>> feature = getCoverFeature();
if (feature != null) {
feature.placeInWorld(serverLevel, blockPos.above(), randomSource, true);
BCLConfigureFeature.placeInWorld(feature, serverLevel, blockPos.above(), randomSource);
}
}
}

View file

@ -1,18 +1,19 @@
package org.betterx.bclib.api.v3.bonemeal;
import org.betterx.bclib.api.v3.levelgen.features.BCLConfigureFeature;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import org.jetbrains.annotations.Nullable;
public class FeatureSpreader implements BonemealNyliumLike {
public final BCLConfigureFeature<? extends Feature<?>, ?> spreadableFeature;
public final BonemealAPI.FeatureProvider spreadableFeature;
public final Block hostBlock;
public FeatureSpreader(Block hostBlock, BCLConfigureFeature<? extends Feature<?>, ?> spreadableFeature) {
public FeatureSpreader(Block hostBlock, BonemealAPI.FeatureProvider spreadableFeature) {
this.spreadableFeature = spreadableFeature;
this.hostBlock = hostBlock;
}
@ -33,7 +34,7 @@ public class FeatureSpreader implements BonemealNyliumLike {
}
@Override
public BCLConfigureFeature<? extends Feature<?>, ?> getCoverFeature() {
return spreadableFeature;
public @Nullable Holder<? extends ConfiguredFeature<?, ?>> getCoverFeature() {
return spreadableFeature.getFeature();
}
}

View file

@ -126,6 +126,18 @@ public class BCLConfigureFeature<F extends Feature<FC>, FC extends FeatureConfig
return placeUnboundInWorld(feature, FeatureConfiguration.NONE, level, pos, random, true);
}
public static boolean placeInWorld(
Holder<? extends ConfiguredFeature<?, ?>> feature,
ServerLevel level,
BlockPos pos,
RandomSource random
) {
if (feature != null && feature.value() != null) {
return placeUnboundInWorld(feature.value().feature(), feature.value().config(), level, pos, random, true);
}
return false;
}
public static <FC extends FeatureConfiguration> boolean placeInWorld(
Feature<FC> feature,
FC config,