Scaffolding

This commit is contained in:
Daniel Mills 2020-03-20 10:17:51 -04:00
parent a97cb3df4f
commit cecbad2eb9
21 changed files with 3096 additions and 22 deletions

16
pom.xml
View File

@ -150,6 +150,22 @@
<version>1.15.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.vecmath</groupId>
<artifactId>vecmath</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>

View File

@ -4,6 +4,7 @@ import java.io.File;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.World;
@ -18,6 +19,10 @@ import ninja.bytecode.iris.util.IO;
public class Iris extends JavaPlugin
{
public static Iris instance;
public static IrisDataManager data;
public static IrisHotloadManager hotloader;
public Iris()
{
IO.delete(new File("iris"));
@ -25,7 +30,9 @@ public class Iris extends JavaPlugin
public void onEnable()
{
instance = this;
hotloader = new IrisHotloadManager();
data = new IrisDataManager(getDataFolder());
Bukkit.getScheduler().scheduleSyncDelayedTask(this, () ->
{
for(World i : Bukkit.getWorlds())
@ -36,7 +43,7 @@ public class Iris extends JavaPlugin
}
}
World world = Bukkit.createWorld(new WorldCreator("iris/" + UUID.randomUUID()).generator(new IrisGenerator()));
World world = Bukkit.createWorld(new WorldCreator("iris/" + UUID.randomUUID()).generator(new IrisGenerator("overworld")));
for(Player i : Bukkit.getOnlinePlayers())
{
@ -48,6 +55,7 @@ public class Iris extends JavaPlugin
}, 5);
}
});
}
public void onDisable()
@ -64,6 +72,36 @@ public class Iris extends JavaPlugin
@Override
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id)
{
return new IrisGenerator();
return new IrisGenerator("overworld");
}
public static void msg(String string)
{
Bukkit.getConsoleSender().sendMessage(ChatColor.GREEN + "[Iris]: " + ChatColor.GRAY + string);
}
public static void warn(String string)
{
msg(ChatColor.YELLOW + string);
}
public static void error(String string)
{
msg(ChatColor.RED + string);
}
public static void verbose(String string)
{
msg(ChatColor.GRAY + string);
}
public static void success(String string)
{
msg(ChatColor.GREEN + string);
}
public static void info(String string)
{
msg(ChatColor.WHITE + string);
}
}

View File

@ -0,0 +1,104 @@
package ninja.bytecode.iris;
import java.io.File;
import org.bukkit.World.Environment;
import org.bukkit.block.Biome;
import com.google.gson.Gson;
import lombok.Getter;
import ninja.bytecode.iris.object.Dispersion;
import ninja.bytecode.iris.object.IrisBiome;
import ninja.bytecode.iris.object.IrisBiomePaletteLayer;
import ninja.bytecode.iris.object.IrisDimension;
import ninja.bytecode.iris.util.IO;
import ninja.bytecode.iris.util.JSONObject;
import ninja.bytecode.iris.util.ResourceLoader;
public class IrisDataManager
{
private File dataFolder;
private File packs;
@Getter
private ResourceLoader<IrisBiome> biomeLoader;
@Getter
private ResourceLoader<IrisDimension> dimensionLoader;
public void hotloaded()
{
packs.mkdirs();
this.biomeLoader = new ResourceLoader<>(packs, "biomes", "Biome", IrisBiome.class);
this.dimensionLoader = new ResourceLoader<>(packs, "dimensions", "Dimension", IrisDimension.class);
writeExamples();
}
public IrisDataManager(File dataFolder)
{
this.dataFolder = dataFolder;
this.packs = new File(dataFolder, "packs");
hotloaded();
}
private void writeExamples()
{
File examples = new File(dataFolder, "example");
examples.mkdirs();
IrisBiome biome = new IrisBiome();
biome.getLayers().clear();
IrisBiomePaletteLayer grass = new IrisBiomePaletteLayer();
grass.add("GRASS_BLOCK");
grass.setDispersion(Dispersion.SCATTER);
grass.setMinHeight(1);
grass.setMaxHeight(1);
IrisBiomePaletteLayer dirt = new IrisBiomePaletteLayer();
grass.add("DIRT");
grass.setDispersion(Dispersion.SCATTER);
grass.setMinHeight(1);
grass.setMaxHeight(2);
IrisBiomePaletteLayer dirtThick = new IrisBiomePaletteLayer();
grass.add("DIRT");
grass.add("COARSE_DIRT");
grass.setDispersion(Dispersion.WISPY);
grass.setMinHeight(1);
grass.setMaxHeight(3);
biome.getLayers().add(dirtThick);
biome.getLayers().add(dirt);
biome.getLayers().add(grass);
IrisDimension dim = new IrisDimension();
dim.getBiomes().add("a_biome");
String biomes = "";
String envs = "";
for(Biome i : Biome.values())
{
biomes += i.name() + "\n";
}
for(Environment i : Environment.values())
{
envs += i.name() + "\n";
}
try
{
new File(examples, "example-pack/biomes").mkdirs();
new File(examples, "example-pack/dimensions").mkdirs();
IO.writeAll(new File(examples, "biome-list.txt"), biomes);
IO.writeAll(new File(examples, "environment-list.txt"), envs);
IO.writeAll(new File(examples, "example-pack/biomes/a_biome.json"), new JSONObject(new Gson().toJson(biome)).toString(4));
IO.writeAll(new File(examples, "example-pack/dimensions/a_dimension.json"), new JSONObject(new Gson().toJson(dim)).toString(4));
}
catch(Throwable e)
{
}
}
}

View File

@ -2,6 +2,7 @@ package ninja.bytecode.iris;
import java.util.List;
import java.util.Random;
import java.util.function.Function;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -11,17 +12,34 @@ import org.bukkit.block.data.BlockData;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.ChunkGenerator;
import ninja.bytecode.iris.layer.GenLayerBiome;
import ninja.bytecode.iris.object.IrisBiome;
import ninja.bytecode.iris.object.IrisDimension;
import ninja.bytecode.iris.util.BiomeResult;
import ninja.bytecode.iris.util.CNG;
import ninja.bytecode.iris.util.PolygonGenerator.EnumPolygonGenerator;
import ninja.bytecode.iris.util.IrisInterpolation;
import ninja.bytecode.iris.util.KList;
import ninja.bytecode.iris.util.RNG;
public class IrisGenerator extends ChunkGenerator
{
// TODO REMOVE OR FIND A BETTER PLACE
private BlockData STONE = Material.STONE.createBlockData();
private String dimensionName;
private GenLayerBiome glBiome;
private CNG terrainNoise;
private boolean initialized = false;
private CNG gen;
private EnumPolygonGenerator<BlockData> pog;
private BlockData[] d = {Material.RED_CONCRETE.createBlockData(), Material.GREEN_CONCRETE.createBlockData(), Material.BLUE_CONCRETE.createBlockData(),
};
public IrisGenerator(String dimensionName)
{
this.dimensionName = dimensionName;
}
public IrisDimension getDimension()
{
return Iris.data.getDimensionLoader().load(dimensionName);
}
public void onInit(World world, RNG rng)
{
@ -31,8 +49,8 @@ public class IrisGenerator extends ChunkGenerator
}
initialized = true;
gen = CNG.signature(rng.nextParallelRNG(0));
pog = new EnumPolygonGenerator<BlockData>(rng.nextParallelRNG(1), 0.1, 1, d, (c) -> c);
glBiome = new GenLayerBiome(this, rng.nextParallelRNG(1));
terrainNoise = CNG.signature(rng.nextParallelRNG(2));
}
@Override
@ -42,26 +60,56 @@ public class IrisGenerator extends ChunkGenerator
}
@Override
public ChunkData generateChunkData(World world, Random no, int x, int z, BiomeGrid biome)
public ChunkData generateChunkData(World world, Random no, int x, int z, BiomeGrid biomeGrid)
{
Iris.hotloader.check();
int i, j, k, height, depth;
double wx, wz, rx, rz, heightLow, heightHigh, heightExponent;
int fluidHeight = getDimension().getFluidHeight();
BiomeResult biomeResult;
IrisBiome biome;
RNG random = new RNG(world.getSeed());
onInit(world, random.nextParallelRNG(0));
ChunkData data = Bukkit.createChunkData(world);
for(int i = 0; i < 16; i++)
for(i = 0; i < 16; i++)
{
for(int j = 0; j < 16; j++)
rx = (x * 16) + i;
wx = ((double) (x * 16) + i) / getDimension().getTerrainZoom();
for(j = 0; j < 16; j++)
{
double wx = (x * 16) + i;
double wz = (z * 16) + j;
rz = (z * 16) + j;
wz = ((double) (z * 16) + j) / getDimension().getTerrainZoom();
depth = 0;
biomeResult = glBiome.generateData(wx, wz);
biome = biomeResult.getBiome();
heightLow = interpolate(rx, rz, (b) -> b.getLowHeight());
heightHigh = interpolate(rx, rz, (b) -> b.getHighHeight());
heightExponent = interpolate(rx, rz, (b) -> b.getHeightExponent());
height = (int) Math.round(terrainNoise.fitDoubleExponent(heightLow, heightHigh, heightExponent, wx, wz)) + fluidHeight;
KList<BlockData> layers = biome.generateLayers(wx, wz, random, height);
data.setBlock(i, 0, j, pog.getChoice(wx, wz));
for(k = Math.max(height, fluidHeight); k >= 0; k--)
{
biomeGrid.setBiome(i, k, j, biome.getDerivative());
data.setBlock(i, k, j, layers.hasIndex(depth) ? layers.get(depth) : STONE);
depth++;
}
}
}
return data;
}
public double interpolate(double rx, double rz, Function<IrisBiome, Double> property)
{
return IrisInterpolation.getNoise(getDimension().getInterpolationFunction(), (int) Math.round(rx), (int) Math.round(rz), getDimension().getInterpolationScale(), (xx, zz) ->
{
BiomeResult neighborResult = glBiome.generateData(xx / getDimension().getTerrainZoom(), zz / getDimension().getTerrainZoom());
return property.apply(neighborResult.getBiome());
});
}
@Override
public List<BlockPopulator> getDefaultPopulators(World world)
{

View File

@ -0,0 +1,57 @@
package ninja.bytecode.iris;
import java.io.File;
import org.bukkit.Bukkit;
import ninja.bytecode.iris.util.ChronoLatch;
import ninja.bytecode.iris.util.FileWatcher;
import ninja.bytecode.iris.util.KList;
public class IrisHotloadManager
{
private ChronoLatch latch;
private KList<FileWatcher> watchers;
public IrisHotloadManager()
{
watchers = new KList<>();
latch = new ChronoLatch(3000);
}
public void check()
{
if(!latch.flip())
{
return;
}
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () ->
{
boolean modified = false;
int c = 0;
for(FileWatcher i : watchers)
{
if(i.checkModified())
{
c++;
Iris.info("File Modified: " + i.getFile().getPath());
modified = true;
}
}
if(modified)
{
watchers.clear();
Iris.success("Hotloading Iris (" + c + " File" + (c == 1 ? "" : "s") + " changed)");
Iris.data.hotloaded();
}
});
}
public void track(File file)
{
watchers.add(new FileWatcher(file));
}
}

View File

@ -0,0 +1,36 @@
package ninja.bytecode.iris.layer;
import ninja.bytecode.iris.IrisGenerator;
import ninja.bytecode.iris.object.IrisBiome;
import ninja.bytecode.iris.util.BiomeResult;
import ninja.bytecode.iris.util.CellGenerator2D;
import ninja.bytecode.iris.util.GenLayer;
import ninja.bytecode.iris.util.KList;
import ninja.bytecode.iris.util.RNG;
public class GenLayerBiome extends GenLayer
{
private CellGenerator2D cells;
public GenLayerBiome(IrisGenerator iris, RNG rng)
{
super(iris, rng);
cells = new CellGenerator2D(rng.nextParallelRNG(2045662));
}
public KList<IrisBiome> getBiomes()
{
return iris.getDimension().buildBiomeList();
}
public BiomeResult generateData(double x, double z)
{
return new BiomeResult(getBiomes().get(cells.getIndex(x / iris.getDimension().getBiomeZoom(), z / iris.getDimension().getBiomeZoom(), getBiomes().size())), cells.getDistance(x / iris.getDimension().getBiomeZoom(), z / iris.getDimension().getBiomeZoom()));
}
@Override
public double generate(double x, double z)
{
return 0;
}
}

View File

@ -0,0 +1,10 @@
package ninja.bytecode.iris.object;
public enum Dispersion
{
SCATTER,
SIMPLEX,
CELLS,
WISPY,
ZEBRA
}

View File

@ -0,0 +1,9 @@
package ninja.bytecode.iris.object;
public enum InterpolationMethod
{
NONE,
BILINEAR,
BICUBIC,
HERMITE
}

View File

@ -0,0 +1,107 @@
package ninja.bytecode.iris.object;
import java.util.List;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import lombok.Data;
import ninja.bytecode.iris.util.CNG;
import ninja.bytecode.iris.util.KList;
import ninja.bytecode.iris.util.RNG;
@Data
public class IrisBiome
{
private String name = "A Biome";
private Biome derivative = Biome.THE_VOID;
private double highHeight = 7;
private double lowHeight = 1;
private double heightExponent = 1;
private KList<IrisBiomePaletteLayer> layers = new KList<IrisBiomePaletteLayer>().qadd(new IrisBiomePaletteLayer());
private transient KList<CNG> layerHeightGenerators;
private transient KList<CNG> layerSurfaceGenerators;
public KList<BlockData> generateLayers(double wx, double wz, RNG random, int maxDepth)
{
KList<BlockData> data = new KList<>();
for(int i = 0; i < layers.size(); i++)
{
CNG hgen = getLayerHeightGenerators(random).get(i);
CNG sgen = getLayerSurfaceGenerators(random).get(i);
int d = hgen.fit(layers.get(i).getMinHeight(), layers.get(i).getMaxHeight(), wx / layers.get(i).getTerrainZoom(), wz / layers.get(i).getTerrainZoom());
if(d < 0)
{
continue;
}
List<BlockData> palette = getLayers().get(i).getBlockData();
for(int j = 0; j < d; j++)
{
if(data.size() >= maxDepth)
{
break;
}
data.add(palette.get(sgen.fit(0, palette.size() - 1, (wx + j) / layers.get(i).getTerrainZoom(), (wz - j) / layers.get(i).getTerrainZoom())));
}
if(data.size() >= maxDepth)
{
break;
}
}
return data;
}
public KList<CNG> getLayerSurfaceGenerators(RNG rng)
{
synchronized(this)
{
if(layerSurfaceGenerators == null)
{
layerSurfaceGenerators = new KList<>();
synchronized(layerSurfaceGenerators)
{
int m = 91235;
for(IrisBiomePaletteLayer i : getLayers())
{
layerSurfaceGenerators.add(i.getGenerator(rng.nextParallelRNG((m += 3) * m * m * m)));
}
}
}
}
return layerSurfaceGenerators;
}
public KList<CNG> getLayerHeightGenerators(RNG rng)
{
synchronized(this)
{
if(layerHeightGenerators == null)
{
layerHeightGenerators = new KList<>();
synchronized(layerHeightGenerators)
{
int m = 7235;
for(IrisBiomePaletteLayer i : getLayers())
{
layerHeightGenerators.add(i.getGenerator(rng.nextParallelRNG((m++) * m * m * m)));
}
}
}
}
return layerHeightGenerators;
}
}

View File

@ -0,0 +1,85 @@
package ninja.bytecode.iris.object;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import lombok.Data;
import ninja.bytecode.iris.util.CNG;
import ninja.bytecode.iris.util.KList;
import ninja.bytecode.iris.util.KMap;
import ninja.bytecode.iris.util.RNG;
@Data
public class IrisBiomePaletteLayer
{
private Dispersion dispersion = Dispersion.WISPY;
private int minHeight = 1;
private int maxHeight = 1;
private double terrainZoom = 5;
private KList<String> palette = new KList<String>().qadd("GRASS_BLOCK");
private transient KMap<Long, CNG> layerGenerators;
private transient KList<BlockData> blockData;
public CNG getGenerator(RNG rng)
{
synchronized(this)
{
long key = rng.nextParallelRNG(1).nextLong();
if(layerGenerators == null)
{
layerGenerators = new KMap<>();
}
if(!layerGenerators.containsKey(key))
{
synchronized(layerGenerators)
{
layerGenerators.put(key, CNG.signature(rng.nextParallelRNG(minHeight + maxHeight + getBlockData().size())));
}
}
return layerGenerators.get(key);
}
}
public KList<String> add(String b)
{
palette.add(b);
return palette;
}
public KList<BlockData> getBlockData()
{
synchronized(this)
{
if(blockData == null)
{
blockData = new KList<>();
synchronized(blockData)
{
for(String i : palette)
{
try
{
Material m = Material.valueOf(i);
if(m != null)
{
blockData.add(m.createBlockData());
}
}
catch(Throwable e)
{
}
}
}
}
}
return blockData;
}
}

View File

@ -0,0 +1,48 @@
package ninja.bytecode.iris.object;
import org.bukkit.World.Environment;
import lombok.Data;
import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.util.KList;
@Data
public class IrisDimension
{
private String name = "A Dimension";
private InterpolationMethod interpolationFunction = InterpolationMethod.BILINEAR;
private double interpolationScale = 5.6;
private Environment environment = Environment.NORMAL;
private KList<String> biomes = new KList<>();
private int fluidHeight = 127;
private double biomeZoom = 5D;
private double terrainZoom = 2D;
private double roughnessZoom = 2D;
private int roughnessHeight = 3;
private transient KList<IrisBiome> biomeCache;
public KList<IrisBiome> buildBiomeList()
{
if(biomeCache == null)
{
synchronized(this)
{
biomeCache = new KList<>();
synchronized(biomeCache)
{
for(String i : biomes)
{
IrisBiome biome = Iris.data.getBiomeLoader().load(i);
if(biome != null)
{
biomeCache.add(biome);
}
}
}
}
}
return biomeCache;
}
}

View File

@ -0,0 +1,17 @@
package ninja.bytecode.iris.util;
import lombok.Data;
import ninja.bytecode.iris.object.IrisBiome;
@Data
public class BiomeResult
{
private IrisBiome biome;
private double distance;
public BiomeResult(IrisBiome biome, double distance)
{
this.biome = biome;
this.distance = distance;
}
}

View File

@ -25,6 +25,9 @@ public class CNG
private NoiseInjector injector;
private RNG rng;
private int oct;
private double patch;
private double up;
private double down;
private double power;
public static CNG signature(RNG rng)
@ -32,14 +35,12 @@ public class CNG
//@builder
return new CNG(rng.nextParallelRNG(17), 1D, 8)
.scale(0.012)
.amp(0.5)
.freq(1.1)
.fractureWith(new CNG(rng.nextParallelRNG(18), 1, 5)
.scale(0.018)
.child(new CNG(rng.nextParallelRNG(19), 0.745, 2)
.child(new CNG(rng.nextParallelRNG(19), 1, 2)
.scale(0.1))
.fractureWith(new CNG(rng.nextParallelRNG(20), 1, 3)
.scale(0.15), 24), 44);
.scale(0.15), 24), 44).down(0.3).patch(2.5);
//@done
}
@ -62,6 +63,7 @@ public class CNG
freq = 1;
amp = 1;
scale = 1;
patch = 1;
fscale = 1;
fracture = null;
generator = new SNG(random);
@ -116,12 +118,66 @@ public class CNG
return this;
}
public CNG patch(double c)
{
patch = c;
return this;
}
public CNG up(double c)
{
up = c;
return this;
}
public CNG down(double c)
{
down = c;
return this;
}
public CNG injectWith(NoiseInjector i)
{
injector = i;
return this;
}
public int fit(int min, int max, double... dim)
{
if(min == max)
{
return min;
}
double noise = noise(dim);
return (int) Math.round(IrisInterpolation.lerp(min, max, noise));
}
public int fitDouble(double min, double max, double... dim)
{
if(min == max)
{
return (int) Math.round(min);
}
double noise = noise(dim);
return (int) Math.round(IrisInterpolation.lerp(min, max, noise));
}
public int fitDoubleExponent(double min, double max, double exponent, double... dim)
{
if(min == max)
{
return (int) Math.round(min);
}
double noise = noise(dim);
return (int) Math.round(IrisInterpolation.lerp(min, max, exponent == 1 ? noise : Math.pow(noise, exponent)));
}
public double noise(double... dim)
{
double f = fracture != null ? (fracture.noise(dim) - 0.5) * fscale : 0D;
@ -134,7 +190,7 @@ public class CNG
hits += oct;
if(children == null)
{
return n;
return (n - down + up) * patch;
}
for(CNG i : children)
@ -144,7 +200,7 @@ public class CNG
m += r[1];
}
return n / m;
return ((n / m) - down + up) * patch;
}
public CNG pow(double power)

View File

@ -0,0 +1,54 @@
package ninja.bytecode.iris.util;
import lombok.Getter;
import lombok.Setter;
import ninja.bytecode.iris.util.FastNoise.CellularDistanceFunction;
import ninja.bytecode.iris.util.FastNoise.CellularReturnType;
import ninja.bytecode.iris.util.FastNoise.NoiseType;
public class CellGenerator2D
{
private FastNoise fn;
private FastNoise fd;
private CNG cng;
@Getter
@Setter
private double cellScale;
@Getter
@Setter
private double shuffle;
public CellGenerator2D(RNG rng)
{
shuffle = 128;
cellScale = 0.73;
cng = CNG.signature(rng.nextParallelRNG(3204));
RNG rx = rng.nextParallelRNG(8735652);
int s = rx.nextInt();
fn = new FastNoise(s);
fn.SetNoiseType(NoiseType.Cellular);
fn.SetCellularReturnType(CellularReturnType.CellValue);
fn.SetCellularDistanceFunction(CellularDistanceFunction.Natural);
fd = new FastNoise(s);
fd.SetNoiseType(NoiseType.Cellular);
fd.SetCellularReturnType(CellularReturnType.Distance2Sub);
fd.SetCellularDistanceFunction(CellularDistanceFunction.Natural);
}
public float getDistance(double x, double z)
{
return ((fd.GetCellular((float) ((x * cellScale) + (cng.noise(x, z) * shuffle)), (float) ((z * cellScale) + (cng.noise(z, x) * shuffle)))) + 1f) / 2f;
}
public float getValue(double x, double z, int possibilities)
{
return ((fn.GetCellular((float) ((x * cellScale) + (cng.noise(x, z) * shuffle)), (float) ((z * cellScale) + (cng.noise(z, x) * shuffle))) + 1f) / 2f) * (possibilities - 1);
}
public int getIndex(double x, double z, int possibilities)
{
return (int) Math.round(getValue(x, z, possibilities));
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
package ninja.bytecode.iris.util;
import java.io.File;
import lombok.Getter;
public class FileWatcher
{
@Getter
private final File file;
private boolean exists;
private long lastModified;
private long size;
public FileWatcher(File file)
{
this.file = file;
readProperties();
}
private void readProperties()
{
exists = file.exists();
lastModified = exists ? file.lastModified() : -1;
size = exists ? file.length() : -1;
}
public boolean checkModified()
{
long m = lastModified;
long g = size;
boolean mod = false;
readProperties();
if(lastModified != m || g != size)
{
mod = true;
}
return mod;
}
}

View File

@ -0,0 +1,17 @@
package ninja.bytecode.iris.util;
import ninja.bytecode.iris.IrisGenerator;
public abstract class GenLayer
{
protected final RNG rng;
protected final IrisGenerator iris;
public GenLayer(IrisGenerator iris, RNG rng)
{
this.iris = iris;
this.rng = rng;
}
public abstract double generate(double x, double z);
}

View File

@ -1,5 +1,7 @@
package ninja.bytecode.iris.util;
import ninja.bytecode.iris.object.InterpolationMethod;
public class IrisInterpolation
{
public static double bezier(double t)
@ -18,6 +20,11 @@ public class IrisInterpolation
return a + (f * (b - a));
}
public static float lerpf(float a, float b, float f)
{
return a + (f * (b - a));
}
public static double lerpBezier(double a, double b, double f)
{
return a + (bezier(f) * (b - a));
@ -181,6 +188,26 @@ public class IrisInterpolation
//@done
}
public static double getNoise(InterpolationMethod method, int x, int z, double rad, NoiseProvider n)
{
if(method.equals(InterpolationMethod.BILINEAR))
{
return getBilinearNoise(x, z, rad, n);
}
else if(method.equals(InterpolationMethod.BICUBIC))
{
return getBicubicNoise(x, z, rad, n);
}
else if(method.equals(InterpolationMethod.HERMITE))
{
return getHermiteNoise(x, z, rad, n);
}
return n.noise(x, z);
}
public static double getHermiteNoise(int x, int z, double rad, NoiseProvider n)
{
int fx = (int) Math.floor(x / rad);

View File

@ -639,4 +639,10 @@ public class KList<T> extends ArrayList<T> implements List<T>
remove(t);
return this;
}
public KList<T> qadd(T t)
{
add(t);
return this;
}
}

View File

@ -151,6 +151,11 @@ public class M
return (T) Double.valueOf(Math.min(max.doubleValue(), Math.max(min.doubleValue(), value.doubleValue())));
}
public static int iclip(int value, int min, int max)
{
return Math.min(max, Math.max(min, value));
}
/**
* Get true or false based on random percent
*

View File

@ -0,0 +1,95 @@
package ninja.bytecode.iris.util;
import java.io.File;
import com.google.gson.Gson;
import ninja.bytecode.iris.Iris;
public class ResourceLoader<T>
{
private File root;
private String folderName;
private String resourceTypeName;
private KMap<String, T> loadCache;
private KList<File> folderCache;
private Class<? extends T> objectClass;
public ResourceLoader(File root, String folderName, String resourceTypeName, Class<? extends T> objectClass)
{
this.objectClass = objectClass;
this.resourceTypeName = resourceTypeName;
this.root = root;
this.folderName = folderName;
loadCache = new KMap<>();
}
public T load(String name)
{
String key = name + "-" + objectClass.getCanonicalName();
if(loadCache.containsKey(key))
{
return loadCache.get(key);
}
for(File i : getFolders())
{
for(File j : i.listFiles())
{
if(j.isFile() && j.getName().endsWith(".json") && j.getName().split("\\Q.\\E")[0].equals(name))
{
try
{
T t = new Gson().fromJson(IO.readAll(j), objectClass);
loadCache.put(key, t);
Iris.hotloader.track(j);
Iris.info("Loading " + resourceTypeName + ": " + j.getPath());
return t;
}
catch(Throwable e)
{
Iris.warn("Couldn't read " + resourceTypeName + " file: " + j.getPath() + ": " + e.getMessage());
}
}
}
}
Iris.warn("Couldn't find " + resourceTypeName + ": " + name);
return null;
}
public KList<File> getFolders()
{
if(folderCache == null)
{
folderCache = new KList<>();
for(File i : root.listFiles())
{
if(i.isDirectory())
{
for(File j : i.listFiles())
{
if(j.isDirectory() && j.getName().equals(folderName))
{
folderCache.add(j);
break;
}
}
}
}
}
return folderCache;
}
public void clearCache()
{
loadCache.clear();
folderCache = null;
}
}