134 lines
4.7 KiB
Java
134 lines
4.7 KiB
Java
package com.hypixel.hytale.server.worldgen.climate;
|
|
|
|
import com.hypixel.hytale.math.util.MathUtil;
|
|
import com.hypixel.hytale.procedurallib.logic.ResultBuffer;
|
|
import com.hypixel.hytale.procedurallib.logic.cell.CellDistanceFunction;
|
|
import com.hypixel.hytale.procedurallib.logic.cell.evaluator.PointEvaluator;
|
|
import com.hypixel.hytale.procedurallib.property.NoiseProperty;
|
|
import javax.annotation.Nonnull;
|
|
|
|
public class ClimateNoise {
|
|
@Nonnull
|
|
public final ClimateNoise.Grid grid;
|
|
@Nonnull
|
|
public final NoiseProperty continent;
|
|
@Nonnull
|
|
public final NoiseProperty temperature;
|
|
@Nonnull
|
|
public final NoiseProperty intensity;
|
|
@Nonnull
|
|
public final ClimateNoise.Thresholds thresholds;
|
|
|
|
public ClimateNoise(
|
|
@Nonnull ClimateNoise.Grid grid,
|
|
@Nonnull NoiseProperty continent,
|
|
@Nonnull NoiseProperty temperature,
|
|
@Nonnull NoiseProperty intensity,
|
|
@Nonnull ClimateNoise.Thresholds thresholds
|
|
) {
|
|
this.grid = grid;
|
|
this.temperature = temperature;
|
|
this.intensity = intensity;
|
|
this.continent = continent;
|
|
this.thresholds = thresholds;
|
|
}
|
|
|
|
public int generate(int seed, double x, double y, @Nonnull ClimateNoise.Buffer buffer, @Nonnull ClimateGraph climate) {
|
|
this.grid.eval(seed, x, y, buffer.pos);
|
|
double c = this.continent.get(seed, x, y);
|
|
double t = this.temperature.get(seed, buffer.pos.x, buffer.pos.y);
|
|
double i = this.intensity.get(seed, buffer.pos.x, buffer.pos.y);
|
|
int index = climate.indexOf(t, i);
|
|
buffer.continent = c;
|
|
buffer.temperature = t;
|
|
buffer.intensity = i;
|
|
buffer.fade = climate.getFade(index);
|
|
int id = climate.getId(index);
|
|
int flags = getContinentFlags(c, this.thresholds);
|
|
return id | flags;
|
|
}
|
|
|
|
private static int getContinentFlags(double value, @Nonnull ClimateNoise.Thresholds thresholds) {
|
|
boolean isLand = value <= thresholds.landShallowOceanOuter;
|
|
boolean isIsland = value >= thresholds.islandShallowOceanOuter;
|
|
boolean isOcean = value > thresholds.land && value < thresholds.island;
|
|
boolean isShore = isLand && value > thresholds.landShoreInner || isIsland && value < thresholds.islandShoreInner;
|
|
int flags = 0;
|
|
if (isOcean) {
|
|
flags |= Integer.MIN_VALUE;
|
|
}
|
|
|
|
if (isShore) {
|
|
flags |= 1073741824;
|
|
}
|
|
|
|
if (isIsland) {
|
|
flags |= 536870912;
|
|
}
|
|
|
|
return flags;
|
|
}
|
|
|
|
public static class Buffer {
|
|
public double continent = 0.0;
|
|
public double temperature = 0.0;
|
|
public double intensity = 0.0;
|
|
public double fade = 0.0;
|
|
public final ResultBuffer.ResultBuffer2d pos = new ResultBuffer.ResultBuffer2d();
|
|
}
|
|
|
|
public static class Grid {
|
|
public final int seedOffset;
|
|
public final double scale;
|
|
@Nonnull
|
|
public final PointEvaluator evaluator;
|
|
@Nonnull
|
|
public final CellDistanceFunction grid;
|
|
public final transient double invScale;
|
|
|
|
public Grid(int seedOffset, double scale, @Nonnull CellDistanceFunction grid, @Nonnull PointEvaluator evaluator) {
|
|
this.seedOffset = seedOffset;
|
|
this.scale = scale;
|
|
this.evaluator = evaluator;
|
|
this.grid = grid;
|
|
this.invScale = 1.0 / scale;
|
|
}
|
|
|
|
public void eval(int seed, double x, double y, ResultBuffer.ResultBuffer2d buffer) {
|
|
x *= this.scale;
|
|
y *= this.scale;
|
|
buffer.distance = Double.MAX_VALUE;
|
|
buffer.distance2 = Double.MAX_VALUE;
|
|
this.grid.nearest2D(seed + this.seedOffset, x, y, MathUtil.floor(x), MathUtil.floor(y), buffer, this.evaluator);
|
|
buffer.x = buffer.x * this.invScale;
|
|
buffer.y = buffer.y * this.invScale;
|
|
}
|
|
}
|
|
|
|
public static class Thresholds {
|
|
public static final double LAND_DEFAULT = 0.5;
|
|
public static final double ISLAND_DEFAULT = 0.8;
|
|
public static final double BEACH_SIZE_DEFAULT = 0.05;
|
|
public static final double SHALLOW_OCEAN_SIZE_DEFAULT = 0.15;
|
|
public final double land;
|
|
public final double island;
|
|
public final double beachSize;
|
|
public final double shallowOceanSize;
|
|
public final transient double landShoreInner;
|
|
public final transient double islandShoreInner;
|
|
public final transient double landShallowOceanOuter;
|
|
public final transient double islandShallowOceanOuter;
|
|
|
|
public Thresholds(double land, double island, double beach, double shore) {
|
|
this.land = land;
|
|
this.island = island;
|
|
this.beachSize = beach;
|
|
this.shallowOceanSize = shore;
|
|
this.landShoreInner = land - beach;
|
|
this.islandShoreInner = island + beach;
|
|
this.landShallowOceanOuter = land + shore;
|
|
this.islandShallowOceanOuter = island - shore * 0.5;
|
|
}
|
|
}
|
|
}
|