minecraft-src/net/minecraft/world/level/levelgen/feature/SculkPatchFeature.java
2025-07-04 01:41:11 +03:00

77 lines
3.1 KiB
Java

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<SculkPatchConfiguration> {
public SculkPatchFeature(Codec<SculkPatchConfiguration> codec) {
super(codec);
}
@Override
public boolean place(FeaturePlaceContext<SculkPatchConfiguration> 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));
}
}
}