Code/net/minecraft/world/level/levelgen/feature/OreFeature.java

197 lines
9.2 KiB
Java
Raw Permalink Normal View History

2025-07-01 06:20:03 +00:00
package net.minecraft.world.level.levelgen.feature;
import com.mojang.serialization.Codec;
import java.util.BitSet;
import java.util.function.Function;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.BulkSectionAccess;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration;
public class OreFeature extends Feature<OreConfiguration> {
public OreFeature(Codec<OreConfiguration> p_66531_) {
super(p_66531_);
}
@Override
public boolean place(FeaturePlaceContext<OreConfiguration> p_160177_) {
RandomSource randomsource = p_160177_.random();
BlockPos blockpos = p_160177_.origin();
WorldGenLevel worldgenlevel = p_160177_.level();
OreConfiguration oreconfiguration = p_160177_.config();
float f = randomsource.nextFloat() * (float) Math.PI;
float f1 = oreconfiguration.size / 8.0F;
int i = Mth.ceil((oreconfiguration.size / 16.0F * 2.0F + 1.0F) / 2.0F);
double d0 = blockpos.getX() + Math.sin(f) * f1;
double d1 = blockpos.getX() - Math.sin(f) * f1;
double d2 = blockpos.getZ() + Math.cos(f) * f1;
double d3 = blockpos.getZ() - Math.cos(f) * f1;
int j = 2;
double d4 = blockpos.getY() + randomsource.nextInt(3) - 2;
double d5 = blockpos.getY() + randomsource.nextInt(3) - 2;
int k = blockpos.getX() - Mth.ceil(f1) - i;
int l = blockpos.getY() - 2 - i;
int i1 = blockpos.getZ() - Mth.ceil(f1) - i;
int j1 = 2 * (Mth.ceil(f1) + i);
int k1 = 2 * (2 + i);
for (int l1 = k; l1 <= k + j1; l1++) {
for (int i2 = i1; i2 <= i1 + j1; i2++) {
if (l <= worldgenlevel.getHeight(Heightmap.Types.OCEAN_FLOOR_WG, l1, i2)) {
return this.doPlace(worldgenlevel, randomsource, oreconfiguration, d0, d1, d2, d3, d4, d5, k, l, i1, j1, k1);
}
}
}
return false;
}
protected boolean doPlace(
WorldGenLevel p_225172_,
RandomSource p_225173_,
OreConfiguration p_225174_,
double p_225175_,
double p_225176_,
double p_225177_,
double p_225178_,
double p_225179_,
double p_225180_,
int p_225181_,
int p_225182_,
int p_225183_,
int p_225184_,
int p_225185_
) {
int i = 0;
BitSet bitset = new BitSet(p_225184_ * p_225185_ * p_225184_);
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
int j = p_225174_.size;
double[] adouble = new double[j * 4];
for (int k = 0; k < j; k++) {
float f = (float)k / j;
double d0 = Mth.lerp(f, p_225175_, p_225176_);
double d1 = Mth.lerp(f, p_225179_, p_225180_);
double d2 = Mth.lerp(f, p_225177_, p_225178_);
double d3 = p_225173_.nextDouble() * j / 16.0;
double d4 = ((Mth.sin((float) Math.PI * f) + 1.0F) * d3 + 1.0) / 2.0;
adouble[k * 4 + 0] = d0;
adouble[k * 4 + 1] = d1;
adouble[k * 4 + 2] = d2;
adouble[k * 4 + 3] = d4;
}
for (int l3 = 0; l3 < j - 1; l3++) {
if (!(adouble[l3 * 4 + 3] <= 0.0)) {
for (int i4 = l3 + 1; i4 < j; i4++) {
if (!(adouble[i4 * 4 + 3] <= 0.0)) {
double d8 = adouble[l3 * 4 + 0] - adouble[i4 * 4 + 0];
double d10 = adouble[l3 * 4 + 1] - adouble[i4 * 4 + 1];
double d12 = adouble[l3 * 4 + 2] - adouble[i4 * 4 + 2];
double d14 = adouble[l3 * 4 + 3] - adouble[i4 * 4 + 3];
if (d14 * d14 > d8 * d8 + d10 * d10 + d12 * d12) {
if (d14 > 0.0) {
adouble[i4 * 4 + 3] = -1.0;
} else {
adouble[l3 * 4 + 3] = -1.0;
}
}
}
}
}
}
try (BulkSectionAccess bulksectionaccess = new BulkSectionAccess(p_225172_)) {
for (int j4 = 0; j4 < j; j4++) {
double d9 = adouble[j4 * 4 + 3];
if (!(d9 < 0.0)) {
double d11 = adouble[j4 * 4 + 0];
double d13 = adouble[j4 * 4 + 1];
double d15 = adouble[j4 * 4 + 2];
int k4 = Math.max(Mth.floor(d11 - d9), p_225181_);
int l = Math.max(Mth.floor(d13 - d9), p_225182_);
int i1 = Math.max(Mth.floor(d15 - d9), p_225183_);
int j1 = Math.max(Mth.floor(d11 + d9), k4);
int k1 = Math.max(Mth.floor(d13 + d9), l);
int l1 = Math.max(Mth.floor(d15 + d9), i1);
for (int i2 = k4; i2 <= j1; i2++) {
double d5 = (i2 + 0.5 - d11) / d9;
if (d5 * d5 < 1.0) {
for (int j2 = l; j2 <= k1; j2++) {
double d6 = (j2 + 0.5 - d13) / d9;
if (d5 * d5 + d6 * d6 < 1.0) {
for (int k2 = i1; k2 <= l1; k2++) {
double d7 = (k2 + 0.5 - d15) / d9;
if (d5 * d5 + d6 * d6 + d7 * d7 < 1.0 && !p_225172_.isOutsideBuildHeight(j2)) {
int l2 = i2 - p_225181_ + (j2 - p_225182_) * p_225184_ + (k2 - p_225183_) * p_225184_ * p_225185_;
if (!bitset.get(l2)) {
bitset.set(l2);
blockpos$mutableblockpos.set(i2, j2, k2);
if (p_225172_.ensureCanWrite(blockpos$mutableblockpos)) {
LevelChunkSection levelchunksection = bulksectionaccess.getSection(blockpos$mutableblockpos);
if (levelchunksection != null) {
int i3 = SectionPos.sectionRelative(i2);
int j3 = SectionPos.sectionRelative(j2);
int k3 = SectionPos.sectionRelative(k2);
BlockState blockstate = levelchunksection.getBlockState(i3, j3, k3);
for (OreConfiguration.TargetBlockState oreconfiguration$targetblockstate : p_225174_.targetStates) {
if (canPlaceOre(
blockstate,
bulksectionaccess::getBlockState,
p_225173_,
p_225174_,
oreconfiguration$targetblockstate,
blockpos$mutableblockpos
)) {
levelchunksection.setBlockState(i3, j3, k3, oreconfiguration$targetblockstate.state, false);
i++;
break;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
return i > 0;
}
public static boolean canPlaceOre(
BlockState p_225187_,
Function<BlockPos, BlockState> p_225188_,
RandomSource p_225189_,
OreConfiguration p_225190_,
OreConfiguration.TargetBlockState p_225191_,
BlockPos.MutableBlockPos p_225192_
) {
if (!p_225191_.target.test(p_225187_, p_225189_)) {
return false;
} else {
return shouldSkipAirCheck(p_225189_, p_225190_.discardChanceOnAirExposure) ? true : !isAdjacentToAir(p_225188_, p_225192_);
}
}
protected static boolean shouldSkipAirCheck(RandomSource p_225169_, float p_225170_) {
if (p_225170_ <= 0.0F) {
return true;
} else {
return p_225170_ >= 1.0F ? false : p_225169_.nextFloat() >= p_225170_;
}
}
}