This commit is contained in:
Daniel Mills 2020-08-16 13:18:02 -04:00
parent d89371a279
commit 2407c3f2f8
35 changed files with 1531 additions and 505 deletions

View File

@ -41,14 +41,14 @@ import com.volmit.iris.util.Permission;
import com.volmit.iris.util.RollingSequence;
import com.volmit.iris.util.ScoreDirection;
public class Iris extends MortarPlugin implements BoardProvider {
public class Iris extends MortarPlugin implements BoardProvider
{
public static KList<GroupedExecutor> executors = new KList<>();
public static Iris instance;
public static IrisDataManager globaldata;
public static ProjectManager proj;
public static IrisHotloadManager hotloader;
public static WandController wand;
private static String last = "";
private BoardManager manager;
private String mem = "...";
private ChronoLatch cl = new ChronoLatch(1000);
@ -65,27 +65,31 @@ public class Iris extends MortarPlugin implements BoardProvider {
@com.volmit.iris.util.Command
public CommandIris commandIris;
public Iris() {
public Iris()
{
IO.delete(new File("iris"));
}
@Override
public void start() {
public void start()
{
}
@Override
public void stop() {
public void stop()
{
}
@Override
public String getTag(String subTag) {
return ChatColor.BOLD + "" + ChatColor.DARK_GRAY + "[" + ChatColor.BOLD + "" + ChatColor.GREEN + "Iris"
+ ChatColor.BOLD + ChatColor.DARK_GRAY + "]" + ChatColor.RESET + "" + ChatColor.GRAY + ": ";
public String getTag(String subTag)
{
return ChatColor.BOLD + "" + ChatColor.DARK_GRAY + "[" + ChatColor.BOLD + "" + ChatColor.GREEN + "Iris" + ChatColor.BOLD + ChatColor.DARK_GRAY + "]" + ChatColor.RESET + "" + ChatColor.GRAY + ": ";
}
public void onEnable() {
public void onEnable()
{
lock = new IrisLock("Iris");
instance = this;
hotloader = new IrisHotloadManager();
@ -93,22 +97,25 @@ public class Iris extends MortarPlugin implements BoardProvider {
wand = new WandController();
postProcessors = loadPostProcessors();
proj = new ProjectManager();
manager = new BoardManager(this,
BoardSettings.builder().boardProvider(this).scoreDirection(ScoreDirection.UP).build());
manager = new BoardManager(this, BoardSettings.builder().boardProvider(this).scoreDirection(ScoreDirection.UP).build());
super.onEnable();
}
public void onDisable() {
public void onDisable()
{
lock.unlock();
proj.close();
for (GroupedExecutor i : executors) {
for(GroupedExecutor i : executors)
{
i.close();
}
for (World i : Bukkit.getWorlds()) {
if (i.getGenerator() instanceof IrisChunkGenerator) {
for(World i : Bukkit.getWorlds())
{
if(i.getGenerator() instanceof IrisChunkGenerator)
{
((IrisChunkGenerator) i).close();
}
}
@ -121,23 +128,28 @@ public class Iris extends MortarPlugin implements BoardProvider {
}
@Override
public String getTitle(Player player) {
public String getTitle(Player player)
{
return ChatColor.GREEN + "Iris";
}
@Override
public List<String> getLines(Player player) {
if (!clf.flip()) {
public List<String> getLines(Player player)
{
if(!clf.flip())
{
return lines;
}
World world = player.getWorld();
lines.clear();
if (world.getGenerator() instanceof IrisChunkGenerator) {
if(world.getGenerator() instanceof IrisChunkGenerator)
{
IrisChunkGenerator g = (IrisChunkGenerator) world.getGenerator();
if (cl.flip()) {
if(cl.flip())
{
mem = Form.memSize(g.guessMemoryUsage(), 2);
}
@ -150,23 +162,21 @@ public class Iris extends MortarPlugin implements BoardProvider {
tp.put(g.getMetrics().getSpeed());
lines.add("&7&m-----------------");
lines.add(ChatColor.GREEN + "Speed" + ChatColor.GRAY + ": " + ChatColor.BOLD + "" + ChatColor.GRAY
+ Form.f(g.getMetrics().getPerSecond().getAverage(), 0) + "/s "
+ Form.duration(g.getMetrics().getTotal().getAverage(), 1) + "");
lines.add(ChatColor.GREEN + "Speed" + ChatColor.GRAY + ": " + ChatColor.BOLD + "" + ChatColor.GRAY + Form.f(g.getMetrics().getPerSecond().getAverage(), 0) + "/s " + Form.duration(g.getMetrics().getTotal().getAverage(), 1) + "");
lines.add(ChatColor.GREEN + "Generators" + ChatColor.GRAY + ": " + Form.f(CNG.creates));
lines.add(ChatColor.GREEN + "Noise" + ChatColor.GRAY + ": " + Form.f((int) hits.getAverage()));
lines.add(ChatColor.GREEN + "Parallax Chunks" + ChatColor.GRAY + ": "
+ Form.f((int) g.getParallaxMap().getLoadedChunks().size()));
lines.add(ChatColor.GREEN + "Objects" + ChatColor.GRAY + ": "
+ Form.f(g.getData().getObjectLoader().count()));
lines.add(ChatColor.GREEN + "Parallax Chunks" + ChatColor.GRAY + ": " + Form.f((int) g.getParallaxMap().getLoadedChunks().size()));
lines.add(ChatColor.GREEN + "Objects" + ChatColor.GRAY + ": " + Form.f(g.getData().getObjectLoader().count()));
lines.add(ChatColor.GREEN + "Memory" + ChatColor.GRAY + ": " + mem);
if (er != null && b != null) {
if(er != null && b != null)
{
lines.add(ChatColor.GREEN + "Biome" + ChatColor.GRAY + ": " + b.getName());
lines.add(ChatColor.GREEN + "File" + ChatColor.GRAY + ": " + b.getLoadKey());
}
if (st != null) {
if(st != null)
{
lines.add(ChatColor.GREEN + "Structure" + ChatColor.GRAY + ": " + st.getStructure().getName());
lines.add(ChatColor.GREEN + "Tile" + ChatColor.GRAY + ": " + st.getTile().toString());
}
@ -174,14 +184,16 @@ public class Iris extends MortarPlugin implements BoardProvider {
lines.add("&7&m-----------------");
}
else {
else
{
lines.add(ChatColor.GREEN + "Join an Iris World!");
}
return lines;
}
private static KList<Class<? extends IrisPostBlockFilter>> loadPostProcessors() {
private static KList<Class<? extends IrisPostBlockFilter>> loadPostProcessors()
{
KList<Class<? extends IrisPostBlockFilter>> g = new KList<Class<? extends IrisPostBlockFilter>>();
g.add(PostFloatingNibDeleter.class);
@ -195,55 +207,57 @@ public class Iris extends MortarPlugin implements BoardProvider {
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
{
return super.onCommand(sender, command, label, args);
}
public void imsg(CommandSender s, String msg) {
s.sendMessage(ChatColor.GREEN + "[" + ChatColor.DARK_GRAY + "Iris" + ChatColor.GREEN + "]" + ChatColor.GRAY
+ ": " + msg);
public void imsg(CommandSender s, String msg)
{
s.sendMessage(ChatColor.GREEN + "[" + ChatColor.DARK_GRAY + "Iris" + ChatColor.GREEN + "]" + ChatColor.GRAY + ": " + msg);
}
@Override
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) {
return new IrisChunkGenerator(16);
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id)
{
return new IrisChunkGenerator(IrisSettings.get().threads);
}
public static void msg(String string) {
public static void msg(String string)
{
lock.lock();
String msg = ChatColor.GREEN + "[Iris]: " + ChatColor.GRAY + string;
if (last.equals(msg)) {
lock.unlock();
return;
}
last = msg;
Bukkit.getConsoleSender().sendMessage(msg);
lock.unlock();
}
public static void warn(String string) {
public static void warn(String string)
{
msg(ChatColor.YELLOW + string);
}
public static void error(String string) {
public static void error(String string)
{
msg(ChatColor.RED + string);
}
public static void verbose(String string) {
public static void verbose(String string)
{
msg(ChatColor.GRAY + string);
}
public static void success(String string) {
public static void success(String string)
{
msg(ChatColor.GREEN + string);
}
public static void info(String string) {
public static void info(String string)
{
msg(ChatColor.WHITE + string);
}
public void hit(long hits2) {
public void hit(long hits2)
{
hits.put(hits2);
}
}

View File

@ -43,12 +43,14 @@ public class IrisDataManager
File packs = this.packs.getName().equals("packs") ? this.packs : dataFolder;
packs.mkdirs();
this.regionLoader = new ResourceLoader<>(packs, "regions", "Region", IrisRegion.class);
this.biomeLoader = new ResourceLoader<>(packs, "biomes", "Biome", IrisBiome.class);
this.dimensionLoader = new ResourceLoader<>(packs, "dimensions", "Dimension", IrisDimension.class);
this.structureLoader = new ResourceLoader<>(packs, "structures", "Structure", IrisStructure.class);
this.generatorLoader = new ResourceLoader<>(packs, "generators", "Generator", IrisGenerator.class);
this.objectLoader = new ObjectResourceLoader(packs, "objects", "Object");
if(packs.getName().equals("packs"))
{
writeExamples();
@ -164,4 +166,13 @@ public class IrisDataManager
generatorLoader.preferFolder(name);
structureLoader.preferFolder(name);
}
public void clearLists()
{
biomeLoader.clearList();
regionLoader.clearList();
dimensionLoader.clearList();
generatorLoader.clearList();
structureLoader.clearList();
}
}

View File

@ -3,19 +3,20 @@ package com.volmit.iris;
import java.io.File;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import com.volmit.iris.util.ChronoLatch;
import com.volmit.iris.util.FileWatcher;
import com.volmit.iris.util.KSet;
import com.volmit.iris.util.FolderWatcher;
public class IrisHotloadManager
{
private ChronoLatch latch;
private KSet<FileWatcher> watchers;
private FolderWatcher w;
public IrisHotloadManager()
{
watchers = new KSet<>();
w = new FolderWatcher(Iris.instance.getDataFolder("packs"));
latch = new ChronoLatch(3000);
}
@ -33,13 +34,87 @@ public class IrisHotloadManager
try
{
for(FileWatcher i : watchers)
if(w.checkModified())
{
if(i.checkModified())
for(File i : w.getCreated())
{
c++;
Iris.info("File Modified: " + i.getFile().getPath());
if(i.isDirectory())
{
continue;
}
if(i.getPath().contains(".git"))
{
continue;
}
if(i.getPath().contains("_docs"))
{
continue;
}
if(i.getName().endsWith(".code-workspace"))
{
continue;
}
modified = true;
c++;
Iris.verbose("File Created: " + i.getPath());
}
for(File i : w.getDeleted())
{
if(i.isDirectory())
{
continue;
}
if(i.getPath().contains("_docs"))
{
continue;
}
if(i.getPath().contains(".git"))
{
continue;
}
if(i.getName().endsWith(".code-workspace"))
{
continue;
}
modified = true;
c++;
Iris.verbose("File Deleted: " + i.getPath());
}
for(File i : w.getChanged())
{
if(i.isDirectory())
{
continue;
}
if(i.getPath().contains(".git"))
{
continue;
}
if(i.getPath().contains("_docs"))
{
continue;
}
if(i.getName().endsWith(".code-workspace"))
{
continue;
}
modified = true;
c++;
Iris.verbose("File Modified: " + i.getPath());
}
}
}
@ -51,8 +126,14 @@ public class IrisHotloadManager
if(modified)
{
watchers.clear();
Iris.success("Hotloading Iris (" + c + " File" + (c == 1 ? "" : "s") + " changed)");
String m = "Hotloaded " + c + " File" + (c == 1 ? "" : "s");
for(Player i : Bukkit.getOnlinePlayers())
{
i.sendMessage(Iris.instance.getTag("Studio") + m);
}
Bukkit.getConsoleSender().sendMessage(Iris.instance.getTag("Studio") + m);
Iris.globaldata.hotloaded();
ch.onHotloaded();
}
@ -61,6 +142,6 @@ public class IrisHotloadManager
public void track(File file)
{
watchers.add(new FileWatcher(file));
}
}

View File

@ -1,14 +1,21 @@
package com.volmit.iris;
import java.io.File;
import java.io.IOException;
import com.google.gson.Gson;
import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.IO;
import com.volmit.iris.util.JSONException;
import com.volmit.iris.util.JSONObject;
public class IrisSettings
{
public static transient IrisSettings settings;
@DontObfuscate
@Desc("Iris generator threads (must be 2 or higher).")
@Desc("Iris generator threads (must be 2 or higher). Threads in iris are not a perfect scale for performance as a lot of data has to be shared. 16 Threads is a good rule of thumb. Use 8 threads on a quad core processor.")
public int threads = 16;
@DontObfuscate
@ -17,14 +24,67 @@ public class IrisSettings
@DontObfuscate
@Desc("Compression level (0-9) lower is faster, but is not as good compression. Best results around 3-5")
public int parallaxCompressionLevel = 3;
public int parallaxCompressionLevel = 2;
@DontObfuscate
@Desc("If A is a child of B, and B is a child of A, how deep should iris follow the children in biomes. Lower is faster gen.")
public int maxBiomeChildDepth = 5;
@DontObfuscate
@Desc("When enabled, The cache is shared for all chunks and cleared periodically instead of per chunk. This uses more memory but provides a ~15% speedup.")
public boolean sharedCaching = true;
@DontObfuscate
@Desc("Allows configs to be changed and hotloaded without reloading.")
public boolean hotloading = true;
public static IrisSettings get()
{
if(settings == null)
{
settings = new IrisSettings();
// TODO LOAD
File s = Iris.instance.getDataFile("settings.json");
if(!s.exists())
{
try
{
IO.writeAll(s, new JSONObject(new Gson().toJson(settings)).toString(4));
}
catch(JSONException | IOException e)
{
e.printStackTrace();
}
}
else
{
try
{
settings = new Gson().fromJson(IO.readAll(s), IrisSettings.class);
}
catch(JSONException | IOException e)
{
e.printStackTrace();
s.delete();
}
}
if(!s.exists())
{
try
{
IO.writeAll(s, new JSONObject(new Gson().toJson(settings)).toString(4));
}
catch(JSONException | IOException e)
{
e.printStackTrace();
}
}
}
return settings;

View File

@ -6,6 +6,7 @@ import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.UUID;
import java.util.concurrent.locks.ReentrantLock;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
@ -56,7 +57,15 @@ import com.volmit.iris.util.MaxNumber;
import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.MortarSender;
import com.volmit.iris.util.O;
import com.volmit.iris.util.RegistryListBiome;
import com.volmit.iris.util.RegistryListDimension;
import com.volmit.iris.util.RegistryListGenerator;
import com.volmit.iris.util.RegistryListObject;
import com.volmit.iris.util.RegistryListRegion;
import com.volmit.iris.util.RegistryListStructure;
import com.volmit.iris.util.Required;
import com.volmit.iris.util.TaskExecutor;
import com.volmit.iris.util.TaskExecutor.TaskGroup;
import lombok.Data;
@ -64,6 +73,8 @@ import lombok.Data;
public class ProjectManager
{
private IrisChunkGenerator currentProject;
private TaskExecutor tx = new TaskExecutor(8, Thread.MIN_PRIORITY, "Iris Compiler");
private ReentrantLock lock = new ReentrantLock();
public ProjectManager()
{
@ -522,7 +533,7 @@ public class ProjectManager
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(), dimension.getLoadKey() + ".code-workspace"), ws.toString(0));
Iris.proj.open(sender, dimension.getName());
}
@ -535,6 +546,7 @@ public class ProjectManager
private JSONObject newWorkspaceConfig()
{
Iris.globaldata.clearLists();
JSONObject ws = new JSONObject();
JSONArray folders = new JSONArray();
JSONObject folder = new JSONObject();
@ -549,7 +561,26 @@ public class ProjectManager
settings.put("workbench.tree.indent", 24);
settings.put("files.autoSave", "onFocusChange");
JSONArray schemas = buildSchemas();
JSONObject jc = new JSONObject();
jc.put("editor.autoIndent", "brackets");
jc.put("editor.acceptSuggestionOnEnter", "smart");
jc.put("editor.cursorSmoothCaretAnimation", true);
jc.put("editor.dragAndDrop", false);
jc.put("files.trimTrailingWhitespace", true);
jc.put("diffEditor.ignoreTrimWhitespace", true);
jc.put("files.trimFinalNewlines", true);
jc.put("editor.suggest.showKeywords", false);
jc.put("editor.suggest.showSnippets", false);
jc.put("editor.suggest.showWords", false);
jc.put("json.maxItemsComputed", 50000);
JSONObject st = new JSONObject();
st.put("strings", true);
jc.put("editor.quickSuggestions", st);
jc.put("editor.suggest.insertMode", "replace");
settings.put("[json]", jc);
settings.put("json.maxItemsComputed", 50000);
JSONArray schemas = buildSchemas(Iris.globaldata);
settings.put("json.schemas", schemas);
ws.put("settings", settings);
@ -565,29 +596,11 @@ public class ProjectManager
{
try
{
Iris.info("Updating Workspace: " + ws.getPath());
J.attemptAsync(() -> writeDocs(ws.getParentFile()));
JSONObject j = new JSONObject(IO.readAll(ws));
JSONObject s = j.getJSONObject("settings");
JSONObject jc = new JSONObject();
jc.put("editor.autoIndent", "brackets");
jc.put("editor.acceptSuggestionOnEnter", "smart");
jc.put("editor.cursorSmoothCaretAnimation", true);
jc.put("editor.dragAndDrop", false);
jc.put("files.trimTrailingWhitespace", true);
jc.put("diffEditor.ignoreTrimWhitespace", true);
jc.put("files.trimFinalNewlines", true);
jc.put("editor.suggest.showKeywords", false);
jc.put("editor.suggest.showSnippets", false);
jc.put("editor.suggest.showWords", false);
JSONObject st = new JSONObject();
st.put("strings", true);
jc.put("editor.quickSuggestions", st);
jc.put("editor.suggest.insertMode", "replace");
s.put("[json]", jc);
s.put("json.schemas", buildSchemas());
j.put("settings", s);
JSONObject j = newWorkspaceConfig();
IO.writeAll(ws, j.toString(4));
Iris.info("Updating Project " + ws.getAbsolutePath());
Iris.info("Updated Workspace: " + ws.getPath());
}
catch(Throwable e)
@ -606,30 +619,43 @@ public class ProjectManager
}
}
private JSONArray buildSchemas()
private void ex(JSONArray schemas, Class<?> c, IrisDataManager dat, String v)
{
JSONObject o = getSchemaEntry(c, dat, v);
lock.lock();
schemas.put(o);
lock.unlock();
}
private JSONArray buildSchemas(IrisDataManager dat)
{
JSONArray schemas = new JSONArray();
schemas.put(getSchemaEntry(IrisDimension.class, "/dimensions/*.json"));
schemas.put(getSchemaEntry(IrisBiome.class, "/biomes/*.json"));
schemas.put(getSchemaEntry(IrisRegion.class, "/regions/*.json"));
schemas.put(getSchemaEntry(IrisGenerator.class, "/generators/*.json"));
schemas.put(getSchemaEntry(IrisStructure.class, "/structures/*.json"));
TaskGroup g = tx.startWork();
g.queue(() -> ex(schemas, IrisDimension.class, dat, "/dimensions/*.json"));
g.queue(() -> ex(schemas, IrisBiome.class, dat, "/biomes/*.json"));
g.queue(() -> ex(schemas, IrisRegion.class, dat, "/regions/*.json"));
g.queue(() -> ex(schemas, IrisGenerator.class, dat, "/generators/*.json"));
g.queue(() -> ex(schemas, IrisStructure.class, dat, "/structures/*.json"));
g.execute();
return schemas;
}
public JSONObject getSchemaEntry(Class<?> i, String... fileMatch)
public JSONObject getSchemaEntry(Class<?> i, IrisDataManager dat, String... fileMatch)
{
Iris.verbose("Processing Folder " + i.getSimpleName() + " " + fileMatch[0]);
JSONObject o = new JSONObject();
o.put("fileMatch", new JSONArray(fileMatch));
o.put("schema", getSchemaFor(i));
o.put("schema", getSchemaFor(i, dat));
return o;
}
public JSONObject getSchemaFor(Class<?> i)
public JSONObject getSchemaFor(Class<?> i, IrisDataManager dat)
{
Iris.verbose("Processing " + i.getSimpleName());
KMap<String, JSONObject> def = new KMap<>();
JSONObject s = getSchemaFor(i, 7, def);
JSONObject s = getSchemaFor(i, 7, def, dat);
JSONObject defx = new JSONObject();
for(String v : def.k())
{
@ -641,7 +667,7 @@ public class ProjectManager
return s;
}
public JSONObject getSchemaFor(Class<?> i, int step, KMap<String, JSONObject> def)
public JSONObject getSchemaFor(Class<?> i, int step, KMap<String, JSONObject> def, IrisDataManager dat)
{
if(step <= 0)
{
@ -670,7 +696,6 @@ public class ProjectManager
JSONObject prop = new JSONObject();
if(k.isAnnotationPresent(Desc.class))
{
if(k.isAnnotationPresent(DependsOn.class))
{
deps.put(k.getName(), new JSONArray(k.getDeclaredAnnotation(DependsOn.class).value()));
@ -726,11 +751,36 @@ public class ProjectManager
{
prop.put("maxLength", (int) k.getDeclaredAnnotation(MaxNumber.class).value());
}
}
if(k.getType().equals(String.class))
{
tp = "string";
if(k.isAnnotationPresent(RegistryListBiome.class))
{
prop.put("enum", new JSONArray(getBiomeList(dat)));
}
if(k.isAnnotationPresent(RegistryListDimension.class))
{
prop.put("enum", new JSONArray(getDimensionList(dat)));
}
if(k.isAnnotationPresent(RegistryListGenerator.class))
{
prop.put("enum", new JSONArray(getGeneratorList(dat)));
}
if(k.isAnnotationPresent(RegistryListObject.class))
{
prop.put("enum", new JSONArray(getObjectList(dat)));
}
if(k.isAnnotationPresent(RegistryListRegion.class))
{
prop.put("enum", new JSONArray(getRegionList(dat)));
}
if(k.isAnnotationPresent(RegistryListStructure.class))
{
prop.put("enum", new JSONArray(getStructureList(dat)));
}
}
if(k.getType().isEnum())
@ -774,7 +824,7 @@ public class ProjectManager
if(k.getType().isAnnotationPresent(Desc.class))
{
prop.put("additionalProperties", false);
prop.put("properties", getSchemaFor(k.getType(), step - 1, def).getJSONObject("properties"));
prop.put("properties", getSchemaFor(k.getType(), step - 1, def, Iris.globaldata).getJSONObject("properties"));
}
}
@ -782,6 +832,11 @@ public class ProjectManager
{
ArrayType t = k.getDeclaredAnnotation(ArrayType.class);
if(t == null)
{
Iris.warn("Expected " + ArrayType.class.getSimpleName() + " in " + k.getName() + " in " + i.getSimpleName());
}
if(t.min() > 0)
{
prop.put("minItems", t.min());
@ -809,6 +864,136 @@ public class ProjectManager
if(t.type().equals(String.class))
{
tx = "string";
if(k.isAnnotationPresent(MinNumber.class))
{
prop.put("minLength", (int) k.getDeclaredAnnotation(MinNumber.class).value());
}
if(k.isAnnotationPresent(MaxNumber.class))
{
prop.put("maxLength", (int) k.getDeclaredAnnotation(MaxNumber.class).value());
}
if(k.isAnnotationPresent(RegistryListBiome.class))
{
String name = "enbiom" + t.type().getSimpleName().toLowerCase();
if(!def.containsKey(name))
{
JSONObject deff = new JSONObject();
deff.put("type", tx);
deff.put("enum", new JSONArray(getBiomeList(dat)));
def.put(name, deff);
}
JSONObject items = new JSONObject();
items.put("$ref", "#/definitions/" + name);
prop.put("items", items);
prop.put("description", k.getAnnotation(Desc.class).value());
prop.put("type", tp);
properties.put(k.getName(), prop);
continue;
}
if(k.isAnnotationPresent(RegistryListDimension.class))
{
String name = "endim" + t.type().getSimpleName().toLowerCase();
if(!def.containsKey(name))
{
JSONObject deff = new JSONObject();
deff.put("type", tx);
deff.put("enum", new JSONArray(getDimensionList(dat)));
def.put(name, deff);
}
JSONObject items = new JSONObject();
items.put("$ref", "#/definitions/" + name);
prop.put("items", items);
prop.put("description", k.getAnnotation(Desc.class).value());
prop.put("type", tp);
properties.put(k.getName(), prop);
continue;
}
if(k.isAnnotationPresent(RegistryListGenerator.class))
{
String name = "engen" + t.type().getSimpleName().toLowerCase();
if(!def.containsKey(name))
{
JSONObject deff = new JSONObject();
deff.put("type", tx);
deff.put("enum", new JSONArray(getGeneratorList(dat)));
def.put(name, deff);
}
JSONObject items = new JSONObject();
items.put("$ref", "#/definitions/" + name);
prop.put("items", items);
prop.put("description", k.getAnnotation(Desc.class).value());
prop.put("type", tp);
properties.put(k.getName(), prop);
continue;
}
if(k.isAnnotationPresent(RegistryListObject.class))
{
String name = "enobj" + t.type().getSimpleName().toLowerCase();
if(!def.containsKey(name))
{
JSONObject deff = new JSONObject();
deff.put("type", tx);
deff.put("enum", new JSONArray(getObjectList(dat)));
def.put(name, deff);
}
JSONObject items = new JSONObject();
items.put("$ref", "#/definitions/" + name);
prop.put("items", items);
prop.put("description", k.getAnnotation(Desc.class).value());
prop.put("type", tp);
properties.put(k.getName(), prop);
continue;
}
if(k.isAnnotationPresent(RegistryListRegion.class))
{
String name = "enreg" + t.type().getSimpleName().toLowerCase();
if(!def.containsKey(name))
{
JSONObject deff = new JSONObject();
deff.put("type", tx);
deff.put("enum", new JSONArray(getRegionList(dat)));
def.put(name, deff);
}
JSONObject items = new JSONObject();
items.put("$ref", "#/definitions/" + name);
prop.put("items", items);
prop.put("description", k.getAnnotation(Desc.class).value());
prop.put("type", tp);
properties.put(k.getName(), prop);
continue;
}
if(k.isAnnotationPresent(RegistryListStructure.class))
{
String name = "enstruct" + t.type().getSimpleName().toLowerCase();
if(!def.containsKey(name))
{
JSONObject deff = new JSONObject();
deff.put("type", tx);
deff.put("enum", new JSONArray(getStructureList(dat)));
def.put(name, deff);
}
JSONObject items = new JSONObject();
items.put("$ref", "#/definitions/" + name);
prop.put("items", items);
prop.put("description", k.getAnnotation(Desc.class).value());
prop.put("type", tp);
properties.put(k.getName(), prop);
continue;
}
}
if(t.type().isEnum())
@ -834,6 +1019,10 @@ public class ProjectManager
JSONObject items = new JSONObject();
items.put("$ref", "#/definitions/" + name);
prop.put("items", items);
prop.put("description", k.getAnnotation(Desc.class).value());
prop.put("type", tp);
properties.put(k.getName(), prop);
continue;
}
if(t.type().isEnum())
@ -857,7 +1046,7 @@ public class ProjectManager
if(!def.containsKey(name))
{
JSONObject deff = new JSONObject();
JSONObject scv = getSchemaFor(t.type(), step - 1, def);
JSONObject scv = getSchemaFor(t.type(), step - 1, def, Iris.globaldata);
deff.put("type", tx);
deff.put("description", t.type().getDeclaredAnnotation(Desc.class).value());
deff.put("additionalProperties", false);
@ -888,7 +1077,7 @@ public class ProjectManager
if(tp.getClass().isAnnotationPresent(Desc.class))
{
prop.put("properties", getSchemaFor(tp.getClass(), step - 1, def).getJSONObject("properties"));
prop.put("properties", getSchemaFor(tp.getClass(), step - 1, def, Iris.globaldata).getJSONObject("properties"));
}
}
@ -907,6 +1096,36 @@ public class ProjectManager
return schema;
}
private String[] getBiomeList(IrisDataManager data)
{
return data.getBiomeLoader().getPossibleKeys();
}
private String[] getDimensionList(IrisDataManager data)
{
return data.getDimensionLoader().getPossibleKeys();
}
private String[] getRegionList(IrisDataManager data)
{
return data.getRegionLoader().getPossibleKeys();
}
private String[] getObjectList(IrisDataManager data)
{
return data.getObjectLoader().getPossibleKeys();
}
private String[] getStructureList(IrisDataManager data)
{
return data.getStructureLoader().getPossibleKeys();
}
private String[] getGeneratorList(IrisDataManager data)
{
return data.getGeneratorLoader().getPossibleKeys();
}
public KList<String> analyzeFolder(File folder, String fn, Object t)
{
KList<String> a = new KList<String>();
@ -941,6 +1160,7 @@ public class ProjectManager
try
{
Iris.info("Reading " + i.getPath());
j = new JSONObject(IO.readAll(i));
o = new Gson().fromJson(j.toString(), t.getClass());
a.addAll(analyze(o, i));

View File

@ -1,6 +1,7 @@
package com.volmit.iris.gen;
import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
@ -12,6 +13,7 @@ import org.bukkit.entity.Player;
import com.volmit.iris.Iris;
import com.volmit.iris.IrisContext;
import com.volmit.iris.IrisSettings;
import com.volmit.iris.gen.atomics.AtomicRegionData;
import com.volmit.iris.noise.CNG;
import com.volmit.iris.object.IrisBiome;
@ -189,18 +191,29 @@ public class IrisChunkGenerator extends CeilingChunkGenerator implements IrisCon
@Override
public void onHotloaded()
{
if(!IrisSettings.get().hotloading)
{
return;
}
if(!isHotloadable())
{
Iris.warn("Hotload skipped (During Chunk Gen). Retrying.");
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, this::onHotloaded);
return;
}
CNG.creates = 0;
getData().dump();
getCache().drop();
Iris.proj.updateWorkspace(getWorkspaceFile());
onHotload();
}
private File getWorkspaceFile()
{
return new File(getDimension().getLoadFile().getParent(), getDimension().getLoadKey() + ".code-workspace");
}
public long guessMemoryUsage()
{
long bytes = 1024 * 1024 * (8 + (getThreads() / 3));
@ -215,6 +228,7 @@ public class IrisChunkGenerator extends CeilingChunkGenerator implements IrisCon
bytes += i.guessMemoryUsage();
}
bytes += getCache().getSize() * 65;
bytes += parallaxMap.getLoadedChunks().size() * 256 * 4 * 460;
bytes += ceilingParallaxMap.getLoadedChunks().size() * 256 * 4 * 460;
bytes += getSliverBuffer() * 220;

View File

@ -33,7 +33,8 @@ import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator implements IObjectPlacer {
public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator implements IObjectPlacer
{
protected KMap<ChunkPosition, AtomicSliver> sliverCache;
protected AtomicWorldData parallaxMap;
protected KMap<ChunkPosition, AtomicSliver> ceilingSliverCache;
@ -43,7 +44,8 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
private IrisLock lockq = new IrisLock("ParallaxQueueLock");
private int sliverBuffer;
public ParallaxChunkGenerator(String dimensionName, int threads) {
public ParallaxChunkGenerator(String dimensionName, int threads)
{
super(dimensionName, threads);
sliverCache = new KMap<>();
ceilingSliverCache = new KMap<>();
@ -51,41 +53,49 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
masterLock = new MasterLock();
}
public void onInit(World world, RNG rng) {
public void onInit(World world, RNG rng)
{
super.onInit(world, rng);
parallaxMap = new AtomicWorldData(world, "floor");
ceilingParallaxMap = new AtomicWorldData(world, "ceiling");
}
protected KMap<ChunkPosition, AtomicSliver> getSliverCache() {
protected KMap<ChunkPosition, AtomicSliver> getSliverCache()
{
return getDimension().isInverted() ? ceilingSliverCache : sliverCache;
}
protected void onClose() {
protected void onClose()
{
super.onClose();
try {
try
{
parallaxMap.unloadAll(true);
ceilingParallaxMap.unloadAll(true);
}
catch (IOException e) {
catch(IOException e)
{
e.printStackTrace();
}
}
@Override
public int getHighest(int x, int z) {
public int getHighest(int x, int z)
{
return getHighest(x, z, false);
}
@Override
public int getHighest(int x, int z, boolean ignoreFluid) {
int h = (int) Math
.round(ignoreFluid ? getTerrainHeight(x, z) : getTerrainWaterHeight(x, z));
public int getHighest(int x, int z, boolean ignoreFluid)
{
int h = (int) Math.round(ignoreFluid ? getTerrainHeight(x, z) : getTerrainWaterHeight(x, z));
if (getDimension().isCarving() && h >= getDimension().getCarvingMin()) {
while (getGlCarve().isCarved(x, h, z)) {
if(getDimension().isCarving() && h >= getDimension().getCarvingMin())
{
while(getGlCarve().isCarved(x, h, z))
{
h--;
}
@ -96,24 +106,28 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
}
@Override
public void set(int x, int y, int z, BlockData d) {
public void set(int x, int y, int z, BlockData d)
{
getMasterLock().lock((x >> 4) + "." + (z >> 4));
getParallaxSliver(x, z).set(y, d);
getMasterLock().unlock((x >> 4) + "." + (z >> 4));
}
@Override
public BlockData get(int x, int y, int z) {
public BlockData get(int x, int y, int z)
{
BlockData b = sampleSliver(x, z).getBlock().get(y);
return b == null ? AIR : b;
}
@Override
public boolean isSolid(int x, int y, int z) {
public boolean isSolid(int x, int y, int z)
{
return get(x, y, z).getMaterial().isSolid();
}
public AtomicSliver getParallaxSliver(int wx, int wz) {
public AtomicSliver getParallaxSliver(int wx, int wz)
{
getMasterLock().lock("gpc");
getMasterLock().lock((wx >> 4) + "." + (wz >> 4));
AtomicSliverMap map = getParallaxChunk(wx >> 4, wz >> 4);
@ -124,24 +138,30 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
return sliver;
}
public boolean isParallaxGenerated(int x, int z) {
public boolean isParallaxGenerated(int x, int z)
{
return getParallaxChunk(x, z).isParallaxGenerated();
}
public boolean isWorldGenerated(int x, int z) {
public boolean isWorldGenerated(int x, int z)
{
return getParallaxChunk(x, z).isWorldGenerated();
}
public AtomicWorldData getParallaxMap() {
public AtomicWorldData getParallaxMap()
{
return getDimension().isInverted() ? ceilingParallaxMap : parallaxMap;
}
public AtomicSliverMap getParallaxChunk(int x, int z) {
try {
public AtomicSliverMap getParallaxChunk(int x, int z)
{
try
{
return getParallaxMap().loadChunk(x, z);
}
catch (IOException e) {
catch(IOException e)
{
fail(e);
}
@ -149,16 +169,18 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
}
@Override
protected void onPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid, HeightMap height,
BiomeMap biomeMap) {
if (getSliverCache().size() > 20000) {
protected void onPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid, HeightMap height, BiomeMap biomeMap)
{
if(getSliverCache().size() > 20000)
{
getSliverCache().clear();
}
super.onPostGenerate(random, x, z, data, grid, height, biomeMap);
PrecisionStopwatch p = PrecisionStopwatch.start();
if (getDimension().isPlaceObjects()) {
if(getDimension().isPlaceObjects())
{
onGenerateParallax(random, x, z);
getParallaxChunk(x, z).inject(data);
setSliverBuffer(getSliverCache().size());
@ -173,50 +195,58 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
getData().getObjectLoader().clean();
}
public IrisStructureResult getStructure(int x, int y, int z) {
public IrisStructureResult getStructure(int x, int y, int z)
{
IrisBiome b = sampleTrueBiome(x, z).getBiome();
IrisRegion r = sampleRegion(x, z);
RNG ro = getMasterRandom().nextParallelRNG(496888 + (x >> 4) + (z >> 4));
int h = (int) Math.round(getTerrainHeight(x, z));
KList<IrisStructurePlacement> p = new KList<>();
for (IrisStructurePlacement i : r.getStructures()) {
if (i.getHeight() > -1) {
if (y >= i.getHeight() && y <= i.getHeight()
+ (i.getStructure(this).getGridHeight() * i.getStructure(this).getMaxLayers())) {
for(IrisStructurePlacement i : r.getStructures())
{
if(i.getHeight() > -1)
{
if(y >= i.getHeight() && y <= i.getHeight() + (i.getStructure(this).getGridHeight() * i.getStructure(this).getMaxLayers()))
{
p.add(i);
}
}
else if (y >= h && y <= i.getStructure(this).getGridHeight() + h) {
else if(y >= h && y <= i.getStructure(this).getGridHeight() + h)
{
p.add(i);
}
}
for (IrisStructurePlacement i : b.getStructures()) {
if (i.getHeight() > -1) {
if (y >= i.getHeight() && y <= i.getHeight()
+ (i.getStructure(this).getGridHeight() * i.getStructure(this).getMaxLayers())) {
for(IrisStructurePlacement i : b.getStructures())
{
if(i.getHeight() > -1)
{
if(y >= i.getHeight() && y <= i.getHeight() + (i.getStructure(this).getGridHeight() * i.getStructure(this).getMaxLayers()))
{
p.add(i);
}
}
else if (y >= h && y <= i.getStructure(this).getGridHeight() + h) {
else if(y >= h && y <= i.getStructure(this).getGridHeight() + h)
{
p.add(i);
}
}
for (IrisStructurePlacement i : p) {
if (!i.hasStructure(ro, x, y, z)) {
for(IrisStructurePlacement i : p)
{
if(!i.hasStructure(ro, x, y, z))
{
continue;
}
int hv = (i.getHeight() == -1 ? 0 : i.getHeight())
+ (Math.floorDiv(y, i.getStructure(this).getGridHeight()) * i.getStructure(this).getGridHeight());
TileResult tile = i.getStructure(this).getTile(ro, Math.floorDiv(i.gridSize(this), x) * i.gridSize(this),
hv, Math.floorDiv(i.gridSize(this), z) * i.gridSize(this));
int hv = (i.getHeight() == -1 ? 0 : i.getHeight()) + (Math.floorDiv(y, i.getStructure(this).getGridHeight()) * i.getStructure(this).getGridHeight());
TileResult tile = i.getStructure(this).getTile(ro, Math.floorDiv(i.gridSize(this), x) * i.gridSize(this), hv, Math.floorDiv(i.gridSize(this), z) * i.gridSize(this));
if (tile != null && tile.getTile() != null) {
if(tile != null && tile.getTile() != null)
{
return new IrisStructureResult(tile.getTile(), i.getStructure(this));
}
}
@ -224,52 +254,58 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
return null;
}
protected void onGenerateParallax(RNG random, int x, int z) {
protected void onGenerateParallax(RNG random, int x, int z)
{
String key = "par." + x + "." + "z";
ChunkPosition rad = getDimension().getParallaxSize(this);
KList<NastyRunnable> q = new KList<>();
for (int ii = x - (rad.getX() / 2); ii <= x + (rad.getX() / 2); ii++) {
for(int ii = x - (rad.getX() / 2); ii <= x + (rad.getX() / 2); ii++)
{
int i = ii;
for (int jj = z - (rad.getZ() / 2); jj <= z + (rad.getZ() / 2); jj++) {
for(int jj = z - (rad.getZ() / 2); jj <= z + (rad.getZ() / 2); jj++)
{
int j = jj;
if (isParallaxGenerated(ii, jj)) {
if(isParallaxGenerated(ii, jj))
{
continue;
}
if (isWorldGenerated(ii, jj)) {
if(isWorldGenerated(ii, jj))
{
continue;
}
getAccelerant().queue(key, () -> {
getAccelerant().queue(key, () ->
{
IrisBiome b = sampleTrueBiome((i * 16) + 7, (j * 16) + 7).getBiome();
RNG ro = getMasterRandom().nextParallelRNG(496888 + i + j);
int g = 1;
searching: for (IrisBiomeMutation k : getDimension().getMutations()) {
for (int l = 0; l < k.getChecks(); l++) {
IrisBiome sa = sampleTrueBiome(
((i * 16) + ro.nextInt(16)) + ro.i(-k.getRadius(), k.getRadius()),
((j * 16) + ro.nextInt(16)) + ro.i(-k.getRadius(), k.getRadius())).getBiome();
IrisBiome sb = sampleTrueBiome(
((i * 16) + ro.nextInt(16)) + ro.i(-k.getRadius(), k.getRadius()),
((j * 16) + ro.nextInt(16)) + ro.i(-k.getRadius(), k.getRadius())).getBiome();
searching: for(IrisBiomeMutation k : getDimension().getMutations())
{
for(int l = 0; l < k.getChecks(); l++)
{
IrisBiome sa = sampleTrueBiome(((i * 16) + ro.nextInt(16)) + ro.i(-k.getRadius(), k.getRadius()), ((j * 16) + ro.nextInt(16)) + ro.i(-k.getRadius(), k.getRadius())).getBiome();
IrisBiome sb = sampleTrueBiome(((i * 16) + ro.nextInt(16)) + ro.i(-k.getRadius(), k.getRadius()), ((j * 16) + ro.nextInt(16)) + ro.i(-k.getRadius(), k.getRadius())).getBiome();
if (sa.getLoadKey().equals(sb.getLoadKey())) {
if(sa.getLoadKey().equals(sb.getLoadKey()))
{
continue;
}
if (k.getRealSideA(this).contains(sa.getLoadKey())
&& k.getRealSideB(this).contains(sb.getLoadKey())) {
for (IrisObjectPlacement m : k.getObjects()) {
if(k.getRealSideA(this).contains(sa.getLoadKey()) && k.getRealSideB(this).contains(sb.getLoadKey()))
{
for(IrisObjectPlacement m : k.getObjects())
{
int gg = g++;
lockq.lock();
q.add(() -> {
placeObject(m, i, j, random.nextParallelRNG(
(34 * ((i * 30) + (j * 30) + gg) * i * j) + i - j + 1569962));
q.add(() ->
{
placeObject(m, i, j, random.nextParallelRNG((34 * ((i * 30) + (j * 30) + gg) * i * j) + i - j + 1569962));
});
lockq.unlock();
}
@ -281,52 +317,61 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
IrisRegion r = sampleRegion((i * 16) + 7, (j * 16) + 7);
for (IrisStructurePlacement k : r.getStructures()) {
for(IrisStructurePlacement k : r.getStructures())
{
lockq.lock();
q.add(() -> {
q.add(() ->
{
k.place(this, random.nextParallelRNG(2228), i, j);
});
lockq.unlock();
}
for (IrisStructurePlacement k : b.getStructures()) {
for(IrisStructurePlacement k : b.getStructures())
{
lockq.lock();
q.add(() -> {
q.add(() ->
{
k.place(this, random.nextParallelRNG(-22228), i, j);
});
lockq.unlock();
}
for (IrisObjectPlacement k : b.getObjects()) {
for(IrisObjectPlacement k : b.getObjects())
{
int gg = g++;
lockq.lock();
q.add(() -> {
placeObject(k, i, j, random
.nextParallelRNG((34 * ((i * 30) + (j * 30) + gg) * i * j) + i - j + 3569222));
q.add(() ->
{
placeObject(k, i, j, random.nextParallelRNG((34 * ((i * 30) + (j * 30) + gg) * i * j) + i - j + 3569222));
});
lockq.unlock();
}
if (getDimension().isCaves()) {
if(getDimension().isCaves())
{
int bx = (i * 16) + ro.nextInt(16);
int bz = (j * 16) + ro.nextInt(16);
IrisBiome biome = sampleCaveBiome(bx, bz).getBiome();
if (biome == null) {
if(biome == null)
{
return;
}
if (biome.getObjects().isEmpty()) {
if(biome.getObjects().isEmpty())
{
return;
}
for (IrisObjectPlacement k : biome.getObjects()) {
for(IrisObjectPlacement k : biome.getObjects())
{
int gg = g++;
lockq.lock();
q.add(() -> {
placeCaveObject(k, i, j, random
.nextParallelRNG((34 * ((i * 30) + (j * 30) + gg) * i * j) + i - j + 1869322));
q.add(() ->
{
placeCaveObject(k, i, j, random.nextParallelRNG((34 * ((i * 30) + (j * 30) + gg) * i * j) + i - j + 1869322));
});
lockq.unlock();
}
@ -340,7 +385,8 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
getAccelerant().waitFor(key);
lockq.lock();
for (NastyRunnable i : q) {
for(NastyRunnable i : q)
{
getAccelerant().queue(key + "-obj", i);
}
lockq.unlock();
@ -348,34 +394,39 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
getAccelerant().waitFor(key + "-obj");
}
public void placeObject(IrisObjectPlacement o, int x, int z, RNG rng) {
for (int i = 0; i < o.getTriesForChunk(rng); i++) {
public void placeObject(IrisObjectPlacement o, int x, int z, RNG rng)
{
for(int i = 0; i < o.getTriesForChunk(rng); i++)
{
rng = rng.nextParallelRNG((i * 3 + 8) - 23040);
o.getSchematic(this, rng).place((x * 16) + rng.nextInt(16), (z * 16) + rng.nextInt(16), this, o, rng);
}
}
public void placeCaveObject(IrisObjectPlacement o, int x, int z, RNG rng) {
for (int i = 0; i < o.getTriesForChunk(rng); i++) {
public void placeCaveObject(IrisObjectPlacement o, int x, int z, RNG rng)
{
for(int i = 0; i < o.getTriesForChunk(rng); i++)
{
rng = rng.nextParallelRNG((i * 3 + 8) - 23040);
int xx = (x * 16) + rng.nextInt(16);
int zz = (z * 16) + rng.nextInt(16);
KList<CaveResult> res = getCaves(xx, zz);
if (res.isEmpty()) {
if(res.isEmpty())
{
continue;
}
o.getSchematic(this, rng).place(xx,
res.get(rng.nextParallelRNG(29345 * (i + 234)).nextInt(res.size())).getFloor() + 2, zz, this, o,
rng);
o.getSchematic(this, rng).place(xx, res.get(rng.nextParallelRNG(29345 * (i + 234)).nextInt(res.size())).getFloor() + 2, zz, this, o, rng);
}
}
public AtomicSliver sampleSliver(int x, int z) {
public AtomicSliver sampleSliver(int x, int z)
{
ChunkPosition key = new ChunkPosition(x, z);
if (getSliverCache().containsKey(key)) {
if(getSliverCache().containsKey(key))
{
return getSliverCache().get(key);
}
@ -387,7 +438,8 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
}
@Override
public boolean isPreventingDecay() {
public boolean isPreventingDecay()
{
return getDimension().isPreventLeafDecay();
}
}

View File

@ -17,7 +17,8 @@ import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public abstract class ParallelChunkGenerator extends BiomeChunkGenerator {
public abstract class ParallelChunkGenerator extends BiomeChunkGenerator
{
private GroupedExecutor accelerant;
private int threads;
protected int cacheX;
@ -25,7 +26,8 @@ public abstract class ParallelChunkGenerator extends BiomeChunkGenerator {
private IrisLock genlock;
protected boolean cachingAllowed;
public ParallelChunkGenerator(String dimensionName, int threads) {
public ParallelChunkGenerator(String dimensionName, int threads)
{
super(dimensionName);
cacheX = 0;
cacheZ = 0;
@ -34,35 +36,37 @@ public abstract class ParallelChunkGenerator extends BiomeChunkGenerator {
cachingAllowed = false;
}
public void changeThreadCount(int tc) {
public void changeThreadCount(int tc)
{
threads = tc;
GroupedExecutor e = accelerant;
accelerant = new GroupedExecutor(threads, Thread.NORM_PRIORITY, "Iris Generator - " + world.getName());
Iris.executors.add(accelerant);
if (e != null) {
if(e != null)
{
e.close();
}
}
protected abstract void onGenerateColumn(int cx, int cz, int wx, int wz, int x, int z, AtomicSliver sliver,
BiomeMap biomeMap, boolean sampled);
protected abstract void onGenerateColumn(int cx, int cz, int wx, int wz, int x, int z, AtomicSliver sliver, BiomeMap biomeMap, boolean sampled);
protected void onGenerateColumn(int cx, int cz, int wx, int wz, int x, int z, AtomicSliver sliver,
BiomeMap biomeMap) {
protected void onGenerateColumn(int cx, int cz, int wx, int wz, int x, int z, AtomicSliver sliver, BiomeMap biomeMap)
{
onGenerateColumn(cx, cz, wx, wz, x, z, sliver, biomeMap, false);
}
protected abstract int onSampleColumnHeight(int cx, int cz, int wx, int wz, int x, int z);
protected abstract void onPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid, HeightMap height,
BiomeMap biomeMap);
protected abstract void onPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid, HeightMap height, BiomeMap biomeMap);
protected int sampleHeight(int x, int z) {
protected int sampleHeight(int x, int z)
{
return onSampleColumnHeight(x >> 4, z >> 4, x, z, x & 15, z & 15);
}
protected void onGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid) {
protected void onGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid)
{
genlock.lock();
cacheX = x;
cacheZ = z;
@ -74,16 +78,19 @@ public abstract class ParallelChunkGenerator extends BiomeChunkGenerator {
BiomeMap biomeMap = new BiomeMap();
int ii, jj;
for (ii = 0; ii < 16; ii++) {
for(ii = 0; ii < 16; ii++)
{
int i = ii;
int wx = (x * 16) + i;
for (jj = 0; jj < 16; jj++) {
for(jj = 0; jj < 16; jj++)
{
int j = jj;
int wz = (z * 16) + j;
AtomicSliver sliver = map.getSliver(i, j);
accelerant.queue(key, () -> {
accelerant.queue(key, () ->
{
onGenerateColumn(x, z, wx, wz, i, j, sliver, biomeMap);
});
}
@ -97,18 +104,21 @@ public abstract class ParallelChunkGenerator extends BiomeChunkGenerator {
genlock.unlock();
}
protected void onClose() {
protected void onClose()
{
accelerant.close();
Iris.executors.remove(accelerant);
}
public void onInit(World world, RNG rng) {
public void onInit(World world, RNG rng)
{
super.onInit(world, rng);
changeThreadCount(threads);
}
@Override
public boolean isParallelCapable() {
public boolean isParallelCapable()
{
return false;
}
}

View File

@ -2,6 +2,7 @@ package com.volmit.iris.gen;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.Bisected.Half;
import org.bukkit.block.data.BlockData;
@ -29,36 +30,42 @@ import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
{
private long lastUpdateRequest = M.ms();
private long lastChunkLoad = M.ms();
private GenLayerCave glCave;
private GenLayerCarve glCarve;
private RNG rockRandom;
public TerrainChunkGenerator(String dimensionName, int threads) {
public TerrainChunkGenerator(String dimensionName, int threads)
{
super(dimensionName, threads);
}
public void onInit(World world, RNG rng) {
public void onInit(World world, RNG rng)
{
super.onInit(world, rng);
rockRandom = getMasterRandom().nextParallelRNG(2858678);
glCave = new GenLayerCave(this, rng.nextParallelRNG(238948));
glCarve = new GenLayerCarve(this, rng.nextParallelRNG(968346576));
}
public KList<CaveResult> getCaves(int x, int z) {
public KList<CaveResult> getCaves(int x, int z)
{
return glCave.genCaves(x, z, x & 15, z & 15, null);
}
@Override
protected void onGenerateColumn(int cx, int cz, int rx, int rz, int x, int z, AtomicSliver sliver,
BiomeMap biomeMap, boolean sampled) {
if (x > 15 || x < 0 || z > 15 || z < 0) {
protected void onGenerateColumn(int cx, int cz, int rx, int rz, int x, int z, AtomicSliver sliver, BiomeMap biomeMap, boolean sampled)
{
if(x > 15 || x < 0 || z > 15 || z < 0)
{
throw new RuntimeException("Invalid OnGenerate call: x:" + x + " z:" + z);
}
try {
try
{
int highestPlaced = 0;
BlockData block;
@ -75,27 +82,29 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
BiomeResult biomeResult = sampleTrueBiome(rx, rz, noise);
IrisBiome biome = biomeResult.getBiome();
if (biome == null) {
if(biome == null)
{
throw new RuntimeException("Null Biome!");
}
KList<BlockData> layers = biome.generateLayers(rx, rz, masterRandom, height, height - getFluidHeight());
KList<BlockData> seaLayers = biome.isSea()
? biome.generateSeaLayers(rx, rz, masterRandom, fluidHeight - height)
: new KList<>();
KList<BlockData> seaLayers = biome.isSea() ? biome.generateSeaLayers(rx, rz, masterRandom, fluidHeight - height) : new KList<>();
boolean caverning = false;
KList<Integer> cavernHeights = new KList<>();
int lastCavernHeight = -1;
boolean bxx = false;
// From Height to Bedrock
for (int k = Math.max(height, fluidHeight); k >= 0; k--) {
for(int k = Math.max(height, fluidHeight); k >= 0; k--)
{
boolean cavernSurface = false;
// Bedrock
if (k == 0) {
if (biomeMap != null) {
if(k == 0)
{
if(biomeMap != null)
{
sliver.set(k, biome.getDerivative());
biomeMap.setBiome(x, z, biome);
}
sliver.set(k, BEDROCK);
@ -103,10 +112,11 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
}
// Carving
if (carvable && glCarve.isCarved(rx, k, rz)) {
if (biomeMap != null) {
if(carvable && glCarve.isCarved(rx, k, rz))
{
if(biomeMap != null)
{
sliver.set(k, biome.getDerivative());
biomeMap.setBiome(x, z, biome);
}
sliver.set(k, CAVE_AIR);
@ -114,7 +124,8 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
continue;
}
else if (carvable && caverning) {
else if(carvable && caverning)
{
lastCavernHeight = k;
cavernSurface = true;
cavernHeights.add(k);
@ -124,24 +135,35 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
boolean underwater = k > height && k <= fluidHeight;
// Set Biome
if (biomeMap != null) {
if(!bxx && biomeMap != null)
{
bxx = true;
sliver.set(k, biome.getGroundBiome(masterRandom, rz, k, rx));
biomeMap.setBiome(x, z, biome);
for(int kv = Math.max(height, fluidHeight); kv < Math.min(Math.max(height, fluidHeight) + 16, 255); kv++)
{
Biome skyBiome = biome.getSkyBiome(masterRandom, rz, kv, rx);
sliver.set(kv, biome.getDerivative());
sliver.set(k, skyBiome);
}
}
// Set Sea Material (water/lava)
if (underwater) {
block = seaLayers.hasIndex(fluidHeight - k) ? layers.get(depth)
: getDimension().getFluid(rockRandom, wx, k, wz);
if(underwater)
{
block = seaLayers.hasIndex(fluidHeight - k) ? layers.get(depth) : getDimension().getFluid(rockRandom, wx, k, wz);
}
// Set Surface Material for cavern layer surfaces
else if (layers.hasIndex(lastCavernHeight - k)) {
else if(layers.hasIndex(lastCavernHeight - k))
{
block = layers.get(lastCavernHeight - k);
}
// Set Surface Material for true surface
else {
else
{
block = layers.hasIndex(depth) ? layers.get(depth) : getDimension().getRock(rockRandom, wx, k, wz);
depth++;
}
@ -151,13 +173,14 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
highestPlaced = Math.max(highestPlaced, k);
// Decorate underwater surface
if (!cavernSurface && (k == height && block.getMaterial().isSolid() && k < fluidHeight)) {
if(!cavernSurface && (k == height && B.isSolid(block.getMaterial()) && k < fluidHeight))
{
decorateUnderwater(biome, sliver, wx, k, wz, rx, rz, block);
}
// Decorate Cavern surfaces, but not the true surface
if ((carvable && cavernSurface) && !(k == Math.max(height, fluidHeight) && block.getMaterial().isSolid()
&& k < 255 && k >= fluidHeight)) {
if((carvable && cavernSurface) && !(k == Math.max(height, fluidHeight) && block.getMaterial().isSolid() && k < 255 && k >= fluidHeight))
{
decorateLand(biome, sliver, wx, k, wz, rx, rz, block);
}
}
@ -167,31 +190,36 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
IrisBiome caveBiome = glBiome.generateData(InferredType.CAVE, wx, wz, rx, rz, region).getBiome();
// Decorate Cave Biome Height Sections
if (caveBiome != null) {
for (CaveResult i : caveResults) {
for (int j = i.getFloor(); j <= i.getCeiling(); j++) {
if(caveBiome != null)
{
for(CaveResult i : caveResults)
{
for(int j = i.getFloor(); j <= i.getCeiling(); j++)
{
sliver.set(j, caveBiome);
sliver.set(j, caveBiome.getGroundBiome(masterRandom, rz, j, rx));
}
KList<BlockData> floor = caveBiome.generateLayers(wx, wz, rockRandom, i.getFloor() - 2,
i.getFloor() - 2);
KList<BlockData> ceiling = caveBiome.generateLayers(wx + 256, wz + 256, rockRandom,
height - i.getCeiling() - 2, height - i.getCeiling() - 2);
KList<BlockData> floor = caveBiome.generateLayers(wx, wz, rockRandom, i.getFloor() - 2, i.getFloor() - 2);
KList<BlockData> ceiling = caveBiome.generateLayers(wx + 256, wz + 256, rockRandom, height - i.getCeiling() - 2, height - i.getCeiling() - 2);
BlockData blockc = null;
for (int j = 0; j < floor.size(); j++) {
if (j == 0) {
for(int j = 0; j < floor.size(); j++)
{
if(j == 0)
{
blockc = floor.get(j);
}
sliver.set(i.getFloor() - j, floor.get(j));
}
for (int j = ceiling.size() - 1; j > 0; j--) {
for(int j = ceiling.size() - 1; j > 0; j--)
{
sliver.set(i.getCeiling() + j, ceiling.get(j));
}
if (blockc != null && !sliver.isSolid(i.getFloor() + 1)) {
if(blockc != null && !sliver.isSolid(i.getFloor() + 1))
{
decorateCave(caveBiome, sliver, wx, i.getFloor(), wz, rx, rz, blockc);
}
}
@ -200,76 +228,91 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
block = sliver.get(Math.max(height, fluidHeight));
// Decorate True Surface
if (block.getMaterial().isSolid()) {
if(block.getMaterial().isSolid())
{
decorateLand(biome, sliver, wx, Math.max(height, fluidHeight), wz, rx, rz, block);
}
}
catch (Throwable e) {
catch(Throwable e)
{
fail(e);
}
}
@Override
protected void onGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid) {
protected void onGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid)
{
super.onGenerate(random, x, z, data, grid);
RNG ro = random.nextParallelRNG((x * x * x) - z);
IrisRegion region = sampleRegion((x * 16) + 7, (z * 16) + 7);
IrisBiome biome = sampleTrueBiome((x * 16) + 7, (z * 16) + 7).getBiome();
for (IrisDepositGenerator k : getDimension().getDeposits()) {
for(IrisDepositGenerator k : getDimension().getDeposits())
{
k.generate(data, ro, this);
}
for (IrisDepositGenerator k : region.getDeposits()) {
for (int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) {
for(IrisDepositGenerator k : region.getDeposits())
{
for(int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++)
{
k.generate(data, ro, this);
}
}
for (IrisDepositGenerator k : biome.getDeposits()) {
for (int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) {
for(IrisDepositGenerator k : biome.getDeposits())
{
for(int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++)
{
k.generate(data, ro, this);
}
}
}
private void decorateLand(IrisBiome biome, AtomicSliver sliver, double wx, int k, double wz, int rx, int rz,
BlockData block) {
if (!getDimension().isDecorate()) {
private void decorateLand(IrisBiome biome, AtomicSliver sliver, double wx, int k, double wz, int rx, int rz, BlockData block)
{
if(!getDimension().isDecorate())
{
return;
}
int j = 0;
for (IrisBiomeDecorator i : biome.getDecorators()) {
if (i.getPartOf().equals(DecorationPart.SHORE_LINE) && (!touchesSea(rx, rz) || k != getFluidHeight())) {
for(IrisBiomeDecorator i : biome.getDecorators())
{
if(i.getPartOf().equals(DecorationPart.SHORE_LINE) && (!touchesSea(rx, rz) || k != getFluidHeight()))
{
continue;
}
BlockData d = i.getBlockData(getMasterRandom()
.nextParallelRNG((int) (38888 + biome.getRarity() + biome.getName().length() + j++)), rx, rz);
BlockData d = i.getBlockData(getMasterRandom().nextParallelRNG((int) (38888 + biome.getRarity() + biome.getName().length() + j++)), rx, rz);
if (d != null) {
if (!B.canPlaceOnto(d.getMaterial(), block.getMaterial())) {
if(d != null)
{
if(!B.canPlaceOnto(d.getMaterial(), block.getMaterial()))
{
continue;
}
if (d.getMaterial().equals(Material.CACTUS)) {
if (!block.getMaterial().equals(Material.SAND) && !block.getMaterial().equals(Material.RED_SAND)) {
if(d.getMaterial().equals(Material.CACTUS))
{
if(!block.getMaterial().equals(Material.SAND) && !block.getMaterial().equals(Material.RED_SAND))
{
sliver.set(k, B.getBlockData("RED_SAND"));
}
}
if (d.getMaterial().equals(Material.WHEAT) || d.getMaterial().equals(Material.CARROTS)
|| d.getMaterial().equals(Material.POTATOES) || d.getMaterial().equals(Material.MELON_STEM)
|| d.getMaterial().equals(Material.PUMPKIN_STEM)) {
if (!block.getMaterial().equals(Material.FARMLAND)) {
if(d.getMaterial().equals(Material.WHEAT) || d.getMaterial().equals(Material.CARROTS) || d.getMaterial().equals(Material.POTATOES) || d.getMaterial().equals(Material.MELON_STEM) || d.getMaterial().equals(Material.PUMPKIN_STEM))
{
if(!block.getMaterial().equals(Material.FARMLAND))
{
sliver.set(k, B.getBlockData("FARMLAND"));
}
}
if (d instanceof Bisected && k < 254) {
if(d instanceof Bisected && k < 254)
{
Bisected t = ((Bisected) d.clone());
t.setHalf(Half.TOP);
Bisected b = ((Bisected) d.clone());
@ -278,17 +321,19 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
sliver.set(k + 2, t);
}
else {
int stack = i.getHeight(getMasterRandom().nextParallelRNG(
(int) (39456 + (10000 * i.getChance()) + i.getStackMax() + i.getStackMin() + i.getZoom())),
rx, rz);
else
{
int stack = i.getHeight(getMasterRandom().nextParallelRNG((int) (39456 + (10000 * i.getChance()) + i.getStackMax() + i.getStackMin() + i.getZoom())), rx, rz);
if (stack == 1) {
if(stack == 1)
{
sliver.set(k + 1, d);
}
else if (k < 255 - stack) {
for (int l = 0; l < stack; l++) {
else if(k < 255 - stack)
{
for(int l = 0; l < stack; l++)
{
sliver.set(k + l + 1, d);
}
}
@ -299,31 +344,36 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
}
}
private void decorateCave(IrisBiome biome, AtomicSliver sliver, double wx, int k, double wz, int rx, int rz,
BlockData block) {
if (!getDimension().isDecorate()) {
private void decorateCave(IrisBiome biome, AtomicSliver sliver, double wx, int k, double wz, int rx, int rz, BlockData block)
{
if(!getDimension().isDecorate())
{
return;
}
int j = 0;
for (IrisBiomeDecorator i : biome.getDecorators()) {
BlockData d = i.getBlockData(
getMasterRandom().nextParallelRNG(2333877 + biome.getRarity() + biome.getName().length() + +j++),
rx, rz);
for(IrisBiomeDecorator i : biome.getDecorators())
{
BlockData d = i.getBlockData(getMasterRandom().nextParallelRNG(2333877 + biome.getRarity() + biome.getName().length() + +j++), rx, rz);
if (d != null) {
if (!B.canPlaceOnto(d.getMaterial(), block.getMaterial())) {
if(d != null)
{
if(!B.canPlaceOnto(d.getMaterial(), block.getMaterial()))
{
continue;
}
if (d.getMaterial().equals(Material.CACTUS)) {
if (!block.getMaterial().equals(Material.SAND) && !block.getMaterial().equals(Material.RED_SAND)) {
if(d.getMaterial().equals(Material.CACTUS))
{
if(!block.getMaterial().equals(Material.SAND) && !block.getMaterial().equals(Material.RED_SAND))
{
sliver.set(k, B.getBlockData("SAND"));
}
}
if (d instanceof Bisected && k < 254) {
if(d instanceof Bisected && k < 254)
{
Bisected t = ((Bisected) d.clone());
t.setHalf(Half.TOP);
Bisected b = ((Bisected) d.clone());
@ -332,17 +382,21 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
sliver.set(k + 2, t);
}
else {
int stack = i.getHeight(getMasterRandom()
.nextParallelRNG((int) (39456 + (1000 * i.getChance()) + i.getZoom() * 10)), rx, rz);
else
{
int stack = i.getHeight(getMasterRandom().nextParallelRNG((int) (39456 + (1000 * i.getChance()) + i.getZoom() * 10)), rx, rz);
if (stack == 1) {
if(stack == 1)
{
sliver.set(k + 1, d);
}
else if (k < 255 - stack) {
for (int l = 0; l < stack; l++) {
if (sliver.isSolid(k + l + 1)) {
else if(k < 255 - stack)
{
for(int l = 0; l < stack; l++)
{
if(sliver.isSolid(k + l + 1))
{
break;
}
@ -356,35 +410,38 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
}
}
private void decorateUnderwater(IrisBiome biome, AtomicSliver sliver, double wx, int y, double wz, int rx, int rz,
BlockData block) {
if (!getDimension().isDecorate()) {
private void decorateUnderwater(IrisBiome biome, AtomicSliver sliver, double wx, int y, double wz, int rx, int rz, BlockData block)
{
if(!getDimension().isDecorate())
{
return;
}
int j = 0;
for (IrisBiomeDecorator i : biome.getDecorators()) {
if (biome.getInferredType().equals(InferredType.SHORE)) {
for(IrisBiomeDecorator i : biome.getDecorators())
{
if(biome.getInferredType().equals(InferredType.SHORE))
{
continue;
}
BlockData d = i.getBlockData(
getMasterRandom().nextParallelRNG(2555 + biome.getRarity() + biome.getName().length() + j++), rx,
rz);
BlockData d = i.getBlockData(getMasterRandom().nextParallelRNG(2555 + biome.getRarity() + biome.getName().length() + j++), rx, rz);
if (d != null) {
int stack = i.getHeight(getMasterRandom().nextParallelRNG((int) (239456 + i.getStackMax()
+ i.getStackMin() + i.getVerticalZoom() + i.getZoom() + i.getBlockData().size() + j)), rx, rz);
if(d != null)
{
int stack = i.getHeight(getMasterRandom().nextParallelRNG((int) (239456 + i.getStackMax() + i.getStackMin() + i.getVerticalZoom() + i.getZoom() + i.getBlockData().size() + j)), rx, rz);
if (stack == 1) {
if(stack == 1)
{
sliver.set(i.getPartOf().equals(DecorationPart.SEA_SURFACE) ? (getFluidHeight() + 1) : (y + 1), d);
}
else if (y < getFluidHeight() - stack) {
for (int l = 0; l < stack; l++) {
sliver.set(i.getPartOf().equals(DecorationPart.SEA_SURFACE) ? (getFluidHeight() + 1 + l)
: (y + l + 1), d);
else if(y < getFluidHeight() - stack)
{
for(int l = 0; l < stack; l++)
{
sliver.set(i.getPartOf().equals(DecorationPart.SEA_SURFACE) ? (getFluidHeight() + 1 + l) : (y + l + 1), d);
}
}
@ -394,22 +451,23 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
}
@Override
protected void onPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid, HeightMap height,
BiomeMap biomeMap) {
protected void onPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid, HeightMap height, BiomeMap biomeMap)
{
onPreParallaxPostGenerate(random, x, z, data, grid, height, biomeMap);
}
protected void onPreParallaxPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid, HeightMap height,
BiomeMap biomeMap) {
protected void onPreParallaxPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid, HeightMap height, BiomeMap biomeMap)
{
}
protected void onPostParallaxPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid,
HeightMap height, BiomeMap biomeMap) {
protected void onPostParallaxPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid, HeightMap height, BiomeMap biomeMap)
{
}
private double getNoiseHeight(int rx, int rz) {
private double getNoiseHeight(int rx, int rz)
{
double wx = getZoomed(rx);
double wz = getZoomed(rz);
double h = getBiomeHeight(wx, wz, rx, rz);
@ -417,8 +475,10 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
return h;
}
public BiomeResult sampleTrueBiomeBase(int x, int z, int height) {
if (!getDimension().getFocus().equals("")) {
public BiomeResult sampleTrueBiomeBase(int x, int z, int height)
{
if(!getDimension().getFocus().equals(""))
{
return focus();
}
@ -428,42 +488,51 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
double sh = region.getShoreHeight(wx, wz);
IrisBiome current = sampleBiome(x, z).getBiome();
if (current.isShore() && height > sh) {
if(current.isShore() && height > sh)
{
return glBiome.generateData(InferredType.LAND, wx, wz, x, z, region);
}
if (current.isShore() || current.isLand() && height <= getDimension().getFluidHeight()) {
if(current.isShore() || current.isLand() && height <= getDimension().getFluidHeight())
{
return glBiome.generateData(InferredType.SEA, wx, wz, x, z, region);
}
if (current.isSea() && height > getDimension().getFluidHeight()) {
if(current.isSea() && height > getDimension().getFluidHeight())
{
return glBiome.generateData(InferredType.LAND, wx, wz, x, z, region);
}
if (height <= getDimension().getFluidHeight()) {
if(height <= getDimension().getFluidHeight())
{
return glBiome.generateData(InferredType.SEA, wx, wz, x, z, region);
}
if (height <= getDimension().getFluidHeight() + sh) {
if(height <= getDimension().getFluidHeight() + sh)
{
return glBiome.generateData(InferredType.SHORE, wx, wz, x, z, region);
}
return glBiome.generateRegionData(wx, wz, x, z, region);
}
public BiomeResult sampleCaveBiome(int x, int z) {
public BiomeResult sampleCaveBiome(int x, int z)
{
double wx = getModifiedX(x, z);
double wz = getModifiedZ(x, z);
return glBiome.generateData(InferredType.CAVE, wx, wz, x, z, sampleRegion(x, z));
}
public BiomeResult sampleTrueBiome(int x, int y, int z) {
if (y < getTerrainHeight(x, z)) {
public BiomeResult sampleTrueBiome(int x, int y, int z)
{
if(y < getTerrainHeight(x, z))
{
double wx = getModifiedX(x, z);
double wz = getModifiedZ(x, z);
BiomeResult r = glBiome.generateData(InferredType.CAVE, wx, wz, x, z, sampleRegion(x, z));
if (r.getBiome() != null) {
if(r.getBiome() != null)
{
return r;
}
}
@ -471,21 +540,26 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
return sampleTrueBiome(x, z);
}
public BiomeResult sampleTrueBiome(int x, int z) {
public BiomeResult sampleTrueBiome(int x, int z)
{
return sampleTrueBiome(x, z, getTerrainHeight(x, z));
}
@Override
public IrisRegion sampleRegion(int x, int z) {
public IrisRegion sampleRegion(int x, int z)
{
return getCache().getRegion(x, z, () -> super.sampleRegion(x, z));
}
public BiomeResult sampleTrueBiome(int x, int z, double noise) {
if (!getDimension().getFocus().equals("")) {
public BiomeResult sampleTrueBiome(int x, int z, double noise)
{
if(!getDimension().getFocus().equals(""))
{
return focus();
}
return getCache().getBiome(x, z, () -> {
return getCache().getBiome(x, z, () ->
{
double wx = getModifiedX(x, z);
double wz = getModifiedZ(x, z);
IrisRegion region = sampleRegion(x, z);
@ -494,7 +568,8 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
BiomeResult res = sampleTrueBiomeBase(x, z, height);
IrisBiome current = res.getBiome();
if (current.isSea() && height > getDimension().getFluidHeight() - sh) {
if(current.isSea() && height > getDimension().getFluidHeight() - sh)
{
return glBiome.generateData(InferredType.SHORE, wx, wz, x, z, region);
}
@ -503,32 +578,38 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator {
}
@Override
protected int onSampleColumnHeight(int cx, int cz, int rx, int rz, int x, int z) {
protected int onSampleColumnHeight(int cx, int cz, int rx, int rz, int x, int z)
{
return (int) Math.round(getTerrainHeight(rx, rz));
}
private boolean touchesSea(int rx, int rz) {
return isFluidAtHeight(rx + 1, rz) || isFluidAtHeight(rx - 1, rz) || isFluidAtHeight(rx, rz - 1)
|| isFluidAtHeight(rx, rz + 1);
private boolean touchesSea(int rx, int rz)
{
return isFluidAtHeight(rx + 1, rz) || isFluidAtHeight(rx - 1, rz) || isFluidAtHeight(rx, rz - 1) || isFluidAtHeight(rx, rz + 1);
}
public boolean isUnderwater(int x, int z) {
public boolean isUnderwater(int x, int z)
{
return isFluidAtHeight(x, z);
}
public boolean isFluidAtHeight(int x, int z) {
public boolean isFluidAtHeight(int x, int z)
{
return Math.round(getTerrainHeight(x, z)) < getFluidHeight();
}
public int getFluidHeight() {
public int getFluidHeight()
{
return getDimension().getFluidHeight();
}
public double getTerrainHeight(int x, int z) {
public double getTerrainHeight(int x, int z)
{
return getCache().getHeight(x, z, () -> getNoiseHeight(x, z) + getFluidHeight());
}
public double getTerrainWaterHeight(int x, int z) {
public double getTerrainWaterHeight(int x, int z)
{
return Math.max(getTerrainHeight(x, z), getFluidHeight());
}
}

View File

@ -3,11 +3,13 @@ package com.volmit.iris.gen.atomics;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import com.volmit.iris.IrisSettings;
import com.volmit.iris.object.IrisRegion;
import com.volmit.iris.util.BiomeResult;
import com.volmit.iris.util.KMap;
public class AtomicMulticache {
public class AtomicMulticache
{
private final AtomicInteger x;
private final AtomicInteger z;
private final KMap<Long, Double> height;
@ -18,7 +20,8 @@ public class AtomicMulticache {
private int w = 0;
private int m = 0;
public AtomicMulticache() {
public AtomicMulticache()
{
x = new AtomicInteger(0);
z = new AtomicInteger(0);
height = new KMap<Long, Double>();
@ -27,83 +30,108 @@ public class AtomicMulticache {
region = new KMap<Long, IrisRegion>();
}
public void targetChunk(int x, int z) {
public void targetChunk(int x, int z)
{
this.x.set(x);
this.z.set(z);
r = 0;
w = 0;
m = 0;
if(!IrisSettings.get().sharedCaching || getSize() > 42000)
{
drop();
}
}
public double getHeight(int x, int z, Supplier<Double> g)
{
return height.compute(pos(x, z), (k, v) ->
{
if(v == null)
{
m++;
w++;
return g.get();
}
r++;
return v;
});
}
public IrisRegion getRegion(int x, int z, Supplier<IrisRegion> g)
{
return region.compute(pos(x, z), (k, v) ->
{
if(v == null)
{
m++;
w++;
return g.get();
}
r++;
return v;
});
}
public BiomeResult getBiome(int x, int z, Supplier<BiomeResult> g)
{
return biome.compute(pos(x, z), (k, v) ->
{
if(v == null)
{
m++;
w++;
return g.get();
}
r++;
return v;
});
}
public BiomeResult getRawBiome(int x, int z, Supplier<BiomeResult> g)
{
return rawBiome.compute(pos(x, z), (k, v) ->
{
if(v == null)
{
m++;
w++;
return g.get();
}
r++;
return v;
});
}
private long pos(int x, int z)
{
return (((long) x) << 32) | (z & 0xffffffffL);
}
public void updateHeight(int x, int z, int h)
{
height.put(pos(x, z), (double) h);
}
public double getSize()
{
return height.size() + region.size() + biome.size() + rawBiome.size();
}
public void drop()
{
height.clear();
region.clear();
biome.clear();
rawBiome.clear();
r = 0;
w = 0;
m = 0;
}
public double getHeight(int x, int z, Supplier<Double> g) {
return height.compute(pos(x, z), (k, v) -> {
if (v == null) {
m++;
w++;
return g.get();
}
r++;
return v;
});
}
public IrisRegion getRegion(int x, int z, Supplier<IrisRegion> g) {
return region.compute(pos(x, z), (k, v) -> {
if (v == null) {
m++;
w++;
return g.get();
}
r++;
return v;
});
}
public BiomeResult getBiome(int x, int z, Supplier<BiomeResult> g) {
return biome.compute(pos(x, z), (k, v) -> {
if (v == null) {
m++;
w++;
return g.get();
}
r++;
return v;
});
}
public BiomeResult getRawBiome(int x, int z, Supplier<BiomeResult> g) {
return rawBiome.compute(pos(x, z), (k, v) -> {
if (v == null) {
m++;
w++;
return g.get();
}
r++;
return v;
});
}
private long pos(int x, int z) {
return (((long) x) << 32) | (z & 0xffffffffL);
}
public void updateHeight(int x, int z, int h) {
height.put(pos(x, z), (double) h);
}
public double getSize() {
return height.size();
}
}

View File

@ -1,6 +1,7 @@
package com.volmit.iris.gen.layer;
import com.volmit.iris.Iris;
import com.volmit.iris.IrisSettings;
import com.volmit.iris.gen.DimensionChunkGenerator;
import com.volmit.iris.noise.CNG;
import com.volmit.iris.object.InferredType;
@ -144,7 +145,7 @@ public class GenLayerBiome extends GenLayer {
public BiomeResult implode(double bx, double bz, IrisRegion regionData, CNG parentCell, BiomeResult parent,
int hits) {
if (hits > 9) {
if (hits > IrisSettings.get().maxBiomeChildDepth) {
return parent;
}

View File

@ -17,6 +17,7 @@ import com.volmit.iris.util.KSet;
import com.volmit.iris.util.MaxNumber;
import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.RNG;
import com.volmit.iris.util.RegistryListBiome;
import com.volmit.iris.util.Required;
import lombok.Data;
@ -85,6 +86,7 @@ public class IrisBiome extends IrisRegistrant implements IRare
@Desc("If this biome has children biomes, and the gen layer chooses one of this biomes children, How will it be shaped?")
private IrisGeneratorStyle childStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@RegistryListBiome
@ArrayType(min = 1, type = String.class)
@DontObfuscate
@Desc("List any biome names (file names without.json) here as children. Portions of this biome can sometimes morph into their children. Iris supports cyclic relationships such as A > B > A > B. Iris will stop checking 9 biomes down the tree.")

View File

@ -9,18 +9,21 @@ import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.IrisInterpolation;
import com.volmit.iris.util.MaxNumber;
import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.RegistryListGenerator;
import com.volmit.iris.util.Required;
import lombok.Data;
@Desc("This represents a link to a generator for a biome")
@Data
public class IrisBiomeGeneratorLink {
public class IrisBiomeGeneratorLink
{
@RegistryListGenerator
@DontObfuscate
@Desc("The generator id")
private String generator = "default";
@DependsOn({ "min", "max" })
@DependsOn({"min", "max"})
@Required
@MinNumber(-256)
@MaxNumber(256)
@ -28,7 +31,7 @@ public class IrisBiomeGeneratorLink {
@Desc("The min block value (value + fluidHeight)")
private int min = 0;
@DependsOn({ "min", "max" })
@DependsOn({"min", "max"})
@Required
@MinNumber(-256)
@MaxNumber(256)
@ -38,16 +41,19 @@ public class IrisBiomeGeneratorLink {
private transient AtomicCache<IrisGenerator> gen = new AtomicCache<>();
public IrisBiomeGeneratorLink() {
public IrisBiomeGeneratorLink()
{
}
public IrisGenerator getCachedGenerator(ContextualChunkGenerator g) {
return gen.aquire(() -> {
IrisGenerator gen = g != null ? g.loadGenerator(getGenerator())
: Iris.globaldata.getGeneratorLoader().load(getGenerator());
public IrisGenerator getCachedGenerator(ContextualChunkGenerator g)
{
return gen.aquire(() ->
{
IrisGenerator gen = g != null ? g.loadGenerator(getGenerator()) : Iris.globaldata.getGeneratorLoader().load(getGenerator());
if (gen == null) {
if(gen == null)
{
gen = new IrisGenerator();
}
@ -55,7 +61,8 @@ public class IrisBiomeGeneratorLink {
});
}
public double getHeight(ContextualChunkGenerator xg, double x, double z, long seed) {
public double getHeight(ContextualChunkGenerator xg, double x, double z, long seed)
{
double g = getCachedGenerator(xg).getHeight(x, z, seed);
g = g < 0 ? 0 : g;
g = g > 1 ? 1 : g;

View File

@ -9,6 +9,8 @@ import com.volmit.iris.util.KList;
import com.volmit.iris.util.KSet;
import com.volmit.iris.util.MaxNumber;
import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.RegistryListBiome;
import com.volmit.iris.util.RegistryListObject;
import com.volmit.iris.util.Required;
import lombok.Data;
@ -17,12 +19,14 @@ import lombok.Data;
@Data
public class IrisBiomeMutation
{
@RegistryListBiome
@Required
@ArrayType(min = 1, type = String.class)
@DontObfuscate
@Desc("One of The following biomes or regions must show up")
private KList<String> sideA = new KList<>();
@RegistryListBiome
@Required
@ArrayType(min = 1, type = String.class)
@DontObfuscate
@ -43,6 +47,7 @@ public class IrisBiomeMutation
@Desc("How many tries per chunk to check for this mutation")
private int checks = 2;
@RegistryListObject
@ArrayType(min = 1, type = IrisObjectPlacement.class)
@DontObfuscate
@Desc("Objects define what schematics (iob files) iris will place in this biome mutation")

View File

@ -21,6 +21,9 @@ import com.volmit.iris.util.KSet;
import com.volmit.iris.util.MaxNumber;
import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.RNG;
import com.volmit.iris.util.RegistryListBiome;
import com.volmit.iris.util.RegistryListDimension;
import com.volmit.iris.util.RegistryListRegion;
import com.volmit.iris.util.Required;
import lombok.Data;
@ -160,6 +163,7 @@ public class IrisDimension extends IrisRegistrant
@Desc("Compatability filters")
private KList<IrisCompatabilityFilter> compatability = getDefaultCompatability();
@RegistryListDimension
@DontObfuscate
@Desc("The ceiling dimension. Leave blank for normal sky.")
private String ceiling = "";
@ -173,6 +177,7 @@ public class IrisDimension extends IrisRegistrant
@Desc("The world environment")
private Environment environment = Environment.NORMAL;
@RegistryListRegion
@Required
@ArrayType(min = 1, type = String.class)
@DontObfuscate
@ -186,6 +191,7 @@ public class IrisDimension extends IrisRegistrant
@Desc("The fluid height for this dimension")
private int fluidHeight = 63;
@RegistryListBiome
@DontObfuscate
@Desc("Keep this either undefined or empty. Setting any biome name into this will force iris to only generate the specified biome. Great for testing.")
private String focus = "";

View File

@ -12,6 +12,7 @@ import java.io.OutputStream;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Waterlogged;
import org.bukkit.block.data.type.Leaves;
import org.bukkit.util.BlockVector;
@ -26,21 +27,19 @@ import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class IrisObject extends IrisRegistrant {
public class IrisObject extends IrisRegistrant
{
private static final Material SNOW = Material.SNOW;
private static final BlockData AIR = B.getBlockData("CAVE_AIR");
private static final BlockData[] SNOW_LAYERS = new BlockData[] { B.getBlockData("minecraft:snow[layers=1]"),
B.getBlockData("minecraft:snow[layers=2]"), B.getBlockData("minecraft:snow[layers=3]"),
B.getBlockData("minecraft:snow[layers=4]"), B.getBlockData("minecraft:snow[layers=5]"),
B.getBlockData("minecraft:snow[layers=6]"), B.getBlockData("minecraft:snow[layers=7]"),
B.getBlockData("minecraft:snow[layers=8]") };
private static final BlockData[] SNOW_LAYERS = new BlockData[] {B.getBlockData("minecraft:snow[layers=1]"), B.getBlockData("minecraft:snow[layers=2]"), B.getBlockData("minecraft:snow[layers=3]"), B.getBlockData("minecraft:snow[layers=4]"), B.getBlockData("minecraft:snow[layers=5]"), B.getBlockData("minecraft:snow[layers=6]"), B.getBlockData("minecraft:snow[layers=7]"), B.getBlockData("minecraft:snow[layers=8]")};
private KMap<BlockVector, BlockData> blocks;
private int w;
private int d;
private int h;
private transient BlockVector center;
public IrisObject(int w, int h, int d) {
public IrisObject(int w, int h, int d)
{
blocks = new KMap<>();
this.w = w;
this.h = h;
@ -48,7 +47,8 @@ public class IrisObject extends IrisRegistrant {
center = new BlockVector(w / 2, h / 2, d / 2);
}
public static BlockVector sampleSize(File file) throws IOException {
public static BlockVector sampleSize(File file) throws IOException
{
FileInputStream in = new FileInputStream(file);
DataInputStream din = new DataInputStream(in);
BlockVector bv = new BlockVector(din.readInt(), din.readInt(), din.readInt());
@ -56,7 +56,8 @@ public class IrisObject extends IrisRegistrant {
return bv;
}
public void read(InputStream in) throws IOException {
public void read(InputStream in) throws IOException
{
DataInputStream din = new DataInputStream(in);
this.w = din.readInt();
this.h = din.readInt();
@ -64,32 +65,36 @@ public class IrisObject extends IrisRegistrant {
center = new BlockVector(w / 2, h / 2, d / 2);
int s = din.readInt();
for (int i = 0; i < s; i++) {
blocks.put(new BlockVector(din.readShort(), din.readShort(), din.readShort()),
B.getBlockData(din.readUTF()));
for(int i = 0; i < s; i++)
{
blocks.put(new BlockVector(din.readShort(), din.readShort(), din.readShort()), B.getBlockData(din.readUTF()));
}
}
public void read(File file) throws IOException {
public void read(File file) throws IOException
{
FileInputStream fin = new FileInputStream(file);
read(fin);
fin.close();
}
public void write(File file) throws IOException {
public void write(File file) throws IOException
{
file.getParentFile().mkdirs();
FileOutputStream out = new FileOutputStream(file);
write(out);
out.close();
}
public void write(OutputStream o) throws IOException {
public void write(OutputStream o) throws IOException
{
DataOutputStream dos = new DataOutputStream(o);
dos.writeInt(w);
dos.writeInt(h);
dos.writeInt(d);
dos.writeInt(blocks.size());
for (BlockVector i : blocks.k()) {
for(BlockVector i : blocks.k())
{
dos.writeShort(i.getBlockX());
dos.writeShort(i.getBlockY());
dos.writeShort(i.getBlockZ());
@ -97,68 +102,102 @@ public class IrisObject extends IrisRegistrant {
}
}
public void setUnsigned(int x, int y, int z, BlockData block) {
if (x >= w || y >= h || z >= d) {
public void setUnsigned(int x, int y, int z, BlockData block)
{
if(x >= w || y >= h || z >= d)
{
throw new RuntimeException(x + " " + y + " " + z + " exceeds limit of " + w + " " + h + " " + d);
}
BlockVector v = new BlockVector(x, y, z).subtract(center).toBlockVector();
if (block == null) {
if(block == null)
{
blocks.remove(v);
}
else {
else
{
blocks.put(v, block);
}
}
public void place(int x, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng) {
public void place(int x, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng)
{
place(x, -1, z, placer, config, rng);
}
public void place(int x, int yv, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng) {
public void place(int x, int yv, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng)
{
int spinx = rng.imax() / 1000;
int spiny = rng.imax() / 1000;
int spinz = rng.imax() / 1000;
int y = yv < 0 ? placer.getHighest(x, z, config.isUnderwater()) + config.getRotation()
.rotate(new BlockVector(0, getCenter().getBlockY(), 0), spinx, spiny, spinz).getBlockY() : yv;
int rty = config.getRotation().rotate(new BlockVector(0, getCenter().getBlockY(), 0), spinx, spiny, spinz).getBlockY();
int ty = config.getTranslate().translate(new BlockVector(0, getCenter().getBlockY(), 0), config.getRotation(), spinx, spiny, spinz).getBlockY();
int y = yv < 0 ? placer.getHighest(x, z, config.isUnderwater()) + rty : yv;
if (yv >= 0 && config.isBottom()) {
if(yv >= 0 && config.isBottom())
{
y += Math.floorDiv(h, 2);
}
KMap<ChunkPosition, Integer> heightmap = config.getSnow() > 0 ? new KMap<>() : null;
if (yv < 0) {
if (!config.isUnderwater() && !config.isOnwater() && placer.isUnderwater(x, z)) {
if(yv < 0)
{
if(!config.isUnderwater() && !config.isOnwater() && placer.isUnderwater(x, z))
{
return;
}
}
if (config.isBore()) {
for (int i = x - Math.floorDiv(w, 2); i <= x + Math.floorDiv(w, 2) - (w % 2 == 0 ? 1 : 0); i++) {
for (int j = y - Math.floorDiv(h, 2); j <= y + Math.floorDiv(h, 2) - (h % 2 == 0 ? 1 : 0); j++) {
for (int k = z - Math.floorDiv(d, 2); k <= z + Math.floorDiv(d, 2) - (d % 2 == 0 ? 1 : 0); k++) {
if(config.isUnderwater() && y + rty + ty >= placer.getFluidHeight())
{
return;
}
if(!config.getClamp().canPlace(y + rty + ty, y - rty + ty))
{
return;
}
if(config.isBore())
{
for(int i = x - Math.floorDiv(w, 2); i <= x + Math.floorDiv(w, 2) - (w % 2 == 0 ? 1 : 0); i++)
{
for(int j = y - Math.floorDiv(h, 2); j <= y + Math.floorDiv(h, 2) - (h % 2 == 0 ? 1 : 0); j++)
{
for(int k = z - Math.floorDiv(d, 2); k <= z + Math.floorDiv(d, 2) - (d % 2 == 0 ? 1 : 0); k++)
{
placer.set(i, j, k, AIR);
}
}
}
}
for (BlockVector g : blocks.keySet()) {
for(BlockVector g : blocks.keySet())
{
BlockVector i = g.clone();
i = config.getRotation().rotate(i.clone(), spinx, spiny, spinz).clone();
i = config.getTranslate().translate(i.clone(), config.getRotation(), spinx, spiny, spinz).clone();
BlockData data = blocks.get(g).clone();
if (placer.isPreventingDecay() && data instanceof Leaves && !((Leaves) data).isPersistent()) {
if(placer.isPreventingDecay() && data instanceof Leaves && !((Leaves) data).isPersistent())
{
((Leaves) data).setPersistent(true);
}
for (IrisObjectReplace j : config.getEdit()) {
if (j.isExact() ? j.getFind().matches(data) : j.getFind().getMaterial().equals(data.getMaterial())) {
data = j.getReplace();
for(IrisObjectReplace j : config.getEdit())
{
if(j.isExact())
{
for(BlockData k : j.getFind())
{
if(j.isExact() ? k.matches(data) : k.getMaterial().equals(data.getMaterial()))
{
data = j.getReplace(rng, i.getX() + x, i.getY() + y, i.getZ() + z).clone();
}
}
}
}
@ -167,36 +206,49 @@ public class IrisObject extends IrisRegistrant {
int yy = y + (int) Math.round(i.getY());
int zz = z + (int) Math.round(i.getZ());
if (heightmap != null) {
if(heightmap != null)
{
ChunkPosition pos = new ChunkPosition(xx, zz);
if (!heightmap.containsKey(pos)) {
if(!heightmap.containsKey(pos))
{
heightmap.put(pos, yy);
}
if (heightmap.get(pos) < yy) {
if(heightmap.get(pos) < yy)
{
heightmap.put(pos, yy);
}
}
if (config.isMeld() && !placer.isSolid(xx, yy, zz)) {
if(config.isMeld() && !placer.isSolid(xx, yy, zz))
{
continue;
}
if(yy <= placer.getFluidHeight() && data instanceof Waterlogged)
{
((Waterlogged) data).setWaterlogged(true);
}
placer.set(xx, yy, zz, data);
}
if (heightmap != null) {
if(heightmap != null)
{
RNG rngx = rng.nextParallelRNG(3468854);
for (ChunkPosition i : heightmap.k()) {
for(ChunkPosition i : heightmap.k())
{
int vx = i.getX();
int vy = heightmap.get(i);
int vz = i.getZ();
if (config.getSnow() > 0) {
if(config.getSnow() > 0)
{
BlockData bd = placer.get(vx, vy, vz);
if (bd != null && bd.getMaterial().equals(SNOW)) {
if(bd != null && bd.getMaterial().equals(SNOW))
{
continue;
}
@ -207,8 +259,10 @@ public class IrisObject extends IrisRegistrant {
}
}
public void place(Location at) {
for (BlockVector i : blocks.keySet()) {
public void place(Location at)
{
for(BlockVector i : blocks.keySet())
{
at.clone().add(0, getCenter().getY(), 0).add(i).getBlock().setBlockData(blocks.get(i), false);
}
}

View File

@ -0,0 +1,40 @@
package com.volmit.iris.object;
import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.MaxNumber;
import com.volmit.iris.util.MinNumber;
import lombok.Data;
@Desc("Translate objects")
@Data
public class IrisObjectLimit
{
@MinNumber(0)
@MaxNumber(255)
@DontObfuscate
@Desc("The minimum height for placement (bottom of object)")
private int minimumHeight = 0;
@MinNumber(0)
@MaxNumber(255)
@DontObfuscate
@Desc("The maximum height for placement (top of object)")
private int maximumHeight = 255;
public IrisObjectLimit()
{
}
public boolean canPlace(int h, int l)
{
if(h > maximumHeight || l < minimumHeight)
{
return false;
}
return true;
}
}

View File

@ -9,6 +9,7 @@ import com.volmit.iris.util.KList;
import com.volmit.iris.util.MaxNumber;
import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.RNG;
import com.volmit.iris.util.RegistryListObject;
import com.volmit.iris.util.Required;
import lombok.Data;
@ -17,6 +18,7 @@ import lombok.Data;
@Data
public class IrisObjectPlacement
{
@RegistryListObject
@Required
@ArrayType(min = 1, type = String.class)
@DontObfuscate
@ -36,6 +38,10 @@ public class IrisObjectPlacement
@Desc("Rotate this objects placement")
private IrisObjectRotation rotation = new IrisObjectRotation();
@DontObfuscate
@Desc("Limit the max height or min height of placement.")
private IrisObjectLimit clamp = new IrisObjectLimit();
@MinNumber(0)
@MaxNumber(1)
@DontObfuscate

View File

@ -3,9 +3,13 @@ package com.volmit.iris.object;
import org.bukkit.block.data.BlockData;
import com.volmit.iris.gen.atomics.AtomicCache;
import com.volmit.iris.noise.CNG;
import com.volmit.iris.util.ArrayType;
import com.volmit.iris.util.B;
import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.RNG;
import com.volmit.iris.util.Required;
import lombok.Data;
@ -14,35 +18,43 @@ import lombok.Data;
@Data
public class IrisObjectReplace
{
@ArrayType(min = 1, type = String.class)
@Required
@Desc("Find this block")
@DontObfuscate
private String find;
private KList<String> find;
@ArrayType(min = 1, type = String.class)
@Required
@Desc("Replace it with this block")
@DontObfuscate
private String replace;
private KList<String> replace;
@Desc("Exactly match the block data or not")
@DontObfuscate
private boolean exact = false;
private transient AtomicCache<BlockData> findData = new AtomicCache<>();
private transient AtomicCache<BlockData> replaceData = new AtomicCache<>();
private transient AtomicCache<CNG> replaceGen = new AtomicCache<>();
private transient AtomicCache<KList<BlockData>> findData = new AtomicCache<>();
private transient AtomicCache<KList<BlockData>> replaceData = new AtomicCache<>();
public IrisObjectReplace()
{
}
public BlockData getFind()
public KList<BlockData> getFind()
{
return findData.aquire(() -> B.getBlockData(find));
}
public BlockData getReplace()
public KList<BlockData> getReplace()
{
return replaceData.aquire(() -> B.getBlockData(replace));
}
public BlockData getReplace(RNG seed, double x, double y, double z)
{
return replaceGen.aquire(() -> NoiseStyle.STATIC.create(seed).bake()).fit(getReplace(), x, y, z);
}
}

View File

@ -7,6 +7,7 @@ import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.MaxNumber;
import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.RNG;
import com.volmit.iris.util.RegistryListBiome;
import com.volmit.iris.util.Required;
import lombok.Data;
@ -15,6 +16,7 @@ import lombok.Data;
@Data
public class IrisRegionRidge
{
@RegistryListBiome
@Required
@DontObfuscate
@Desc("The biome name")

View File

@ -6,6 +6,7 @@ import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.RNG;
import com.volmit.iris.util.RegistryListBiome;
import com.volmit.iris.util.Required;
import lombok.Data;
@ -14,6 +15,7 @@ import lombok.Data;
@Data
public class IrisRegionSpot
{
@RegistryListBiome
@Required
@DontObfuscate
@Desc("The biome to be placed")

View File

@ -10,6 +10,7 @@ import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.MaxNumber;
import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.RNG;
import com.volmit.iris.util.RegistryListStructure;
import com.volmit.iris.util.Required;
import lombok.Data;
@ -18,6 +19,7 @@ import lombok.Data;
@Data
public class IrisStructurePlacement
{
@RegistryListStructure
@Required
@DontObfuscate
@Desc("The structure tileset to use")

View File

@ -4,6 +4,7 @@ import com.volmit.iris.util.ArrayType;
import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.RegistryListObject;
import com.volmit.iris.util.Required;
import lombok.Data;
@ -45,6 +46,7 @@ public class IrisStructureTile
@Desc("Is this structure allowed to place if there is supposed to be a west wall?")
private StructureTileCondition west = StructureTileCondition.AGNOSTIC;
@RegistryListObject
@Required
@ArrayType(min = 1, type = String.class)
@DontObfuscate

View File

@ -13,12 +13,23 @@ public class B
private static final KMap<String, BlockData> bdc = new KMap<>();
private static final KList<String> nulls = new KList<>();
private static final IrisDimension defaultCompat = new IrisDimension();
private static final KMap<Material, Boolean> solid = new KMap<>();
public static BlockData get(String bd)
{
return getBlockData(bd);
}
public static boolean isSolid(Material mat)
{
if(!solid.containsKey(mat))
{
solid.put(mat, mat.isSolid());
}
return solid.get(mat);
}
public static Material mat(String bd)
{
return getBlockData(bd).getMaterial();
@ -214,4 +225,21 @@ public class B
|| m.equals(B.mat("SOUL_TORCH"));
//@done
}
public static KList<BlockData> getBlockData(KList<String> find)
{
KList<BlockData> b = new KList<>();
for(String i : find)
{
BlockData bd = getBlockData(i);
if(bd != null)
{
b.add(bd);
}
}
return b;
}
}

View File

@ -2,14 +2,9 @@ package com.volmit.iris.util;
import java.io.File;
import lombok.Data;
import lombok.Getter;
@Data
public class FileWatcher
{
@Getter
private final File file;
protected final File file;
private boolean exists;
private long lastModified;
private long size;
@ -20,11 +15,11 @@ public class FileWatcher
readProperties();
}
private void readProperties()
protected void readProperties()
{
exists = file.exists();
lastModified = exists ? file.lastModified() : -1;
size = exists ? file.length() : -1;
size = exists ? file.isDirectory() ? -2 : file.length() : -1;
}
public boolean checkModified()

View File

@ -0,0 +1,122 @@
package com.volmit.iris.util;
import java.io.File;
public class FolderWatcher extends FileWatcher
{
private KMap<File, FolderWatcher> watchers;
private KList<File> changed;
private KList<File> created;
private KList<File> deleted;
public FolderWatcher(File file)
{
super(file);
}
protected void readProperties()
{
if(watchers == null)
{
watchers = new KMap<>();
changed = new KList<>();
created = new KList<>();
deleted = new KList<>();
}
if(file.isDirectory())
{
for(File i : file.listFiles())
{
if(!watchers.containsKey(i))
{
watchers.put(i, new FolderWatcher(i));
}
}
if(watchers == null)
{
System.out.print("wtf");
}
for(File i : watchers.k())
{
if(!i.exists())
{
watchers.remove(i);
}
}
}
else
{
super.readProperties();
}
}
public boolean checkModified()
{
changed.clear();
created.clear();
deleted.clear();
if(file.isDirectory())
{
KMap<File, FolderWatcher> w = watchers.copy();
readProperties();
for(File i : w.k())
{
if(!watchers.containsKey(i))
{
deleted.add(i);
}
}
for(File i : watchers.k())
{
if(!w.containsKey(i))
{
created.add(i);
}
else
{
FolderWatcher fw = watchers.get(i);
if(fw.checkModified())
{
changed.add(fw.file);
}
changed.addAll(fw.getChanged());
created.addAll(fw.getCreated());
deleted.addAll(fw.getDeleted());
}
}
return !changed.isEmpty() || !created.isEmpty() || !deleted.isEmpty();
}
return super.checkModified();
}
public KMap<File, FolderWatcher> getWatchers()
{
return watchers;
}
public KList<File> getChanged()
{
return changed;
}
public KList<File> getCreated()
{
return created;
}
public KList<File> getDeleted()
{
return deleted;
}
}

View File

@ -2,7 +2,8 @@ package com.volmit.iris.util;
import org.bukkit.block.data.BlockData;
public interface IObjectPlacer {
public interface IObjectPlacer
{
public int getHighest(int x, int z);
public int getHighest(int x, int z, boolean ignoreFluid);
@ -16,4 +17,6 @@ public interface IObjectPlacer {
public boolean isSolid(int x, int y, int z);
public boolean isUnderwater(int x, int z);
public int getFluidHeight();
}

View File

@ -100,6 +100,43 @@ public class ObjectResourceLoader extends ResourceLoader<IrisObject>
}
}
public String[] getPossibleKeys()
{
if(possibleKeys != null)
{
return possibleKeys;
}
Iris.info("Building " + resourceTypeName + " Possibility Lists");
KSet<String> m = new KSet<>();
for(File i : getFolders())
{
for(File j : i.listFiles())
{
if(j.isFile() && j.getName().endsWith(".iob"))
{
m.add(j.getName().replaceAll("\\Q.json\\E", ""));
}
else if(j.isDirectory())
{
for(File k : j.listFiles())
{
if(k.isFile() && k.getName().endsWith(".iob"))
{
m.add(j.getName() + "/" + k.getName().replaceAll("\\Q.iob\\E", ""));
}
}
}
}
}
KList<String> v = new KList<>(m);
possibleKeys = v.toArray(new String[v.size()]);
return possibleKeys;
}
public File findFile(String name)
{
lock.lock();

View File

@ -0,0 +1,14 @@
package com.volmit.iris.util;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target({PARAMETER, TYPE, FIELD})
public @interface RegistryListBiome
{
}

View File

@ -0,0 +1,14 @@
package com.volmit.iris.util;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target({PARAMETER, TYPE, FIELD})
public @interface RegistryListDimension
{
}

View File

@ -0,0 +1,14 @@
package com.volmit.iris.util;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target({PARAMETER, TYPE, FIELD})
public @interface RegistryListGenerator
{
}

View File

@ -0,0 +1,14 @@
package com.volmit.iris.util;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target({PARAMETER, TYPE, FIELD})
public @interface RegistryListObject
{
}

View File

@ -0,0 +1,14 @@
package com.volmit.iris.util;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target({PARAMETER, TYPE, FIELD})
public @interface RegistryListRegion
{
}

View File

@ -0,0 +1,14 @@
package com.volmit.iris.util;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target({PARAMETER, TYPE, FIELD})
public @interface RegistryListStructure
{
}

View File

@ -21,6 +21,7 @@ public class ResourceLoader<T extends IrisRegistrant>
protected String cname;
protected IrisLock lock;
protected String preferredFolder = null;
protected String[] possibleKeys = null;
public ResourceLoader(File root, String folderName, String resourceTypeName, Class<? extends T> objectClass)
{
@ -34,6 +35,43 @@ public class ResourceLoader<T extends IrisRegistrant>
loadCache = new KMap<>();
}
public String[] getPossibleKeys()
{
if(possibleKeys != null)
{
return possibleKeys;
}
Iris.info("Building " + resourceTypeName + " Possibility Lists");
KSet<String> m = new KSet<>();
for(File i : getFolders())
{
for(File j : i.listFiles())
{
if(j.isFile() && j.getName().endsWith(".json"))
{
m.add(j.getName().replaceAll("\\Q.json\\E", ""));
}
else if(j.isDirectory())
{
for(File k : j.listFiles())
{
if(k.isFile() && k.getName().endsWith(".json"))
{
m.add(j.getName() + "/" + k.getName().replaceAll("\\Q.json\\E", ""));
}
}
}
}
}
KList<String> v = new KList<>(m);
possibleKeys = v.toArray(new String[v.size()]);
return possibleKeys;
}
public long count()
{
return loadCache.size();
@ -155,6 +193,7 @@ public class ResourceLoader<T extends IrisRegistrant>
public void clearCache()
{
possibleKeys = null;
loadCache.clear();
folderCache = null;
}
@ -191,4 +230,10 @@ public class ResourceLoader<T extends IrisRegistrant>
{
preferredFolder = name;
}
public void clearList()
{
folderCache = null;
possibleKeys = null;
}
}