diff --git a/build.gradle b/build.gradle index 0cc7bd840..528db0f56 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ plugins { } group 'com.volmit.iris' -version '1.6.5' +version '1.6.6' def apiVersion = '1.17' def name = 'Iris' def main = 'com.volmit.iris.Iris' @@ -137,13 +137,14 @@ dependencies { implementation "net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT" implementation "net.kyori:adventure-platform-bukkit:4.0.0-SNAPSHOT" implementation 'net.kyori:adventure-api:4.8.1' -\ -// Dynamically Loaded + + // Dynamically Loaded implementation 'it.unimi.dsi:fastutil:8.5.4' implementation 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2' implementation 'org.zeroturnaround:zt-zip:1.14' implementation 'com.google.code.gson:gson:2.8.7' implementation 'org.ow2.asm:asm:9.2' implementation 'com.google.guava:guava:30.1.1-jre' - + implementation 'bsf:bsf:2.4.0' + implementation 'rhino:js:1.7R2' } \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index 9c2c52cc4..863eebfcf 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -29,7 +29,7 @@ import com.volmit.iris.core.link.MythicMobsLink; import com.volmit.iris.core.link.OraxenLink; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.core.tools.IrisWorlds; +import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.framework.EngineCompositeGenerator; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.biome.IrisBiomeCustom; @@ -266,8 +266,8 @@ public class Iris extends VolmitPlugin implements Listener { proj.close(); for (World i : Bukkit.getWorlds()) { - if (IrisWorlds.isIrisWorld(i)) { - IrisWorlds.access(i).close(); + if (IrisToolbelt.isIrisWorld(i)) { + IrisToolbelt.access(i).close(); } } diff --git a/src/main/java/com/volmit/iris/core/IrisBoardManager.java b/src/main/java/com/volmit/iris/core/IrisBoardManager.java index 7dca937e8..8116a4de5 100644 --- a/src/main/java/com/volmit/iris/core/IrisBoardManager.java +++ b/src/main/java/com/volmit/iris/core/IrisBoardManager.java @@ -148,12 +148,12 @@ public class IrisBoardManager implements BoardProvider, Listener { if (engine != null) { v.add("&7&m------------------"); KList f = new KList<>(); - f.add(engine.getFramework().getEngineParallax().forEachFeature(x, z)); + f.add(engine.getEngineParallax().forEachFeature(x, z)); v.add(C.AQUA + "Engine" + C.GRAY + ": " + engine.getName() + " " + engine.getMinHeight() + "-" + engine.getMaxHeight()); v.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName()); v.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiome(x, y, z).getName()); v.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z))); - v.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getFramework().getComplex().getSlopeStream().get(x, z), 2)); + v.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getComplex().getSlopeStream().get(x, z), 2)); v.add(C.AQUA + "Features" + C.GRAY + ": " + Form.f(f.size())); v.add(C.AQUA + "Energy" + C.GRAY + ": " + Form.f(engine.getWorldManager().getEnergy(), 0)); v.add(C.AQUA + "Sat" + C.GRAY + ": " + Form.f(engine.getWorldManager().getEntityCount()) + "e / " + Form.f(engine.getWorldManager().getChunkCount()) + "c (" + Form.pc(engine.getWorldManager().getEntitySaturation(), 0) + ")"); diff --git a/src/main/java/com/volmit/iris/core/command/CommandIris.java b/src/main/java/com/volmit/iris/core/command/CommandIris.java index 7e3d37420..d88d7fadc 100644 --- a/src/main/java/com/volmit/iris/core/command/CommandIris.java +++ b/src/main/java/com/volmit/iris/core/command/CommandIris.java @@ -21,9 +21,13 @@ package com.volmit.iris.core.command; import com.volmit.iris.Iris; import com.volmit.iris.core.command.jigsaw.CommandIrisJigsaw; import com.volmit.iris.core.command.object.CommandIrisObject; +import com.volmit.iris.core.command.pregen.CommandIrisPregen; import com.volmit.iris.core.command.studio.CommandIrisStudio; import com.volmit.iris.core.command.what.CommandIrisWhat; -import com.volmit.iris.core.command.world.*; +import com.volmit.iris.core.command.world.CommandIrisCreate; +import com.volmit.iris.core.command.world.CommandIrisFix; +import com.volmit.iris.core.command.world.CommandIrisUpdateWorld; +import com.volmit.iris.core.command.world.CommandIrisVerify; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.plugin.Command; import com.volmit.iris.util.plugin.MortarCommand; diff --git a/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsaw.java b/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsaw.java index fce3ce457..78e8193ca 100644 --- a/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsaw.java +++ b/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsaw.java @@ -69,6 +69,6 @@ public class CommandIrisJigsaw extends MortarCommand { @Override protected String getArgsUsage() { - return ""; + return "[subcommand]"; } } diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java new file mode 100644 index 000000000..53fdf10c9 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java @@ -0,0 +1,70 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.command.pregen; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.tools.IrisToolbelt; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.plugin.Command; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; + +public class CommandIrisPregen extends MortarCommand { + @Command + private CommandIrisPregenStart start; + + @Command + private CommandIrisPregenStop stop; + + @Command + private CommandIrisPregenPause toggle; + + public CommandIrisPregen() { + super("pregen", "preg", "p"); + requiresPermission(Iris.perm); + setCategory("Pregen"); + setDescription("Pregeneration Commands"); + } + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + if (sender.isPlayer()) { + if (!IrisToolbelt.isIrisWorld(sender.player().getWorld())) { + sender.sendMessage("Pregen only works in Iris worlds!"); + } + } else { + sender.sendMessage("Note that pregeneration only works in Iris worlds!"); + } + + sender.sendMessage("Iris Pregen Commands:"); + printHelp(sender); + sender.sendMessage("Pregen wiki page: https://docs.volmit.com/iris/pregeneration"); + return true; + } + + @Override + protected String getArgsUsage() { + return "[subcommand]"; + } +} diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenPause.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenPause.java new file mode 100644 index 000000000..6dac3c1a5 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenPause.java @@ -0,0 +1,37 @@ +package com.volmit.iris.core.command.pregen; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.gui.PregeneratorJob; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; + +public class CommandIrisPregenPause extends MortarCommand { + + public CommandIrisPregenPause() { + super("pause", "toggle", "t", "continue", "resume", "p", "c", "unpause", "up"); + requiresPermission(Iris.perm); + setCategory("Pregen"); + setDescription("Toggle an ongoing pregeneration task"); + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + if (PregeneratorJob.pauseResume()) { + sender.sendMessage("Paused/unpaused pregeneration task, now: " + (PregeneratorJob.isPaused() ? "Paused" : "Running") + "."); + } else { + sender.sendMessage("No active pregeneration tasks to pause/unpause."); + } + return true; + } + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + + } + + @Override + protected String getArgsUsage() { + return ""; + } +} diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStart.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStart.java new file mode 100644 index 000000000..10eff2735 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStart.java @@ -0,0 +1,298 @@ +package com.volmit.iris.core.command.pregen; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.gui.PregeneratorJob; +import com.volmit.iris.core.pregenerator.PregenTask; +import com.volmit.iris.core.tools.IrisToolbelt; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.math.Position2; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; +import org.bukkit.Bukkit; +import org.bukkit.World; + + +public class CommandIrisPregenStart extends MortarCommand { + + private static final KList argus = new KList<>("radius=", "x=", "z="); + + public CommandIrisPregenStart() { + super("start", "s", "create", "c", "new", "+"); + requiresPermission(Iris.perm); + setCategory("Pregen"); + setDescription(""" + Create a new pregeneration task. + Command usage: + /iris pregen create [radius=] [x=] [z=] [world=] [-here] + + Examples: + /iris pregen start 5k -here + /iris pregen start radius=5000 x=10r z=10r world=IrisWorld + /iris pregen start 10k world=WorldName + + : Sets both width and height to a value. (Size is: 2 * radius by 2 * radius) + & : Give the center point of the pregen. + : Specify a different world name for generation than the one you're currently in. + The console is not in any world, so this is required for console! + If you specify this, the `-here` is ignored. + -here: If added, the center location is set to your position (player only) + This overrides and . + + For all numeric values (radius, centerX, etc.) you may use: + c => 16, r => 512, k => 1000 + Example: entering '1000' is the same as '1k' (1 * 1000) + https://docs.volmit.com/iris/pregeneration"""); + } + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + + // Add arguments + argus.forEach(p -> { + boolean hasArg = false; + for (String arg : args) { + if (!arg.contains("=") || !p.contains("=")) { + continue; + } + if (arg.split("=")[0].equals(p.split("=")[0])) { + hasArg = true; + break; + } + } + if (!hasArg) { + list.add(p); + } + }); + + // Add -here + boolean hasHere = false; + for (String arg : args) { + if (arg.equals("-here")) { + hasHere = true; + break; + } + } + if (!hasHere) { + list.add("-here"); + } + + // Add Iris worlds + if (Bukkit.getWorlds().isEmpty()) { + list.add("world="); + } else { + Bukkit.getWorlds().forEach(w -> { + if (IrisToolbelt.isIrisWorld(w)) { + list.add("world=" + w.getName()); + } + }); + } + } + + @Override + protected String getArgsUsage() { + return " [x=] [z=] [world=] [-here]"; + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + + if (PregeneratorJob.getInstance() != null) { + sender.sendMessage("Pregeneration task already ongoing. You can stop it with /ir p stop."); + sender.sendMessage("Cannot create new pregen while one is already going. Cancelling..."); + return true; + } + + World world = null; + int width = -1; + int height = -1; + int x = 0; + int z = 0; + boolean here = false; + + // Check all arguments + KList failed = new KList<>(); + for (String a : args) { + if (a.equals("-here")) { + here = true; + } else if (a.contains("=")) { + String pre = a.split("=")[0]; + String val = a.split("=")[1]; + if (pre.equals("world")) { + world = Bukkit.getWorld(val); + if (world == null) { + failed.add(a + " (invalid world)"); + sender.sendMessage("Entered world is " + val + ", but that world does not exist."); + sender.sendMessage("Cancelling the command."); + sender.sendMessage(getDescription()); + return true; + } + } else if (!isVal(val)) { + failed.add(a + " (non-value)"); + } else { + switch (pre) { + case "width" -> width = getVal(val); + case "height" -> height = getVal(val); + case "radius" -> { + width = getVal(val); + height = getVal(val); + } + case "x" -> x = getVal(val); + case "z" -> z = getVal(val); + default -> failed.add(a + " (no type)"); + } + } + } else if (isVal(a)) { + width = getVal(a); + height = getVal(a); + } else { + failed.add(a + " (nothing)"); + } + } + + // Checking if a radius was specified or forgotten + if (width == -1 || height == -1) { + sender.sendMessage("Radius not specified! Cancelling..."); + sender.sendMessage(getDescription()); + return true; + } + + // World specified & cancelling `-here` if it's another world + if (world == null) { + if (sender.isPlayer()) { + world = sender.player().getWorld(); + } else { + sender.sendMessage("Must specify world= if sending from console! Cancelling..."); + sender.sendMessage(getDescription()); + return true; + } + } else { + if (sender.isPlayer()) { + if (!world.equals(sender.player().getWorld())) { + if (here) { + sender.sendMessage("Ignoring `-here` because `world=` is specified!"); + here = false; + } + } + } + } + + // Checking if -here is used + if (here) { + if (sender.isPlayer()) { + x = sender.player().getLocation().getBlockX(); + z = sender.player().getLocation().getBlockZ(); + } else { + sender.sendMessage("Specifying -here does not work from console!"); + } + } + + // Build details print + StringBuilder details = new StringBuilder("Pregeneration details:") + .append("\n") + .append(" - World > ") + .append(world.getName()) + .append("\n") + .append(" - Radius > ") + .append(width) + .append("(") + .append(width * 2) + .append(" by ") + .append(height * 2) + .append(")\n") + .append(" - Center x,z > ") + .append(x) + .append(",") + .append(z) + .append("\n") + + // Append failed args + .append(failed.isEmpty() ? "(No failed arguments)\n" : "FAILED ARGS:\n"); + for (String s : failed) { + details.append(s).append("\n"); + } + + // Start pregen and append info to details + if (pregenerate(world, width, height, x, z)) { + details.append("Successfully started pregen"); + } else { + details.append("Failed to start pregen. Doublecheck your arguments!"); + } + + // Send details + sender.sendMessage(details.toString()); + + return true; + } + + /** + * Pregenerate a + * + * @param world world with a + * @param width and + * @param height with center + * @param x and + * @param z coords + * @return true if successful + */ + private boolean pregenerate(World world, int width, int height, int x, int z) { + try { + IrisToolbelt.pregenerate(PregenTask + .builder() + .center(new Position2(x, z)) + .width(width >> 9 + 1) + .height(height >> 9 + 1) + .build(), world); + } catch (Throwable e) { + Iris.reportError(e); + e.printStackTrace(); + return false; + } + return true; + } + + /** + * Get the ingeger value from an argument that may contain `c` `chunks` `r` `regions` or `k`
+ * "5r" returns 5 * 512 = 2560 + * + * @param arg the string argument to parse into a value + * @return the integer value result + */ + private int getVal(String arg) { + + if (arg.toLowerCase().endsWith("c") || arg.toLowerCase().endsWith("chunks")) { + return Integer.parseInt(arg.toLowerCase().replaceAll("\\Qc\\E", "").replaceAll("\\Qchunks\\E", "")) * 16; + } + + if (arg.toLowerCase().endsWith("r") || arg.toLowerCase().endsWith("regions")) { + return Integer.parseInt(arg.toLowerCase().replaceAll("\\Qr\\E", "").replaceAll("\\Qregions\\E", "")) * 512; + } + + if (arg.toLowerCase().endsWith("k")) { + return Integer.parseInt(arg.toLowerCase().replaceAll("\\Qk\\E", "")) * 1000; + } + + return Integer.parseInt(arg.toLowerCase()); + } + + /** + * Checks if the + * + * @param arg string value + * @return is valid -> true + */ + private boolean isVal(String arg) { + try { + Integer.parseInt( + arg.toLowerCase() + .replace("chunks", "") + .replace("c", "") + .replace("regions", "") + .replace("r", "") + .replace("k", "") + ); + } catch (NumberFormatException e) { + return false; + } + return true; + } +} diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStop.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStop.java new file mode 100644 index 000000000..13312b0db --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStop.java @@ -0,0 +1,37 @@ +package com.volmit.iris.core.command.pregen; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.gui.PregeneratorJob; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; + +public class CommandIrisPregenStop extends MortarCommand { + + public CommandIrisPregenStop() { + super("stop", "s", "x", "close"); + requiresPermission(Iris.perm); + setCategory("Pregen"); + setDescription("Stop an ongoing pregeneration task"); + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + if (PregeneratorJob.shutdownInstance()) { + sender.sendMessage("Stopped pregeneration task"); + } else { + sender.sendMessage("No active pregeneration tasks to stop"); + } + return true; + } + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + + } + + @Override + protected String getArgsUsage() { + return ""; + } +} diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudio.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudio.java index 198c5cae6..993cdf13f 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudio.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudio.java @@ -29,6 +29,9 @@ public class CommandIrisStudio extends MortarCommand { @Command private CommandIrisStudioCreate create; + @Command + private CommandIrisStudioExecute execute; + @Command private CommandIrisStudioOpen open; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExecute.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExecute.java new file mode 100644 index 000000000..269b0a498 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExecute.java @@ -0,0 +1,75 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.command.studio; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.tools.IrisToolbelt; +import com.volmit.iris.core.tools.IrisWorlds; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.framework.IrisAccess; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; + +public class CommandIrisStudioExecute extends MortarCommand { + public CommandIrisStudioExecute() { + super("execute", "ex"); + requiresPermission(Iris.perm.studio); + setDescription("Execute a script"); + setCategory("Studio"); + } + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + if ((args.length == 0 || args.length == 1) && sender.isPlayer() && IrisWorlds.isIrisWorld(sender.player().getWorld())) { + IrisData data = IrisWorlds.access(sender.player().getWorld()).getData(); + if (data == null) { + sender.sendMessage("Tab complete options only work for summons while in an Iris world."); + } else if (args.length == 0) { + list.add(data.getScriptLoader().getPossibleKeys()); + } else if (args.length == 1) { + list.add(data.getScriptLoader().getPossibleKeys(args[0])); + } + } + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + if (!IrisSettings.get().isStudio()) { + sender.sendMessage("To use Iris Studio, please enable studio in Iris/settings.json"); + return true; + } + + IrisAccess a = IrisToolbelt.access(sender.player().getWorld()); + + if (a != null) { + ((Engine) a.getEngineAccess(0)).getExecution().execute(args[0]); + Iris.info("Executed. See script output in console."); + } + + return true; + } + + @Override + protected String getArgsUsage() { + return ""; + } +} diff --git a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhat.java b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhat.java index 3651c024d..b979e6668 100644 --- a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhat.java +++ b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhat.java @@ -42,7 +42,6 @@ public class CommandIrisWhat extends MortarCommand { public CommandIrisWhat() { super("what", "w", "?"); - setDescription("Get timings for this world"); requiresPermission(Iris.perm.studio); setCategory("Wut"); setDescription("Figure out what stuff is"); @@ -62,6 +61,6 @@ public class CommandIrisWhat extends MortarCommand { @Override protected String getArgsUsage() { - return ""; + return "[subcommand]"; } } diff --git a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBiome.java b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBiome.java index d26ad8eee..00a6929f1 100644 --- a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBiome.java +++ b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBiome.java @@ -33,7 +33,6 @@ import org.bukkit.entity.Player; public class CommandIrisWhatBiome extends MortarCommand { public CommandIrisWhatBiome() { super("biome", "bi", "b"); - setDescription("Get the biome data you are in."); requiresPermission(Iris.perm.studio); setCategory("Wut"); setDescription("What biome am I in"); diff --git a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBlock.java b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBlock.java index 780985b46..818d1ecb3 100644 --- a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBlock.java +++ b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBlock.java @@ -31,10 +31,9 @@ import org.bukkit.entity.Player; public class CommandIrisWhatBlock extends MortarCommand { public CommandIrisWhatBlock() { super("block", "l", "bl"); - setDescription("Get the block data for looking."); + setDescription("Get the block data of the block you're looking at."); requiresPermission(Iris.perm.studio); setCategory("Wut"); - setDescription("WAILA, WAWLA etc"); } @Override diff --git a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatFeatures.java b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatFeatures.java index 30a3bf329..b348d0f00 100644 --- a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatFeatures.java +++ b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatFeatures.java @@ -37,7 +37,6 @@ public class CommandIrisWhatFeatures extends MortarCommand { setDescription("Get the noise feature data in chunk."); requiresPermission(Iris.perm.studio); setCategory("Wut"); - setDescription("WAILA, WAWLA etc"); } @Override @@ -54,7 +53,7 @@ public class CommandIrisWhatFeatures extends MortarCommand { if (IrisWorlds.isIrisWorld(c.getWorld())) { int m = 1; - for (IrisFeaturePositional i : ((Engine) IrisWorlds.access(c.getWorld()).getEngineAccess(p.getLocation().getBlockY())).getFramework().getEngineParallax().getFeaturesInChunk(c)) { + for (IrisFeaturePositional i : ((Engine) IrisWorlds.access(c.getWorld()).getEngineAccess(p.getLocation().getBlockY())).getEngineParallax().getFeaturesInChunk(c)) { sender.sendMessage("#" + m++ + " " + new JSONObject(new Gson().toJson(i)).toString(4)); } } else { diff --git a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatHand.java b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatHand.java index b5ad52fa5..9158da06b 100644 --- a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatHand.java +++ b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatHand.java @@ -30,10 +30,9 @@ import org.bukkit.entity.Player; public class CommandIrisWhatHand extends MortarCommand { public CommandIrisWhatHand() { super("hand", "h"); - setDescription("Get the block data for holding."); + setDescription("Get the block data for the block you're holding."); requiresPermission(Iris.perm.studio); setCategory("Wut"); - setDescription("What block am I holding"); } @Override diff --git a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatObjects.java b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatObjects.java index b949de69e..b23f705f9 100644 --- a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatObjects.java +++ b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatObjects.java @@ -51,7 +51,7 @@ import java.util.Objects; public class CommandIrisWhatObjects extends MortarCommand { public CommandIrisWhatObjects() { super("objects", "o", "obj", "capture", "capt"); - setDescription("Capture nearby information to help with reporting problems"); + setDescription("Capture nearby information to help with reporting problems. Can specify the number of threads like /ir w o 4"); requiresPermission(Iris.perm.studio); setCategory("World"); } diff --git a/src/main/java/com/volmit/iris/core/command/world/CommandIrisFix.java b/src/main/java/com/volmit/iris/core/command/world/CommandIrisFix.java index 8d91fa0a1..27f655d8d 100644 --- a/src/main/java/com/volmit/iris/core/command/world/CommandIrisFix.java +++ b/src/main/java/com/volmit/iris/core/command/world/CommandIrisFix.java @@ -55,13 +55,13 @@ public class CommandIrisFix extends MortarCommand { int viewDistance = args.length > 0 ? Integer.parseInt(args[0]) : -1; if (viewDistance <= 1) { J.a(() -> { - int fixed = a.getCompound().getDefaultEngine().getFramework().getEngineParallax().repairChunk(sender.player().getLocation().getChunk()); + int fixed = a.getCompound().getDefaultEngine().getEngineParallax().repairChunk(sender.player().getLocation().getChunk()); sender.sendMessage("Fixed " + Form.f(fixed) + " blocks!"); }); } else { AtomicInteger v = new AtomicInteger(); J.a(() -> { - new Spiraler(viewDistance, viewDistance, (x, z) -> v.set(v.get() + a.getCompound().getDefaultEngine().getFramework().getEngineParallax().repairChunk(sender.player().getWorld().getChunkAt(x, z)))).drain(); + new Spiraler(viewDistance, viewDistance, (x, z) -> v.set(v.get() + a.getCompound().getDefaultEngine().getEngineParallax().repairChunk(sender.player().getWorld().getChunkAt(x, z)))).drain(); sender.sendMessage("Fixed " + Form.f(v.get()) + " blocks in " + (viewDistance * viewDistance) + " chunks!"); }); } diff --git a/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java b/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java deleted file mode 100644 index cd083c332..000000000 --- a/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.core.command.world; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.gui.PregeneratorJob; -import com.volmit.iris.core.pregenerator.PregenTask; -import com.volmit.iris.core.pregenerator.methods.HybridPregenMethod; -import com.volmit.iris.core.tools.IrisToolbelt; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.math.Position2; -import com.volmit.iris.util.plugin.MortarCommand; -import com.volmit.iris.util.plugin.VolmitSender; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.entity.Player; - -import java.awt.*; - -public class CommandIrisPregen extends MortarCommand { - public CommandIrisPregen() { - super("pregen", "preg", "p"); - setDescription( - """ - Pregen this world with optional parameters:\s - '1k' = 1000 * 2 by 1000 * 2 blocks, '1c' = 2 by 2 chunks, and '1r' = 64 by 64 chunks. - If you are using the console or want to pregen a world you're not in: - also specify the name of the world. E.g. /ir pregen 5k world""" - ); - requiresPermission(Iris.perm.studio); - setCategory("Pregen"); - } - - @Override - public void addTabOptions(VolmitSender sender, String[] args, KList list) { - list.add("stop"); - list.add("pause"); - list.add("resume"); - list.add("500"); - list.add("1000"); - list.add("10k"); - list.add("25k"); - list.add("10c"); - list.add("25c"); - list.add("5r"); - list.add("10r"); - for (World w : Bukkit.getServer().getWorlds()) { - list.add(w.getName()); - } - } - - @Override - public boolean handle(VolmitSender sender, String[] args) { - if (args.length == 0) { - sender.sendMessage("/iris pregen "); - return true; - } - - if (args[0].equalsIgnoreCase("stop") || args[0].equalsIgnoreCase("x")) { - if (PregeneratorJob.shutdownInstance()) { - sender.sendMessage("Stopped Pregen. Finishing last region file before shutting down..."); - } else { - sender.sendMessage("No Active Pregens."); - } - return true; - } else if (args[0].equalsIgnoreCase("pause") || args[0].equalsIgnoreCase("resume")) { - if (PregeneratorJob.getInstance() != null) { - PregeneratorJob.pauseResume(); - - if (PregeneratorJob.isPaused()) { - sender.sendMessage("Pregen Paused"); - } else { - sender.sendMessage("Pregen Resumed"); - } - } else { - sender.sendMessage("No Active Pregens"); - } - - return true; - } else if (sender.isPlayer()) { - Player p = sender.player(); - World world; - if (args.length != 2) { - world = p.getWorld(); - } else { - try { - world = Bukkit.getWorld(args[1]); - } catch (Exception e) { - Iris.reportError(e); - sender.sendMessage("Could not find specified world"); - sender.sendMessage("Please doublecheck your command. E.g. /ir pregen 5k world"); - return true; - } - } - try { - IrisToolbelt.pregenerate(PregenTask - .builder() - .center(new Position2(0, 0)) - .radius(((getVal(args[0]) >> 4) >> 5) + 1) - .build(), world); - } catch (NumberFormatException e) { - Iris.reportError(e); - sender.sendMessage("Invalid argument in command"); - return true; - } catch (NullPointerException e) { - Iris.reportError(e); - e.printStackTrace(); - sender.sendMessage("No radius specified (check error in console)"); - } catch (HeadlessException e) { - Iris.reportError(e); - sender.sendMessage("If you are seeing this and are using a hosted server, please turn off 'useServerLaunchedGUIs' in the settings"); - } - - return true; - } else { - if (args.length < 1) { - sender.sendMessage("Please specify the radius of the pregen and the name of the world. E.g. /ir pregen 5k world"); - return true; - } - if (args.length < 2) { - sender.sendMessage("Please specify the name of the world after the command. E.g. /ir pregen 5k world"); - return true; - } - World world = Bukkit.getWorld(args[1]); - try { - new PregeneratorJob(PregenTask - .builder() - .center(new Position2(0, 0)) - .radius(((getVal(args[0]) >> 4) >> 5) + 1) - .build(), - new HybridPregenMethod(world, Runtime.getRuntime().availableProcessors())); - } catch (NumberFormatException e) { - Iris.reportError(e); - sender.sendMessage("Invalid argument in command"); - return true; - } catch (NullPointerException e) { - Iris.reportError(e); - sender.sendMessage("Not all required parameters specified"); - } catch (HeadlessException e) { - Iris.reportError(e); - sender.sendMessage("If you are seeing this and are using a hosted server, please turn off 'useServerLaunchedGUIs' in the settings"); - } - - return true; - } - } - - private int getVal(String arg) { - - if (arg.toLowerCase().endsWith("c") || arg.toLowerCase().endsWith("chunks")) { - return Integer.parseInt(arg.toLowerCase().replaceAll("\\Qc\\E", "").replaceAll("\\Qchunks\\E", "")) * 16; - } - - if (arg.toLowerCase().endsWith("r") || arg.toLowerCase().endsWith("regions")) { - return Integer.parseInt(arg.toLowerCase().replaceAll("\\Qr\\E", "").replaceAll("\\Qregions\\E", "")) * 512; - } - - if (arg.toLowerCase().endsWith("k")) { - return Integer.parseInt(arg.toLowerCase().replaceAll("\\Qk\\E", "")) * 1000; - } - - return Integer.parseInt(arg.toLowerCase()); - } - - @Override - protected String getArgsUsage() { - return "[radius]"; - } -} diff --git a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java index 801b98d6f..6757a5a7f 100644 --- a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java +++ b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java @@ -103,9 +103,9 @@ public class PregeneratorJob implements PregenListener { return instance; } - public static void pauseResume() { + public static boolean pauseResume() { if (instance == null) { - return; + return false; } if (isPaused()) { @@ -113,6 +113,7 @@ public class PregeneratorJob implements PregenListener { } else { instance.pregenerator.pause(); } + return true; } public static boolean isPaused() { diff --git a/src/main/java/com/volmit/iris/core/gui/VisionGUI.java b/src/main/java/com/volmit/iris/core/gui/VisionGUI.java index db2dfb07e..4aefbb6bd 100644 --- a/src/main/java/com/volmit/iris/core/gui/VisionGUI.java +++ b/src/main/java/com/volmit/iris/core/gui/VisionGUI.java @@ -191,12 +191,12 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener BiFunction colorFunction = (d, dx) -> Color.black.getRGB(); switch (currentType) { - case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD -> colorFunction = (x, z) -> engine.getFramework().getComplex().getTrueBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); - case BIOME_LAND -> colorFunction = (x, z) -> engine.getFramework().getComplex().getLandBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); - case BIOME_SEA -> colorFunction = (x, z) -> engine.getFramework().getComplex().getSeaBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); - case REGION -> colorFunction = (x, z) -> engine.getFramework().getComplex().getRegionStream().get(x, z).getColor(engine.getFramework().getComplex(), currentType).getRGB(); - case CAVE_LAND -> colorFunction = (x, z) -> engine.getFramework().getComplex().getCaveBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); - case HEIGHT -> colorFunction = (x, z) -> Color.getHSBColor(engine.getFramework().getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB(); + case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD -> colorFunction = (x, z) -> engine.getComplex().getTrueBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); + case BIOME_LAND -> colorFunction = (x, z) -> engine.getComplex().getLandBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); + case BIOME_SEA -> colorFunction = (x, z) -> engine.getComplex().getSeaBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); + case REGION -> colorFunction = (x, z) -> engine.getComplex().getRegionStream().get(x, z).getColor(engine.getComplex(), currentType).getRGB(); + case CAVE_LAND -> colorFunction = (x, z) -> engine.getComplex().getCaveBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); + case HEIGHT -> colorFunction = (x, z) -> Color.getHSBColor(engine.getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB(); } return colorFunction.apply(wx, wz); @@ -629,8 +629,8 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener } private void renderHoverOverlay(Graphics2D g, boolean detailed) { - IrisBiome biome = engine.getFramework().getComplex().getTrueBiomeStream().get(getWorldX(hx), getWorldZ(hz)); - IrisRegion region = engine.getFramework().getComplex().getRegionStream().get(getWorldX(hx), getWorldZ(hz)); + IrisBiome biome = engine.getComplex().getTrueBiomeStream().get(getWorldX(hx), getWorldZ(hz)); + IrisRegion region = engine.getComplex().getRegionStream().get(getWorldX(hx), getWorldZ(hz)); KList l = new KList<>(); l.add("Biome: " + biome.getName()); l.add("Region: " + region.getName() + "(" + region.getLoadKey() + ")"); @@ -692,7 +692,7 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener } private void open() { - IrisComplex complex = engine.getFramework().getComplex(); + IrisComplex complex = engine.getComplex(); File r = null; switch (currentType) { case BIOME, LAYER_LOAD, DECORATOR_LOAD, OBJECT_LOAD, HEIGHT -> r = complex.getTrueBiomeStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode(); @@ -710,7 +710,7 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener if (player != null) { int xx = (int) getWorldX(hx); int zz = (int) getWorldZ(hz); - double h = engine.getFramework().getComplex().getTrueHeightStream().get(xx, zz); + double h = engine.getComplex().getTrueHeightStream().get(xx, zz); player.teleport(new Location(player.getWorld(), xx, h, zz)); notify("Teleporting to " + xx + ", " + (int) h + ", " + zz); } else { diff --git a/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java b/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java index bd6e5d1c0..944b4af3a 100644 --- a/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java +++ b/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java @@ -38,12 +38,12 @@ public class IrisRenderer { BiFunction colorFunction = (d, dx) -> Color.black.getRGB(); switch (currentType) { - case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD -> colorFunction = (x, z) -> renderer.getFramework().getComplex().getTrueBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); - case BIOME_LAND -> colorFunction = (x, z) -> renderer.getFramework().getComplex().getLandBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); - case BIOME_SEA -> colorFunction = (x, z) -> renderer.getFramework().getComplex().getSeaBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); - case REGION -> colorFunction = (x, z) -> renderer.getFramework().getComplex().getRegionStream().get(x, z).getColor(renderer.getFramework().getComplex(), currentType).getRGB(); - case CAVE_LAND -> colorFunction = (x, z) -> renderer.getFramework().getComplex().getCaveBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); - case HEIGHT -> colorFunction = (x, z) -> Color.getHSBColor(renderer.getFramework().getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB(); + case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD -> colorFunction = (x, z) -> renderer.getComplex().getTrueBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); + case BIOME_LAND -> colorFunction = (x, z) -> renderer.getComplex().getLandBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); + case BIOME_SEA -> colorFunction = (x, z) -> renderer.getComplex().getSeaBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); + case REGION -> colorFunction = (x, z) -> renderer.getComplex().getRegionStream().get(x, z).getColor(renderer.getComplex(), currentType).getRGB(); + case CAVE_LAND -> colorFunction = (x, z) -> renderer.getComplex().getCaveBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); + case HEIGHT -> colorFunction = (x, z) -> Color.getHSBColor(renderer.getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB(); } double x, z; diff --git a/src/main/java/com/volmit/iris/core/link/IrisPapiExpansion.java b/src/main/java/com/volmit/iris/core/link/IrisPapiExpansion.java index ea33c8100..cd1d70476 100644 --- a/src/main/java/com/volmit/iris/core/link/IrisPapiExpansion.java +++ b/src/main/java/com/volmit/iris/core/link/IrisPapiExpansion.java @@ -85,7 +85,7 @@ public class IrisPapiExpansion extends PlaceholderExpansion { } else if (p.equalsIgnoreCase("terrain_slope")) { if (a != null) { return ((Engine) a.getEngineAccess(l.getBlockY())) - .getFramework().getComplex().getSlopeStream() + .getComplex().getSlopeStream() .get(l.getX(), l.getZ()) + ""; } } else if (p.equalsIgnoreCase("terrain_height")) { diff --git a/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java b/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java index cc87b439d..5a1907ca3 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java @@ -34,12 +34,15 @@ public class PregenTask { private Position2 center = new Position2(0, 0); @Builder.Default - private int radius = 1; + private int width = 1; + + @Builder.Default + private int height = 1; private static final KList order = computeChunkOrder(); public void iterateRegions(Spiraled s) { - new Spiraler(radius * 2, radius * 2, s) + new Spiraler(getWidth() * 2, getHeight() * 2, s) .setOffset(center.getX(), center.getZ()).drain(); } @@ -50,7 +53,7 @@ public class PregenTask { } public void iterateAllChunks(Spiraled s) { - new Spiraler(radius * 2, radius * 2, (x, z) -> iterateRegion(x, z, s)) + new Spiraler(getWidth() * 2, getHeight() * 2, (x, z) -> iterateRegion(x, z, s)) .setOffset(center.getX(), center.getZ()).drain(); } diff --git a/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java b/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java index 27820352f..c77d29000 100644 --- a/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java +++ b/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java @@ -20,6 +20,7 @@ package com.volmit.iris.core.project; import com.volmit.iris.Iris; import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.project.loader.IrisRegistrant; import com.volmit.iris.core.project.loader.ResourceLoader; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.util.collection.KList; @@ -91,6 +92,25 @@ public class SchemaBuilder { o.put("type", getType(c)); JSONArray required = new JSONArray(); + if (c.isAssignableFrom(IrisRegistrant.class) || IrisRegistrant.class.isAssignableFrom(c)) { + for (Field k : IrisRegistrant.class.getDeclaredFields()) { + k.setAccessible(true); + + if (Modifier.isStatic(k.getModifiers()) || Modifier.isFinal(k.getModifiers()) || Modifier.isTransient(k.getModifiers())) { + continue; + } + + JSONObject property = buildProperty(k, c); + + if (property.getBoolean("!required")) { + required.put(k.getName()); + } + + property.remove("!required"); + properties.put(k.getName(), property); + } + } + for (Field k : c.getDeclaredFields()) { k.setAccessible(true); diff --git a/src/main/java/com/volmit/iris/core/project/loader/IrisData.java b/src/main/java/com/volmit/iris/core/project/loader/IrisData.java index ce9bc6743..e56fdc42d 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/IrisData.java +++ b/src/main/java/com/volmit/iris/core/project/loader/IrisData.java @@ -22,6 +22,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.block.IrisBlockData; +import com.volmit.iris.engine.object.common.IrisScript; import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.engine.object.entity.IrisEntity; import com.volmit.iris.engine.object.jigsaw.IrisJigsawPiece; @@ -35,6 +36,8 @@ import com.volmit.iris.engine.object.objects.IrisObject; import com.volmit.iris.engine.object.regional.IrisRegion; import com.volmit.iris.engine.object.spawners.IrisSpawner; import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.context.IrisContext; +import com.volmit.iris.util.format.C; import com.volmit.iris.util.math.RNG; import lombok.Data; @@ -58,6 +61,7 @@ public class IrisData { private ResourceLoader blockLoader; private ResourceLoader expressionLoader; private ResourceLoader objectLoader; + private ResourceLoader scriptLoader; private KMap, ResourceLoader> loaders = new KMap<>(); private boolean closed; private final File dataFolder; @@ -76,6 +80,40 @@ public class IrisData { hotloaded(); } + public void preprocessObject(IrisRegistrant t) { + try { + IrisContext ctx = IrisContext.get(); + Engine engine = this.engine; + + if (engine == null && ctx != null && ctx.getEngine() != null) { + engine = ctx.getEngine(); + } + + if (engine == null && t.getPreprocessors().isNotEmpty()) { + Iris.error("Failed to preprocess object " + t.getLoadKey() + " because there is no engine context here. (See stack below)"); + try { + throw new RuntimeException(); + } catch (Throwable ex) { + ex.printStackTrace(); + } + } + + if (engine != null && t.getPreprocessors().isNotEmpty()) { + synchronized (this) { + engine.getExecution().getAPI().setPreprocessorObject(t); + + for (String i : t.getPreprocessors()) { + engine.getExecution().execute(i); + Iris.debug("Loader<" + C.GREEN + t.getTypeName() + C.LIGHT_PURPLE + "> iprocess " + C.YELLOW + t.getLoadKey() + C.LIGHT_PURPLE + " in " + i); + } + } + } + } catch (Throwable e) { + Iris.error("Failed to preprocess object!"); + e.printStackTrace(); + } + } + public void close() { closed = true; dump(); @@ -96,6 +134,8 @@ public class IrisData { ResourceLoader r = null; if (registrant.equals(IrisObject.class)) { r = (ResourceLoader) new ObjectResourceLoader(dataFolder, this, rr.getFolderName(), rr.getTypeName()); + } else if (registrant.equals(IrisScript.class)) { + r = (ResourceLoader) new ScriptResourceLoader(dataFolder, this, rr.getFolderName(), rr.getTypeName()); } else { r = new ResourceLoader(dataFolder, this, rr.getFolderName(), rr.getTypeName(), registrant); } @@ -133,6 +173,7 @@ public class IrisData { this.blockLoader = registerLoader(IrisBlockData.class); this.expressionLoader = registerLoader(IrisExpression.class); this.objectLoader = registerLoader(IrisObject.class); + this.scriptLoader = registerLoader(IrisScript.class); } public void dump() { @@ -195,6 +236,10 @@ public class IrisData { return loadAny(key, (dm) -> dm.getSpawnerLoader().load(key, false)); } + public static IrisScript loadAnyScript(String key) { + return loadAny(key, (dm) -> dm.getScriptLoader().load(key, false)); + } + public static IrisRegion loadAnyRegion(String key) { return loadAny(key, (dm) -> dm.getRegionLoader().load(key, false)); } diff --git a/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java b/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java index fa7a3a775..c457f19b4 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java +++ b/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java @@ -19,6 +19,11 @@ package com.volmit.iris.core.project.loader; import com.volmit.iris.Iris; +import com.volmit.iris.engine.object.annotations.ArrayType; +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.annotations.RegistryListResource; +import com.volmit.iris.engine.object.common.IrisScript; +import com.volmit.iris.util.collection.KList; import lombok.Data; import java.awt.*; @@ -26,6 +31,11 @@ import java.io.File; @Data public abstract class IrisRegistrant { + @Desc("Preprocess this object in-memory when it's loaded, run scripts using the variable 'Iris.getPreprocessorObject()' and modify properties about this object before it's used.") + @RegistryListResource(IrisScript.class) + @ArrayType(min = 1, type = String.class) + private KList preprocessors = new KList<>(); + private transient IrisData loader; private transient String loadKey; diff --git a/src/main/java/com/volmit/iris/core/project/loader/ResourceLoader.java b/src/main/java/com/volmit/iris/core/project/loader/ResourceLoader.java index 5232fa9e6..a3ed3dbf9 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/ResourceLoader.java +++ b/src/main/java/com/volmit/iris/core/project/loader/ResourceLoader.java @@ -178,10 +178,11 @@ public class ResourceLoader { try { PrecisionStopwatch p = PrecisionStopwatch.start(); T t = new Gson().fromJson(IO.readAll(j), objectClass); - loadCache.put(key, t); t.setLoadKey(name); t.setLoadFile(j); t.setLoader(manager); + getManager().preprocessObject(t); + loadCache.put(key, t); logLoad(j, t); lock.unlock(); tlt.addAndGet(p.getMilliseconds()); diff --git a/src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java b/src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java new file mode 100644 index 000000000..ac0da6875 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java @@ -0,0 +1,152 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.project.loader; + +import com.volmit.iris.Iris; +import com.volmit.iris.engine.object.common.IrisScript; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KSet; +import com.volmit.iris.util.io.IO; +import com.volmit.iris.util.scheduling.PrecisionStopwatch; + +import java.io.File; + +public class ScriptResourceLoader extends ResourceLoader { + + public ScriptResourceLoader(File root, IrisData idm, String folderName, String resourceTypeName) { + super(root, idm, folderName, resourceTypeName, IrisScript.class); + } + + public boolean supportsSchemas() { + return false; + } + + public int getSize() { + return loadCache.size(); + } + + public IrisScript loadFile(File j, String key, String name) { + lock.lock(); + try { + PrecisionStopwatch p = PrecisionStopwatch.start(); + IrisScript t = new IrisScript(IO.readAll(j)); + loadCache.put(key, t); + t.setLoadKey(name); + t.setLoader(manager); + t.setLoadFile(j); + logLoad(j, t); + lock.unlock(); + tlt.addAndGet(p.getMilliseconds()); + return t; + } catch (Throwable e) { + Iris.reportError(e); + lock.unlock(); + Iris.warn("Couldn't read " + resourceTypeName + " file: " + j.getPath() + ": " + e.getMessage()); + return null; + } + } + + public String[] getPossibleKeys() { + if (possibleKeys != null) { + return possibleKeys; + } + + Iris.debug("Building " + resourceTypeName + " Possibility Lists"); + KSet m = new KSet<>(); + + for (File i : getFolders()) { + for (File j : i.listFiles()) { + if (j.isFile() && j.getName().endsWith(".js")) { + m.add(j.getName().replaceAll("\\Q.js\\E", "")); + } else if (j.isDirectory()) { + for (File k : j.listFiles()) { + if (k.isFile() && k.getName().endsWith(".js")) { + m.add(j.getName() + "/" + k.getName().replaceAll("\\Q.js\\E", "")); + } else if (k.isDirectory()) { + for (File l : k.listFiles()) { + if (l.isFile() && l.getName().endsWith(".js")) { + m.add(j.getName() + "/" + k.getName() + "/" + l.getName().replaceAll("\\Q.js\\E", "")); + } + } + } + } + } + } + } + + KList v = new KList<>(m); + possibleKeys = v.toArray(new String[0]); + return possibleKeys; + } + + public File findFile(String name) { + lock.lock(); + for (File i : getFolders(name)) { + for (File j : i.listFiles()) { + if (j.isFile() && j.getName().endsWith(".js") && j.getName().split("\\Q.\\E")[0].equals(name)) { + lock.unlock(); + return j; + } + } + + File file = new File(i, name + ".js"); + + if (file.exists()) { + lock.unlock(); + return file; + } + } + + Iris.warn("Couldn't find " + resourceTypeName + ": " + name); + + lock.unlock(); + return null; + } + + public IrisScript load(String name, boolean warn) { + String key = name + "-" + objectClass.getCanonicalName(); + + if (loadCache.containsKey(key)) { + IrisScript t = loadCache.get(key); + return t; + } + + lock.lock(); + for (File i : getFolders(name)) { + for (File j : i.listFiles()) { + if (j.isFile() && j.getName().endsWith(".js") && j.getName().split("\\Q.\\E")[0].equals(name)) { + lock.unlock(); + return loadFile(j, key, name); + } + } + + File file = new File(i, name + ".js"); + + if (file.exists()) { + lock.unlock(); + return loadFile(file, key, name); + } + } + + Iris.warn("Couldn't find " + resourceTypeName + ": " + name); + + lock.unlock(); + return null; + } +} diff --git a/src/main/java/com/volmit/iris/engine/IrisComplex.java b/src/main/java/com/volmit/iris/engine/IrisComplex.java index c4825025e..83b8bf3bd 100644 --- a/src/main/java/com/volmit/iris/engine/IrisComplex.java +++ b/src/main/java/com/volmit/iris/engine/IrisComplex.java @@ -230,7 +230,7 @@ public class IrisComplex implements DataProvider { objectChanceStream = ProceduralStream.ofDouble((x, z) -> { if (engine.getDimension().hasFeatures(engine)) { AtomicDouble str = new AtomicDouble(1D); - for (IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) { + for (IrisFeaturePositional i : engine.getEngineParallax().forEachFeature(x, z)) { str.set(Math.min(str.get(), i.getObjectChanceModifier(x, z, rng, getData()))); } @@ -241,7 +241,7 @@ public class IrisComplex implements DataProvider { }); trueBiomeStream = focus != null ? ProceduralStream.of((x, y) -> focus, Interpolated.of(a -> 0D, b -> focus)).convertAware2D((b, x, z) -> { - for (IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) { + for (IrisFeaturePositional i : engine.getEngineParallax().forEachFeature(x, z)) { IrisBiome bx = i.filter(x, z, b, rng); if (bx != null) { @@ -257,7 +257,7 @@ public class IrisComplex implements DataProvider { fixBiomeType(h, baseBiomeStream.get(x, z), regionStream.get(x, z), x, z, fluidHeight)) .convertAware2D((b, x, z) -> { - for (IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) { + for (IrisFeaturePositional i : engine.getEngineParallax().forEachFeature(x, z)) { IrisBiome bx = i.filter(x, z, b, rng); if (bx != null) { @@ -271,7 +271,7 @@ public class IrisComplex implements DataProvider { .cache2D(cacheSize); trueBiomeStream = focus != null ? ProceduralStream.of((x, y) -> focus, Interpolated.of(a -> 0D, b -> focus)).convertAware2D((b, x, z) -> { - for (IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) { + for (IrisFeaturePositional i : engine.getEngineParallax().forEachFeature(x, z)) { IrisBiome bx = i.filter(x, z, b, rng); if (bx != null) { @@ -287,7 +287,7 @@ public class IrisComplex implements DataProvider { fixBiomeType(h, baseBiomeStream.get(x, z), regionStream.get(x, z), x, z, fluidHeight)) .convertAware2D((b, x, z) -> { - for (IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) { + for (IrisFeaturePositional i : engine.getEngineParallax().forEachFeature(x, z)) { IrisBiome bx = i.filter(x, z, b, rng); if (bx != null) { @@ -330,17 +330,17 @@ public class IrisComplex implements DataProvider { int m = heightf; if (engine.getDimension().isCarving() && engine.getDimension().getTerrainMode().equals(IrisTerrainMode.NORMAL)) { - if (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getFramework().getTerrainActuator()).getRng(), heightf)) { + if (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) { m--; - while (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getFramework().getTerrainActuator()).getRng(), heightf)) { + while (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) { m--; } } } if (engine.getDimension().isCaves()) { - KList caves = ((IrisCaveModifier) engine.getFramework().getCaveModifier()).genCaves(rx, rz, 0, 0, null); + KList caves = ((IrisCaveModifier) engine.getCaveModifier()).genCaves(rx, rz, 0, 0, null); boolean again = true; while (again) { @@ -458,7 +458,7 @@ public class IrisComplex implements DataProvider { AtomicDouble noise = new AtomicDouble(h + fluidHeight + overlayStream.get(x, z)); if (features) { - List p = engine.getFramework().getEngineParallax().forEachFeature(x, z); + List p = engine.getEngineParallax().forEachFeature(x, z); for (IrisFeaturePositional i : p) { noise.set(i.filter(x, z, noise.get(), rng, getData())); diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index 6be28e39f..5d43511c7 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -20,24 +20,34 @@ package com.volmit.iris.engine; import com.google.gson.Gson; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.events.IrisEngineHotloadEvent; +import com.volmit.iris.engine.actuator.IrisBiomeActuator; +import com.volmit.iris.engine.actuator.IrisDecorantActuator; +import com.volmit.iris.engine.actuator.IrisTerrainIslandActuator; +import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.*; +import com.volmit.iris.engine.modifier.IrisCaveModifier; +import com.volmit.iris.engine.modifier.IrisDepositModifier; +import com.volmit.iris.engine.modifier.IrisPostModifier; +import com.volmit.iris.engine.modifier.IrisRavineModifier; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.biome.IrisBiomePaletteLayer; import com.volmit.iris.engine.object.decoration.IrisDecorator; import com.volmit.iris.engine.object.engine.IrisEngineData; import com.volmit.iris.engine.object.objects.IrisObjectPlacement; +import com.volmit.iris.engine.scripting.EngineExecutionEnvironment; import com.volmit.iris.util.context.IrisContext; import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.io.IO; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.PrecisionStopwatch; -import lombok.Getter; -import lombok.Setter; +import lombok.Data; import org.bukkit.Chunk; import org.bukkit.World; import org.bukkit.block.Biome; @@ -47,62 +57,48 @@ import org.bukkit.generator.BlockPopulator; import java.io.File; import java.io.IOException; import java.util.Random; +import java.util.concurrent.atomic.AtomicBoolean; +@Data public class IrisEngine extends BlockPopulator implements Engine { - @Getter private final EngineCompound compound; - - @Getter private final EngineTarget target; - - @Getter private final IrisContext context; - - @Getter - private final EngineFramework framework; - - @Getter private final EngineEffects effects; - - @Getter + private final EngineExecutionEnvironment execution; private final EngineWorldManager worldManager; - - @Setter - @Getter private volatile int parallelism; - - @Getter private final int index; - - @Getter private final EngineMetrics metrics; - - @Setter - @Getter private volatile int minHeight; private boolean failing; private boolean closed; private int cacheId; private final int art; - - @Getter private double maxBiomeObjectDensity; - - @Getter private double maxBiomeLayerDensity; - - @Getter private double maxBiomeDecoratorDensity; - + private final IrisComplex complex; + private final EngineParallaxManager engineParallax; + private final EngineActuator terrainNormalActuator; + private final EngineActuator terrainIslandActuator; + private final EngineActuator decorantActuator; + private final EngineActuator biomeActuator; + private final EngineModifier depositModifier; + private final EngineModifier caveModifier; + private final EngineModifier ravineModifier; + private final EngineModifier postModifier; private final AtomicCache engineData = new AtomicCache<>(); + private final AtomicBoolean cleaning; + private final ChronoLatch cleanLatch; public IrisEngine(EngineTarget target, EngineCompound compound, int index) { + execution = new IrisExecutionEnvironment(this); Iris.info("Initializing Engine: " + target.getWorld().name() + "/" + target.getDimension().getLoadKey() + " (" + target.getHeight() + " height)"); metrics = new EngineMetrics(32); this.target = target; getData().setEngine(this); getEngineData(); - this.framework = new IrisEngineFramework(this); worldManager = new IrisWorldManager(this); this.compound = compound; minHeight = 0; @@ -116,10 +112,26 @@ public class IrisEngine extends BlockPopulator implements Engine { Iris.callEvent(new IrisEngineHotloadEvent(this)); context = new IrisContext(this); context.touch(); + this.complex = new IrisComplex(this); + this.engineParallax = new IrisEngineParallax(this); + this.terrainNormalActuator = new IrisTerrainNormalActuator(this); + this.terrainIslandActuator = new IrisTerrainIslandActuator(this); + this.decorantActuator = new IrisDecorantActuator(this); + this.biomeActuator = new IrisBiomeActuator(this); + this.depositModifier = new IrisDepositModifier(this); + this.ravineModifier = new IrisRavineModifier(this); + this.caveModifier = new IrisCaveModifier(this); + this.postModifier = new IrisPostModifier(this); + cleaning = new AtomicBoolean(false); + cleanLatch = new ChronoLatch(Math.max(10000, Math.min(IrisSettings.get().getParallax() + .getParallaxChunkEvictionMS(), IrisSettings.get().getParallax().getParallaxRegionEvictionMS()))); + } @Override public IrisEngineData getEngineData() { + World w = null; + return engineData.aquire(() -> { File f = new File(getWorld().worldFolder(), "iris/engine-data/" + getDimension().getLoadKey() + "-" + getIndex() + ".json"); @@ -173,9 +185,16 @@ public class IrisEngine extends BlockPopulator implements Engine { J.car(art); closed = true; getWorldManager().close(); - getFramework().close(); getTarget().close(); saveEngineData(); + getEngineParallax().close(); + getTerrainActuator().close(); + getDecorantActuator().close(); + getBiomeActuator().close(); + getDepositModifier().close(); + getRavineModifier().close(); + getCaveModifier().close(); + getPostModifier().close(); } @Override @@ -185,7 +204,35 @@ public class IrisEngine extends BlockPopulator implements Engine { @Override public void recycle() { - getFramework().recycle(); + if (!cleanLatch.flip()) { + return; + } + + if (cleaning.get()) { + cleanLatch.flipDown(); + return; + } + + cleaning.set(true); + + try { + getParallax().cleanup(); + getData().getObjectLoader().clean(); + } catch (Throwable e) { + Iris.reportError(e); + Iris.error("Cleanup failed!"); + e.printStackTrace(); + } + + cleaning.lazySet(false); + } + + + public EngineActuator getTerrainActuator() { + return switch (getDimension().getTerrainMode()) { + case NORMAL -> getTerrainNormalActuator(); + case ISLANDS -> getTerrainIslandActuator(); + }; } @BlockCoordinates @@ -211,18 +258,18 @@ public class IrisEngine extends BlockPopulator implements Engine { switch (getDimension().getTerrainMode()) { case NORMAL -> { - getFramework().getEngineParallax().generateParallaxArea(x >> 4, z >> 4); - getFramework().getTerrainActuator().actuate(x, z, vblocks, multicore); - getFramework().getBiomeActuator().actuate(x, z, vbiomes, multicore); - getFramework().getCaveModifier().modify(x, z, vblocks, multicore); - getFramework().getRavineModifier().modify(x, z, vblocks, multicore); - getFramework().getPostModifier().modify(x, z, vblocks, multicore); - getFramework().getDecorantActuator().actuate(x, z, blocks, multicore); - getFramework().getEngineParallax().insertParallax(x >> 4, z >> 4, blocks); - getFramework().getDepositModifier().modify(x, z, blocks, multicore); + getEngineParallax().generateParallaxArea(x >> 4, z >> 4); + getTerrainActuator().actuate(x, z, vblocks, multicore); + getBiomeActuator().actuate(x, z, vbiomes, multicore); + getCaveModifier().modify(x, z, vblocks, multicore); + getRavineModifier().modify(x, z, vblocks, multicore); + getPostModifier().modify(x, z, vblocks, multicore); + getDecorantActuator().actuate(x, z, blocks, multicore); + getEngineParallax().insertParallax(x >> 4, z >> 4, blocks); + getDepositModifier().modify(x, z, blocks, multicore); } case ISLANDS -> { - getFramework().getTerrainActuator().actuate(x, z, vblocks, multicore); + getTerrainActuator().actuate(x, z, vblocks, multicore); } } diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineFramework.java b/src/main/java/com/volmit/iris/engine/IrisEngineFramework.java deleted file mode 100644 index b50843661..000000000 --- a/src/main/java/com/volmit/iris/engine/IrisEngineFramework.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.engine.actuator.IrisBiomeActuator; -import com.volmit.iris.engine.actuator.IrisDecorantActuator; -import com.volmit.iris.engine.actuator.IrisTerrainIslandActuator; -import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator; -import com.volmit.iris.engine.framework.*; -import com.volmit.iris.engine.modifier.IrisCaveModifier; -import com.volmit.iris.engine.modifier.IrisDepositModifier; -import com.volmit.iris.engine.modifier.IrisPostModifier; -import com.volmit.iris.engine.modifier.IrisRavineModifier; -import com.volmit.iris.util.scheduling.ChronoLatch; -import lombok.Getter; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; - -import java.util.concurrent.atomic.AtomicBoolean; - -public class IrisEngineFramework implements EngineFramework { - - @Getter - private final Engine engine; - - @Getter - private final IrisComplex complex; - - @Getter - final EngineParallaxManager engineParallax; - - @Getter - private final EngineActuator terrainNormalActuator; - - @Getter - private final EngineActuator terrainIslandActuator; - - @Getter - private final EngineActuator decorantActuator; - - @Getter - private final EngineActuator biomeActuator; - - @Getter - private final EngineModifier depositModifier; - - @Getter - private final EngineModifier caveModifier; - - @Getter - private final EngineModifier ravineModifier; - - @Getter - private final EngineModifier postModifier; - - private final AtomicBoolean cleaning; - private final ChronoLatch cleanLatch; - - public IrisEngineFramework(Engine engine) { - this.engine = engine; - this.complex = new IrisComplex(getEngine()); - this.engineParallax = new IrisEngineParallax(getEngine()); - this.terrainNormalActuator = new IrisTerrainNormalActuator(getEngine()); - this.terrainIslandActuator = new IrisTerrainIslandActuator(getEngine()); - this.decorantActuator = new IrisDecorantActuator(getEngine()); - this.biomeActuator = new IrisBiomeActuator(getEngine()); - this.depositModifier = new IrisDepositModifier(getEngine()); - this.ravineModifier = new IrisRavineModifier(getEngine()); - this.caveModifier = new IrisCaveModifier(engine); - this.postModifier = new IrisPostModifier(engine); - cleaning = new AtomicBoolean(false); - cleanLatch = new ChronoLatch(Math.max(10000, Math.min(IrisSettings.get().getParallax().getParallaxChunkEvictionMS(), IrisSettings.get().getParallax().getParallaxRegionEvictionMS()))); - } - - @Override - public synchronized void recycle() { - if (!cleanLatch.flip()) { - return; - } - - if (cleaning.get()) { - cleanLatch.flipDown(); - return; - } - - cleaning.set(true); - - try { - getEngine().getParallax().cleanup(); - getData().getObjectLoader().clean(); - } catch (Throwable e) { - Iris.reportError(e); - Iris.error("Cleanup failed!"); - e.printStackTrace(); - } - - cleaning.lazySet(false); - } - - @Override - public EngineActuator getTerrainActuator() { - return switch (getEngine().getDimension().getTerrainMode()) { - case NORMAL -> getTerrainNormalActuator(); - case ISLANDS -> getTerrainIslandActuator(); - }; - } - - @Override - public void close() { - getEngineParallax().close(); - getTerrainActuator().close(); - getDecorantActuator().close(); - getBiomeActuator().close(); - getDepositModifier().close(); - getRavineModifier().close(); - getCaveModifier().close(); - getPostModifier().close(); - } -} diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java index f9f0994c3..72ac19a93 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java @@ -30,8 +30,7 @@ public class IrisEngineMantle implements EngineMantle { private final Engine engine; private final Mantle mantle; - public IrisEngineMantle(Engine engine) - { + public IrisEngineMantle(Engine engine) { this.engine = engine; this.mantle = new Mantle(new File(engine.getWorld().worldFolder(), "mantle/" + engine.getIndex()), engine.getTarget().getHeight()); } diff --git a/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java b/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java new file mode 100644 index 000000000..78a1c3ea9 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java @@ -0,0 +1,75 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine; + +import com.volmit.iris.Iris; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.scripting.EngineExecutionEnvironment; +import com.volmit.iris.engine.scripting.IrisScriptingAPI; +import com.volmit.iris.util.format.C; +import lombok.Data; +import org.apache.bsf.BSFException; +import org.apache.bsf.BSFManager; +import org.apache.bsf.engines.javascript.JavaScriptEngine; + +@Data +public class IrisExecutionEnvironment implements EngineExecutionEnvironment { + private final BSFManager manager; + private final Engine engine; + private final IrisScriptingAPI api; + private JavaScriptEngine javaScriptEngine; + + public IrisExecutionEnvironment(Engine engine) { + this.engine = engine; + this.api = new IrisScriptingAPI(engine); + this.manager = new BSFManager(); + this.manager.setClassLoader(Iris.class.getClassLoader()); + try { + this.manager.declareBean("Iris", api, api.getClass()); + this.javaScriptEngine = (JavaScriptEngine) this.manager.loadScriptingEngine("javascript"); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + @Override + public IrisScriptingAPI getAPI() { + return api; + } + + public void execute(String script) { + Iris.debug("Execute Script (void) " + C.DARK_GREEN + script); + try { + javaScriptEngine.exec("", 0, 0, getEngine().getData().getScriptLoader().load(script)); + } catch (BSFException e) { + e.printStackTrace(); + } + } + + public Object evaluate(String script) { + Iris.debug("Execute Script (for result) " + C.DARK_GREEN + script); + try { + return javaScriptEngine.eval("", 0, 0, getEngine().getData().getScriptLoader().load(script)); + } catch (BSFException e) { + e.printStackTrace(); + } + + return null; + } +} diff --git a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java index 04e9cf732..77fd87e71 100644 --- a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java +++ b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java @@ -87,8 +87,18 @@ public class IrisWorldManager extends EngineAssignedWorldManager { looper = new Looper() { @Override protected long loop() { + if (getEngine().isClosed()) { + interrupt(); + } + + if (getDimension().isInfiniteEnergy()) { + energy += 1000; + fixEnergy(); + } + if (M.ms() < charge) { energy += 70; + fixEnergy(); } if (cln.flip()) { @@ -126,6 +136,10 @@ public class IrisWorldManager extends EngineAssignedWorldManager { } private boolean onAsyncTick() { + if (getEngine().isClosed()) { + return false; + } + actuallySpawned = 0; if (energy < 100) { @@ -147,7 +161,11 @@ public class IrisWorldManager extends EngineAssignedWorldManager { } if (cl.flip()) { - J.s(() -> precount = getEngine().getWorld().realWorld().getEntities()); + try { + J.s(() -> precount = getEngine().getWorld().realWorld().getEntities()); + } catch (Throwable e) { + close(); + } } int chunkCooldownSeconds = 60; @@ -188,7 +206,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager { getData().getSpawnerLoader() .loadAll(getDimension().getEntitySpawners()) .shuffleCopy(RNG.r).stream().filter(this::canSpawn), - getData().getSpawnerLoader().streamAll(getEngine().getFramework().getEngineParallax() + getData().getSpawnerLoader().streamAll(getEngine().getEngineParallax() .getFeaturesInChunk(c).stream() .flatMap((o) -> o.getFeature().getEntitySpawners().stream())) .filter(this::canSpawn)) @@ -216,7 +234,11 @@ public class IrisWorldManager extends EngineAssignedWorldManager { } } - spawn(c, v); + try { + spawn(c, v); + } catch (Throwable e) { + J.s(() -> spawn(c, v)); + } } //@done } diff --git a/src/main/java/com/volmit/iris/engine/framework/Engine.java b/src/main/java/com/volmit/iris/engine/framework/Engine.java index 6a5d7b2d2..a42fad916 100644 --- a/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -22,6 +22,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.gui.components.RenderType; import com.volmit.iris.core.gui.components.Renderer; import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.object.basic.IrisColor; import com.volmit.iris.engine.object.biome.IrisBiome; @@ -34,6 +35,7 @@ import com.volmit.iris.engine.object.loot.IrisLootTable; import com.volmit.iris.engine.object.meta.InventorySlotType; import com.volmit.iris.engine.object.regional.IrisRegion; import com.volmit.iris.engine.parallax.ParallaxAccess; +import com.volmit.iris.engine.scripting.EngineExecutionEnvironment; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.context.IrisContext; import com.volmit.iris.util.data.B; @@ -61,10 +63,32 @@ import java.util.Arrays; import java.util.UUID; public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootProvider, BlockUpdater, Renderer, Hotloadable { + IrisComplex getComplex(); + + void recycle(); + + EngineParallaxManager getEngineParallax(); + + EngineActuator getTerrainActuator(); + + EngineActuator getDecorantActuator(); + + EngineActuator getBiomeActuator(); + + EngineModifier getCaveModifier(); + + EngineModifier getRavineModifier(); + + EngineModifier getDepositModifier(); + + EngineModifier getPostModifier(); + void close(); IrisContext getContext(); + EngineExecutionEnvironment getExecution(); + double getMaxBiomeObjectDensity(); double getMaxBiomeDecoratorDensity(); @@ -78,19 +102,15 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro void setParallelism(int parallelism); default UUID getBiomeID(int x, int z) { - return getFramework().getComplex().getBaseBiomeIDStream().get(x, z); + return getComplex().getBaseBiomeIDStream().get(x, z); } int getParallelism(); EngineTarget getTarget(); - EngineFramework getFramework(); - void setMinHeight(int min); - void recycle(); - int getIndex(); int getMinHeight(); @@ -149,7 +169,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro IrisBiome biome = getSurfaceBiome((int) x, (int) z); int height = getHeight((int) x, (int) z); double heightFactor = M.lerpInverse(0, getHeight(), height); - Color irc = region.getColor(this.getFramework().getComplex(), RenderType.BIOME); + Color irc = region.getColor(this.getComplex(), RenderType.BIOME); Color ibc = biome.getColor(this, RenderType.BIOME); Color rc = irc != null ? irc : Color.GREEN.darker(); Color bc = ibc != null ? ibc : biome.isAquatic() ? Color.BLUE : Color.YELLOW; @@ -161,7 +181,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro @BlockCoordinates @Override default IrisRegion getRegion(int x, int z) { - return getFramework().getComplex().getRegionStream().get(x, z); + return getComplex().getRegionStream().get(x, z); } @Override @@ -172,13 +192,13 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro @BlockCoordinates @Override default IrisBiome getCaveBiome(int x, int z) { - return getFramework().getComplex().getCaveBiomeStream().get(x, z); + return getComplex().getCaveBiomeStream().get(x, z); } @BlockCoordinates @Override default IrisBiome getSurfaceBiome(int x, int z) { - return getFramework().getComplex().getTrueBiomeStream().get(x, z); + return getComplex().getTrueBiomeStream().get(x, z); } @BlockCoordinates @@ -189,7 +209,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro @BlockCoordinates default int getHeight(int x, int z, boolean ignoreFluid) { - return getFramework().getEngineParallax().getHighest(x, z, getData(), ignoreFluid); + return getEngineParallax().getHighest(x, z, getData(), ignoreFluid); } @BlockCoordinates @@ -323,7 +343,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro list.clear(); } - list.addAll(r.getLootTables(getFramework().getComplex())); + list.addAll(r.getLootTables(getComplex())); } @BlockCoordinates @@ -331,8 +351,8 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro default KList getLootTables(RNG rng, Block b) { int rx = b.getX(); int rz = b.getZ(); - double he = getFramework().getComplex().getHeightStream().get(rx, rz); - PlacedObject po = getFramework().getEngine().getObjectPlacement(rx, b.getY(), rz); + double he = getComplex().getHeightStream().get(rx, rz); + PlacedObject po = getObjectPlacement(rx, b.getY(), rz); if (po != null && po.getPlacement() != null) { if (B.isStorageChest(b.getBlockData())) { @@ -342,9 +362,9 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro } } } - IrisRegion region = getFramework().getComplex().getRegionStream().get(rx, rz); - IrisBiome biomeSurface = getFramework().getComplex().getTrueBiomeStream().get(rx, rz); - IrisBiome biomeUnder = b.getY() < he ? getFramework().getComplex().getCaveBiomeStream().get(rx, rz) : biomeSurface; + IrisRegion region = getComplex().getRegionStream().get(rx, rz); + IrisBiome biomeSurface = getComplex().getTrueBiomeStream().get(rx, rz); + IrisBiome biomeUnder = b.getY() < he ? getComplex().getCaveBiomeStream().get(rx, rz) : biomeSurface; KList tables = new KList<>(); double multiplier = 1D * getDimension().getLoot().getMultiplier() * region.getLoot().getMultiplier() * biomeSurface.getLoot().getMultiplier() * biomeUnder.getLoot().getMultiplier(); injectTables(tables, getDimension().getLoot()); diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java b/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java index be73f0c4f..6903159b5 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java @@ -72,15 +72,11 @@ public interface EngineComponent { return getTarget().getWorld().seed(); } - default EngineFramework getFramework() { - return getEngine().getFramework(); - } - default int getParallelism() { return getEngine().getParallelism(); } default IrisComplex getComplex() { - return getFramework().getComplex(); + return getEngine().getComplex(); } } diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java b/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java index f3cb1ab41..d41bb377b 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java @@ -731,6 +731,8 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce ticker.interrupt(); } + cleaner.interrupt(); + if (getComposite() != null) { getComposite().close(); diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java b/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java index 662892b8e..77321ccef 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java @@ -156,7 +156,7 @@ public interface EngineCompound extends Listener, Hotloadable, DataProvider { Engine e = getEngine(i); if (e.getDimension().isBedrock()) { - int m = ((IrisTerrainNormalActuator) e.getFramework().getTerrainActuator()).getLastBedrock(); + int m = ((IrisTerrainNormalActuator) e.getTerrainActuator()).getLastBedrock(); if (f > m) { f = m; diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineFramework.java b/src/main/java/com/volmit/iris/engine/framework/EngineFramework.java deleted file mode 100644 index bf3b7c6e8..000000000 --- a/src/main/java/com/volmit/iris/engine/framework/EngineFramework.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.framework; - -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.engine.IrisComplex; -import com.volmit.iris.util.data.DataProvider; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; - -public interface EngineFramework extends DataProvider { - Engine getEngine(); - - IrisComplex getComplex(); - - EngineParallaxManager getEngineParallax(); - - default IrisData getData() { - return getComplex().getData(); - } - - default void recycle() { - getEngine().getParallax().cleanup(); - getData().getObjectLoader().clean(); - } - - EngineActuator getTerrainActuator(); - - EngineActuator getDecorantActuator(); - - EngineActuator getBiomeActuator(); - - EngineModifier getCaveModifier(); - - EngineModifier getRavineModifier(); - - EngineModifier getDepositModifier(); - - EngineModifier getPostModifier(); - - void close(); -} diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java b/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java index 6530674e0..7c4a729f8 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java @@ -74,10 +74,6 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { int getParallaxSize(); - default EngineFramework getFramework() { - return getEngine().getFramework(); - } - default ParallaxAccess getParallaxAccess() { return getEngine().getParallax(); } @@ -87,7 +83,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { } default IrisComplex getComplex() { - return getEngine().getFramework().getComplex(); + return getEngine().getComplex(); } default KList getAllRegions() { @@ -214,13 +210,13 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { KList pos = new KList<>(); for (IrisFeaturePositional i : getEngine().getDimension().getSpecificFeatures()) { - if (i.shouldFilter((x << 4) + 8, (z << 4) + 8, getEngine().getFramework().getComplex().getRng(), getData())) { + if (i.shouldFilter((x << 4) + 8, (z << 4) + 8, getEngine().getComplex().getRng(), getData())) { pos.add(i); } } for (IrisFeaturePositional i : getParallaxAccess().getMetaR(x, z).getFeatures()) { - if (i.shouldFilter((x << 4) + 8, (z << 4) + 8, getEngine().getFramework().getComplex().getRng(), getData())) { + if (i.shouldFilter((x << 4) + 8, (z << 4) + 8, getEngine().getComplex().getRng(), getData())) { pos.add(i); } } @@ -242,7 +238,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { } for (IrisFeaturePositional i : getEngine().getDimension().getSpecificFeatures()) { - if (i.shouldFilter(x, z, getEngine().getFramework().getComplex().getRng(), getData())) { + if (i.shouldFilter(x, z, getEngine().getComplex().getRng(), getData())) { pos.add(i); } } @@ -259,7 +255,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { try { for (IrisFeaturePositional k : m.getFeatures()) { - if (k.shouldFilter(x, z, getEngine().getFramework().getComplex().getRng(), getData())) { + if (k.shouldFilter(x, z, getEngine().getComplex().getRng(), getData())) { pos.add(k); } } diff --git a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java index 97e55341c..5dc36b852 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java @@ -22,8 +22,6 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.framework.EngineComponent; -import com.volmit.iris.engine.framework.EngineFramework; import com.volmit.iris.engine.framework.EngineTarget; import com.volmit.iris.engine.object.common.IObjectPlacer; import com.volmit.iris.engine.object.dimensional.IrisDimension; @@ -34,8 +32,7 @@ import com.volmit.iris.util.mantle.Mantle; import org.bukkit.block.TileState; import org.bukkit.block.data.BlockData; -public interface EngineMantle extends IObjectPlacer -{ +public interface EngineMantle extends IObjectPlacer { BlockData AIR = B.get("AIR"); Mantle getMantle(); @@ -66,7 +63,7 @@ public interface EngineMantle extends IObjectPlacer @Override default void set(int x, int y, int z, BlockData d) { - getMantle().set(x,y,z,d == null ? AIR : d); + getMantle().set(x, y, z, d == null ? AIR : d); } @Override @@ -77,7 +74,7 @@ public interface EngineMantle extends IObjectPlacer @Override default BlockData get(int x, int y, int z) { - BlockData block = getMantle().get(x,y,z,BlockData.class); + BlockData block = getMantle().get(x, y, z, BlockData.class); if (block == null) { return AIR; @@ -111,8 +108,7 @@ public interface EngineMantle extends IObjectPlacer return getEngine().getDimension().isDebugSmartBore(); } - default void trim(long dur) - { + default void trim(long dur) { getMantle().trim(dur); } @@ -132,16 +128,11 @@ public interface EngineMantle extends IObjectPlacer return getEngine().getDimension(); } - default EngineFramework getFramework() { - return getEngine().getFramework(); - } - default IrisComplex getComplex() { - return getFramework().getComplex(); + return getEngine().getComplex(); } - default void close() - { + default void close() { getMantle().close(); } } diff --git a/src/main/java/com/volmit/iris/engine/mantle/MantleSized.java b/src/main/java/com/volmit/iris/engine/mantle/MantleSized.java new file mode 100644 index 000000000..b6552e8f5 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/mantle/MantleSized.java @@ -0,0 +1,23 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.mantle; + +public interface MantleSized { + int getMaxChunkSize(); +} diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java index 303686b51..91c23922f 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java @@ -62,11 +62,11 @@ public class IrisPostModifier extends EngineAssignedModifier { @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") private void post(int currentPostX, int currentPostZ, Hunk currentData, int x, int z) { - int h = getFramework().getEngineParallax().trueHeight(x, z); - int ha = getFramework().getEngineParallax().trueHeight(x + 1, z); - int hb = getFramework().getEngineParallax().trueHeight(x, z + 1); - int hc = getFramework().getEngineParallax().trueHeight(x - 1, z); - int hd = getFramework().getEngineParallax().trueHeight(x, z - 1); + int h = getEngine().getEngineParallax().trueHeight(x, z); + int ha = getEngine().getEngineParallax().trueHeight(x + 1, z); + int hb = getEngine().getEngineParallax().trueHeight(x, z + 1); + int hc = getEngine().getEngineParallax().trueHeight(x - 1, z); + int hd = getEngine().getEngineParallax().trueHeight(x, z - 1); // Floating Nibs int g = 0; @@ -234,7 +234,7 @@ public class IrisPostModifier extends EngineAssignedModifier { IrisBiome cave = getComplex().getCaveBiomeStream().get(x, z); if (cave != null) { - for (CaveResult i : ((IrisCaveModifier) getFramework().getCaveModifier()).genCaves(x, z, 0, 0, null)) { + for (CaveResult i : ((IrisCaveModifier) getEngine().getCaveModifier()).genCaves(x, z, 0, 0, null)) { if (i.getCeiling() >= currentData.getMax2DParallelism() || i.getFloor() < 0) { continue; } diff --git a/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java b/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java new file mode 100644 index 000000000..413b488e9 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java @@ -0,0 +1,51 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.object.common; + +import com.volmit.iris.core.project.loader.IrisRegistrant; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class IrisScript extends IrisRegistrant { + private final String source; + + public IrisScript() { + this(""); + } + + public IrisScript(String source) { + this.source = source; + } + + @Override + public String getFolderName() { + return "scripts"; + } + + @Override + public String getTypeName() { + return "Script"; + } + + public String toString() { + return source; + } +} diff --git a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java index 7e632b308..a908c4dd4 100644 --- a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java +++ b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java @@ -316,6 +316,9 @@ public class IrisDimension extends IrisRegistrant { @Desc("Define carve layers") private KList carveLayers = new KList<>(); + @Desc("If true, the spawner system has infinite energy. This is NOT recommended because it would allow for mobs to keep spawning over and over without a rate limit") + private boolean infiniteEnergy = false; + @MinNumber(0.0001) @MaxNumber(512) @Desc("The rock zoom mostly for zooming in on a wispy palette") diff --git a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java index 6c34aeb91..d38dc10a6 100644 --- a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java +++ b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java @@ -21,10 +21,8 @@ package com.volmit.iris.engine.object.entity; import com.volmit.iris.Iris; import com.volmit.iris.core.project.loader.IrisRegistrant; import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.object.annotations.ArrayType; -import com.volmit.iris.engine.object.annotations.Desc; -import com.volmit.iris.engine.object.annotations.RegistryListSpecialEntity; -import com.volmit.iris.engine.object.annotations.Required; +import com.volmit.iris.engine.object.annotations.*; +import com.volmit.iris.engine.object.common.IrisScript; import com.volmit.iris.engine.object.loot.IrisLoot; import com.volmit.iris.engine.object.loot.IrisLootReference; import com.volmit.iris.engine.object.loot.IrisLootTable; @@ -155,17 +153,39 @@ public class IrisEntity extends IrisRegistrant { @Desc("Create a mob from another plugin, such as Mythic Mobs. Should be in the format of a namespace of PluginName:MobName") private String specialType = ""; + @Desc("Set the entity type to UNKNOWN, then define a script here which ends with the entity variable (the result). You can use Iris.getLocation() to find the target location. You can spawn any entity this way.") + @RegistryListResource(IrisScript.class) + private String spawnerScript = ""; + + @ArrayType(min = 1, type = String.class) + @Desc("Set the entity type to UNKNOWN, then define a script here. You can use Iris.getLocation() to find the target location. You can spawn any entity this way.") + @RegistryListResource(IrisScript.class) + private KList postSpawnScripts = new KList<>(); + public Entity spawn(Engine gen, Location at) { return spawn(gen, at, new RNG(at.hashCode())); } public Entity spawn(Engine gen, Location at, RNG rng) { - Entity e = doSpawn(at); + Entity ee = doSpawn(at); - if (e == null) { + if (!spawnerScript.isEmpty() && ee == null) { + synchronized (this) { + gen.getExecution().getAPI().setLocation(at); + try { + ee = (Entity) gen.getExecution().evaluate(spawnerScript); + } catch (Throwable ex) { + Iris.error("You must return an Entity in your scripts to use entity scripts!"); + ex.printStackTrace(); + } + } + } + + if (ee == null) { return null; } + Entity e = ee; e.setCustomName(getCustomName() != null ? C.translateAlternateColorCodes('&', getCustomName()) : null); e.setCustomNameVisible(isCustomNameVisible()); e.setGlowing(isGlowing()); @@ -286,10 +306,25 @@ public class IrisEntity extends IrisRegistrant { spawnEffect.apply(e); } + if (postSpawnScripts.isNotEmpty()) { + synchronized (this) { + gen.getExecution().getAPI().setLocation(at); + gen.getExecution().getAPI().setEntity(ee); + + for (String i : postSpawnScripts) { + gen.getExecution().execute(i); + } + } + } + return e; } private Entity doSpawn(Location at) { + if (type.equals(EntityType.UNKNOWN)) { + return null; + } + if (!Bukkit.isPrimaryThread()) { // Someone called spawn (worldedit maybe?) on a non server thread // Due to the structure of iris, we will call it sync and busy wait until it's done. diff --git a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java index 371d4c138..8a811e5af 100644 --- a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java +++ b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java @@ -22,7 +22,6 @@ import com.volmit.iris.Iris; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.framework.EngineFramework; import com.volmit.iris.engine.modifier.IrisCaveModifier; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.MinNumber; @@ -86,12 +85,11 @@ public class IrisEntitySpawn implements IRare { Location l = switch (getReferenceSpawner().getGroup()) { case NORMAL -> new Location(c.getWorld(), x, hf + 1, z); case CAVE -> { - IrisComplex comp = gen.getFramework().getComplex(); - EngineFramework frame = gen.getFramework(); + IrisComplex comp = gen.getComplex(); IrisBiome cave = comp.getCaveBiomeStream().get(x, z); KList r = new KList<>(); if (cave != null) { - for (CaveResult i : ((IrisCaveModifier) frame.getCaveModifier()).genCaves(x, z)) { + for (CaveResult i : ((IrisCaveModifier) gen.getCaveModifier()).genCaves(x, z)) { if (i.getCeiling() >= gen.getHeight() || i.getFloor() < 0 || i.getCeiling() - 2 <= i.getFloor()) { continue; } diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisEngineStreamType.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisEngineStreamType.java index e69675f7f..6f88ee4ef 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisEngineStreamType.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisEngineStreamType.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.noise; -import com.volmit.iris.engine.framework.EngineFramework; +import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.util.stream.ProceduralStream; @@ -56,13 +56,13 @@ public enum IrisEngineStreamType { @Desc("Represents the identity of regions. Each region has a unique number (very large numbers)") REGION_IDENTITY((f) -> f.getComplex().getRegionIdentityStream()); - private final Function> getter; + private final Function> getter; - IrisEngineStreamType(Function> getter) { + IrisEngineStreamType(Function> getter) { this.getter = getter; } - public ProceduralStream get(EngineFramework engine) { + public ProceduralStream get(Engine engine) { return getter.apply(engine); } } diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisEngineValueType.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisEngineValueType.java index fc1e1c427..f7a0ecb4d 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisEngineValueType.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisEngineValueType.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.noise; -import com.volmit.iris.engine.framework.EngineFramework; +import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.annotations.Desc; import java.util.function.Function; @@ -26,28 +26,28 @@ import java.util.function.Function; @Desc("Represents a value from the engine") public enum IrisEngineValueType { @Desc("Represents actual height of the engine") - ENGINE_HEIGHT((f) -> Double.valueOf(f.getEngine().getHeight())), + ENGINE_HEIGHT((f) -> Double.valueOf(f.getHeight())), @Desc("Represents virtual bottom of the engine in the compound. If this engine is on top of another engine, it's min height would be at the maxHeight of the previous engine + 1") - ENGINE_MIN_HEIGHT((f) -> Double.valueOf(f.getEngine().getMinHeight())), + ENGINE_MIN_HEIGHT((f) -> Double.valueOf(f.getMinHeight())), @Desc("Represents virtual top of the engine in the compound. If this engine is below another engine, it's max height would be at the minHeight of the next engine - 1") - ENGINE_MAX_HEIGHT((f) -> Double.valueOf(f.getEngine().getMaxHeight())), + ENGINE_MAX_HEIGHT((f) -> Double.valueOf(f.getMaxHeight())), @Desc("Represents the position of the engine in the dimensional compound. The bottom (first) dimension stasts at 0. Each new dimension added stacks on top with n+1 for the id.") - ENGINE_INDEX((f) -> Double.valueOf(f.getEngine().getIndex())), + ENGINE_INDEX((f) -> Double.valueOf(f.getIndex())), @Desc("The fluid height defined in the dimension file") FLUID_HEIGHT((f) -> Double.valueOf(f.getComplex().getFluidHeight())), ; - private final Function getter; + private final Function getter; - IrisEngineValueType(Function getter) { + IrisEngineValueType(Function getter) { this.getter = getter; } - public Double get(EngineFramework engine) { + public Double get(Engine engine) { return getter.apply(engine); } } diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisExpressionLoad.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisExpressionLoad.java index c393bdd3f..45c6f6c67 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisExpressionLoad.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisExpressionLoad.java @@ -59,11 +59,11 @@ public class IrisExpressionLoad { public double getValue(RNG rng, IrisData data, double x, double z) { if (engineValue != null) { - return valueCache.aquire(() -> engineValue.get(data.getEngine().getFramework())); + return valueCache.aquire(() -> engineValue.get(data.getEngine())); } if (engineStreamValue != null) { - return streamCache.aquire(() -> engineStreamValue.get(data.getEngine().getFramework())).get(x, z); + return streamCache.aquire(() -> engineStreamValue.get(data.getEngine())).get(x, z); } if (styleValue != null) { @@ -75,11 +75,11 @@ public class IrisExpressionLoad { public double getValue(RNG rng, IrisData data, double x, double y, double z) { if (engineValue != null) { - return valueCache.aquire(() -> engineValue.get(data.getEngine().getFramework())); + return valueCache.aquire(() -> engineValue.get(data.getEngine())); } if (engineStreamValue != null) { - return streamCache.aquire(() -> engineStreamValue.get(data.getEngine().getFramework())).get(x, z); + return streamCache.aquire(() -> engineStreamValue.get(data.getEngine())).get(x, z); } if (styleValue != null) { diff --git a/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java b/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java new file mode 100644 index 000000000..100279ece --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java @@ -0,0 +1,38 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.scripting; + +import com.volmit.iris.engine.framework.Engine; +import org.apache.bsf.BSFManager; + +public interface EngineExecutionEnvironment { + Engine getEngine(); + + IrisScriptingAPI getAPI(); + + BSFManager getManager(); + + void execute(String script); + + Object evaluate(String script); + + default void close() { + + } +} diff --git a/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java b/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java new file mode 100644 index 000000000..9c19a7bb5 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java @@ -0,0 +1,92 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.scripting; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.engine.IrisComplex; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.object.biome.IrisBiome; +import com.volmit.iris.engine.object.dimensional.IrisDimension; +import com.volmit.iris.engine.object.noise.IrisExpression; +import lombok.Data; +import org.bukkit.Location; +import org.bukkit.entity.Entity; + +@Data +public class IrisScriptingAPI { + private final Engine engine; + private IrisRegistrant preprocessorObject; + private double x = 0; + private double y = 0; + private double z = 0; + private Location location; + private Entity entity; + + public IrisScriptingAPI(Engine engine) { + this.engine = engine; + } + + public IrisData getData() { + return getEngine().getData(); + } + + public IrisComplex getComplex() { + return getEngine().getComplex(); + } + + public long getSeed() { + return getEngine().getTarget().getWorld().seed(); + } + + public double expression(String expressionName, double x, double y, double z) { + IrisExpression expression = getData().getExpressionLoader().load(expressionName); + return expression.evaluate(getComplex().getRng(), x, y, z); + } + + public double expression(String expressionName, double x, double z) { + IrisExpression expression = getData().getExpressionLoader().load(expressionName); + return expression.evaluate(getComplex().getRng(), x, z); + } + + public IrisBiome getBiomeAt(int x, int z) { + return getEngine().getSurfaceBiome(x, z); + } + + public IrisDimension getDimension() { + return getEngine().getDimension(); + } + + public void info(String log) { + Iris.info(log); + } + + public void debug(String log) { + Iris.debug(log); + } + + public void warn(String log) { + Iris.warn(log); + } + + public void error(String log) { + Iris.error(log); + } +} diff --git a/src/main/java/com/volmit/iris/util/context/IrisContext.java b/src/main/java/com/volmit/iris/util/context/IrisContext.java index d25065fdd..3795e955a 100644 --- a/src/main/java/com/volmit/iris/util/context/IrisContext.java +++ b/src/main/java/com/volmit/iris/util/context/IrisContext.java @@ -31,6 +31,7 @@ import lombok.Data; public class IrisContext { private static ChronoLatch cl = new ChronoLatch(60000); private static KMap context = new KMap<>(); + private final Engine engine; public static IrisContext get() { return context.get(Thread.currentThread()); @@ -50,8 +51,6 @@ public class IrisContext { } } - private final Engine engine; - public void touch() { IrisContext.touch(this); } @@ -61,6 +60,6 @@ public class IrisContext { } public IrisComplex getComplex() { - return engine.getFramework().getComplex(); + return engine.getComplex(); } } diff --git a/src/main/java/com/volmit/iris/util/io/ReactiveFolder.java b/src/main/java/com/volmit/iris/util/io/ReactiveFolder.java index 8dc1fe0b6..81df14fa9 100644 --- a/src/main/java/com/volmit/iris/util/io/ReactiveFolder.java +++ b/src/main/java/com/volmit/iris/util/io/ReactiveFolder.java @@ -46,7 +46,7 @@ public class ReactiveFolder { if (checkCycle % 3 == 0 ? fw.checkModified() : fw.checkModifiedFast()) { for (File i : fw.getCreated()) { - if (i.getName().endsWith(".iob") || i.getName().endsWith(".json")) { + if (i.getName().endsWith(".iob") || i.getName().endsWith(".json") || i.getName().endsWith(".js")) { modified = true; break; } @@ -54,7 +54,7 @@ public class ReactiveFolder { if (!modified) { for (File i : fw.getChanged()) { - if (i.getName().endsWith(".iob") || i.getName().endsWith(".json")) { + if (i.getName().endsWith(".iob") || i.getName().endsWith(".json") || i.getName().endsWith(".js")) { modified = true; break; } @@ -63,7 +63,7 @@ public class ReactiveFolder { if (!modified) { for (File i : fw.getDeleted()) { - if (i.getName().endsWith(".iob") || i.getName().endsWith(".json")) { + if (i.getName().endsWith(".iob") || i.getName().endsWith(".json") || i.getName().endsWith(".js")) { modified = true; break; } diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java index 136c3b27e..ebbd93916 100644 --- a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java +++ b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java @@ -18,7 +18,7 @@ package com.volmit.iris.util.mantle; -import com.volmit.iris.util.data.Varint; +import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.matter.IrisMatter; import com.volmit.iris.util.matter.Matter; @@ -33,6 +33,7 @@ import java.util.concurrent.atomic.AtomicReferenceArray; * Mantle Chunks are fully atomic & thread safe */ public class MantleChunk { + private final KSet flags; private final AtomicReferenceArray sections; /** @@ -43,6 +44,7 @@ public class MantleChunk { @ChunkCoordinates public MantleChunk(int sectionHeight) { sections = new AtomicReferenceArray<>(sectionHeight); + flags = new KSet<>(); } /** @@ -55,7 +57,12 @@ public class MantleChunk { */ public MantleChunk(int sectionHeight, DataInputStream din) throws IOException, ClassNotFoundException { this(sectionHeight); - int s = Varint.readUnsignedVarInt(din); + int s = din.readByte(); + int f = din.readByte(); + + for (int i = 0; i < f; i++) { + flags.add(din.readUTF()); + } for (int i = 0; i < s; i++) { if (din.readBoolean()) { @@ -64,6 +71,18 @@ public class MantleChunk { } } + public void flag(String s, boolean f) { + if (f) { + flags.add(s); + } else { + flags.remove(s); + } + } + + public boolean isFlagged(String s) { + return flags.contains(s); + } + /** * Check if a section exists (same as get(section) != null) * @@ -130,7 +149,12 @@ public class MantleChunk { * @throws IOException shit happens */ public void write(DataOutputStream dos) throws IOException { - Varint.writeUnsignedVarInt(sections.length(), dos); + dos.writeByte(sections.length()); + dos.writeByte(flags.size()); + + for (String i : flags) { + dos.writeUTF(i); + } for (int i = 0; i < sections.length(); i++) { if (exists(i)) { diff --git a/src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java new file mode 100644 index 000000000..6201b08f1 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java @@ -0,0 +1,57 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.matter.slices; + +import com.volmit.iris.engine.object.feature.IrisFeaturePositional; +import com.volmit.iris.util.matter.Sliced; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +@Sliced +public class ZoneMatter extends RawMatter { + public ZoneMatter() { + this(1, 1, 1); + } + + public ZoneMatter(int width, int height, int depth) { + super(width, height, depth, IrisFeaturePositional.class); + } + + @Override + public void setRaw(int x, int y, int z, IrisFeaturePositional t) { + for (int i = 0; i < getHeight(); i++) { + if (get(x, i, z) == null) { + super.setRaw(x, i, z, t); + break; + } + } + } + + @Override + public void writeNode(IrisFeaturePositional b, DataOutputStream dos) throws IOException { + b.write(dos); + } + + @Override + public IrisFeaturePositional readNode(DataInputStream din) throws IOException { + return IrisFeaturePositional.read(din); + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 03f999133..59767aa97 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -12,6 +12,8 @@ libraries: - com.google.code.gson:gson:2.8.7 - it.unimi.dsi:fastutil:8.5.4 - com.google.guava:guava:30.1.1-jre + - bsf:bsf:2.4.0 + - rhino:js:1.7R2 commands: iris: aliases: [ ir, irs ]