package net.minecraft.world.level.levelgen.feature; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import java.util.Optional; import java.util.function.Function; import java.util.function.Predicate; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.tags.BlockTags; import net.minecraft.tags.TagKey; import net.minecraft.util.RandomSource; import net.minecraft.world.level.LevelSimulatedReader; import net.minecraft.world.level.LevelWriter; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.levelgen.feature.configurations.BlockColumnConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.BlockPileConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.BlockStateConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.ColumnFeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.CountConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.DeltaFeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.DiskConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.DripstoneClusterConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.EndGatewayConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.FallenTreeConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.GeodeConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.HugeMushroomFeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.LargeDripstoneConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.LayerConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.MultifaceGrowthConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.NetherForestVegetationConfig; import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.PointedDripstoneConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.ProbabilityFeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.RandomBooleanFeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.RandomFeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.RandomPatchConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.ReplaceBlockConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.ReplaceSphereConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.RootSystemConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.SculkPatchConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.SimpleBlockConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.SimpleRandomFeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.SpikeConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.SpringConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.TwistingVinesConfig; import net.minecraft.world.level.levelgen.feature.configurations.UnderwaterMagmaConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.VegetationPatchConfiguration; public abstract class Feature { public static final Feature NO_OP = register("no_op", new NoOpFeature(NoneFeatureConfiguration.CODEC)); public static final Feature TREE = register("tree", new TreeFeature(TreeConfiguration.CODEC)); public static final Feature FALLEN_TREE = register("fallen_tree", new FallenTreeFeature(FallenTreeConfiguration.CODEC)); public static final Feature FLOWER = register("flower", new RandomPatchFeature(RandomPatchConfiguration.CODEC)); public static final Feature NO_BONEMEAL_FLOWER = register("no_bonemeal_flower", new RandomPatchFeature(RandomPatchConfiguration.CODEC)); public static final Feature RANDOM_PATCH = register("random_patch", new RandomPatchFeature(RandomPatchConfiguration.CODEC)); public static final Feature BLOCK_PILE = register("block_pile", new BlockPileFeature(BlockPileConfiguration.CODEC)); public static final Feature SPRING = register("spring_feature", new SpringFeature(SpringConfiguration.CODEC)); public static final Feature CHORUS_PLANT = register("chorus_plant", new ChorusPlantFeature(NoneFeatureConfiguration.CODEC)); public static final Feature REPLACE_SINGLE_BLOCK = register( "replace_single_block", new ReplaceBlockFeature(ReplaceBlockConfiguration.CODEC) ); public static final Feature VOID_START_PLATFORM = register( "void_start_platform", new VoidStartPlatformFeature(NoneFeatureConfiguration.CODEC) ); public static final Feature DESERT_WELL = register("desert_well", new DesertWellFeature(NoneFeatureConfiguration.CODEC)); public static final Feature FOSSIL = register("fossil", new FossilFeature(FossilFeatureConfiguration.CODEC)); public static final Feature HUGE_RED_MUSHROOM = register( "huge_red_mushroom", new HugeRedMushroomFeature(HugeMushroomFeatureConfiguration.CODEC) ); public static final Feature HUGE_BROWN_MUSHROOM = register( "huge_brown_mushroom", new HugeBrownMushroomFeature(HugeMushroomFeatureConfiguration.CODEC) ); public static final Feature ICE_SPIKE = register("ice_spike", new IceSpikeFeature(NoneFeatureConfiguration.CODEC)); public static final Feature GLOWSTONE_BLOB = register("glowstone_blob", new GlowstoneFeature(NoneFeatureConfiguration.CODEC)); public static final Feature FREEZE_TOP_LAYER = register("freeze_top_layer", new SnowAndFreezeFeature(NoneFeatureConfiguration.CODEC)); public static final Feature VINES = register("vines", new VinesFeature(NoneFeatureConfiguration.CODEC)); public static final Feature BLOCK_COLUMN = register("block_column", new BlockColumnFeature(BlockColumnConfiguration.CODEC)); public static final Feature VEGETATION_PATCH = register( "vegetation_patch", new VegetationPatchFeature(VegetationPatchConfiguration.CODEC) ); public static final Feature WATERLOGGED_VEGETATION_PATCH = register( "waterlogged_vegetation_patch", new WaterloggedVegetationPatchFeature(VegetationPatchConfiguration.CODEC) ); public static final Feature ROOT_SYSTEM = register("root_system", new RootSystemFeature(RootSystemConfiguration.CODEC)); public static final Feature MULTIFACE_GROWTH = register( "multiface_growth", new MultifaceGrowthFeature(MultifaceGrowthConfiguration.CODEC) ); public static final Feature UNDERWATER_MAGMA = register( "underwater_magma", new UnderwaterMagmaFeature(UnderwaterMagmaConfiguration.CODEC) ); public static final Feature MONSTER_ROOM = register("monster_room", new MonsterRoomFeature(NoneFeatureConfiguration.CODEC)); public static final Feature BLUE_ICE = register("blue_ice", new BlueIceFeature(NoneFeatureConfiguration.CODEC)); public static final Feature ICEBERG = register("iceberg", new IcebergFeature(BlockStateConfiguration.CODEC)); public static final Feature FOREST_ROCK = register("forest_rock", new BlockBlobFeature(BlockStateConfiguration.CODEC)); public static final Feature DISK = register("disk", new DiskFeature(DiskConfiguration.CODEC)); public static final Feature LAKE = register("lake", new LakeFeature(LakeFeature.Configuration.CODEC)); public static final Feature ORE = register("ore", new OreFeature(OreConfiguration.CODEC)); public static final Feature END_PLATFORM = register("end_platform", new EndPlatformFeature(NoneFeatureConfiguration.CODEC)); public static final Feature END_SPIKE = register("end_spike", new SpikeFeature(SpikeConfiguration.CODEC)); public static final Feature END_ISLAND = register("end_island", new EndIslandFeature(NoneFeatureConfiguration.CODEC)); public static final Feature END_GATEWAY = register("end_gateway", new EndGatewayFeature(EndGatewayConfiguration.CODEC)); public static final SeagrassFeature SEAGRASS = register("seagrass", new SeagrassFeature(ProbabilityFeatureConfiguration.CODEC)); public static final Feature KELP = register("kelp", new KelpFeature(NoneFeatureConfiguration.CODEC)); public static final Feature CORAL_TREE = register("coral_tree", new CoralTreeFeature(NoneFeatureConfiguration.CODEC)); public static final Feature CORAL_MUSHROOM = register("coral_mushroom", new CoralMushroomFeature(NoneFeatureConfiguration.CODEC)); public static final Feature CORAL_CLAW = register("coral_claw", new CoralClawFeature(NoneFeatureConfiguration.CODEC)); public static final Feature SEA_PICKLE = register("sea_pickle", new SeaPickleFeature(CountConfiguration.CODEC)); public static final Feature SIMPLE_BLOCK = register("simple_block", new SimpleBlockFeature(SimpleBlockConfiguration.CODEC)); public static final Feature BAMBOO = register("bamboo", new BambooFeature(ProbabilityFeatureConfiguration.CODEC)); public static final Feature HUGE_FUNGUS = register("huge_fungus", new HugeFungusFeature(HugeFungusConfiguration.CODEC)); public static final Feature NETHER_FOREST_VEGETATION = register( "nether_forest_vegetation", new NetherForestVegetationFeature(NetherForestVegetationConfig.CODEC) ); public static final Feature WEEPING_VINES = register("weeping_vines", new WeepingVinesFeature(NoneFeatureConfiguration.CODEC)); public static final Feature TWISTING_VINES = register("twisting_vines", new TwistingVinesFeature(TwistingVinesConfig.CODEC)); public static final Feature BASALT_COLUMNS = register("basalt_columns", new BasaltColumnsFeature(ColumnFeatureConfiguration.CODEC)); public static final Feature DELTA_FEATURE = register("delta_feature", new DeltaFeature(DeltaFeatureConfiguration.CODEC)); public static final Feature REPLACE_BLOBS = register( "netherrack_replace_blobs", new ReplaceBlobsFeature(ReplaceSphereConfiguration.CODEC) ); public static final Feature FILL_LAYER = register("fill_layer", new FillLayerFeature(LayerConfiguration.CODEC)); public static final BonusChestFeature BONUS_CHEST = register("bonus_chest", new BonusChestFeature(NoneFeatureConfiguration.CODEC)); public static final Feature BASALT_PILLAR = register("basalt_pillar", new BasaltPillarFeature(NoneFeatureConfiguration.CODEC)); public static final Feature SCATTERED_ORE = register("scattered_ore", new ScatteredOreFeature(OreConfiguration.CODEC)); public static final Feature RANDOM_SELECTOR = register( "random_selector", new RandomSelectorFeature(RandomFeatureConfiguration.CODEC) ); public static final Feature SIMPLE_RANDOM_SELECTOR = register( "simple_random_selector", new SimpleRandomSelectorFeature(SimpleRandomFeatureConfiguration.CODEC) ); public static final Feature RANDOM_BOOLEAN_SELECTOR = register( "random_boolean_selector", new RandomBooleanSelectorFeature(RandomBooleanFeatureConfiguration.CODEC) ); public static final Feature GEODE = register("geode", new GeodeFeature(GeodeConfiguration.CODEC)); public static final Feature DRIPSTONE_CLUSTER = register( "dripstone_cluster", new DripstoneClusterFeature(DripstoneClusterConfiguration.CODEC) ); public static final Feature LARGE_DRIPSTONE = register( "large_dripstone", new LargeDripstoneFeature(LargeDripstoneConfiguration.CODEC) ); public static final Feature POINTED_DRIPSTONE = register( "pointed_dripstone", new PointedDripstoneFeature(PointedDripstoneConfiguration.CODEC) ); public static final Feature SCULK_PATCH = register("sculk_patch", new SculkPatchFeature(SculkPatchConfiguration.CODEC)); private final MapCodec>> configuredCodec; private static > F register(String p_65808_, F p_65809_) { return Registry.register(BuiltInRegistries.FEATURE, p_65808_, p_65809_); } public Feature(Codec p_65786_) { this.configuredCodec = p_65786_.fieldOf("config").xmap(p_65806_ -> new ConfiguredFeature<>(this, (FC)p_65806_), ConfiguredFeature::config); } public MapCodec>> configuredCodec() { return this.configuredCodec; } protected void setBlock(LevelWriter p_65791_, BlockPos p_65792_, BlockState p_65793_) { p_65791_.setBlock(p_65792_, p_65793_, 3); } public static Predicate isReplaceable(TagKey p_204736_) { return p_204739_ -> !p_204739_.is(p_204736_); } protected void safeSetBlock(WorldGenLevel p_159743_, BlockPos p_159744_, BlockState p_159745_, Predicate p_159746_) { if (p_159746_.test(p_159743_.getBlockState(p_159744_))) { p_159743_.setBlock(p_159744_, p_159745_, 2); } } public abstract boolean place(FeaturePlaceContext p_159749_); public boolean place(FC p_225029_, WorldGenLevel p_225030_, ChunkGenerator p_225031_, RandomSource p_225032_, BlockPos p_225033_) { return p_225030_.ensureCanWrite(p_225033_) ? this.place(new FeaturePlaceContext<>(Optional.empty(), p_225030_, p_225031_, p_225032_, p_225033_, p_225029_)) : false; } protected static boolean isStone(BlockState p_159748_) { return p_159748_.is(BlockTags.BASE_STONE_OVERWORLD); } public static boolean isDirt(BlockState p_159760_) { return p_159760_.is(BlockTags.DIRT); } public static boolean isGrassOrDirt(LevelSimulatedReader p_65789_, BlockPos p_65790_) { return p_65789_.isStateAtPosition(p_65790_, Feature::isDirt); } public static boolean checkNeighbors(Function p_159754_, BlockPos p_159755_, Predicate p_159756_) { BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); for (Direction direction : Direction.values()) { blockpos$mutableblockpos.setWithOffset(p_159755_, direction); if (p_159756_.test(p_159754_.apply(blockpos$mutableblockpos))) { return true; } } return false; } public static boolean isAdjacentToAir(Function p_159751_, BlockPos p_159752_) { return checkNeighbors(p_159751_, p_159752_, BlockBehaviour.BlockStateBase::isAir); } protected void markAboveForPostProcessing(WorldGenLevel p_159740_, BlockPos p_159741_) { BlockPos.MutableBlockPos blockpos$mutableblockpos = p_159741_.mutable(); for (int i = 0; i < 2; i++) { blockpos$mutableblockpos.move(Direction.UP); if (p_159740_.getBlockState(blockpos$mutableblockpos).isAir()) { return; } p_159740_.getChunk(blockpos$mutableblockpos).markPosForPostprocessing(blockpos$mutableblockpos); } } }