mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-19 10:43:14 +00:00
Scaffolding
This commit is contained in:
parent
a97cb3df4f
commit
cecbad2eb9
16
pom.xml
16
pom.xml
@ -150,6 +150,22 @@
|
|||||||
<version>1.15.1-R0.1-SNAPSHOT</version>
|
<version>1.15.1-R0.1-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</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>
|
<dependency>
|
||||||
<groupId>org.bukkit</groupId>
|
<groupId>org.bukkit</groupId>
|
||||||
<artifactId>bukkit</artifactId>
|
<artifactId>bukkit</artifactId>
|
||||||
|
@ -4,6 +4,7 @@ import java.io.File;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
@ -18,6 +19,10 @@ import ninja.bytecode.iris.util.IO;
|
|||||||
|
|
||||||
public class Iris extends JavaPlugin
|
public class Iris extends JavaPlugin
|
||||||
{
|
{
|
||||||
|
public static Iris instance;
|
||||||
|
public static IrisDataManager data;
|
||||||
|
public static IrisHotloadManager hotloader;
|
||||||
|
|
||||||
public Iris()
|
public Iris()
|
||||||
{
|
{
|
||||||
IO.delete(new File("iris"));
|
IO.delete(new File("iris"));
|
||||||
@ -25,7 +30,9 @@ public class Iris extends JavaPlugin
|
|||||||
|
|
||||||
public void onEnable()
|
public void onEnable()
|
||||||
{
|
{
|
||||||
|
instance = this;
|
||||||
|
hotloader = new IrisHotloadManager();
|
||||||
|
data = new IrisDataManager(getDataFolder());
|
||||||
Bukkit.getScheduler().scheduleSyncDelayedTask(this, () ->
|
Bukkit.getScheduler().scheduleSyncDelayedTask(this, () ->
|
||||||
{
|
{
|
||||||
for(World i : Bukkit.getWorlds())
|
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())
|
for(Player i : Bukkit.getOnlinePlayers())
|
||||||
{
|
{
|
||||||
@ -48,6 +55,7 @@ public class Iris extends JavaPlugin
|
|||||||
}, 5);
|
}, 5);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDisable()
|
public void onDisable()
|
||||||
@ -64,6 +72,36 @@ public class Iris extends JavaPlugin
|
|||||||
@Override
|
@Override
|
||||||
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id)
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
104
src/main/java/ninja/bytecode/iris/IrisDataManager.java
Normal file
104
src/main/java/ninja/bytecode/iris/IrisDataManager.java
Normal 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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ package ninja.bytecode.iris;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -11,17 +12,34 @@ import org.bukkit.block.data.BlockData;
|
|||||||
import org.bukkit.generator.BlockPopulator;
|
import org.bukkit.generator.BlockPopulator;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
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.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;
|
import ninja.bytecode.iris.util.RNG;
|
||||||
|
|
||||||
public class IrisGenerator extends ChunkGenerator
|
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 boolean initialized = false;
|
||||||
private CNG gen;
|
|
||||||
private EnumPolygonGenerator<BlockData> pog;
|
public IrisGenerator(String dimensionName)
|
||||||
private BlockData[] d = {Material.RED_CONCRETE.createBlockData(), Material.GREEN_CONCRETE.createBlockData(), Material.BLUE_CONCRETE.createBlockData(),
|
{
|
||||||
};
|
this.dimensionName = dimensionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IrisDimension getDimension()
|
||||||
|
{
|
||||||
|
return Iris.data.getDimensionLoader().load(dimensionName);
|
||||||
|
}
|
||||||
|
|
||||||
public void onInit(World world, RNG rng)
|
public void onInit(World world, RNG rng)
|
||||||
{
|
{
|
||||||
@ -31,8 +49,8 @@ public class IrisGenerator extends ChunkGenerator
|
|||||||
}
|
}
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
gen = CNG.signature(rng.nextParallelRNG(0));
|
glBiome = new GenLayerBiome(this, rng.nextParallelRNG(1));
|
||||||
pog = new EnumPolygonGenerator<BlockData>(rng.nextParallelRNG(1), 0.1, 1, d, (c) -> c);
|
terrainNoise = CNG.signature(rng.nextParallelRNG(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -42,26 +60,56 @@ public class IrisGenerator extends ChunkGenerator
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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());
|
RNG random = new RNG(world.getSeed());
|
||||||
onInit(world, random.nextParallelRNG(0));
|
onInit(world, random.nextParallelRNG(0));
|
||||||
ChunkData data = Bukkit.createChunkData(world);
|
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;
|
rz = (z * 16) + j;
|
||||||
double wz = (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;
|
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
|
@Override
|
||||||
public List<BlockPopulator> getDefaultPopulators(World world)
|
public List<BlockPopulator> getDefaultPopulators(World world)
|
||||||
{
|
{
|
||||||
|
57
src/main/java/ninja/bytecode/iris/IrisHotloadManager.java
Normal file
57
src/main/java/ninja/bytecode/iris/IrisHotloadManager.java
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
36
src/main/java/ninja/bytecode/iris/layer/GenLayerBiome.java
Normal file
36
src/main/java/ninja/bytecode/iris/layer/GenLayerBiome.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
10
src/main/java/ninja/bytecode/iris/object/Dispersion.java
Normal file
10
src/main/java/ninja/bytecode/iris/object/Dispersion.java
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package ninja.bytecode.iris.object;
|
||||||
|
|
||||||
|
public enum Dispersion
|
||||||
|
{
|
||||||
|
SCATTER,
|
||||||
|
SIMPLEX,
|
||||||
|
CELLS,
|
||||||
|
WISPY,
|
||||||
|
ZEBRA
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package ninja.bytecode.iris.object;
|
||||||
|
|
||||||
|
public enum InterpolationMethod
|
||||||
|
{
|
||||||
|
NONE,
|
||||||
|
BILINEAR,
|
||||||
|
BICUBIC,
|
||||||
|
HERMITE
|
||||||
|
}
|
107
src/main/java/ninja/bytecode/iris/object/IrisBiome.java
Normal file
107
src/main/java/ninja/bytecode/iris/object/IrisBiome.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
48
src/main/java/ninja/bytecode/iris/object/IrisDimension.java
Normal file
48
src/main/java/ninja/bytecode/iris/object/IrisDimension.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
17
src/main/java/ninja/bytecode/iris/util/BiomeResult.java
Normal file
17
src/main/java/ninja/bytecode/iris/util/BiomeResult.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -25,6 +25,9 @@ public class CNG
|
|||||||
private NoiseInjector injector;
|
private NoiseInjector injector;
|
||||||
private RNG rng;
|
private RNG rng;
|
||||||
private int oct;
|
private int oct;
|
||||||
|
private double patch;
|
||||||
|
private double up;
|
||||||
|
private double down;
|
||||||
private double power;
|
private double power;
|
||||||
|
|
||||||
public static CNG signature(RNG rng)
|
public static CNG signature(RNG rng)
|
||||||
@ -32,14 +35,12 @@ public class CNG
|
|||||||
//@builder
|
//@builder
|
||||||
return new CNG(rng.nextParallelRNG(17), 1D, 8)
|
return new CNG(rng.nextParallelRNG(17), 1D, 8)
|
||||||
.scale(0.012)
|
.scale(0.012)
|
||||||
.amp(0.5)
|
|
||||||
.freq(1.1)
|
|
||||||
.fractureWith(new CNG(rng.nextParallelRNG(18), 1, 5)
|
.fractureWith(new CNG(rng.nextParallelRNG(18), 1, 5)
|
||||||
.scale(0.018)
|
.scale(0.018)
|
||||||
.child(new CNG(rng.nextParallelRNG(19), 0.745, 2)
|
.child(new CNG(rng.nextParallelRNG(19), 1, 2)
|
||||||
.scale(0.1))
|
.scale(0.1))
|
||||||
.fractureWith(new CNG(rng.nextParallelRNG(20), 1, 3)
|
.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
|
//@done
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,6 +63,7 @@ public class CNG
|
|||||||
freq = 1;
|
freq = 1;
|
||||||
amp = 1;
|
amp = 1;
|
||||||
scale = 1;
|
scale = 1;
|
||||||
|
patch = 1;
|
||||||
fscale = 1;
|
fscale = 1;
|
||||||
fracture = null;
|
fracture = null;
|
||||||
generator = new SNG(random);
|
generator = new SNG(random);
|
||||||
@ -116,12 +118,66 @@ public class CNG
|
|||||||
return this;
|
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)
|
public CNG injectWith(NoiseInjector i)
|
||||||
{
|
{
|
||||||
injector = i;
|
injector = i;
|
||||||
return this;
|
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)
|
public double noise(double... dim)
|
||||||
{
|
{
|
||||||
double f = fracture != null ? (fracture.noise(dim) - 0.5) * fscale : 0D;
|
double f = fracture != null ? (fracture.noise(dim) - 0.5) * fscale : 0D;
|
||||||
@ -134,7 +190,7 @@ public class CNG
|
|||||||
hits += oct;
|
hits += oct;
|
||||||
if(children == null)
|
if(children == null)
|
||||||
{
|
{
|
||||||
return n;
|
return (n - down + up) * patch;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(CNG i : children)
|
for(CNG i : children)
|
||||||
@ -144,7 +200,7 @@ public class CNG
|
|||||||
m += r[1];
|
m += r[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return n / m;
|
return ((n / m) - down + up) * patch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CNG pow(double power)
|
public CNG pow(double power)
|
||||||
|
54
src/main/java/ninja/bytecode/iris/util/CellGenerator2D.java
Normal file
54
src/main/java/ninja/bytecode/iris/util/CellGenerator2D.java
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
2197
src/main/java/ninja/bytecode/iris/util/FastNoise.java
Normal file
2197
src/main/java/ninja/bytecode/iris/util/FastNoise.java
Normal file
File diff suppressed because it is too large
Load Diff
42
src/main/java/ninja/bytecode/iris/util/FileWatcher.java
Normal file
42
src/main/java/ninja/bytecode/iris/util/FileWatcher.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
17
src/main/java/ninja/bytecode/iris/util/GenLayer.java
Normal file
17
src/main/java/ninja/bytecode/iris/util/GenLayer.java
Normal 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);
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package ninja.bytecode.iris.util;
|
package ninja.bytecode.iris.util;
|
||||||
|
|
||||||
|
import ninja.bytecode.iris.object.InterpolationMethod;
|
||||||
|
|
||||||
public class IrisInterpolation
|
public class IrisInterpolation
|
||||||
{
|
{
|
||||||
public static double bezier(double t)
|
public static double bezier(double t)
|
||||||
@ -18,6 +20,11 @@ public class IrisInterpolation
|
|||||||
return a + (f * (b - a));
|
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)
|
public static double lerpBezier(double a, double b, double f)
|
||||||
{
|
{
|
||||||
return a + (bezier(f) * (b - a));
|
return a + (bezier(f) * (b - a));
|
||||||
@ -181,6 +188,26 @@ public class IrisInterpolation
|
|||||||
//@done
|
//@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)
|
public static double getHermiteNoise(int x, int z, double rad, NoiseProvider n)
|
||||||
{
|
{
|
||||||
int fx = (int) Math.floor(x / rad);
|
int fx = (int) Math.floor(x / rad);
|
||||||
|
@ -639,4 +639,10 @@ public class KList<T> extends ArrayList<T> implements List<T>
|
|||||||
remove(t);
|
remove(t);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KList<T> qadd(T t)
|
||||||
|
{
|
||||||
|
add(t);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,6 +151,11 @@ public class M
|
|||||||
return (T) Double.valueOf(Math.min(max.doubleValue(), Math.max(min.doubleValue(), value.doubleValue())));
|
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
|
* Get true or false based on random percent
|
||||||
*
|
*
|
||||||
|
95
src/main/java/ninja/bytecode/iris/util/ResourceLoader.java
Normal file
95
src/main/java/ninja/bytecode/iris/util/ResourceLoader.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user