88 lines
3.4 KiB
Java
88 lines
3.4 KiB
Java
package net.minecraft.world.level.levelgen.structure.placement;
|
|
|
|
import com.mojang.serialization.Codec;
|
|
import com.mojang.serialization.DataResult;
|
|
import com.mojang.serialization.MapCodec;
|
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
import java.util.Optional;
|
|
import net.minecraft.core.Vec3i;
|
|
import net.minecraft.world.level.ChunkPos;
|
|
import net.minecraft.world.level.chunk.ChunkGeneratorStructureState;
|
|
import net.minecraft.world.level.levelgen.LegacyRandomSource;
|
|
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
|
|
|
public class RandomSpreadStructurePlacement extends StructurePlacement {
|
|
public static final MapCodec<RandomSpreadStructurePlacement> CODEC = RecordCodecBuilder.<RandomSpreadStructurePlacement>mapCodec(
|
|
instance -> placementCodec(instance)
|
|
.<int, int, RandomSpreadType>and(
|
|
instance.group(
|
|
Codec.intRange(0, 4096).fieldOf("spacing").forGetter(RandomSpreadStructurePlacement::spacing),
|
|
Codec.intRange(0, 4096).fieldOf("separation").forGetter(RandomSpreadStructurePlacement::separation),
|
|
RandomSpreadType.CODEC.optionalFieldOf("spread_type", RandomSpreadType.LINEAR).forGetter(RandomSpreadStructurePlacement::spreadType)
|
|
)
|
|
)
|
|
.apply(instance, RandomSpreadStructurePlacement::new)
|
|
)
|
|
.validate(RandomSpreadStructurePlacement::validate);
|
|
private final int spacing;
|
|
private final int separation;
|
|
private final RandomSpreadType spreadType;
|
|
|
|
private static DataResult<RandomSpreadStructurePlacement> validate(RandomSpreadStructurePlacement placement) {
|
|
return placement.spacing <= placement.separation ? DataResult.error(() -> "Spacing has to be larger than separation") : DataResult.success(placement);
|
|
}
|
|
|
|
public RandomSpreadStructurePlacement(
|
|
Vec3i locateOffset,
|
|
StructurePlacement.FrequencyReductionMethod frequencyReductionMethod,
|
|
float frequency,
|
|
int salt,
|
|
Optional<StructurePlacement.ExclusionZone> exclusionZone,
|
|
int spacing,
|
|
int separation,
|
|
RandomSpreadType spreadType
|
|
) {
|
|
super(locateOffset, frequencyReductionMethod, frequency, salt, exclusionZone);
|
|
this.spacing = spacing;
|
|
this.separation = separation;
|
|
this.spreadType = spreadType;
|
|
}
|
|
|
|
public RandomSpreadStructurePlacement(int spacing, int separation, RandomSpreadType spreadType, int salt) {
|
|
this(Vec3i.ZERO, StructurePlacement.FrequencyReductionMethod.DEFAULT, 1.0F, salt, Optional.empty(), spacing, separation, spreadType);
|
|
}
|
|
|
|
public int spacing() {
|
|
return this.spacing;
|
|
}
|
|
|
|
public int separation() {
|
|
return this.separation;
|
|
}
|
|
|
|
public RandomSpreadType spreadType() {
|
|
return this.spreadType;
|
|
}
|
|
|
|
public ChunkPos getPotentialStructureChunk(long seed, int regionX, int regionZ) {
|
|
int i = Math.floorDiv(regionX, this.spacing);
|
|
int j = Math.floorDiv(regionZ, this.spacing);
|
|
WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
|
worldgenRandom.setLargeFeatureWithSalt(seed, i, j, this.salt());
|
|
int k = this.spacing - this.separation;
|
|
int l = this.spreadType.evaluate(worldgenRandom, k);
|
|
int m = this.spreadType.evaluate(worldgenRandom, k);
|
|
return new ChunkPos(i * this.spacing + l, j * this.spacing + m);
|
|
}
|
|
|
|
@Override
|
|
protected boolean isPlacementChunk(ChunkGeneratorStructureState structureState, int x, int z) {
|
|
ChunkPos chunkPos = this.getPotentialStructureChunk(structureState.getLevelSeed(), x, z);
|
|
return chunkPos.x == x && chunkPos.z == z;
|
|
}
|
|
|
|
@Override
|
|
public StructurePlacementType<?> type() {
|
|
return StructurePlacementType.RANDOM_SPREAD;
|
|
}
|
|
}
|