Skip to content

Commit

Permalink
icicle heights and density
Browse files Browse the repository at this point in the history
  • Loading branch information
TheDeathlyCow committed Nov 30, 2023
1 parent d4fc276 commit c44145c
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import net.minecraft.block.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.floatprovider.ClampedNormalFloatProvider;
import net.minecraft.util.math.floatprovider.FloatProvider;
import net.minecraft.util.math.floatprovider.UniformFloatProvider;
import net.minecraft.util.math.intprovider.IntProvider;
Expand All @@ -14,6 +16,8 @@
import net.minecraft.world.StructureWorldAccess;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.WorldView;
import net.minecraft.world.gen.feature.DripstoneClusterFeature;
import net.minecraft.world.gen.feature.DripstoneClusterFeatureConfig;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.FeatureConfig;
import net.minecraft.world.gen.feature.util.CaveSurface;
Expand Down Expand Up @@ -41,8 +45,11 @@ public boolean generate(FeatureContext<IcicleFeatureConfig> context) {
int xRadius = config.radius.get(random);
int zRadius = config.radius.get(random);

float density = config.density.get(random);
int icicleHeight = config.icicleHeight.get(random);

// generate
generate(worldAccess, random, origin, xRadius, zRadius, config);
generate(worldAccess, random, origin, xRadius, zRadius, density, icicleHeight, config);

return true;
}
Expand All @@ -53,16 +60,17 @@ private void generate(
BlockPos origin,
int xRadius,
int zRadius,
float density,
int icicleHeight,
IcicleFeatureConfig config
) {
BlockPos pos;
float ceilingDensity = config.density.get(random);
float floorDensity = config.density.get(random);

for (int x = -xRadius; x < xRadius; x++) {
for (int z = -zRadius; z < zRadius; z++) {
pos = origin.add(x, 0, z);
generateColumn(world, random, pos, ceilingDensity, floorDensity, config);
double icicleChance = this.icicleChance(xRadius, zRadius, x, z, config);
generateColumn(world, random, pos, x, z, density, icicleChance, icicleHeight, config);
}
}
}
Expand All @@ -71,8 +79,10 @@ private void generateColumn(
WorldAccess world,
Random random,
BlockPos position,
float ceilingDensity,
float floorDensity,
int localX, int localZ,
float density,
double icicleChance,
int icicleHeight,
IcicleFeatureConfig config
) {

Expand All @@ -94,20 +104,40 @@ private void generateColumn(
return;
}

boolean shouldGenerateCeiling = random.nextDouble() < icicleChance;
boolean shouldGenerateFloor = random.nextDouble() < icicleChance;


int floorIcicleLength = 0;
int ceilingIcicleLength = 0;


// build ice layers
if (ceilingHeight.isPresent() && random.nextDouble() < ceilingDensity && !this.isLava(world, position.withY(ceilingHeight.getAsInt()))) {
if (ceilingHeight.isPresent() && shouldGenerateCeiling && !this.isLava(world, position.withY(ceilingHeight.getAsInt()))) {
int thickness = config.packedIceBlockLayerThickness.get(random);
this.placePackedIceBlocks(world, position.withY(ceilingHeight.getAsInt()), thickness, Direction.UP);
ceilingIcicleLength = getHeight(
random,
localX, localZ,
density,
icicleHeight,
config
);
}

if (floorHeight.isPresent() && random.nextDouble() < floorDensity && !this.isLava(world, position.withY(floorHeight.getAsInt()))) {
if (floorHeight.isPresent() && shouldGenerateFloor && !this.isLava(world, position.withY(floorHeight.getAsInt()))) {
int thickness = config.packedIceBlockLayerThickness.get(random);
this.placePackedIceBlocks(world, position.withY(floorHeight.getAsInt()), thickness, Direction.DOWN);
floorIcicleLength = getHeight(
random,
localX, localZ,
density,
icicleHeight,
config
);
}

// place icicles
int floorIcicleLength = config.icicleHeight.get(random);
int ceilingIcicleLength = config.icicleHeight.get(random);
boolean merge = false;

// adjust icicle heights if they would intersect with each other or terrain
Expand All @@ -128,7 +158,8 @@ private void generateColumn(
}
}

if (ceilingHeight.isPresent() && random.nextDouble() < ceilingDensity) {
// place icicles
if (ceilingHeight.isPresent() && shouldGenerateCeiling && ceilingIcicleLength > 0) {
IcicleHelper.generateIcicle(
world,
position.withY(ceilingHeight.getAsInt() - 1),
Expand All @@ -137,7 +168,7 @@ private void generateColumn(
merge
);
}
if (floorHeight.isPresent() && random.nextDouble() < floorDensity) {
if (floorHeight.isPresent() && shouldGenerateFloor && floorIcicleLength > 0) {
IcicleHelper.generateIcicle(
world,
position.withY(floorHeight.getAsInt() + 1),
Expand All @@ -162,13 +193,49 @@ private void placePackedIceBlocks(WorldAccess world, BlockPos pos, int thickness
}
}

private int getHeight(Random random, int localX, int localZ, float density, int maxHeight, IcicleFeatureConfig config) {
if (random.nextFloat() > density) {
return 0;
}
int absoluteDistanceManhattan = Math.abs(localX) + Math.abs(localZ);
float mean = MathHelper.clampedMap(
absoluteDistanceManhattan,
1.0f,
config.maxDistanceFromCenterAffectingHeightBias,
maxHeight / 2.0f,
1.0f
);
return (int) clampedGaussian(random, 1.0f, maxHeight, mean, config.heightDeviation);
}

private static float clampedGaussian(Random random, float min, float max, float mean, float deviation) {
return ClampedNormalFloatProvider.get(random, mean, deviation, min, max);
}

private double icicleChance(int radiusX, int radiusZ, int localX, int localZ, IcicleFeatureConfig config) {
int distanceToEdgeX = radiusX - Math.abs(localX);
int distanceToEdgeZ = radiusZ - Math.abs(localZ);
int minDistanceToEdge = Math.min(distanceToEdgeX, distanceToEdgeZ);
return MathHelper.clampedMap(
minDistanceToEdge,
0.0, IcicleFeatureConfig.MAX_DIST_FROM_CENTER_AFFECTING_COLUMN_CHANCE,
IcicleFeatureConfig.CHANCE_OF_COLUMN_AT_MAX_DISTANCE, 1.0
);
}

public record IcicleFeatureConfig(
IntProvider icicleHeight,
IntProvider radius,
FloatProvider density,
int floorToCeilingSearchRange,
IntProvider packedIceBlockLayerThickness
IntProvider packedIceBlockLayerThickness,
int heightDeviation,
int maxDistanceFromCenterAffectingHeightBias
) implements FeatureConfig {

private static final double MAX_DIST_FROM_CENTER_AFFECTING_COLUMN_CHANCE = 3.0;
private static final double CHANCE_OF_COLUMN_AT_MAX_DISTANCE = 0.1;

public static final Codec<IcicleFeatureConfig> CODEC = RecordCodecBuilder.create(
instance -> instance.group(
IntProvider.createValidatingCodec(0, 10)
Expand All @@ -181,7 +248,7 @@ public record IcicleFeatureConfig(
.forGetter(config -> config.radius),
FloatProvider.createValidatedCodec(0f, 1f)
.fieldOf("density")
.orElse(UniformFloatProvider.create(0.3f, 0.7f))
.orElse(UniformFloatProvider.create(0.1f, 0.4f))
.forGetter(config -> config.density),
Codec.intRange(1, 32)
.fieldOf("floor_to_ceiling_search_range")
Expand All @@ -190,7 +257,15 @@ public record IcicleFeatureConfig(
IntProvider.createValidatingCodec(1, 32)
.fieldOf("packed_ice_layer_thickness")
.orElse(UniformIntProvider.create(1, 4))
.forGetter(config -> config.packedIceBlockLayerThickness)
.forGetter(config -> config.packedIceBlockLayerThickness),
Codec.intRange(1, 64)
.fieldOf("height_deviation")
.orElse(3)
.forGetter(config -> config.heightDeviation),
Codec.intRange(1, 64)
.fieldOf("max_distance_from_center_affecting_height_bias")
.orElse(8)
.forGetter(config -> config.maxDistanceFromCenterAffectingHeightBias)
).apply(instance, IcicleFeatureConfig::new)
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"icicle_height": {
"type": "minecraft:uniform",
"value": {
"min_inclusive": 1,
"max_inclusive": 4
"min_inclusive": 3,
"max_inclusive": 6
}
},
"radius": {
Expand All @@ -15,20 +15,16 @@
"max_inclusive": 8
}
},
"density": {
"type": "minecraft:uniform",
"value": {
"min_inclusive": 0.3,
"max_inclusive": 0.7
}
},
"density": 1.0,
"floor_to_ceiling_search_range": 12,
"packed_ice_layer_thickness": {
"type": "minecraft:uniform",
"value": {
"min_inclusive": 4,
"max_inclusive": 7
}
}
},
"height_deviation": 3,
"max_distance_from_center_affecting_height_bias": 8
}
}

0 comments on commit c44145c

Please sign in to comment.