package net.minecraft.world.level.levelgen.feature; import com.mojang.serialization.Codec; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.util.RandomSource; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.SculkBehaviour; import net.minecraft.world.level.block.SculkShriekerBlock; import net.minecraft.world.level.block.SculkSpreader; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.feature.configurations.SculkPatchConfiguration; public class SculkPatchFeature extends Feature { public SculkPatchFeature(Codec codec) { super(codec); } @Override public boolean place(FeaturePlaceContext context) { WorldGenLevel worldGenLevel = context.level(); BlockPos blockPos = context.origin(); if (!this.canSpreadFrom(worldGenLevel, blockPos)) { return false; } else { SculkPatchConfiguration sculkPatchConfiguration = context.config(); RandomSource randomSource = context.random(); SculkSpreader sculkSpreader = SculkSpreader.createWorldGenSpreader(); int i = sculkPatchConfiguration.spreadRounds() + sculkPatchConfiguration.growthRounds(); for (int j = 0; j < i; j++) { for (int k = 0; k < sculkPatchConfiguration.chargeCount(); k++) { sculkSpreader.addCursors(blockPos, sculkPatchConfiguration.amountPerCharge()); } boolean bl = j < sculkPatchConfiguration.spreadRounds(); for (int l = 0; l < sculkPatchConfiguration.spreadAttempts(); l++) { sculkSpreader.updateCursors(worldGenLevel, blockPos, randomSource, bl); } sculkSpreader.clear(); } BlockPos blockPos2 = blockPos.below(); if (randomSource.nextFloat() <= sculkPatchConfiguration.catalystChance() && worldGenLevel.getBlockState(blockPos2).isCollisionShapeFullBlock(worldGenLevel, blockPos2)) { worldGenLevel.setBlock(blockPos, Blocks.SCULK_CATALYST.defaultBlockState(), 3); } int k = sculkPatchConfiguration.extraRareGrowths().sample(randomSource); for (int l = 0; l < k; l++) { BlockPos blockPos3 = blockPos.offset(randomSource.nextInt(5) - 2, 0, randomSource.nextInt(5) - 2); if (worldGenLevel.getBlockState(blockPos3).isAir() && worldGenLevel.getBlockState(blockPos3.below()).isFaceSturdy(worldGenLevel, blockPos3.below(), Direction.UP)) { worldGenLevel.setBlock(blockPos3, Blocks.SCULK_SHRIEKER.defaultBlockState().setValue(SculkShriekerBlock.CAN_SUMMON, true), 3); } } return true; } } private boolean canSpreadFrom(LevelAccessor level, BlockPos pos) { BlockState blockState = level.getBlockState(pos); if (blockState.getBlock() instanceof SculkBehaviour) { return true; } else { return !blockState.isAir() && (!blockState.is(Blocks.WATER) || !blockState.getFluidState().isSource()) ? false : Direction.stream().map(pos::relative).anyMatch(blockPos -> level.getBlockState(blockPos).isCollisionShapeFullBlock(level, blockPos)); } } }