minecraft-src/net/minecraft/world/level/levelgen/placement/CountOnEveryLayerPlacement.java
2025-07-04 02:00:41 +03:00

89 lines
2.6 KiB
Java

package net.minecraft.world.level.levelgen.placement;
import com.mojang.serialization.MapCodec;
import java.util.stream.Stream;
import java.util.stream.Stream.Builder;
import net.minecraft.core.BlockPos;
import net.minecraft.util.RandomSource;
import net.minecraft.util.valueproviders.ConstantInt;
import net.minecraft.util.valueproviders.IntProvider;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.Heightmap;
@Deprecated
public class CountOnEveryLayerPlacement extends PlacementModifier {
public static final MapCodec<CountOnEveryLayerPlacement> CODEC = IntProvider.codec(0, 256)
.fieldOf("count")
.xmap(CountOnEveryLayerPlacement::new, countOnEveryLayerPlacement -> countOnEveryLayerPlacement.count);
private final IntProvider count;
private CountOnEveryLayerPlacement(IntProvider count) {
this.count = count;
}
public static CountOnEveryLayerPlacement of(IntProvider count) {
return new CountOnEveryLayerPlacement(count);
}
public static CountOnEveryLayerPlacement of(int count) {
return of(ConstantInt.of(count));
}
@Override
public Stream<BlockPos> getPositions(PlacementContext context, RandomSource random, BlockPos pos) {
Builder<BlockPos> builder = Stream.builder();
int i = 0;
boolean bl;
do {
bl = false;
for (int j = 0; j < this.count.sample(random); j++) {
int k = random.nextInt(16) + pos.getX();
int l = random.nextInt(16) + pos.getZ();
int m = context.getHeight(Heightmap.Types.MOTION_BLOCKING, k, l);
int n = findOnGroundYPosition(context, k, m, l, i);
if (n != Integer.MAX_VALUE) {
builder.add(new BlockPos(k, n, l));
bl = true;
}
}
i++;
} while (bl);
return builder.build();
}
@Override
public PlacementModifierType<?> type() {
return PlacementModifierType.COUNT_ON_EVERY_LAYER;
}
private static int findOnGroundYPosition(PlacementContext context, int x, int y, int z, int count) {
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(x, y, z);
int i = 0;
BlockState blockState = context.getBlockState(mutableBlockPos);
for (int j = y; j >= context.getMinY() + 1; j--) {
mutableBlockPos.setY(j - 1);
BlockState blockState2 = context.getBlockState(mutableBlockPos);
if (!isEmpty(blockState2) && isEmpty(blockState) && !blockState2.is(Blocks.BEDROCK)) {
if (i == count) {
return mutableBlockPos.getY() + 1;
}
i++;
}
blockState = blockState2;
}
return Integer.MAX_VALUE;
}
private static boolean isEmpty(BlockState state) {
return state.isAir() || state.is(Blocks.WATER) || state.is(Blocks.LAVA);
}
}