From ce0249f28ec4d7d61fc3b51f1fbd28e5f7539126 Mon Sep 17 00:00:00 2001 From: Dan Macbook Date: Tue, 11 Aug 2020 16:27:48 -0400 Subject: [PATCH] New Noise System --- .../java/com/volmit/iris/IrisDataManager.java | 2 - .../java/com/volmit/iris/ProjectManager.java | 555 ++++++++++-------- src/main/java/com/volmit/iris/noise/CNG.java | 185 +++--- .../com/volmit/iris/noise/CNGFactory.java | 9 + .../com/volmit/iris/noise/OctaveNoise.java | 6 + .../com/volmit/iris/noise/SimplexNoise.java | 63 +- .../com/volmit/iris/object/Dispersion.java | 12 - .../com/volmit/iris/object/IrisBiome.java | 16 +- .../iris/object/IrisBiomeDecorator.java | 44 +- .../iris/object/IrisBiomePaletteLayer.java | 30 +- .../com/volmit/iris/object/IrisDimension.java | 210 ++----- .../iris/object/IrisNoiseGenerator.java | 6 +- .../com/volmit/iris/object/NoiseStyle.java | 103 ++++ 13 files changed, 679 insertions(+), 562 deletions(-) create mode 100644 src/main/java/com/volmit/iris/noise/CNGFactory.java create mode 100644 src/main/java/com/volmit/iris/noise/OctaveNoise.java delete mode 100644 src/main/java/com/volmit/iris/object/Dispersion.java create mode 100644 src/main/java/com/volmit/iris/object/NoiseStyle.java diff --git a/src/main/java/com/volmit/iris/IrisDataManager.java b/src/main/java/com/volmit/iris/IrisDataManager.java index a0de2ef53..926cb547e 100644 --- a/src/main/java/com/volmit/iris/IrisDataManager.java +++ b/src/main/java/com/volmit/iris/IrisDataManager.java @@ -112,14 +112,12 @@ public class IrisDataManager IrisNoiseGenerator n = new IrisNoiseGenerator(); n.setSeed(1000); IrisNoiseGenerator nf = new IrisNoiseGenerator(); - nf.setIrisBased(false); nf.setOctaves(3); nf.setOpacity(16); nf.setZoom(24); nf.setSeed(44); n.getFracture().add(nf); IrisNoiseGenerator nf2 = new IrisNoiseGenerator(); - nf2.setIrisBased(false); nf2.setOctaves(8); nf2.setOpacity(24); nf2.setZoom(64); diff --git a/src/main/java/com/volmit/iris/ProjectManager.java b/src/main/java/com/volmit/iris/ProjectManager.java index 7764df751..ae64182e7 100644 --- a/src/main/java/com/volmit/iris/ProjectManager.java +++ b/src/main/java/com/volmit/iris/ProjectManager.java @@ -3,6 +3,7 @@ package com.volmit.iris; import java.awt.Desktop; import java.io.File; import java.io.IOException; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.UUID; @@ -22,7 +23,6 @@ import com.google.gson.Gson; import com.volmit.iris.gen.IrisChunkGenerator; import com.volmit.iris.gen.post.Post; import com.volmit.iris.object.DecorationPart; -import com.volmit.iris.object.Dispersion; import com.volmit.iris.object.Envelope; import com.volmit.iris.object.InterpolationMethod; import com.volmit.iris.object.IrisBiome; @@ -35,6 +35,7 @@ import com.volmit.iris.object.IrisObjectPlacement; import com.volmit.iris.object.IrisRegion; import com.volmit.iris.object.IrisStructure; import com.volmit.iris.object.IrisStructureTile; +import com.volmit.iris.object.NoiseStyle; import com.volmit.iris.object.StructureTileCondition; import com.volmit.iris.util.ArrayType; import com.volmit.iris.util.ChronoLatch; @@ -59,41 +60,31 @@ import com.volmit.iris.util.Required; import lombok.Data; @Data -public class ProjectManager -{ +public class ProjectManager { private IrisChunkGenerator currentProject; - public ProjectManager() - { + public ProjectManager() { } - public boolean isProjectOpen() - { + public boolean isProjectOpen() { return currentProject != null; } - public void open(MortarSender sender, String dimm) - { - open(sender, dimm, () -> - { + public void open(MortarSender sender, String dimm) { + open(sender, dimm, () -> { }); } - public void open(MortarSender sender, String dimm, Runnable onDone) - { + public void open(MortarSender sender, String dimm, Runnable onDone) { Iris.globaldata.dump(); IrisDimension d = Iris.globaldata.getDimensionLoader().load(dimm); - J.attemptAsync(() -> - { - try - { + J.attemptAsync(() -> { + try { File f = d.getLoadFile().getParentFile().getParentFile(); - for(File i : f.listFiles()) - { - if(i.getName().endsWith(".code-workspace")) - { + for (File i : f.listFiles()) { + if (i.getName().endsWith(".code-workspace")) { sender.sendMessage("Updating Workspace"); updateWorkspace(i); Desktop.getDesktop().open(i); @@ -102,19 +93,16 @@ public class ProjectManager } } - catch(Throwable e) - { + catch (Throwable e) { e.printStackTrace(); } }); - if(d == null) - { + if (d == null) { sender.sendMessage("Can't find dimension: " + dimm); return; } - if(isProjectOpen()) - { + if (isProjectOpen()) { sender.sendMessage("Please Wait. Closing Current Project..."); close(); } @@ -128,52 +116,45 @@ public class ProjectManager O done = new O(); done.set(false); - J.a(() -> - { + J.a(() -> { double last = 0; int req = 740; - while(!done.get()) - { + while (!done.get()) { boolean derp = false; double v = (double) gx.getGenerated() / (double) req; - if(last > v || v > 1) - { + if (last > v || v > 1) { derp = true; v = last; } - else - { + else { last = v; } sender.sendMessage("Generating " + Form.pc(v) + (derp ? " (Waiting on Server...)" : "")); J.sleep(3000); - if(gx.isFailing()) - { + if (gx.isFailing()) { sender.sendMessage("Generation Failed!"); return; } } }); - World world = Bukkit.createWorld(new WorldCreator("iris/" + UUID.randomUUID()).seed(1337).generator(gx).generateStructures(false).type(WorldType.NORMAL).environment(d.getEnvironment())); + World world = Bukkit.createWorld(new WorldCreator("iris/" + UUID.randomUUID()).seed(1337).generator(gx) + .generateStructures(false).type(WorldType.NORMAL).environment(d.getEnvironment())); done.set(true); sender.sendMessage("Generating 100%"); - if(sender.isPlayer()) - { + if (sender.isPlayer()) { sender.player().teleport(new Location(world, 150, 150, 275)); } - Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> - { + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> { sender.sendMessage("Hotloading Active! Change any files and watch them appear as you load new chunks!"); - if(sender.isPlayer()) - { + if (sender.isPlayer()) { sender.player().setGameMode(GameMode.SPECTATOR); } @@ -181,10 +162,8 @@ public class ProjectManager }, 0); } - public void close() - { - if(isProjectOpen()) - { + public void close() { + if (isProjectOpen()) { currentProject.close(); File folder = currentProject.getWorld().getWorldFolder(); Bukkit.unloadWorld(currentProject.getWorld(), false); @@ -194,8 +173,7 @@ public class ProjectManager } } - public File compilePackage(MortarSender sender, String dim, boolean obfuscate) - { + public File compilePackage(MortarSender sender, String dim, boolean obfuscate) { Iris.globaldata.dump(); String dimm = dim; IrisDimension dimension = Iris.globaldata.getDimensionLoader().load(dimm); @@ -217,17 +195,13 @@ public class ProjectManager StringBuilder c = new StringBuilder(); sender.sendMessage("Serializing Objects"); - for(IrisStructure i : structures) - { - for(IrisStructureTile j : i.getTiles()) - { + for (IrisStructure i : structures) { + for (IrisStructureTile j : i.getTiles()) { b.append(j.hashCode()); KList newNames = new KList<>(); - for(String k : j.getObjects()) - { - if(renameObjects.containsKey(k)) - { + for (String k : j.getObjects()) { + if (renameObjects.containsKey(k)) { newNames.add(renameObjects.get(k)); continue; } @@ -242,17 +216,13 @@ public class ProjectManager } } - for(IrisBiome i : biomes) - { - for(IrisObjectPlacement j : i.getObjects()) - { + for (IrisBiome i : biomes) { + for (IrisObjectPlacement j : i.getObjects()) { b.append(j.hashCode()); KList newNames = new KList<>(); - for(String k : j.getPlace()) - { - if(renameObjects.containsKey(k)) - { + for (String k : j.getPlace()) { + if (renameObjects.containsKey(k)) { newNames.add(renameObjects.get(k)); continue; } @@ -267,17 +237,13 @@ public class ProjectManager } } - for(IrisBiomeMutation i : dimension.getMutations()) - { - for(IrisObjectPlacement j : i.getObjects()) - { + for (IrisBiomeMutation i : dimension.getMutations()) { + for (IrisObjectPlacement j : i.getObjects()) { b.append(j.hashCode()); KList newNames = new KList<>(); - for(String k : j.getPlace()) - { - if(renameObjects.containsKey(k)) - { + for (String k : j.getPlace()) { + if (renameObjects.containsKey(k)) { newNames.add(renameObjects.get(k)); continue; } @@ -297,71 +263,59 @@ public class ProjectManager ChronoLatch cl = new ChronoLatch(1000); O ggg = new O(); ggg.set(0); - biomes.forEach((i) -> i.getObjects().forEach((j) -> j.getPlace().forEach((k) -> - { - try - { + biomes.forEach((i) -> i.getObjects().forEach((j) -> j.getPlace().forEach((k) -> { + try { File f = Iris.globaldata.getObjectLoader().findFile(lookupObjects.get(k).get(0)); IO.copyFile(f, new File(folder, "objects/" + k + ".iob")); gb.append(IO.hash(f)); ggg.set(ggg.get() + 1); - if(cl.flip()) - { + if (cl.flip()) { int g = ggg.get(); ggg.set(0); sender.sendMessage("Wrote another " + g + " Objects"); } } - catch(Throwable e) - { + catch (Throwable e) { } }))); - structures.forEach((i) -> i.getTiles().forEach((j) -> j.getObjects().forEach((k) -> - { - try - { + structures.forEach((i) -> i.getTiles().forEach((j) -> j.getObjects().forEach((k) -> { + try { File f = Iris.globaldata.getObjectLoader().findFile(lookupObjects.get(k).get(0)); IO.copyFile(f, new File(folder, "objects/" + k + ".iob")); gb.append(IO.hash(f)); ggg.set(ggg.get() + 1); - if(cl.flip()) - { + if (cl.flip()) { int g = ggg.get(); ggg.set(0); sender.sendMessage("Wrote another " + g + " Objects"); } } - catch(Throwable e) - { + catch (Throwable e) { } }))); - dimension.getMutations().forEach((i) -> i.getObjects().forEach((j) -> j.getPlace().forEach((k) -> - { - try - { + dimension.getMutations().forEach((i) -> i.getObjects().forEach((j) -> j.getPlace().forEach((k) -> { + try { File f = Iris.globaldata.getObjectLoader().findFile(lookupObjects.get(k).get(0)); IO.copyFile(f, new File(folder, "objects/" + k + ".iob")); gb.append(IO.hash(f)); ggg.set(ggg.get() + 1); - if(cl.flip()) - { + if (cl.flip()) { int g = ggg.get(); ggg.set(0); sender.sendMessage("Wrote another " + g + " Objects"); } } - catch(Throwable e) - { + catch (Throwable e) { } }))); @@ -372,14 +326,12 @@ public class ProjectManager Iris.info("Writing Dimensional Scaffold"); - try - { + try { a = new JSONObject(new Gson().toJson(dimension)).toString(0); IO.writeAll(new File(folder, "dimensions/" + dimension.getLoadKey() + ".json"), a); b.append(IO.hash(a)); - for(IrisGenerator i : generators) - { + for (IrisGenerator i : generators) { a = new JSONObject(new Gson().toJson(i)).toString(0); IO.writeAll(new File(folder, "generators/" + i.getLoadKey() + ".json"), a); b.append(IO.hash(a)); @@ -388,22 +340,19 @@ public class ProjectManager c.append(IO.hash(b.toString())); b = new StringBuilder(); - for(IrisRegion i : regions) - { + for (IrisRegion i : regions) { a = new JSONObject(new Gson().toJson(i)).toString(0); IO.writeAll(new File(folder, "regions/" + i.getLoadKey() + ".json"), a); b.append(IO.hash(a)); } - for(IrisStructure i : structures) - { + for (IrisStructure i : structures) { a = new JSONObject(new Gson().toJson(i)).toString(0); IO.writeAll(new File(folder, "structures/" + i.getLoadKey() + ".json"), a); b.append(IO.hash(a)); } - for(IrisBiome i : biomes) - { + for (IrisBiome i : biomes) { a = new JSONObject(new Gson().toJson(i)).toString(0); IO.writeAll(new File(folder, "biomes/" + i.getLoadKey() + ".json"), a); b.append(IO.hash(a)); @@ -426,22 +375,20 @@ public class ProjectManager return p; } - catch(Throwable e) - { + catch (Throwable e) { e.printStackTrace(); } sender.sendMessage("Failed!"); return null; } - public void create(MortarSender sender, String s) - { + public void create(MortarSender sender, String s) { IrisDimension dimension = new IrisDimension(); dimension.setLoadKey(s); dimension.setName(Form.capitalizeWords(s.replaceAll("\\Q-\\E", " "))); - if(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "dimensions", dimension.getLoadKey() + ".json").exists()) - { + if (Iris.instance.getDataFile("packs", dimension.getLoadKey(), "dimensions", dimension.getLoadKey() + ".json") + .exists()) { sender.sendMessage("Project Already Exists! Open it instead!"); return; } @@ -506,29 +453,46 @@ public class ProjectManager exampleRegion.getSeaBiomes().add(exampleOcean1.getLoadKey()); dimension.getRegions().add(exampleRegion.getLoadKey()); - try - { + try { JSONObject ws = newWorkspaceConfig(); - IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "dimensions", dimension.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(dimension)).toString(4)); - IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "regions", exampleRegion.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(exampleRegion)).toString(4)); - IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "biomes", exampleLand1.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(exampleLand1)).toString(4)); - IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "biomes", exampleLand2.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(exampleLand2)).toString(4)); - IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "biomes", exampleShore1.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(exampleShore1)).toString(4)); - IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "biomes", exampleOcean1.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(exampleOcean1)).toString(4)); - IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "generators", gen.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(gen)).toString(4)); - IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), dimension.getLoadKey() + ".code-workspace"), ws.toString(4)); + IO.writeAll( + Iris.instance.getDataFile("packs", dimension.getLoadKey(), "dimensions", + dimension.getLoadKey() + ".json"), + new JSONObject(new Gson().toJson(dimension)).toString(4)); + IO.writeAll( + Iris.instance.getDataFile("packs", dimension.getLoadKey(), "regions", + exampleRegion.getLoadKey() + ".json"), + new JSONObject(new Gson().toJson(exampleRegion)).toString(4)); + IO.writeAll( + Iris.instance.getDataFile("packs", dimension.getLoadKey(), "biomes", + exampleLand1.getLoadKey() + ".json"), + new JSONObject(new Gson().toJson(exampleLand1)).toString(4)); + IO.writeAll( + Iris.instance.getDataFile("packs", dimension.getLoadKey(), "biomes", + exampleLand2.getLoadKey() + ".json"), + new JSONObject(new Gson().toJson(exampleLand2)).toString(4)); + IO.writeAll( + Iris.instance.getDataFile("packs", dimension.getLoadKey(), "biomes", + exampleShore1.getLoadKey() + ".json"), + new JSONObject(new Gson().toJson(exampleShore1)).toString(4)); + IO.writeAll( + Iris.instance.getDataFile("packs", dimension.getLoadKey(), "biomes", + exampleOcean1.getLoadKey() + ".json"), + new JSONObject(new Gson().toJson(exampleOcean1)).toString(4)); + IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "generators", + gen.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(gen)).toString(4)); + IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), + dimension.getLoadKey() + ".code-workspace"), ws.toString(4)); Iris.proj.open(sender, dimension.getName()); } - catch(JSONException | IOException e) - { + catch (JSONException | IOException e) { sender.sendMessage("Failed! Check the console."); e.printStackTrace(); } } - private JSONObject newWorkspaceConfig() - { + private JSONObject newWorkspaceConfig() { JSONObject ws = new JSONObject(); JSONArray folders = new JSONArray(); JSONObject folder = new JSONObject(); @@ -550,10 +514,8 @@ public class ProjectManager return ws; } - public void updateWorkspace(File ws) - { - try - { + public void updateWorkspace(File ws) { + try { J.attemptAsync(() -> writeDocs(ws.getParentFile())); JSONObject j = new JSONObject(IO.readAll(ws)); JSONObject s = j.getJSONObject("settings"); @@ -563,24 +525,21 @@ public class ProjectManager Iris.info("Updating Project " + ws.getAbsolutePath()); } - catch(Throwable e) - { - Iris.warn("Project invalid: " + ws.getAbsolutePath() + " Re-creating. You may loose some vs-code workspace settings! But not your actual project!"); + catch (Throwable e) { + Iris.warn("Project invalid: " + ws.getAbsolutePath() + + " Re-creating. You may loose some vs-code workspace settings! But not your actual project!"); - try - { + try { IO.writeAll(ws, newWorkspaceConfig()); } - catch(IOException e1) - { + catch (IOException e1) { e1.printStackTrace(); } } } - private JSONArray buildSchemas() - { + private JSONArray buildSchemas() { JSONArray schemas = new JSONArray(); schemas.put(getSchemaEntry(IrisDimension.class, "/dimensions/*.json")); schemas.put(getSchemaEntry(IrisBiome.class, "/biomes/*.json")); @@ -590,8 +549,7 @@ public class ProjectManager return schemas; } - public JSONObject getSchemaEntry(Class i, String... fileMatch) - { + public JSONObject getSchemaEntry(Class i, String... fileMatch) { JSONObject o = new JSONObject(); o.put("fileMatch", new JSONArray(fileMatch)); o.put("schema", getSchemaFor(i)); @@ -599,13 +557,11 @@ public class ProjectManager return o; } - public JSONObject getSchemaFor(Class i) - { + public JSONObject getSchemaFor(Class i) { KMap def = new KMap<>(); JSONObject s = getSchemaFor(i, 7, def); JSONObject defx = new JSONObject(); - for(String v : def.k()) - { + for (String v : def.k()) { defx.put(v, def.get(v)); } @@ -614,18 +570,15 @@ public class ProjectManager return s; } - public JSONObject getSchemaFor(Class i, int step, KMap def) - { - if(step <= 0) - { + public JSONObject getSchemaFor(Class i, int step, KMap def) { + if (step <= 0) { JSONObject m = new JSONObject(); m.put("properties", new JSONObject()); return m; } JSONObject schema = new JSONObject(); - if(i.isAnnotationPresent(Desc.class)) - { + if (i.isAnnotationPresent(Desc.class)) { schema.put("$schema", "http://json-schema.org/draft-07/schema#"); schema.put("$id", "http://volmit.com/iris-schema/" + i.getSimpleName().toLowerCase() + ".json"); schema.put("title", i.getSimpleName().replaceAll("\\QIris\\E", "")); @@ -637,160 +590,130 @@ public class ProjectManager JSONObject properties = new JSONObject(); JSONArray req = new JSONArray(); - for(java.lang.reflect.Field k : i.getDeclaredFields()) - { + for (java.lang.reflect.Field k : i.getDeclaredFields()) { JSONObject prop = new JSONObject(); - if(k.isAnnotationPresent(Desc.class)) - { + if (k.isAnnotationPresent(Desc.class)) { String tp = "object"; - if(k.getType().equals(int.class) || k.getType().equals(long.class)) - { + if (k.getType().equals(int.class) || k.getType().equals(long.class)) { tp = "integer"; - if(k.isAnnotationPresent(MinNumber.class)) - { + if (k.isAnnotationPresent(MinNumber.class)) { prop.put("minimum", (int) k.getDeclaredAnnotation(MinNumber.class).value()); } - if(k.isAnnotationPresent(MaxNumber.class)) - { + if (k.isAnnotationPresent(MaxNumber.class)) { prop.put("maximum", (int) k.getDeclaredAnnotation(MaxNumber.class).value()); } } - if(k.getType().equals(double.class) || k.getType().equals(float.class)) - { + if (k.getType().equals(double.class) || k.getType().equals(float.class)) { tp = "number"; - if(k.isAnnotationPresent(MinNumber.class)) - { + if (k.isAnnotationPresent(MinNumber.class)) { prop.put("minimum", k.getDeclaredAnnotation(MinNumber.class).value()); } - if(k.isAnnotationPresent(MaxNumber.class)) - { + if (k.isAnnotationPresent(MaxNumber.class)) { prop.put("maximum", k.getDeclaredAnnotation(MaxNumber.class).value()); } } - if(k.getType().equals(boolean.class)) - { + if (k.getType().equals(boolean.class)) { tp = "boolean"; } - if(k.getType().equals(String.class)) - { + if (k.getType().equals(String.class)) { tp = "string"; - if(k.isAnnotationPresent(MinNumber.class)) - { + if (k.isAnnotationPresent(MinNumber.class)) { prop.put("minLength", (int) k.getDeclaredAnnotation(MinNumber.class).value()); } - if(k.isAnnotationPresent(MaxNumber.class)) - { + if (k.isAnnotationPresent(MaxNumber.class)) { prop.put("maxLength", (int) k.getDeclaredAnnotation(MaxNumber.class).value()); } } - if(k.getType().equals(String.class)) - { + if (k.getType().equals(String.class)) { tp = "string"; } - if(k.getType().isEnum()) - { + if (k.getType().isEnum()) { tp = "string"; JSONArray a = new JSONArray(); - for(Object gg : k.getType().getEnumConstants()) - { + for (Object gg : k.getType().getEnumConstants()) { a.put(((Enum) gg).name()); } prop.put("enum", a); } - if(k.getType().equals(String.class) && k.getName().equals("potionEffect")) - { + if (k.getType().equals(String.class) && k.getName().equals("potionEffect")) { tp = "string"; JSONArray a = new JSONArray(); - for(PotionEffectType gg : PotionEffectType.values()) - { + for (PotionEffectType gg : PotionEffectType.values()) { a.put(gg.getName().toUpperCase().replaceAll("\\Q \\E", "_")); } prop.put("enum", a); } - if(k.getType().equals(KList.class)) - { + if (k.getType().equals(KList.class)) { tp = "array"; } - if(k.isAnnotationPresent(Required.class)) - { + if (k.isAnnotationPresent(Required.class)) { req.put(k.getName()); } - if(tp.equals("object")) - { - if(k.getType().isAnnotationPresent(Desc.class)) - { - prop.put("properties", getSchemaFor(k.getType(), step - 1, def).getJSONObject("properties")); + if (tp.equals("object")) { + if (k.getType().isAnnotationPresent(Desc.class)) { + prop.put("properties", + getSchemaFor(k.getType(), step - 1, def).getJSONObject("properties")); } } - if(tp.equals("array")) - { + if (tp.equals("array")) { ArrayType t = k.getDeclaredAnnotation(ArrayType.class); - if(t.min() > 0) - { + if (t.min() > 0) { prop.put("minItems", t.min()); } - if(t != null) - { + if (t != null) { String tx = "object"; - if(t.type().equals(int.class) || k.getType().equals(long.class)) - { + if (t.type().equals(int.class) || k.getType().equals(long.class)) { tx = "integer"; } - if(t.type().equals(double.class) || k.getType().equals(float.class)) - { + if (t.type().equals(double.class) || k.getType().equals(float.class)) { tx = "number"; } - if(t.type().equals(boolean.class)) - { + if (t.type().equals(boolean.class)) { tx = "boolean"; } - if(t.type().equals(String.class)) - { + if (t.type().equals(String.class)) { tx = "string"; } - if(t.type().isEnum()) - { + if (t.type().isEnum()) { tx = "string"; JSONArray a = new JSONArray(); - for(Object gg : t.type().getEnumConstants()) - { + for (Object gg : t.type().getEnumConstants()) { a.put(((Enum) gg).name()); } String name = "enum" + t.type().getSimpleName().toLowerCase(); - if(!def.containsKey(name)) - { + if (!def.containsKey(name)) { JSONObject deff = new JSONObject(); deff.put("type", tx); deff.put("enum", a); @@ -802,33 +725,27 @@ public class ProjectManager prop.put("items", items); } - if(t.type().isEnum()) - { + if (t.type().isEnum()) { tx = "string"; } - if(t.type().equals(KList.class)) - { + if (t.type().equals(KList.class)) { tx = "array"; } JSONObject items = new JSONObject(); - if(tx.equals("object")) - { - if(t.type().isAnnotationPresent(Desc.class)) - { + if (tx.equals("object")) { + if (t.type().isAnnotationPresent(Desc.class)) { String name = t.type().getSimpleName().toLowerCase(); - if(!def.containsKey(name)) - { + if (!def.containsKey(name)) { JSONObject deff = new JSONObject(); JSONObject scv = getSchemaFor(t.type(), step - 1, def); deff.put("type", tx); deff.put("description", t.type().getDeclaredAnnotation(Desc.class).value()); deff.put("properties", scv.getJSONObject("properties")); - if(scv.has("required")) - { + if (scv.has("required")) { deff.put("required", scv.getJSONArray("required")); } def.put(name, deff); @@ -837,23 +754,21 @@ public class ProjectManager items.put("$ref", "#/definitions/" + name); } - else - { + else { items.put("type", tx); } } - else - { + else { items.put("type", tx); } prop.put("items", items); } - if(tp.getClass().isAnnotationPresent(Desc.class)) - { - prop.put("properties", getSchemaFor(tp.getClass(), step - 1, def).getJSONObject("properties")); + if (tp.getClass().isAnnotationPresent(Desc.class)) { + prop.put("properties", + getSchemaFor(tp.getClass(), step - 1, def).getJSONObject("properties")); } } @@ -870,85 +785,209 @@ public class ProjectManager return schema; } - public void writeDocs(File folder) throws IOException, JSONException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException - { + public KList analyzeFolder(File folder, String fn, Object t) { + KList a = new KList(); + + if (!new File(folder, fn).exists()) { + return a; + } + + if (!new File(folder, fn).isDirectory()) { + a.add("ERROR: " + new File(folder, fn).getAbsolutePath() + " must be a folder, not a file!"); + return a; + } + + for (File i : new File(folder, fn).listFiles()) { + if (i.isFile() && i.getName().endsWith(".json")) { + if (!i.getName().toLowerCase().equals(i.getName())) { + a.add("WARN: " + i.getAbsolutePath() + " has upper case letters in the file name."); + } + + if (i.getName().contains(" ")) { + a.add("WARN: " + i.getAbsolutePath() + " has spaces in the file name."); + } + + Object o; + JSONObject j; + + try { + j = new JSONObject(IO.readAll(i)); + o = new Gson().fromJson(j.toString(), t.getClass()); + a.addAll(analyze(o, i)); + + verify(j, o, a, i); + } + + catch (Throwable e) { + a.add("ERROR: Failed to read " + i.getAbsolutePath() + ": " + e.getMessage()); + } + } + + else { + a.add("WARN: " + i.getAbsolutePath() + " should not be in this directory."); + } + } + + return a; + } + + private void verify(JSONObject j, Object o, KList a, File m) { + for (String i : j.keySet()) { + try { + JSONObject jj = j.getJSONObject(i); + + try { + Field f = o.getClass().getField(i); + + if (f.isEnumConstant() || f.getType().isEnum() || f.getType().isPrimitive()) { + a.add("ERROR: Unexptected type: " + i + " into " + f.getType() + + " expected. Got a jsonObject in " + o.getClass() + " in " + m.getAbsolutePath()); + continue; + } + + f.setAccessible(true); + Object oo = f.get(o); + + if (oo == null) { + a.add("WARN: Incorrect injection on " + o.getClass() + "." + i); + } + + verify(jj, oo, a, m); + } + + catch (Throwable e) { + a.add("WARN: Unexptected Field: " + i + " in " + o.getClass()); + } + } + + catch (Throwable enn) { + + } + } + } + + public KList analyze(File project) { + KList a = new KList(); + + a.addAll(analyzeFolder(project, "dimensions", new IrisDimension())); + a.addAll(analyzeFolder(project, "biomes", new IrisBiome())); + a.addAll(analyzeFolder(project, "regions", new IrisRegion())); + a.addAll(analyzeFolder(project, "generators", new IrisGenerator())); + a.addAll(analyzeFolder(project, "structures", new IrisStructure())); + + return a; + } + + public KList analyze(Object o, File file) { + KList a = new KList(); + + String t; + try { + t = IO.readAll(file); + } catch (IOException e1) { + a.add("ERROR: Unable to read " + file.getAbsolutePath() + ": " + e1.getMessage()); + return a; + } + + JSONObject j; + + try { + j = new JSONObject(t); + } + + catch (Throwable e) { + a.add("ERROR: Unable to parse json " + file.getAbsolutePath() + ": " + e.getMessage()); + return a; + } + + for (String i : j.keySet()) { + try { + Field f = o.getClass().getField(i); + + if (f == null) { + throw new NullPointerException(); + } + } + + catch (Throwable e) { + a.add("WARN: Unreconized Field (key): " + i + " in " + file.getAbsolutePath() + + ". Delete this key/value pair"); + } + } + + return a; + } + + public void writeDocs(File folder) + throws IOException, JSONException, InstantiationException, IllegalAccessException, IllegalArgumentException, + InvocationTargetException, NoSuchMethodException, SecurityException { File of = new File(folder, "_docs"); KList m = new KList<>(); - for(Biome i : Biome.values()) - { + for (Biome i : Biome.values()) { m.add(i.name()); } IO.writeAll(new File(of, "biomes.txt"), m.toString("\n")); m = new KList<>(); - for(Particle i : Particle.values()) - { + for (Particle i : Particle.values()) { m.add(i.name()); } IO.writeAll(new File(of, "particles.txt"), m.toString("\n")); m = new KList<>(); - for(Dispersion i : Dispersion.values()) - { + for (NoiseStyle i : NoiseStyle.values()) { m.add(i.name()); } - IO.writeAll(new File(of, "dispersion.txt"), m.toString("\n")); + IO.writeAll(new File(of, "noise-style.txt"), m.toString("\n")); m = new KList<>(); - for(DecorationPart i : DecorationPart.values()) - { + for (DecorationPart i : DecorationPart.values()) { m.add(i.name()); } IO.writeAll(new File(of, "decoration-part.txt"), m.toString("\n")); m = new KList<>(); - for(Envelope i : Envelope.values()) - { + for (Envelope i : Envelope.values()) { m.add(i.name()); } IO.writeAll(new File(of, "envelope.txt"), m.toString("\n")); m = new KList<>(); - for(Environment i : Environment.values()) - { + for (Environment i : Environment.values()) { m.add(i.name()); } IO.writeAll(new File(of, "environment.txt"), m.toString("\n")); m = new KList<>(); - for(StructureTileCondition i : StructureTileCondition.values()) - { + for (StructureTileCondition i : StructureTileCondition.values()) { m.add(i.name()); } IO.writeAll(new File(of, "structure-tile-condition.txt"), m.toString("\n")); m = new KList<>(); - for(InterpolationMethod i : InterpolationMethod.values()) - { + for (InterpolationMethod i : InterpolationMethod.values()) { m.add(i.name()); } IO.writeAll(new File(of, "interpolation-method.txt"), m.toString("\n")); m = new KList<>(); - for(Class i : Iris.postProcessors) - { + for (Class i : Iris.postProcessors) { m.add(i.getDeclaredAnnotation(Post.class).value()); } IO.writeAll(new File(of, "post-processors.txt"), m.toString("\n")); m = new KList<>(); - for(PotionEffectType i : PotionEffectType.values()) - { + for (PotionEffectType i : PotionEffectType.values()) { m.add(i.getName().toUpperCase().replaceAll("\\Q \\E", "_")); } } diff --git a/src/main/java/com/volmit/iris/noise/CNG.java b/src/main/java/com/volmit/iris/noise/CNG.java index c6e264e63..a3939c6f8 100644 --- a/src/main/java/com/volmit/iris/noise/CNG.java +++ b/src/main/java/com/volmit/iris/noise/CNG.java @@ -1,31 +1,30 @@ package com.volmit.iris.noise; +import java.util.List; + import com.volmit.iris.util.IrisInterpolation; import com.volmit.iris.util.KList; import com.volmit.iris.util.NoiseInjector; import com.volmit.iris.util.RNG; -public class CNG -{ +public class CNG { public static long hits = 0; public static long creates = 0; - public static final NoiseInjector ADD = (s, v) -> new double[] {s + v, 1}; - public static final NoiseInjector SRC_SUBTRACT = (s, v) -> new double[] {s - v < 0 ? 0 : s - v, -1}; - public static final NoiseInjector DST_SUBTRACT = (s, v) -> new double[] {v - s < 0 ? 0 : s - v, -1}; - public static final NoiseInjector MULTIPLY = (s, v) -> new double[] {s * v, 0}; - public static final NoiseInjector MAX = (s, v) -> new double[] {Math.max(s, v), 0}; - public static final NoiseInjector MIN = (s, v) -> new double[] {Math.min(s, v), 0}; - public static final NoiseInjector SRC_MOD = (s, v) -> new double[] {s % v, 0}; - public static final NoiseInjector SRC_POW = (s, v) -> new double[] {Math.pow(s, v), 0}; - public static final NoiseInjector DST_MOD = (s, v) -> new double[] {v % s, 0}; - public static final NoiseInjector DST_POW = (s, v) -> new double[] {Math.pow(v, s), 0}; - private double freq; - private double amp; + public static final NoiseInjector ADD = (s, v) -> new double[] { s + v, 1 }; + public static final NoiseInjector SRC_SUBTRACT = (s, v) -> new double[] { s - v < 0 ? 0 : s - v, -1 }; + public static final NoiseInjector DST_SUBTRACT = (s, v) -> new double[] { v - s < 0 ? 0 : s - v, -1 }; + public static final NoiseInjector MULTIPLY = (s, v) -> new double[] { s * v, 0 }; + public static final NoiseInjector MAX = (s, v) -> new double[] { Math.max(s, v), 0 }; + public static final NoiseInjector MIN = (s, v) -> new double[] { Math.min(s, v), 0 }; + public static final NoiseInjector SRC_MOD = (s, v) -> new double[] { s % v, 0 }; + public static final NoiseInjector SRC_POW = (s, v) -> new double[] { Math.pow(s, v), 0 }; + public static final NoiseInjector DST_MOD = (s, v) -> new double[] { v % s, 0 }; + public static final NoiseInjector DST_POW = (s, v) -> new double[] { Math.pow(v, s), 0 }; private double scale; private double fscale; private KList children; private CNG fracture; - private SNG generator; + private NoiseGenerator generator; private final double opacity; private NoiseInjector injector; private RNG rng; @@ -35,51 +34,52 @@ public class CNG private double down; private double power; - public static CNG signature(RNG rng) - { - //@builder - return new CNG(rng.nextParallelRNG(17), 1D, 3) - .scale(0.012) - .fractureWith(new CNG(rng.nextParallelRNG(18), 1, 2) - .scale(0.018) - .child(new CNG(rng.nextParallelRNG(19), 1, 2) - .scale(0.1)) - .fractureWith(new CNG(rng.nextParallelRNG(20), 1, 2) - .scale(0.15), 24), 44).down(0.3).patch(2.5); - //@done + public static CNG signature(RNG rng) { + return signature(rng, NoiseType.SIMPLEX); } - public CNG(RNG random) - { + public static CNG signature(RNG rng, NoiseType t) { + // @builder + return new CNG(rng.nextParallelRNG(17), t, 1D, 3).scale(0.012) + .fractureWith(new CNG(rng.nextParallelRNG(18), 1, 2).scale(0.018) + .child(new CNG(rng.nextParallelRNG(19), 1, 2).scale(0.1)) + .fractureWith(new CNG(rng.nextParallelRNG(20), 1, 2).scale(0.15), 24), 44) + .down(0.3).patch(2.5); + // @done + } + + public CNG(RNG random) { this(random, 1); } - public CNG(RNG random, int octaves) - { + public CNG(RNG random, int octaves) { this(random, 1D, octaves); } - public CNG(RNG random, double opacity, int octaves) - { - creates += octaves; + public CNG(RNG random, double opacity, int octaves) { + this(random, NoiseType.SIMPLEX, opacity, octaves); + } + + public CNG(RNG random, NoiseType t, double opacity, int octaves) { + creates++; this.oct = octaves; this.rng = random; power = 1; - freq = 1; - amp = 1; scale = 1; patch = 1; fscale = 1; fracture = null; - generator = new SNG(random); + generator = t.create(random.nextParallelRNG(33).lmax()); this.opacity = opacity; this.injector = ADD; + + if (generator instanceof OctaveNoise) { + ((OctaveNoise) generator).setOctaves(octaves); + } } - public CNG child(CNG c) - { - if(children == null) - { + public CNG child(CNG c) { + if (children == null) { children = new KList<>(); } @@ -88,69 +88,71 @@ public class CNG } @Deprecated - public RNG nextRNG() - { + public RNG nextRNG() { return getRNG().nextRNG(); } - public RNG getRNG() - { + public RNG getRNG() { return rng; } - public CNG fractureWith(CNG c, double scale) - { + public CNG fractureWith(CNG c, double scale) { fracture = c; fscale = scale; return this; } - public CNG scale(double c) - { + public CNG scale(double c) { scale = c; return this; } - public CNG freq(double c) - { - freq = c; - return this; - } - - public CNG amp(double c) - { - amp = c; - return this; - } - - public CNG patch(double c) - { + public CNG patch(double c) { patch = c; return this; } - public CNG up(double c) - { + public CNG up(double c) { up = c; return this; } - public CNG down(double c) - { + public CNG down(double c) { down = c; return this; } - public CNG injectWith(NoiseInjector i) - { + public CNG injectWith(NoiseInjector i) { injector = i; return this; } - public int fit(int min, int max, double... dim) - { - if(min == max) - { + public T fit(T[] v, double... dim) { + if (v.length == 0) { + return null; + } + + if (v.length == 1) { + return v[0]; + } + + return v[fit(0, v.length - 1, dim)]; + } + + public T fit(List v, double... dim) { + if (v.size() == 0) { + return null; + } + + if (v.size() == 1) { + return v.get(0); + } + + return v.get(fit(0, v.size() - 1, dim)); + } + + public int fit(int min, int max, double... dim) { + if (min == max) { return min; } @@ -159,10 +161,8 @@ public class CNG return (int) Math.round(IrisInterpolation.lerp(min, max, noise)); } - public int fitDouble(double min, double max, double... dim) - { - if(min == max) - { + public int fitDouble(double min, double max, double... dim) { + if (min == max) { return (int) Math.round(min); } @@ -171,10 +171,8 @@ public class CNG return (int) Math.round(IrisInterpolation.lerp(min, max, noise)); } - public double fitDoubleD(double min, double max, double... dim) - { - if(min == max) - { + public double fitDoubleD(double min, double max, double... dim) { + if (min == max) { return min; } @@ -183,10 +181,8 @@ public class CNG return IrisInterpolation.lerp(min, max, noise); } - public int fitDoubleExponent(double min, double max, double exponent, double... dim) - { - if(min == max) - { + public int fitDoubleExponent(double min, double max, double exponent, double... dim) { + if (min == max) { return (int) Math.round(min); } @@ -195,23 +191,20 @@ public class CNG 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 x = dim.length > 0 ? dim[0] + f : 0D; double y = dim.length > 1 ? dim[1] - f : 0D; double z = dim.length > 2 ? dim[2] + f : 0D; - double n = ((generator.noise(x * scale, y * scale, z * scale, oct, freq, amp, true) / 2D) + 0.5D) * opacity; + double n = generator.noise(x * scale, y * scale, z * scale) * opacity; n = power != 1D ? Math.pow(n, power) : n; double m = 1; hits += oct; - if(children == null) - { + if (children == null) { return (n - down + up) * patch; } - for(CNG i : children) - { + for (CNG i : children) { double[] r = injector.combine(n, i.noise(dim)); n = r[0]; m += r[1]; @@ -220,9 +213,13 @@ public class CNG return ((n / m) - down + up) * patch; } - public CNG pow(double power) - { + public CNG pow(double power) { this.power = power; return this; } + + public CNG oct(int octaves) { + oct = octaves; + return this; + } } diff --git a/src/main/java/com/volmit/iris/noise/CNGFactory.java b/src/main/java/com/volmit/iris/noise/CNGFactory.java new file mode 100644 index 000000000..2b2a2b033 --- /dev/null +++ b/src/main/java/com/volmit/iris/noise/CNGFactory.java @@ -0,0 +1,9 @@ +package com.volmit.iris.noise; + +import com.volmit.iris.util.RNG; + +@FunctionalInterface +public interface CNGFactory +{ + CNG create(RNG seed); +} diff --git a/src/main/java/com/volmit/iris/noise/OctaveNoise.java b/src/main/java/com/volmit/iris/noise/OctaveNoise.java new file mode 100644 index 000000000..c0ca0b931 --- /dev/null +++ b/src/main/java/com/volmit/iris/noise/OctaveNoise.java @@ -0,0 +1,6 @@ +package com.volmit.iris.noise; + +public interface OctaveNoise +{ + public void setOctaves(int o); +} diff --git a/src/main/java/com/volmit/iris/noise/SimplexNoise.java b/src/main/java/com/volmit/iris/noise/SimplexNoise.java index 377f7c7d6..8286a3777 100644 --- a/src/main/java/com/volmit/iris/noise/SimplexNoise.java +++ b/src/main/java/com/volmit/iris/noise/SimplexNoise.java @@ -1,24 +1,79 @@ package com.volmit.iris.noise; -public class SimplexNoise implements NoiseGenerator { +public class SimplexNoise implements NoiseGenerator, OctaveNoise { private final OpenSimplex n; + private int octaves; public SimplexNoise(long seed) { this.n = new OpenSimplex(seed); + octaves = 1; } @Override public double noise(double x) { - return (n.noise2(x, 0) / 2D) + 0.5D; + if (octaves <= 1) { + return (n.noise2_XBeforeY(x, 0) / 2D) + 0.5D; + } + + double result = 0; + double amp = 1; + double freq = 1; + double max = 0; + + for (int i = 0; i < octaves; i++) { + result += ((n.noise2_XBeforeY(x * freq, 0) * amp) / 2D) + 0.5D; + max += amp; + freq *= 2; + amp *= 2; + } + + return result / max; } @Override public double noise(double x, double z) { - return (n.noise2(x, z) / 2D) + 0.5D; + if (octaves <= 1) { + return (n.noise2(x, z) / 2D) + 0.5D; + } + + double result = 0; + double amp = 1; + double freq = 1; + double max = 0; + + for (int i = 0; i < octaves; i++) { + result += ((n.noise2(x * freq, z * freq) * amp) / 2D) + 0.5D; + max += amp; + freq *= 2; + amp *= 2; + } + + return result / max; } @Override public double noise(double x, double y, double z) { - return (n.noise3_XZBeforeY(x, y, z) / 2D) + 0.5D; + if (octaves <= 1) { + return (n.noise3_XZBeforeY(x, y, z) / 2D) + 0.5D; + } + + double result = 0; + double amp = 1; + double freq = 1; + double max = 0; + + for (int i = 0; i < octaves; i++) { + result += ((n.noise3_XZBeforeY(x * freq, y * freq, z * freq) * amp) / 2D) + 0.5D; + max += amp; + freq *= 2; + amp *= 2; + } + + return result / max; + } + + @Override + public void setOctaves(int o) { + octaves = o; } } diff --git a/src/main/java/com/volmit/iris/object/Dispersion.java b/src/main/java/com/volmit/iris/object/Dispersion.java deleted file mode 100644 index 338930182..000000000 --- a/src/main/java/com/volmit/iris/object/Dispersion.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.volmit.iris.object; - -import com.volmit.iris.util.DontObfuscate; - -public enum Dispersion -{ - @DontObfuscate - SCATTER, - - @DontObfuscate - WISPY; -} diff --git a/src/main/java/com/volmit/iris/object/IrisBiome.java b/src/main/java/com/volmit/iris/object/IrisBiome.java index 2ab8d0820..2ca446564 100644 --- a/src/main/java/com/volmit/iris/object/IrisBiome.java +++ b/src/main/java/com/volmit/iris/object/IrisBiome.java @@ -41,7 +41,7 @@ public class IrisBiome extends IrisRegistrant implements IRare @DontObfuscate @Desc("This changes the dispersion of the biome colors if multiple derivatives are chosen.") - private Dispersion biomeDispersion = Dispersion.SCATTER; + private NoiseStyle biomeStyle = NoiseStyle.SIMPLEX; @MinNumber(0.0001) @DontObfuscate @@ -156,7 +156,7 @@ public class IrisBiome extends IrisRegistrant implements IRare { return biomeGenerator.aquire(() -> { - return CNG.signature(random.nextParallelRNG(213949 + 228888 + getRarity() + getName().length())).scale(biomeDispersion.equals(Dispersion.SCATTER) ? 1000D : 0.1D); + return biomeStyle.create(random.nextParallelRNG(213949 + 228888 + getRarity() + getName().length())); }); } @@ -187,7 +187,7 @@ public class IrisBiome extends IrisRegistrant implements IRare for(int i = 0; i < layers.size(); i++) { CNG hgen = getLayerHeightGenerators(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()); + int d = hgen.fit(layers.get(i).getMinHeight(), layers.get(i).getMaxHeight(), wx / layers.get(i).getZoom(), wz / layers.get(i).getZoom()); if(d < 0) { @@ -203,7 +203,7 @@ public class IrisBiome extends IrisRegistrant implements IRare try { - data.add(getLayers().get(i).get(random.nextParallelRNG(i + j), (wx + j) / layers.get(i).getTerrainZoom(), j, (wz - j) / layers.get(i).getTerrainZoom())); + data.add(getLayers().get(i).get(random.nextParallelRNG(i + j), (wx + j) / layers.get(i).getZoom(), j, (wz - j) / layers.get(i).getZoom())); } catch(Throwable e) @@ -234,7 +234,7 @@ public class IrisBiome extends IrisRegistrant implements IRare for(int i = 0; i < layers.size(); i++) { CNG hgen = getLayerHeightGenerators(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()); + int d = hgen.fit(layers.get(i).getMinHeight(), layers.get(i).getMaxHeight(), wx / layers.get(i).getZoom(), wz / layers.get(i).getZoom()); if(d < 0) { @@ -245,7 +245,7 @@ public class IrisBiome extends IrisRegistrant implements IRare { try { - data.add(getLayers().get(i).get(random.nextParallelRNG(i + j), (wx + j) / layers.get(i).getTerrainZoom(), j, (wz - j) / layers.get(i).getTerrainZoom())); + data.add(getLayers().get(i).get(random.nextParallelRNG(i + j), (wx + j) / layers.get(i).getZoom(), j, (wz - j) / layers.get(i).getZoom())); } catch(Throwable e) @@ -298,7 +298,7 @@ public class IrisBiome extends IrisRegistrant implements IRare for(int i = 0; i < seaLayers.size(); i++) { CNG hgen = getLayerSeaHeightGenerators(random).get(i); - int d = hgen.fit(seaLayers.get(i).getMinHeight(), seaLayers.get(i).getMaxHeight(), wx / seaLayers.get(i).getTerrainZoom(), wz / seaLayers.get(i).getTerrainZoom()); + int d = hgen.fit(seaLayers.get(i).getMinHeight(), seaLayers.get(i).getMaxHeight(), wx / seaLayers.get(i).getZoom(), wz / seaLayers.get(i).getZoom()); if(d < 0) { @@ -314,7 +314,7 @@ public class IrisBiome extends IrisRegistrant implements IRare try { - data.add(getSeaLayers().get(i).get(random.nextParallelRNG(i + j), (wx + j) / seaLayers.get(i).getTerrainZoom(), j, (wz - j) / seaLayers.get(i).getTerrainZoom())); + data.add(getSeaLayers().get(i).get(random.nextParallelRNG(i + j), (wx + j) / seaLayers.get(i).getZoom(), j, (wz - j) / seaLayers.get(i).getZoom())); } catch(Throwable e) diff --git a/src/main/java/com/volmit/iris/object/IrisBiomeDecorator.java b/src/main/java/com/volmit/iris/object/IrisBiomeDecorator.java index 6e1f842f7..a056dcfb9 100644 --- a/src/main/java/com/volmit/iris/object/IrisBiomeDecorator.java +++ b/src/main/java/com/volmit/iris/object/IrisBiomeDecorator.java @@ -23,15 +23,15 @@ public class IrisBiomeDecorator { @DontObfuscate @Desc("The varience dispersion is used when multiple blocks are put in the palette. Scatter scrambles them, Wispy shows streak-looking varience") - private Dispersion variance = Dispersion.SCATTER; + private NoiseStyle variance = NoiseStyle.STATIC; @DontObfuscate @Desc("Dispersion is used to pick places to spawn. Scatter randomly places them (vanilla) or Wispy for a streak like patch system.") - private Dispersion dispersion = Dispersion.SCATTER; + private NoiseStyle dispersion = NoiseStyle.STATIC; @DontObfuscate @Desc("If this decorator has a height more than 1 this changes how it picks the height between your maxes. Scatter = random, Wispy = wavy heights") - private Dispersion verticalVariance = Dispersion.SCATTER; + private NoiseStyle heightVariance = NoiseStyle.STATIC; @DontObfuscate @Desc("Tells iris where this decoration is a part of. I.e. SHORE_LINE or SEA_SURFACE") @@ -51,8 +51,13 @@ public class IrisBiomeDecorator @MinNumber(0.0001) @DontObfuscate - @Desc("The zoom is for zooming in or out wispy dispersions. Makes patches bigger the higher this zoom value is/") + @Desc("The zoom is for zooming in or out wispy dispersions. Makes patches bigger the higher this zoom value is") private double zoom = 1; + + @MinNumber(0.0001) + @DontObfuscate + @Desc("The zoom is for zooming in or out variance. Makes patches have more or less of one type.") + private double varianceZoom = 1; @MinNumber(0.0001) @DontObfuscate @@ -73,6 +78,7 @@ public class IrisBiomeDecorator private KList palette = new KList().qadd("GRASS"); private transient KMap layerGenerators; + private transient KMap layerVarianceGenerators; private transient AtomicCache heightGenerator = new AtomicCache<>(); private transient AtomicCache> blockData = new AtomicCache<>(); @@ -83,14 +89,14 @@ public class IrisBiomeDecorator return stackMin; } - return getGenerator(rng).fit(stackMin, stackMax, x * (verticalVariance.equals(Dispersion.SCATTER) ? 1000D : 1D), z * (verticalVariance.equals(Dispersion.SCATTER) ? 1000D : 1D)); + return getHeightGenerator(rng).fit(stackMin, stackMax, x ,z); } public CNG getHeightGenerator(RNG rng) { return heightGenerator.aquire(() -> { - return CNG.signature(rng.nextParallelRNG(getBlockData().size() + stackMax + stackMin)).scale(1D / verticalZoom); + return heightVariance.create(rng.nextParallelRNG(getBlockData().size() + stackMax + stackMin)).scale(1D / verticalZoom); }); } @@ -105,11 +111,28 @@ public class IrisBiomeDecorator if(!layerGenerators.containsKey(key)) { - layerGenerators.put(key, CNG.signature(rng.nextParallelRNG((int) (getBlockData().size() + key))).scale(1D / zoom)); + layerGenerators.put(key, dispersion.create(rng.nextParallelRNG((int) (getBlockData().size() + key))).scale(1D / zoom)); } return layerGenerators.get(key); } + + public CNG getVarianceGenerator(RNG rng) + { + long key = rng.nextParallelRNG(4).nextLong(); + + if(layerVarianceGenerators == null) + { + layerGenerators = new KMap<>(); + } + + if(!layerVarianceGenerators.containsKey(key)) + { + layerVarianceGenerators.put(key, variance.create(rng.nextParallelRNG((int) (getBlockData().size() + key))).scale(1D / varianceZoom)); + } + + return layerVarianceGenerators.get(key); + } public KList add(String b) { @@ -134,9 +157,8 @@ public class IrisBiomeDecorator return null; } - RNG nrng = dispersion.equals(Dispersion.SCATTER) ? rng.nextParallelRNG((int) (z - (int) ((x + 34856) * (int) (x + z + (int) (28835521 + (getChance() * 1000) + getStackMin() + getStackMax() + (getZoom() * 556)))))) : null; - double xx = dispersion.equals(Dispersion.SCATTER) ? nrng.i(-1000000, 1000000) + z : x; - double zz = dispersion.equals(Dispersion.SCATTER) ? nrng.i(-1000000, 1000000) - x : z; + double xx = x; + double zz = z; xx /= getZoom(); zz /= getZoom(); @@ -147,7 +169,7 @@ public class IrisBiomeDecorator return getBlockData().get(0); } - return getBlockData().get(getGenerator(rng.nextParallelRNG(44)).fit(0, getBlockData().size() - 1, xx, zz)); + return getVarianceGenerator(rng.nextParallelRNG(44)).fit(getBlockData(), xx, zz); } return null; diff --git a/src/main/java/com/volmit/iris/object/IrisBiomePaletteLayer.java b/src/main/java/com/volmit/iris/object/IrisBiomePaletteLayer.java index 9128561df..955831a76 100644 --- a/src/main/java/com/volmit/iris/object/IrisBiomePaletteLayer.java +++ b/src/main/java/com/volmit/iris/object/IrisBiomePaletteLayer.java @@ -21,8 +21,8 @@ import lombok.Data; public class IrisBiomePaletteLayer { @DontObfuscate - @Desc("The dispersion of materials from the palette") - private Dispersion dispersion = Dispersion.SCATTER; + @Desc("The style of noise") + private NoiseStyle style = NoiseStyle.STATIC; @MinNumber(0) @MaxNumber(256) @@ -39,7 +39,7 @@ public class IrisBiomePaletteLayer @MinNumber(0.0001) @DontObfuscate @Desc("The terrain zoom mostly for zooming in on a wispy palette") - private double terrainZoom = 5; + private double zoom = 5; @Required @ArrayType(min = 1, type = String.class) @@ -68,35 +68,15 @@ public class IrisBiomePaletteLayer return getBlockData().get(0); } - if(dispersion.equals(Dispersion.SCATTER)) - { - return getBlockData().get(getLayerGenerator(rng).fit(0, 30000000, x, y, z) % getBlockData().size()); - } - - else - { - return getBlockData().get(getLayerGenerator(rng).fit(0, getBlockData().size() - 1, x, y, z)); - } + return getLayerGenerator(rng).fit(getBlockData(), x, y, z); } public CNG getLayerGenerator(RNG rng) { return layerGenerator.aquire(() -> { - CNG layerGenerator = new CNG(rng); RNG rngx = rng.nextParallelRNG(minHeight + maxHeight + getBlockData().size()); - - switch(dispersion) - { - case SCATTER: - layerGenerator = CNG.signature(rngx).freq(1000000); - break; - case WISPY: - layerGenerator = CNG.signature(rngx); - break; - } - - return layerGenerator; + return style.create(rngx); }); } diff --git a/src/main/java/com/volmit/iris/object/IrisDimension.java b/src/main/java/com/volmit/iris/object/IrisDimension.java index 420ec5266..2ae88fa6e 100644 --- a/src/main/java/com/volmit/iris/object/IrisDimension.java +++ b/src/main/java/com/volmit/iris/object/IrisDimension.java @@ -29,8 +29,7 @@ import lombok.EqualsAndHashCode; @Desc("Represents a dimension") @Data @EqualsAndHashCode(callSuper = false) -public class IrisDimension extends IrisRegistrant -{ +public class IrisDimension extends IrisRegistrant { public static final BlockData STONE = Material.STONE.createBlockData(); public static final BlockData WATER = Material.WATER.createBlockData(); @@ -238,8 +237,12 @@ public class IrisDimension extends IrisRegistrant private KList deposits = new KList<>(); @DontObfuscate - @Desc("The dispersion of materials for the rock palette") - private Dispersion rockDispersion = Dispersion.SCATTER; + @Desc("The noise style for rock types") + private NoiseStyle rockStyle = NoiseStyle.STATIC; + + @DontObfuscate + @Desc("The noise style for fluid types") + private NoiseStyle fluidStyle = NoiseStyle.STATIC; @MinNumber(0.0001) @MaxNumber(512) @@ -274,33 +277,29 @@ public class IrisDimension extends IrisRegistrant private transient AtomicCache rad = new AtomicCache<>(); private transient boolean inverted = false; - public KList getPostBlockProcessors(PostBlockChunkGenerator g) - { - return cacheFilters.aquire(() -> - { + public KList getPostBlockProcessors(PostBlockChunkGenerator g) { + return cacheFilters.aquire(() -> { KList cacheFilters = new KList<>(); - for(IrisPostProcessor i : getPostProcessors()) - { + for (IrisPostProcessor i : getPostProcessors()) { cacheFilters.add(g.createProcessor(i.getProcessor(), i.getPhase())); } g.setMinPhase(0); g.setMaxPhase(0); - for(IrisPostBlockFilter i : cacheFilters) - { + for (IrisPostBlockFilter i : cacheFilters) { g.setMinPhase(Math.min(g.getMinPhase(), i.getPhase())); g.setMaxPhase(Math.max(g.getMaxPhase(), i.getPhase())); } - Iris.info("Post Processing: " + cacheFilters.size() + " filters. Phases: " + g.getMinPhase() + " - " + g.getMaxPhase()); + Iris.info("Post Processing: " + cacheFilters.size() + " filters. Phases: " + g.getMinPhase() + " - " + + g.getMaxPhase()); return cacheFilters; }); } - public static KList getDefaultCompatability() - { + public static KList getDefaultCompatability() { KList filters = new KList<>(); // Below 1.16 @@ -439,18 +438,15 @@ public class IrisDimension extends IrisRegistrant return filters; } - public CNG getCoordFracture(RNG rng, int signature) - { - return coordFracture.aquire(() -> - { + public CNG getCoordFracture(RNG rng, int signature) { + return coordFracture.aquire(() -> { CNG coordFracture = CNG.signature(rng.nextParallelRNG(signature)); coordFracture.scale(0.012 / coordFractureZoom); return coordFracture; }); } - private KList getDefaultPostProcessors() - { + private KList getDefaultPostProcessors() { KList p = new KList(); p.add(new IrisPostProcessor("wall-painter")); @@ -460,59 +456,32 @@ public class IrisDimension extends IrisRegistrant return p; } - public BlockData getRock(RNG rng, double x, double y, double z) - { - if(getRockData().isEmpty()) - { + public BlockData getRock(RNG rng, double x, double y, double z) { + if (getRockData().isEmpty()) { return STONE; } - if(getRockData().size() == 1) - { + if (getRockData().size() == 1) { return getRockData().get(0); } - if(rockDispersion.equals(Dispersion.SCATTER)) - { - return getRockData().get(getRockGenerator(rng).fit(0, 30000000, x, y, z) % getRockData().size()); - } - - else - { - return getRockData().get(getRockGenerator(rng).fit(0, getRockData().size() - 1, x, y, z)); - } + return getRockGenerator(rng).fit(getRockData(), x, y, z); } - public CNG getRockGenerator(RNG rng) - { - return rockLayerGenerator.aquire(() -> - { - RNG rngx = rng.nextParallelRNG((int) (getRockData().size() * getRegions().size() * getCaveScale() * getLandZoom() * 10357)); - CNG rockLayerGenerator = new CNG(rng); - switch(rockDispersion) - { - case SCATTER: - rockLayerGenerator = CNG.signature(rngx).freq(1000000); - break; - case WISPY: - rockLayerGenerator = CNG.signature(rngx); - break; - } - - return rockLayerGenerator; + public CNG getRockGenerator(RNG rng) { + return rockLayerGenerator.aquire(() -> { + RNG rngx = rng.nextParallelRNG( + (int) (getRockData().size() * getRegions().size() * getCaveScale() * getLandZoom() * 10357)); + return rockStyle.create(rngx); }); } - public KList getRockData() - { - return rockData.aquire(() -> - { + public KList getRockData() { + return rockData.aquire(() -> { KList rockData = new KList<>(); - for(String ix : rockPalette) - { + for (String ix : rockPalette) { BlockData bx = B.getBlockData(ix); - if(bx != null) - { + if (bx != null) { rockData.add(bx); } } @@ -521,59 +490,32 @@ public class IrisDimension extends IrisRegistrant }); } - public BlockData getFluid(RNG rng, double x, double y, double z) - { - if(getFluidData().isEmpty()) - { + public BlockData getFluid(RNG rng, double x, double y, double z) { + if (getFluidData().isEmpty()) { return WATER; } - if(getFluidData().size() == 1) - { + if (getFluidData().size() == 1) { return getFluidData().get(0); } - if(rockDispersion.equals(Dispersion.SCATTER)) - { - return getFluidData().get(getFluidGenerator(rng).fit(0, 30000000, x, y, z) % getFluidData().size()); - } - - else - { - return getFluidData().get(getFluidGenerator(rng).fit(0, getFluidData().size() - 1, x, y, z)); - } + return getFluidGenerator(rng).fit(getFluidData(), x, y, z); } - public CNG getFluidGenerator(RNG rng) - { - return fluidLayerGenerator.aquire(() -> - { - RNG rngx = rng.nextParallelRNG(getFluidData().size() * (int) (getRockData().size() * getRegions().size() * getCaveScale() * getLandZoom() * 10357)); - CNG fluidLayerGenerator = new CNG(rng); - switch(rockDispersion) - { - case SCATTER: - fluidLayerGenerator = CNG.signature(rngx).freq(1000000); - break; - case WISPY: - fluidLayerGenerator = CNG.signature(rngx); - break; - } - - return fluidLayerGenerator; + public CNG getFluidGenerator(RNG rng) { + return fluidLayerGenerator.aquire(() -> { + RNG rngx = rng.nextParallelRNG(getFluidData().size() + * (int) (getRockData().size() * getRegions().size() * getCaveScale() * getLandZoom() * 10357)); + return fluidStyle.create(rngx); }); } - public KList getFluidData() - { - return fluidData.aquire(() -> - { + public KList getFluidData() { + return fluidData.aquire(() -> { KList fluidData = new KList<>(); - for(String ix : fluidPalette) - { + for (String ix : fluidPalette) { BlockData bx = B.getBlockData(ix); - if(bx != null) - { + if (bx != null) { fluidData.add(bx); } } @@ -582,49 +524,40 @@ public class IrisDimension extends IrisRegistrant }); } - public double getDimensionAngle() - { + public double getDimensionAngle() { return rad.aquire(() -> Math.toRadians(dimensionAngleDeg)); } - public double sinRotate() - { + public double sinRotate() { return sinr.aquire(() -> Math.sin(getDimensionAngle())); } - public double cosRotate() - { + public double cosRotate() { return cosr.aquire(() -> Math.cos(getDimensionAngle())); } - public KList getAllRegions(ContextualChunkGenerator g) - { + public KList getAllRegions(ContextualChunkGenerator g) { KList r = new KList<>(); - for(String i : getRegions()) - { + for (String i : getRegions()) { r.add(g != null ? g.loadRegion(i) : Iris.globaldata.getRegionLoader().load(i)); } return r; } - public KList getAllBiomes(ContextualChunkGenerator g) - { + public KList getAllBiomes(ContextualChunkGenerator g) { KList r = new KList<>(); - for(IrisRegion i : getAllRegions(g)) - { + for (IrisRegion i : getAllRegions(g)) { r.addAll(i.getAllBiomes(g)); } return r; } - public ChunkPosition getParallaxSize(ContextualChunkGenerator g) - { - return parallaxSize.aquire(() -> - { + public ChunkPosition getParallaxSize(ContextualChunkGenerator g) { + return parallaxSize.aquire(() -> { int x = 0; int z = 0; @@ -632,50 +565,40 @@ public class IrisDimension extends IrisRegistrant KList r = getAllRegions(g); KList b = getAllBiomes(g); - for(IrisBiome i : b) - { - for(IrisObjectPlacement j : i.getObjects()) - { + for (IrisBiome i : b) { + for (IrisObjectPlacement j : i.getObjects()) { objects.addAll(j.getPlace()); } } - for(String i : objects) - { - try - { + for (String i : objects) { + try { BlockVector bv = IrisObject.sampleSize(g.getData().getObjectLoader().findFile(i)); x = bv.getBlockX() > x ? bv.getBlockX() : x; z = bv.getBlockZ() > z ? bv.getBlockZ() : z; } - catch(Throwable e) - { + catch (Throwable e) { } } - for(IrisDepositGenerator i : getDeposits()) - { + for (IrisDepositGenerator i : getDeposits()) { int max = i.getMaxDimension(); x = max > x ? max : x; z = max > z ? max : z; } - for(IrisRegion v : r) - { - for(IrisDepositGenerator i : v.getDeposits()) - { + for (IrisRegion v : r) { + for (IrisDepositGenerator i : v.getDeposits()) { int max = i.getMaxDimension(); x = max > x ? max : x; z = max > z ? max : z; } } - for(IrisBiome v : b) - { - for(IrisDepositGenerator i : v.getDeposits()) - { + for (IrisBiome v : b) { + for (IrisDepositGenerator i : v.getDeposits()) { int max = i.getMaxDimension(); x = max > x ? max : x; z = max > z ? max : z; @@ -691,12 +614,9 @@ public class IrisDimension extends IrisRegistrant }); } - public BlockData resolve(String bd) - { - for(IrisCompatabilityFilter i : getCompatability()) - { - if(i.getWhen().equalsIgnoreCase(bd)) - { + public BlockData resolve(String bd) { + for (IrisCompatabilityFilter i : getCompatability()) { + if (i.getWhen().equalsIgnoreCase(bd)) { return i.getReplace(); } } diff --git a/src/main/java/com/volmit/iris/object/IrisNoiseGenerator.java b/src/main/java/com/volmit/iris/object/IrisNoiseGenerator.java index 30ab266a4..c2b90e922 100644 --- a/src/main/java/com/volmit/iris/object/IrisNoiseGenerator.java +++ b/src/main/java/com/volmit/iris/object/IrisNoiseGenerator.java @@ -69,8 +69,8 @@ public class IrisNoiseGenerator private boolean enabled = true; @DontObfuscate - @Desc("If this generator uses the default iris swirly/wispy noise generator. Set to false for pure simplex.") - private boolean irisBased = true; + @Desc("The Noise Style") + private NoiseStyle style = NoiseStyle.IRIS; @MinNumber(1) @DontObfuscate @@ -97,7 +97,7 @@ public class IrisNoiseGenerator protected CNG getGenerator(long superSeed) { - return generator.aquire(() -> irisBased ? CNG.signature(new RNG(superSeed + 33955677 - seed)) : new CNG(new RNG(superSeed + 33955677 - seed), 1D, octaves)); + return generator.aquire(() -> style.create(new RNG(superSeed + 33955677 - seed)).oct(octaves)); } public double getMax() diff --git a/src/main/java/com/volmit/iris/object/NoiseStyle.java b/src/main/java/com/volmit/iris/object/NoiseStyle.java new file mode 100644 index 000000000..5600fd2eb --- /dev/null +++ b/src/main/java/com/volmit/iris/object/NoiseStyle.java @@ -0,0 +1,103 @@ +package com.volmit.iris.object; + +import com.volmit.iris.noise.CNG; +import com.volmit.iris.noise.CNGFactory; +import com.volmit.iris.noise.NoiseType; +import com.volmit.iris.util.Desc; +import com.volmit.iris.util.DontObfuscate; +import com.volmit.iris.util.RNG; + +@Desc("Styles of noise") +@DontObfuscate +public enum NoiseStyle { + @Desc("White Noise is like static. Useful for block scattering but not terrain.") + @DontObfuscate + STATIC(rng -> new CNG(rng, NoiseType.WHITE, 1D, 1)), + + @Desc("White Noise is like static. Useful for block scattering but not terrain. 4 Times finer.") + @DontObfuscate + STATIC_FINE(rng -> new CNG(rng, NoiseType.WHITE, 1D, 1).scale(4)), + + @Desc("White Noise is like static. Useful for block scattering but not terrain. 16 Times finer.") + @DontObfuscate + STATIC_ULTRA_FINE(rng -> new CNG(rng, NoiseType.WHITE, 1D, 1).scale(16)), + + @Desc("Wispy Perlin-looking simplex noise. The 'iris' style noise.") + @DontObfuscate + IRIS(rng -> CNG.signature(rng)), + + @Desc("Basic, Smooth & Fast Simplex noise.") + @DontObfuscate + SIMPLEX(rng -> new CNG(rng, 1D, 1)), + + @Desc("Basic, Smooth & Fast Simplex noise. Uses 2 octaves") + @DontObfuscate + BIOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 2)), + + @Desc("Basic, Smooth & Fast Simplex noise. Uses 3 octaves") + @DontObfuscate + TRIOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 3)), + + @Desc("Basic, Smooth & Fast Simplex noise. Uses 4 octaves") + @DontObfuscate + QUADOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 4)), + + @Desc("Basic, Smooth & Fast Simplex noise. Uses 5 octaves") + @DontObfuscate + QUINTOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 5)), + + @Desc("Basic, Smooth & Fast Simplex noise. Uses 6 octaves") + @DontObfuscate + SEXOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 6)), + + @Desc("Basic, Smooth & Fast Simplex noise. Uses 7 octaves") + @DontObfuscate + SEPTOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 7)), + + @Desc("Basic, Smooth & Fast Simplex noise. Uses 8 octaves") + @DontObfuscate + OCTOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 8)), + + @Desc("Basic, Smooth & Fast Simplex noise. Uses 9 octaves") + @DontObfuscate + NONOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 9)), + + @Desc("Basic, Smooth & Fast Simplex noise. Uses 10 octaves") + @DontObfuscate + VIGOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 10)), + + @Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.") + @DontObfuscate + CELLULAR(rng -> new CNG(rng, NoiseType.CELLULAR, 1D, 1)), + + @Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders. Cells are distorted using Iris styled wispy noise.") + @DontObfuscate + CELLULAR_IRIS(rng -> CNG.signature(rng, NoiseType.CELLULAR)), + + @Desc("Inverse of vascular, height gets to 1.0 as it approaches the center of a cell") + @DontObfuscate + PERTERB(rng -> new CNG(rng, NoiseType.CELLULAR_HEIGHT, 1D, 1)), + + @Desc("Inverse of vascular, height gets to 1.0 as it approaches the center of a cell, using the iris style.") + @DontObfuscate + PERTERB_IRIS(rng -> CNG.signature(rng, NoiseType.CELLULAR_HEIGHT)), + + @Desc("Vascular noise gets higher as the position nears a cell border.") + @DontObfuscate + VASCULAR(rng -> new CNG(rng, NoiseType.VASCULAR, 1D, 1)), + + @Desc("Vascular noise gets higher as the position nears a cell border. Cells are distorted using Iris styled wispy noise.") + @DontObfuscate + VASCULAR_IRIS(rng -> CNG.signature(rng, NoiseType.VASCULAR)), + + ; + private CNGFactory f; + + private NoiseStyle(CNGFactory f) { + this.f = f; + } + + public CNG create(RNG seed) { + return f.create(seed); + } +}