diff --git a/.github/workflows/gradlebuild.yml b/.github/workflows/gradlebuild.yml
new file mode 100644
index 000000000..c2e7040dc
--- /dev/null
+++ b/.github/workflows/gradlebuild.yml
@@ -0,0 +1,25 @@
+name: Gradle Build
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: set up JDK 16
+ uses: actions/setup-java@v2
+ with:
+ java-version: '16'
+ distribution: 'adopt'
+
+ - name: Grant execute permission for gradlew
+ run: chmod +x gradlew
+ - name: Build with Gradle
+ run: ./gradlew build
diff --git a/build.gradle b/build.gradle
index fc5a8fed1..753f55c8a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -32,7 +32,7 @@ plugins {
}
group 'com.volmit.iris'
-version '1.7.4'
+version '1.7.8'
def apiVersion = '1.17'
def name = getRootProject().getName() // See settings.gradle
def main = 'com.volmit.iris.Iris'
@@ -187,6 +187,7 @@ dependencies {
implementation 'net.kyori:adventure-api:4.8.1'
// Dynamically Loaded
+ implementation 'io.timeandspace:smoothie-map:2.0.2'
implementation 'it.unimi.dsi:fastutil:8.5.4'
implementation 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2'
implementation 'org.zeroturnaround:zt-zip:1.14'
@@ -195,4 +196,5 @@ dependencies {
implementation 'com.google.guava:guava:30.1.1-jre'
implementation 'bsf:bsf:2.4.0'
implementation 'rhino:js:1.7R2'
+ implementation 'com.github.ben-manes.caffeine:caffeine:3.0.3'
}
diff --git a/out/production/resources/plugin.yml b/out/production/resources/plugin.yml
index 641130bc2..59767aa97 100644
--- a/out/production/resources/plugin.yml
+++ b/out/production/resources/plugin.yml
@@ -17,7 +17,5 @@ libraries:
commands:
iris:
aliases: [ ir, irs ]
- irisd:
- aliases: [ ird, irsd ]
api-version: ${apiversion}
hotload-dependencies: false
\ 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 fd93d97a8..46b66ae70 100644
--- a/src/main/java/com/volmit/iris/Iris.java
+++ b/src/main/java/com/volmit/iris/Iris.java
@@ -27,11 +27,11 @@ import com.volmit.iris.core.link.MultiverseCoreLink;
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.IrisProject;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.core.service.StudioSVC;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.biome.IrisBiomeCustom;
+import com.volmit.iris.engine.object.block.IrisBlockData;
import com.volmit.iris.engine.object.common.IrisWorld;
import com.volmit.iris.engine.object.compat.IrisCompat;
import com.volmit.iris.engine.object.dimensional.IrisDimension;
@@ -116,12 +116,10 @@ public class Iris extends VolmitPlugin implements Listener {
sender.setTag(getTag());
instance = this;
compat = IrisCompat.configured(getDataFile("compat.json"));
-
linkMultiverseCore = new MultiverseCoreLink();
linkOraxen = new OraxenLink();
linkMythicMobs = new MythicMobsLink();
configWatcher = new FileWatcher(getDataFile("settings.json"));
-
services.values().forEach(IrisService::onEnable);
services.values().forEach(this::registerListener);
}
@@ -165,6 +163,7 @@ public class Iris extends VolmitPlugin implements Listener {
HandlerList.unregisterAll((Plugin) this);
postShutdown.forEach(Runnable::run);
services.clear();
+ MultiBurst.burst.close();
super.onDisable();
}
@@ -604,14 +603,7 @@ public class Iris extends VolmitPlugin implements Listener {
}
public static void verbose(String string) {
- try {
- if (IrisSettings.get().getGeneral().isVerbose()) {
- msg(C.GRAY + string);
- }
- } catch (Throwable e) {
- msg(C.GRAY + string);
- Iris.reportError(e);
- }
+ debug(string);
}
public static void success(String string) {
@@ -683,7 +675,7 @@ public class Iris extends VolmitPlugin implements Listener {
}
public boolean isMCA() {
- return !IrisSettings.get().getGenerator().isDisableMCA();
+ return IrisSettings.get().getGenerator().isHeadlessPregeneration();
}
public static void reportErrorChunk(int x, int z, Throwable e, String extra) {
@@ -704,7 +696,7 @@ public class Iris extends VolmitPlugin implements Listener {
}
}
- public static synchronized void reportError(Throwable e) {
+ public static void reportError(Throwable e) {
if (IrisSettings.get().getGeneral().isDebug()) {
String n = e.getClass().getCanonicalName() + "-" + e.getStackTrace()[0].getClassName() + "-" + e.getStackTrace()[0].getLineNumber();
diff --git a/src/main/java/com/volmit/iris/core/IrisSettings.java b/src/main/java/com/volmit/iris/core/IrisSettings.java
index 7c72ea270..7025af4e3 100644
--- a/src/main/java/com/volmit/iris/core/IrisSettings.java
+++ b/src/main/java/com/volmit/iris/core/IrisSettings.java
@@ -20,6 +20,7 @@ package com.volmit.iris.core;
import com.google.gson.Gson;
import com.volmit.iris.Iris;
+import com.volmit.iris.engine.object.basic.IrisRange;
import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.io.IO;
import com.volmit.iris.util.json.JSONException;
@@ -56,6 +57,11 @@ public class IrisSettings {
return getParallax().getParallaxRegionEvictionMS();
}
+ public static int getPriority(int c)
+ {
+ return Math.max(Math.min(c, Thread.MAX_PRIORITY), Thread.MIN_PRIORITY);
+ }
+
public static int getThreadCount(int c) {
if (c < 2 && c >= 0) {
return 2;
@@ -82,13 +88,7 @@ public class IrisSettings {
@Data
public static class IrisSettingsConcurrency {
- public int engineThreadCount = -1;
- public int engineThreadPriority = 6;
- public int pregenThreadCount = -1;
- public int pregenThreadPriority = 8;
- public int miscThreadCount = -4;
- public int miscThreadPriority = 3;
- public boolean unstableLockingHeuristics = false;
+ public int parallelism = -1;
}
@Data
@@ -101,7 +101,6 @@ public class IrisSettings {
public static class IrisSettingsGeneral {
public boolean commandSounds = true;
public boolean debug = false;
- public boolean verbose = false;
public boolean ignoreWorldEdit = false;
public boolean disableNMS = false;
public boolean keepProductionOnReload = false;
@@ -115,7 +114,6 @@ public class IrisSettings {
@Data
public static class IrisSettingsGUI {
-
public boolean useServerLaunchedGuis = true;
public boolean maximumPregenGuiFPS = false;
public boolean localPregenGui = true;
@@ -124,10 +122,8 @@ public class IrisSettings {
@Data
public static class IrisSettingsGenerator {
public String defaultWorldType = "overworld";
- public boolean disableMCA = false;
+ public boolean headlessPregeneration = false;
public boolean systemEffects = true;
- public boolean systemEntitySpawnOverrides = true;
- public boolean systemEntityInitialSpawns = true;
public int maxBiomeChildDepth = 4;
public boolean preventLeafDecay = true;
}
@@ -162,65 +158,14 @@ public class IrisSettings {
try {
String ss = IO.readAll(s);
settings = new Gson().fromJson(ss, IrisSettings.class);
-
- J.a(() ->
- {
- try {
- JSONObject j = new JSONObject(ss);
- boolean u = false;
- for (String i : def.keySet()) {
- if (!j.has(i)) {
- u = true;
- j.put(i, def.get(i));
- Iris.warn("Adding new config key: " + i);
- }
- }
-
- for (String i : new KSet<>(j.keySet())) {
- if (!def.has(i)) {
- u = true;
- j.remove(i);
- Iris.warn("Removing unused config key: " + i);
- }
- }
-
- if (u) {
- try {
- IO.writeAll(s, j.toString(4));
- Iris.info("Updated Configuration Files");
- } catch (Throwable e) {
- e.printStackTrace();
- Iris.reportError(e);
- }
- }
- } catch (Throwable ee) {
- Iris.reportError(ee);
- Iris.error("Configuration Error in settings.json! " + ee.getClass().getSimpleName() + ": " + ee.getMessage());
- Iris.warn("Attempting to fix configuration while retaining valid in-memory settings...");
-
- try {
- IO.writeAll(s, new JSONObject(new Gson().toJson(settings)).toString(4));
- Iris.info("Configuration Fixed!");
- } catch (IOException e) {
- Iris.reportError(e);
- e.printStackTrace();
- Iris.error("ERROR! CONFIGURATION IMPOSSIBLE TO READ! Using an unmodifiable configuration from memory. Please delete the settings.json at some point to try to restore configurability!");
- }
- }
- });
+ try {
+ IO.writeAll(s, new JSONObject(new Gson().toJson(settings)).toString(4));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
} catch (Throwable ee) {
Iris.reportError(ee);
Iris.error("Configuration Error in settings.json! " + ee.getClass().getSimpleName() + ": " + ee.getMessage());
- Iris.warn("Attempting to fix configuration while retaining valid in-memory settings...");
-
- try {
- IO.writeAll(s, new JSONObject(new Gson().toJson(settings)).toString(4));
- Iris.info("Configuration Fixed!");
- } catch (IOException e) {
- Iris.reportError(e);
- e.printStackTrace();
- Iris.error("ERROR! CONFIGURATION IMPOSSIBLE TO READ! Using an unmodifiable configuration from memory. Please delete the settings.json at some point to try to restore configurability!");
- }
}
}
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 993cdf13f..ada87b74f 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
@@ -32,6 +32,9 @@ public class CommandIrisStudio extends MortarCommand {
@Command
private CommandIrisStudioExecute execute;
+ @Command
+ private CommandIrisStudioCompile compile;
+
@Command
private CommandIrisStudioOpen open;
diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioCompile.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioCompile.java
new file mode 100644
index 000000000..6aacda65a
--- /dev/null
+++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioCompile.java
@@ -0,0 +1,68 @@
+/*
+ * 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.IrisProject;
+import com.volmit.iris.core.service.ConversionSVC;
+import com.volmit.iris.core.service.StudioSVC;
+import com.volmit.iris.util.collection.KList;
+import com.volmit.iris.util.plugin.MortarCommand;
+import com.volmit.iris.util.plugin.VolmitSender;
+import com.volmit.iris.util.scheduling.jobs.Job;
+import com.volmit.iris.util.scheduling.jobs.JobCollection;
+
+public class CommandIrisStudioCompile extends MortarCommand {
+ public CommandIrisStudioCompile() {
+ super("compile");
+ requiresPermission(Iris.perm.studio);
+ setDescription("Compiles a pack for speed");
+ setCategory("Studio");
+ }
+
+ @Override
+ public void addTabOptions(VolmitSender sender, String[] args, KList list) {
+
+ }
+
+ @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;
+ }
+
+ if(args.length == 0)
+ {
+ sender.sendMessage(getArgsUsage());
+ return true;
+ }
+
+ IrisProject project = new IrisProject(Iris.instance.getDataFolder(StudioSVC.WORKSPACE_NAME, args[0]));
+ project.compile(sender);
+
+ return true;
+ }
+
+ @Override
+ protected String getArgsUsage() {
+ return "[project]";
+ }
+}
diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java
index f705d75e8..dcb5d5ee1 100644
--- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java
+++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java
@@ -66,7 +66,7 @@ public class CommandIrisStudioUpdate extends MortarCommand {
IrisData data = IrisData.get(Iris.service(StudioSVC.class).getWorkspaceFolder(args[0]));
int t = data.getObjectLoader().getPossibleKeys().length;
ChronoLatch cl = new ChronoLatch(250, false);
- MultiBurst bx = new MultiBurst("Object Rewriter", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors());
+ MultiBurst bx = MultiBurst.burst;
BurstExecutor b = bx.burst();
int g = 0;
for (String f : data.getObjectLoader().getPossibleKeys()) {
@@ -102,7 +102,6 @@ public class CommandIrisStudioUpdate extends MortarCommand {
int finalG = g;
J.a(() -> {
b.complete();
- bx.shutdownNow();
sender.sendMessage("Done! Rewrote " + Form.f(finalG) + " Objects!");
});
}
diff --git a/src/main/java/com/volmit/iris/core/decrees/DecStudio.java b/src/main/java/com/volmit/iris/core/decrees/DecStudio.java
index cd5efd934..90abc32d3 100644
--- a/src/main/java/com/volmit/iris/core/decrees/DecStudio.java
+++ b/src/main/java/com/volmit/iris/core/decrees/DecStudio.java
@@ -78,6 +78,7 @@ import java.io.File;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
import java.util.function.Supplier;
@Decree(name = "studio", aliases = {"std", "s"}, description = "Studio Commands", studio = true)
@@ -133,7 +134,7 @@ public class DecStudio implements DecreeExecutor {
KList jobs = new KList<>();
KList files = new KList();
files(Iris.instance.getDataFolder("packs", project.getLoadKey()), files);
- MultiBurst burst = new MultiBurst("Cleaner", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors() * 2);
+ MultiBurst burst = MultiBurst.burst;
jobs.add(new SingleJob("Updating Workspace", () -> {
if (!new IrisProject(Iris.service(StudioSVC.class).getWorkspaceFolder(project.getLoadKey())).updateWorkspace()) {
@@ -208,7 +209,7 @@ public class DecStudio implements DecreeExecutor {
IrisData data = IrisData.get(Iris.service(StudioSVC.class).getWorkspaceFolder(project.getLoadKey()));
for (String f : data.getObjectLoader().getPossibleKeys()) {
- CompletableFuture> gg = burst.complete(() -> {
+ Future> gg = burst.complete(() -> {
File ff = data.getObjectLoader().findFile(f);
IrisObject oo = new IrisObject(0, 0, 0);
try {
@@ -237,8 +238,6 @@ public class DecStudio implements DecreeExecutor {
jobs.add(q);
}
- jobs.add(new SingleJob("Finishing Up", burst::shutdownNow));
-
new JobCollection("Cleaning", jobs).execute(sender());
}
diff --git a/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java b/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java
index fa612adcb..66ab5bd39 100644
--- a/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java
+++ b/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java
@@ -59,7 +59,7 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List
static double ascale = 10;
CNG cng = NoiseStyle.STATIC.create(new RNG(RNG.r.nextLong()));
@SuppressWarnings("CanBeFinal")
- MultiBurst gx = new MultiBurst("Iris Noise Renderer", Thread.MAX_PRIORITY, Runtime.getRuntime().availableProcessors());
+ MultiBurst gx = MultiBurst.burst;
ReentrantLock l = new ReentrantLock();
BufferedImage img;
int w = 0;
@@ -213,7 +213,7 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List
});
}
- e.complete(1000);
+ e.complete();
gg.drawImage(img, 0, 0, getParent().getWidth() * accuracy, getParent().getHeight() * accuracy, (img, infoflags, x, y, width, height) -> true);
}
@@ -299,7 +299,6 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List
frame.addWindowListener(new java.awt.event.WindowAdapter() {
@Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
- nv.gx.shutdownLater();
Iris.instance.unregisterListener(nv);
}
});
diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java
index 43e9ca166..c3f8c7169 100644
--- a/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java
+++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java
@@ -29,11 +29,12 @@ import org.bukkit.Chunk;
import org.bukkit.World;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
public class AsyncPregenMethod implements PregeneratorMethod {
private final World world;
private final MultiBurst burst;
- private final KList> future;
+ private final KList> future;
public AsyncPregenMethod(World world, int threads) {
if (!PaperLib.isPaper()) {
@@ -41,7 +42,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
}
this.world = world;
- burst = new MultiBurst("Iris Async Pregenerator", IrisSettings.get().getConcurrency().getPregenThreadPriority(), threads);
+ burst = MultiBurst.burst;
future = new KList<>(1024);
}
@@ -69,7 +70,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
}
private void waitForChunks() {
- for (CompletableFuture> i : future.copy()) {
+ for (Future> i : future.copy()) {
try {
i.get();
future.remove(i);
@@ -92,7 +93,6 @@ public class AsyncPregenMethod implements PregeneratorMethod {
@Override
public void close() {
waitForChunks();
- burst.shutdownAndAwait();
unloadAndSaveAllChunks();
}
@@ -114,7 +114,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
@Override
public void generateChunk(int x, int z, PregenListener listener) {
- if (future.size() > IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount())) {
+ if (future.size() > IrisSettings.getThreadCount((int) IrisSettings.get().getConcurrency().getParallelism())) { // TODO: FIX
waitForChunks();
}
diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java
index 1f8b06397..f6e5a6f04 100644
--- a/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java
+++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java
@@ -42,7 +42,7 @@ public class HybridPregenMethod implements PregeneratorMethod {
}
private boolean supportsHeadless(World world) {
- return IrisToolbelt.access(world) != null && !IrisSettings.get().getGenerator().isDisableMCA();
+ return IrisToolbelt.access(world) != null && IrisSettings.get().getGenerator().isHeadlessPregeneration();
}
@Override
diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java
index 6a378f786..d796ce182 100644
--- a/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java
+++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java
@@ -95,7 +95,7 @@ public class MedievalPregenMethod implements PregeneratorMethod {
@Override
public void generateChunk(int x, int z, PregenListener listener) {
- if (futures.size() > IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount())) {
+ if (futures.size() > IrisSettings.getThreadCount((int) IrisSettings.get().getConcurrency().getParallelism())) {
waitForChunks();
}
diff --git a/src/main/java/com/volmit/iris/core/project/IrisProject.java b/src/main/java/com/volmit/iris/core/project/IrisProject.java
index bc4564a3b..1a949fdc7 100644
--- a/src/main/java/com/volmit/iris/core/project/IrisProject.java
+++ b/src/main/java/com/volmit/iris/core/project/IrisProject.java
@@ -22,6 +22,7 @@ import com.google.gson.Gson;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
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.core.tools.IrisToolbelt;
import com.volmit.iris.engine.object.biome.IrisBiome;
@@ -30,6 +31,7 @@ import com.volmit.iris.engine.object.dimensional.IrisDimension;
import com.volmit.iris.engine.object.entity.IrisEntity;
import com.volmit.iris.engine.object.loot.IrisLootTable;
import com.volmit.iris.engine.object.noise.IrisGenerator;
+import com.volmit.iris.engine.object.objects.IrisObject;
import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
import com.volmit.iris.engine.object.regional.IrisRegion;
import com.volmit.iris.engine.object.spawners.IrisSpawner;
@@ -37,7 +39,9 @@ import com.volmit.iris.engine.platform.PlatformChunkGenerator;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.collection.KSet;
+import com.volmit.iris.util.data.B;
import com.volmit.iris.util.exceptions.IrisException;
+import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.io.IO;
import com.volmit.iris.util.json.JSONArray;
@@ -48,6 +52,10 @@ import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.O;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
+import com.volmit.iris.util.scheduling.jobs.Job;
+import com.volmit.iris.util.scheduling.jobs.JobCollection;
+import com.volmit.iris.util.scheduling.jobs.ParallelQueueJob;
+import com.volmit.iris.util.scheduling.jobs.QueueJob;
import lombok.Data;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
@@ -443,7 +451,6 @@ public class IrisProject {
return null;
}
-
public static int clean(VolmitSender s, File clean) {
int c = 0;
if (clean.isDirectory()) {
@@ -499,4 +506,153 @@ public class IrisProject {
}
}
}
+
+ public void compile(VolmitSender sender) {
+ IrisData data = IrisData.get(getPath());
+ KList jobs = new KList();
+ KList files = new KList();
+ KList objects = new KList();
+ files(getPath(), files);
+ filesObjects(getPath(), objects);
+
+ jobs.add(new ParallelQueueJob() {
+ @Override
+ public void execute(File f) {
+ try {
+ IrisObject o = new IrisObject(0,0,0);
+ o.read(f);
+
+ if(o.getBlocks().isEmpty())
+ {
+ sender.sendMessageRaw("" + f.getPath() +
+ "'>- IOB " + f.getName() + " has 0 blocks!");
+ }
+
+ if(o.getW() == 0 || o.getH() == 0 || o.getD() == 0)
+ {
+ sender.sendMessageRaw("" + f.getPath() + "\nThe width height or depth has a zero in it (bad format)" +
+ "'>- IOB " + f.getName() + " is not 3D!");
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "IOB";
+ }
+ }.queue(objects));
+
+ jobs.add(new ParallelQueueJob() {
+ @Override
+ public void execute(File f) {
+ try {
+ JSONObject p = new JSONObject(IO.readAll(f));
+ fixBlocks(p);
+ scanForErrors(data, f, p, sender);
+ IO.writeAll(f, p.toString(4));
+
+ } catch (Throwable e) {
+ sender.sendMessageRaw("" + f.getPath() +
+ "\n" +e.getMessage() +
+ "'>- JSON Error " + f.getName());
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "JSON";
+ }
+ }.queue(files));
+
+ new JobCollection("Compile", jobs).execute(sender);
+ }
+
+ private void scanForErrors(IrisData data, File f, JSONObject p, VolmitSender sender) {
+ String key = data.toLoadKey(f);
+ ResourceLoader> loader = data.getTypedLoaderFor(f);
+
+ if(loader == null)
+ {
+ sender.sendMessageBasic("Can't find loader for " + f.getPath());
+ return;
+ }
+
+ IrisRegistrant load = loader.load(key);
+ compare(load.getClass(), p, sender, new KList<>());
+ load.scanForErrors(p, sender);
+ }
+
+ public void compare(Class> c, JSONObject j, VolmitSender sender, KList path)
+ {
+ try
+ {
+ Object o = c.getClass().getConstructor().newInstance();
+ }
+
+ catch(Throwable e)
+ {
+
+ }
+ }
+
+ public void files(File clean, KList files) {
+ if (clean.isDirectory()) {
+ for (File i : clean.listFiles()) {
+ files(i, files);
+ }
+ } else if (clean.getName().endsWith(".json")) {
+ try {
+ files.add(clean);
+ } catch (Throwable e) {
+ Iris.reportError(e);
+ }
+ }
+ }
+
+ public void filesObjects(File clean, KList files) {
+ if (clean.isDirectory()) {
+ for (File i : clean.listFiles()) {
+ filesObjects(i, files);
+ }
+ } else if (clean.getName().endsWith(".iob")) {
+ try {
+ files.add(clean);
+ } catch (Throwable e) {
+ Iris.reportError(e);
+ }
+ }
+ }
+
+ private void fixBlocks(JSONObject obj) {
+ for (String i : obj.keySet()) {
+ Object o = obj.get(i);
+
+ if (i.equals("block") && o instanceof String && !o.toString().trim().isEmpty() && !o.toString().contains(":")) {
+ obj.put(i, "minecraft:" + o);
+ }
+
+ if (o instanceof JSONObject) {
+ fixBlocks((JSONObject) o);
+ } else if (o instanceof JSONArray) {
+ fixBlocks((JSONArray) o);
+ }
+ }
+ }
+
+ private void fixBlocks(JSONArray obj) {
+ for (int i = 0; i < obj.length(); i++) {
+ Object o = obj.get(i);
+
+ if (o instanceof JSONObject) {
+ fixBlocks((JSONObject) o);
+ } else if (o instanceof JSONArray) {
+ fixBlocks((JSONArray) o);
+ }
+ }
+ }
}
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 c77d29000..989f3126e 100644
--- a/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java
+++ b/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java
@@ -32,6 +32,7 @@ import org.bukkit.enchantments.Enchantment;
import org.bukkit.potion.PotionEffectType;
import java.awt.*;
+import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;
@@ -536,8 +537,8 @@ public class SchemaBuilder {
d.add("* Default Value is " + value);
}
}
- } catch (Throwable e) {
- Iris.reportError(e);
+ } catch (Throwable ignored) {
+
}
description.forEach((g) -> d.add(g.trim()));
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 5b18e1fdc..518a151ab 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
@@ -19,9 +19,11 @@
package com.volmit.iris.core.project.loader;
import com.volmit.iris.Iris;
+import com.volmit.iris.core.service.StudioSVC;
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.cave.IrisCave;
import com.volmit.iris.engine.object.common.IrisScript;
import com.volmit.iris.engine.object.dimensional.IrisDimension;
import com.volmit.iris.engine.object.entity.IrisEntity;
@@ -42,8 +44,9 @@ import com.volmit.iris.util.math.RNG;
import lombok.Data;
import java.io.File;
-import java.util.Objects;
+import java.util.*;
import java.util.function.Function;
+import java.util.stream.Collectors;
@Data
public class IrisData {
@@ -63,6 +66,7 @@ public class IrisData {
private ResourceLoader expressionLoader;
private ResourceLoader objectLoader;
private ResourceLoader scriptLoader;
+ private ResourceLoader caveLoader;
private KMap, ResourceLoader extends IrisRegistrant>> loaders = new KMap<>();
private boolean closed;
private final File dataFolder;
@@ -87,6 +91,23 @@ public class IrisData {
dataLoaders.v().forEach(IrisData::cleanupEngine);
}
+ public ResourceLoader> getTypedLoaderFor(File f) {
+ String[] k = f.getPath().split("\\Q"+File.separator+"\\E");
+
+ for(String i : k)
+ {
+ for(ResourceLoader> j : loaders.values())
+ {
+ if(j.getFolderName().equals(i))
+ {
+ return j;
+ }
+ }
+ }
+
+ return null;
+ }
+
public void cleanupEngine()
{
if(engine != null && engine.isClosed())
@@ -199,6 +220,7 @@ public class IrisData {
this.jigsawStructureLoader = registerLoader(IrisJigsawStructure.class);
this.jigsawPieceLoader = registerLoader(IrisJigsawPiece.class);
this.generatorLoader = registerLoader(IrisGenerator.class);
+ this.caveLoader = registerLoader(IrisCave.class);
this.blockLoader = registerLoader(IrisBlockData.class);
this.expressionLoader = registerLoader(IrisExpression.class);
this.objectLoader = registerLoader(IrisObject.class);
@@ -273,6 +295,10 @@ public class IrisData {
return loadAny(key, (dm) -> dm.getRegionLoader().load(key, false));
}
+ public static IrisCave loadAnyCave(String key) {
+ return loadAny(key, (dm) -> dm.getCaveLoader().load(key, false));
+ }
+
public static IrisDimension loadAnyDimension(String key) {
return loadAny(key, (dm) -> dm.getDimensionLoader().load(key, false));
}
@@ -304,4 +330,39 @@ public class IrisData {
return null;
}
+
+ public String toLoadKey(File f) {
+ if(f.getPath().startsWith(getDataFolder().getPath()))
+ {
+ String[] full = f.getPath().split("\\Q" + File.separator + "\\E");
+ String[] df = getDataFolder().getPath().split("\\Q" + File.separator + "\\E");
+ String g = "";
+ boolean m = true;
+ for(int i = 0; i < full.length; i++)
+ {
+ if(i >= df.length)
+ {
+ if(m)
+ {
+ m = false;
+ continue;
+ }
+
+ g += "/" + full[i];
+ }
+ }
+
+ String ff = g.toString().substring(1).split("\\Q.\\E")[0];
+ return ff;
+ }
+
+ else
+ {
+ Iris.error("Forign file from loader " + f.getPath() + " (loader realm: " + getDataFolder().getPath() + ")");
+ }
+
+ Iris.error("Failed to load " + f.getPath() + " (loader realm: " + getDataFolder().getPath() + ")");
+
+ return null;
+ }
}
\ No newline at end of file
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 c457f19b4..40072e565 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
@@ -24,6 +24,8 @@ 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 com.volmit.iris.util.json.JSONObject;
+import com.volmit.iris.util.plugin.VolmitSender;
import lombok.Data;
import java.awt.*;
@@ -55,4 +57,6 @@ public abstract class IrisRegistrant {
return getLoadFile();
}
+
+ public abstract void scanForErrors(JSONObject p, VolmitSender sender);
}
diff --git a/src/main/java/com/volmit/iris/core/service/CommandSVC.java b/src/main/java/com/volmit/iris/core/service/CommandSVC.java
index 13c636d03..6adaeb2b7 100644
--- a/src/main/java/com/volmit/iris/core/service/CommandSVC.java
+++ b/src/main/java/com/volmit/iris/core/service/CommandSVC.java
@@ -29,7 +29,7 @@ import com.volmit.iris.util.plugin.IrisService;
public class CommandSVC implements IrisService, DecreeSystem {
@Override
public void onEnable() {
- Iris.instance.getCommand("irisd").setExecutor(this);
+ // TODO Iris.instance.getCommand("irisd").setExecutor(this);
}
@Override
diff --git a/src/main/java/com/volmit/iris/core/service/PreservationSVC.java b/src/main/java/com/volmit/iris/core/service/PreservationSVC.java
index 49a7a8ad0..a6ea2ac7f 100644
--- a/src/main/java/com/volmit/iris/core/service/PreservationSVC.java
+++ b/src/main/java/com/volmit/iris/core/service/PreservationSVC.java
@@ -31,7 +31,6 @@ import java.util.concurrent.ExecutorService;
public class PreservationSVC implements IrisService
{
private KList threads = new KList<>();
- private KList bursts = new KList<>();
private KList services = new KList<>();
private Looper dereferencer;
@@ -42,7 +41,7 @@ public class PreservationSVC implements IrisService
public void register(MultiBurst burst)
{
- bursts.add(burst);
+
}
public void register(ExecutorService service)
@@ -94,20 +93,6 @@ public class PreservationSVC implements IrisService
}
}
- for(MultiBurst i : bursts)
- {
- try
- {
- i.shutdownNow();
- Iris.info("Shutdown Multiburst " + i);
- }
-
- catch(Throwable e)
- {
- Iris.reportError(e);
- }
- }
-
for(ExecutorService i : services)
{
try
diff --git a/src/main/java/com/volmit/iris/core/service/StudioSVC.java b/src/main/java/com/volmit/iris/core/service/StudioSVC.java
index 5adadda95..214c581a6 100644
--- a/src/main/java/com/volmit/iris/core/service/StudioSVC.java
+++ b/src/main/java/com/volmit/iris/core/service/StudioSVC.java
@@ -82,18 +82,6 @@ public class StudioSVC implements IrisService {
IrisToolbelt.evacuate(i);
IrisToolbelt.access(i).close();
}
-
- else
- {
- if(!IrisSettings.get().getGeneral().isKeepProductionOnReload())
- {
- IrisToolbelt.evacuate(i);
- IrisToolbelt.access(i).close();
- Iris.error("You cannot reload Iris while production worlds are active!");
- Iris.error("To prevent corrupted chunks, Iris is shutting the server down now!");
- Bukkit.shutdown();
- }
- }
}
}
}
diff --git a/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java b/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java
index 8277f117b..dfb0ca4b0 100644
--- a/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java
+++ b/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java
@@ -128,7 +128,7 @@ public class IrisToolbelt {
return pregenerate(task, new HeadlessPregenMethod(((HeadlessGenerator) gen).getWorld(), (HeadlessGenerator) gen));
}
- return pregenerate(task, new HybridPregenMethod(gen.getEngine().getWorld().realWorld(), IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount())));
+ return pregenerate(task, new HybridPregenMethod(gen.getEngine().getWorld().realWorld(), IrisSettings.getThreadCount((int) IrisSettings.get().getConcurrency().getParallelism())));
}
/**
@@ -144,7 +144,7 @@ public class IrisToolbelt {
return pregenerate(task, access(world));
}
- return pregenerate(task, new HybridPregenMethod(world, IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount())));
+ return pregenerate(task, new HybridPregenMethod(world, IrisSettings.getThreadCount((int) IrisSettings.get().getConcurrency().getParallelism())));
}
/**
diff --git a/src/main/java/com/volmit/iris/engine/IrisComplex.java b/src/main/java/com/volmit/iris/engine/IrisComplex.java
index 43a11c3d3..cfff636a1 100644
--- a/src/main/java/com/volmit/iris/engine/IrisComplex.java
+++ b/src/main/java/com/volmit/iris/engine/IrisComplex.java
@@ -30,7 +30,6 @@ import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.common.CaveResult;
import com.volmit.iris.engine.object.decoration.IrisDecorationPart;
import com.volmit.iris.engine.object.decoration.IrisDecorator;
-import com.volmit.iris.engine.object.dimensional.IrisTerrainMode;
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
import com.volmit.iris.engine.object.noise.IrisGenerator;
import com.volmit.iris.engine.object.noise.IrisInterpolator;
@@ -65,9 +64,6 @@ public class IrisComplex implements DataProvider {
private ProceduralStream regionStyleStream;
private ProceduralStream regionIdentityStream;
private ProceduralStream regionIDStream;
- private ProceduralStream islandStream;
- private ProceduralStream islandHeightStream;
- private ProceduralStream islandDepthStream;
private ProceduralStream bridgeStream;
private ProceduralStream landBiomeStream;
private ProceduralStream caveBiomeStream;
@@ -86,8 +82,6 @@ public class IrisComplex implements DataProvider {
private ProceduralStream heightFluidStream;
private ProceduralStream trueHeightStream;
private ProceduralStream slopeStream;
- private ProceduralStream islandTopStream;
- private ProceduralStream islandBottomStream;
private ProceduralStream topSurfaceStream;
private ProceduralStream rngStream;
private ProceduralStream chunkRngStream;
@@ -167,11 +161,6 @@ public class IrisComplex implements DataProvider {
: regionStyleStream
.selectRarity(engine.getDimension().getRegions(), (i) -> data.getRegionLoader().load(i))
.convertCached((s) -> data.getRegionLoader().load(s)).cache2D(cacheSize);
- islandStream = regionStyleStream
- .seededChance(rng.nextParallelRNG(29349), 23968888888L,
- 1D / engine.getDimension().getIslandMode().getIslandChance());
- islandHeightStream = regionIdentityStream.style(rng.nextParallelRNG(330466), engine.getDimension().getIslandMode().getHeight(), data);
- islandDepthStream = engine.getDimension().getIslandMode().getIslandDepth().stream(rng.nextParallelRNG(-39578888), data);
regionIDStream = regionIdentityStream.convertCached((i) -> new UUID(Double.doubleToLongBits(i), String.valueOf(i * 38445).hashCode() * 3245556666L));
caveBiomeStream = regionStream.convert((r)
-> engine.getDimension().getCaveBiomeStyle().create(rng.nextParallelRNG(InferredType.CAVE.ordinal()), getData()).stream()
@@ -334,13 +323,11 @@ public class IrisComplex implements DataProvider {
int heightf = (int) Math.round(getHeightStream().get(rx, rz));
int m = heightf;
- if (engine.getDimension().isCarving() && engine.getDimension().getTerrainMode().equals(IrisTerrainMode.NORMAL)) {
- if (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) {
- m--;
+ if (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) {
+ m--;
- while (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) {
- m--;
- }
+ while (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) {
+ m--;
}
}
@@ -367,27 +354,9 @@ public class IrisComplex implements DataProvider {
d.hashCode());
})
.cache2D(cacheSize);
- islandTopStream = islandStream.convertAware2D((i, x, z) ->
- i ? heightStream.round()
- .subtract(fluidHeight)
- .add((xx, zz) -> getIslandHeight(xx.intValue(), zz.intValue(), engine.getDimension()
- .getIslandMode().getIslandEdgeInterpolator()))
- .get(x, z) : 0);
- islandBottomStream = islandStream.convertAware2D((i, x, z) ->
- i ? islandHeightStream.subtract(islandDepthStream).round().get(x, z) : 0);
//@done
}
- private double getIslandHeight(int x, int z, IrisInterpolator interp) {
- return interp.interpolate(x, z, (xx, zz) -> {
- if (getIslandStream().get(xx, zz)) {
- return getIslandHeightStream().get(xx, zz);
- }
-
- return 0;
- });
- }
-
private IrisRegion findRegion(IrisBiome focus, Engine engine) {
for (IrisRegion i : engine.getDimension().getAllRegions(engine)) {
if (i.getAllBiomeIds().contains(focus.getLoadKey())) {
diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java
index cb973fc0c..d2a5cd90a 100644
--- a/src/main/java/com/volmit/iris/engine/IrisEngine.java
+++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java
@@ -26,7 +26,6 @@ import com.volmit.iris.core.events.IrisEngineHotloadEvent;
import com.volmit.iris.core.service.PreservationSVC;
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.*;
@@ -49,6 +48,7 @@ import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.io.IO;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.math.RNG;
+import com.volmit.iris.util.math.RollingSequence;
import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
@@ -96,8 +96,7 @@ public class IrisEngine extends BlockPopulator implements Engine {
private double maxBiomeLayerDensity;
private double maxBiomeDecoratorDensity;
private IrisComplex complex;
- private EngineActuator terrainNormalActuator;
- private EngineActuator terrainIslandActuator;
+ private EngineActuator terrainActuator;
private EngineActuator decorantActuator;
private EngineActuator biomeActuator;
private EngineModifier depositModifier;
@@ -132,6 +131,7 @@ public class IrisEngine extends BlockPopulator implements Engine {
closed = false;
art = J.ar(this::tickRandomPlayer, 0);
setupEngine();
+ Iris.debug("Engine Initialized " + getCacheID());
}
private void tickRandomPlayer() {
@@ -145,8 +145,7 @@ public class IrisEngine extends BlockPopulator implements Engine {
worldManager.close();
complex.close();
execution.close();
- terrainNormalActuator.close();
- terrainIslandActuator.close();
+ terrainActuator.close();
decorantActuator.close();
biomeActuator.close();
depositModifier.close();
@@ -158,20 +157,31 @@ public class IrisEngine extends BlockPopulator implements Engine {
private void setupEngine()
{
- cacheId = RNG.r.nextInt();
- worldManager = new IrisWorldManager(this);
- complex = new IrisComplex(this);
- execution = new IrisExecutionEnvironment(this);
- terrainNormalActuator = new IrisTerrainNormalActuator(this);
- terrainIslandActuator = new IrisTerrainIslandActuator(this);
- decorantActuator = new IrisDecorantActuator(this);
- biomeActuator = new IrisBiomeActuator(this);
- depositModifier = new IrisDepositModifier(this);
- ravineModifier = new IrisRavineModifier(this);
- caveModifier = new IrisCaveModifier(this);
- postModifier = new IrisPostModifier(this);
- effects = new IrisEngineEffects(this);
- J.a(this::computeBiomeMaxes);
+ try
+ {
+ Iris.debug("Setup Engine " + getCacheID());
+ cacheId = RNG.r.nextInt();
+ worldManager = new IrisWorldManager(this);
+ complex = new IrisComplex(this);
+ execution = new IrisExecutionEnvironment(this);
+ terrainActuator = new IrisTerrainNormalActuator(this);
+ decorantActuator = new IrisDecorantActuator(this);
+ biomeActuator = new IrisBiomeActuator(this);
+ depositModifier = new IrisDepositModifier(this);
+ ravineModifier = new IrisRavineModifier(this);
+ caveModifier = new IrisCaveModifier(this);
+ postModifier = new IrisPostModifier(this);
+ effects = new IrisEngineEffects(this);
+ J.a(this::computeBiomeMaxes);
+ }
+
+ catch(Throwable e)
+ {
+ Iris.error("FAILED TO SETUP ENGINE!");
+ e.printStackTrace();
+ }
+
+ Iris.debug("Engine Setup Complete " + getCacheID());
}
@Override
@@ -374,13 +384,6 @@ public class IrisEngine extends BlockPopulator implements Engine {
});
}
- public EngineActuator getTerrainActuator() {
- return switch (getDimension().getTerrainMode()) {
- case NORMAL -> getTerrainNormalActuator();
- case ISLANDS -> getTerrainIslandActuator();
- };
- }
-
@BlockCoordinates
@Override
public double modifyX(double x) {
@@ -406,23 +409,24 @@ public class IrisEngine extends BlockPopulator implements Engine {
try {
PrecisionStopwatch p = PrecisionStopwatch.start();
Hunk blocks = vblocks.listen((xx, y, zz, t) -> catchBlockUpdates(x + xx, y + getMinHeight(), z + zz, t));
+ getMantle().generateMatter(x >> 4, z >> 4, multicore);
- switch (getDimension().getTerrainMode()) {
- case NORMAL -> {
- getMantle().generateMatter(x >> 4, z >> 4, multicore);
- 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);
- getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore);
- getDepositModifier().modify(x, z, blocks, multicore);
- }
- case ISLANDS -> {
- getTerrainActuator().actuate(x, z, vblocks, multicore);
- }
- }
+ burst().burst(multicore,
+ () -> getTerrainActuator().actuate(x, z, vblocks, multicore),
+ () -> getBiomeActuator().actuate(x, z, vbiomes, multicore)
+ );
+ burst().burst(multicore,
+ () -> getCaveModifier().modify(x, z, vblocks, multicore),
+ () -> getDecorantActuator().actuate(x, z, blocks, multicore),
+ () -> getRavineModifier().modify(x, z, vblocks, multicore)
+ );
+
+ getPostModifier().modify(x, z, vblocks, multicore);
+
+ burst().burst(multicore,
+ () -> getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore),
+ () -> getDepositModifier().modify(x, z, vblocks, multicore)
+ );
getMetrics().getTotal().put(p.getMilliseconds());
generated.incrementAndGet();
diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java
index 132056578..819b0f227 100644
--- a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java
+++ b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java
@@ -18,7 +18,9 @@
package com.volmit.iris.engine;
+import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
import com.volmit.iris.Iris;
+import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.mantle.EngineMantle;
import com.volmit.iris.engine.mantle.MantleComponent;
@@ -27,6 +29,7 @@ import com.volmit.iris.engine.mantle.components.MantleJigsawComponent;
import com.volmit.iris.engine.mantle.components.MantleObjectComponent;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.deposits.IrisDepositGenerator;
+import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
import com.volmit.iris.engine.object.feature.IrisFeaturePotential;
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement;
import com.volmit.iris.engine.object.objects.IrisObject;
@@ -36,16 +39,22 @@ import com.volmit.iris.engine.object.regional.IrisRegion;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.collection.KSet;
+import com.volmit.iris.util.documentation.BlockCoordinates;
+import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.mantle.Mantle;
+import com.volmit.iris.util.mantle.MantleFlag;
import com.volmit.iris.util.parallel.BurstExecutor;
+import com.volmit.iris.util.stream.ProceduralStream;
+import com.volmit.iris.util.stream.interpolation.Interpolated;
+import com.volmit.iris.util.stream.utility.CachedStream2D;
import lombok.Data;
import org.bukkit.util.BlockVector;
import java.io.File;
import java.io.IOException;
+import java.util.List;
import java.util.Map;
-import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
@Data
@@ -53,12 +62,13 @@ public class IrisEngineMantle implements EngineMantle {
private final Engine engine;
private final Mantle mantle;
private final KList components;
- private final CompletableFuture radius;
+ private final int radius;
+ private final AtomicCache radCache = new AtomicCache<>();
public IrisEngineMantle(Engine engine) {
this.engine = engine;
this.mantle = new Mantle(new File(engine.getWorld().worldFolder(), "mantle"), engine.getTarget().getHeight());
- radius = burst().completeValue(this::computeParallaxSize);
+ radius = radCache.aquire(this::computeParallaxSize);
components = new KList<>();
registerComponent(new MantleFeatureComponent(this));
registerComponent(new MantleJigsawComponent(this));
diff --git a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java
index 81e6f7dab..c36f20cf5 100644
--- a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java
+++ b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java
@@ -211,7 +211,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
.shuffleCopy(RNG.r).stream()
.filter(this::canSpawn),
getData().getSpawnerLoader().streamAll(getEngine().getMantle()
- .getFeaturesInChunk(c).stream()
+ .forEachFeature(c).stream()
.flatMap((o) -> o.getFeature().getEntitySpawners().stream()))
.filter(this::canSpawn))
.filter((i) -> i.isValid(biome))
@@ -294,6 +294,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
private KList spawnRandomly(List types) {
KList rarityTypes = new KList<>();
int totalRarity = 0;
+
for (IrisEntitySpawn i : types) {
totalRarity += IRare.get(i);
}
@@ -344,7 +345,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
public void onChunkLoad(Chunk e, boolean generated) {
if (generated) {
energy += 1.2;
- spawnIn(e, true);
+ J.a(() -> spawnIn(e, true), RNG.r.i(5, 50));
} else {
energy += 0.3;
}
diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java
index 45b8fd31c..347aad64c 100644
--- a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java
+++ b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java
@@ -68,8 +68,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator {
@Override
public void onActuate(int x, int z, Hunk h, boolean multicore) {
PrecisionStopwatch p = PrecisionStopwatch.start();
- BurstExecutor burst = burst().burst();
- burst.setMulticore(multicore);
+ BurstExecutor burst = burst().burst(multicore);
for (int xf = 0; xf < h.getWidth(); xf++) {
int finalXf = xf;
diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java
index 744f30048..60cab2592 100644
--- a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java
+++ b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java
@@ -90,8 +90,7 @@ public class IrisDecorantActuator extends EngineAssignedActuator {
}
PrecisionStopwatch p = PrecisionStopwatch.start();
- BurstExecutor burst = burst().burst();
- burst.setMulticore(multicore);
+ BurstExecutor burst = burst().burst(multicore);
for (int i = 0; i < output.getWidth(); i++) {
int finalI = i;
diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java
deleted file mode 100644
index e9890d3ea..000000000
--- a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java
+++ /dev/null
@@ -1,95 +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.actuator;
-
-import com.volmit.iris.engine.framework.Engine;
-import com.volmit.iris.engine.framework.EngineAssignedActuator;
-import com.volmit.iris.engine.object.biome.IrisBiome;
-import com.volmit.iris.util.collection.KList;
-import com.volmit.iris.util.documentation.BlockCoordinates;
-import com.volmit.iris.util.hunk.Hunk;
-import com.volmit.iris.util.math.RNG;
-import com.volmit.iris.util.scheduling.PrecisionStopwatch;
-import lombok.Getter;
-import org.bukkit.Material;
-import org.bukkit.block.data.BlockData;
-
-public class IrisTerrainIslandActuator extends EngineAssignedActuator {
- private static final BlockData AIR = Material.AIR.createBlockData();
- private static final BlockData BEDROCK = Material.BEDROCK.createBlockData();
- private static final BlockData WEB = Material.COBWEB.createBlockData();
- private static final BlockData BLACK_GLASS = Material.BLACK_STAINED_GLASS.createBlockData();
- private static final BlockData WHITE_GLASS = Material.WHITE_STAINED_GLASS.createBlockData();
- private static final BlockData CAVE_AIR = Material.CAVE_AIR.createBlockData();
- @Getter
- private final RNG rng;
- private final boolean carving;
- @Getter
- private final int lastBedrock = -1;
-
- public IrisTerrainIslandActuator(Engine engine) {
- super(engine, "TerrainIsland");
- rng = new RNG(engine.getWorld().seed());
- carving = getDimension().isCarving() && getDimension().getCarveLayers().isNotEmpty();
- }
-
- @BlockCoordinates
- @Override
- public void onActuate(int x, int z, Hunk h, boolean multicore) {
- PrecisionStopwatch p = PrecisionStopwatch.start();
- int i, zf, depth, surface, realX, realZ;
- IrisBiome biome;
- KList blocks, fblocks;
- int hi, lo;
- double hh;
-
- for (int xf = 0; xf < h.getWidth(); xf++) {
- for (zf = 0; zf < h.getDepth(); zf++) {
- realX = (int) modX(xf + x);
- realZ = (int) modZ(zf + z);
-
- if (getComplex().getIslandStream().get(realX, realZ)) {
- biome = getComplex().getTrueBiomeStream().get(realX, realZ);
- hh = getComplex().getTrueHeightStream().get(realX, realZ) - getComplex().getFluidHeight();
- depth = (int) (getComplex().getIslandDepthStream().get(realX, realZ).intValue() + hh);
- blocks = biome.generateLayers(realX, realZ, rng, depth, depth, getData(), getComplex());
- hi = getComplex().getIslandTopStream().get(realX, realZ);
- lo = getComplex().getIslandBottomStream().get(realX, realZ);
-
- // 10
- // 6
-
- // hf = 4
-
- for (i = hi; i >= lo; i--) {
- int hf = (i - hi);
- if (blocks.hasIndex(hf)) {
- h.set(xf, i, zf, blocks.get(hf));
- continue;
- }
-
- h.set(xf, i, zf, getComplex().getRockStream().get(realX, realZ));
- }
- }
- }
- }
-
- getEngine().getMetrics().getTerrain().put(p.getMilliseconds());
- }
-}
diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java
index c99951982..56fce5f95 100644
--- a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java
+++ b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java
@@ -55,8 +55,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator
public void onActuate(int x, int z, Hunk h, boolean multicore) {
PrecisionStopwatch p = PrecisionStopwatch.start();
- BurstExecutor e = getEngine().burst().burst(h.getWidth());
- e.setMulticore(multicore);
+ BurstExecutor e = burst().burst(multicore);
for (int xf = 0; xf < h.getWidth(); xf++) {
int finalXf = xf;
e.queue(() -> terrainSliver(x, z, finalXf, h));
@@ -67,70 +66,6 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator
getEngine().getMetrics().getTerrain().put(p.getMilliseconds());
}
- public void generateGround(int realX, int realZ, int xf, int zf, Hunk h, int surface, int bottom, int height, int fluidOrHeight, IrisBiome biome)
- {
- if(surface == bottom || surface-1 == bottom)
- {
- return;
- }
-
- KList blocks = null;
- KList fblocks = null;
- int depth,fdepth;
-
- for (int i = surface; i >= bottom; i--) {
- if (i >= h.getHeight()) {
- continue;
- }
-
- if (i == 0) {
- if (getDimension().isBedrock()) {
- h.set(xf, i, zf, BEDROCK);
- lastBedrock = i;
- continue;
- }
- }
-
- if (carving && getDimension().isCarved(getData(), realX, i, realZ, rng, height)) {
- continue;
- }
-
- if (getDimension().getCaverns() != null && getDimension().getCaverns().isCavern(rng, realX, i, realZ, height, getData())) {
- continue;
- }
-
- if (i > height && i <= fluidOrHeight) {
- fdepth = fluidOrHeight - i;
-
- if (fblocks == null) {
- fblocks = biome.generateSeaLayers(realX, realZ, rng, fluidOrHeight - height, getData());
- }
-
- if (fblocks.hasIndex(fdepth)) {
- h.set(xf, i, zf, fblocks.get(fdepth));
- continue;
- }
-
- h.set(xf, i, zf, getComplex().getFluidStream().get(realX, +realZ));
- continue;
- }
-
- if (i <= height) {
- depth = surface - i;
- if (blocks == null) {
- blocks = biome.generateLayers(realX, realZ, rng, surface - bottom, surface, getData(), getComplex());
- }
-
- if (blocks.hasIndex(depth)) {
- h.set(xf, i, zf, blocks.get(depth));
- continue;
- }
-
- h.set(xf, i, zf, getComplex().getRockStream().get(realX, realZ));
- }
- }
- }
-
private int fluidOrHeight(int height)
{
return Math.max(getDimension().getFluidHeight(), height);
@@ -146,12 +81,12 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator
*/
@BlockCoordinates
public void terrainSliver(int x, int z, int xf, Hunk h) {
- int i, realX, realZ, hf, he;
+ int zf, realX, realZ, hf, he;
IrisBiome biome;
- for (i = 0; i < h.getDepth(); i++) {
+ for (zf = 0; zf < h.getDepth(); zf++) {
realX = (int) modX(xf + x);
- realZ = (int) modZ(i + z);
+ realZ = (int) modZ(zf + z);
biome = getComplex().getTrueBiomeStream().get(realX, realZ);
he = (int) Math.round(Math.min(h.getHeight(), getComplex().getHeightStream().get(realX, realZ)));
hf = Math.round(Math.max(Math.min(h.getHeight(), getDimension().getFluidHeight()), he));
@@ -160,7 +95,65 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator
continue;
}
- generateGround(realX, realZ, xf, i, h, hf, 0, he, hf, biome);
+ KList blocks = null;
+ KList fblocks = null;
+ int depth,fdepth;
+
+ for (int i = hf; i >= 0; i--) {
+ if (i >= h.getHeight()) {
+ continue;
+ }
+
+ if (i == 0) {
+ if (getDimension().isBedrock()) {
+ h.set(xf, i, zf, BEDROCK);
+ lastBedrock = i;
+ continue;
+ }
+ }
+
+ if (carving && getDimension().isCarved(getData(), realX, i, realZ, rng, he)) {
+ continue;
+ }
+
+ if (getDimension().getCaverns() != null && getDimension().getCaverns().isCavern(rng, realX, i, realZ, he, getData())) {
+ continue;
+ }
+
+ if (i > he && i <= hf) {
+ fdepth = hf - i;
+
+ if (fblocks == null) {
+ fblocks = biome.generateSeaLayers(realX, realZ, rng, hf - he, getData());
+ }
+
+ if (fblocks.hasIndex(fdepth)) {
+ h.set(xf, i, zf, fblocks.get(fdepth));
+ continue;
+ }
+
+ h.set(xf, i, zf, getComplex().getFluidStream().get(realX, +realZ));
+ continue;
+ }
+
+ if (i <= he) {
+ depth = he - i;
+ if (blocks == null) {
+ blocks = biome.generateLayers(realX, realZ, rng,
+ he,
+ he,
+ getData(),
+ getComplex());
+ }
+
+ if (blocks.hasIndex(depth)) {
+ h.set(xf, i, zf, blocks.get(depth));
+ continue;
+ }
+
+ h.set(xf, i, zf, getComplex().getRockStream().get(realX, realZ));
+ }
+ }
}
}
}
diff --git a/src/main/java/com/volmit/iris/engine/data/chunk/MCATerrainChunk.java b/src/main/java/com/volmit/iris/engine/data/chunk/MCATerrainChunk.java
index 523bb88c0..c09941c07 100644
--- a/src/main/java/com/volmit/iris/engine/data/chunk/MCATerrainChunk.java
+++ b/src/main/java/com/volmit/iris/engine/data/chunk/MCATerrainChunk.java
@@ -18,6 +18,7 @@
package com.volmit.iris.engine.data.chunk;
+import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.BiomeBaseInjector;
import com.volmit.iris.util.nbt.mca.Chunk;
import com.volmit.iris.util.nbt.mca.NBTWorld;
@@ -69,7 +70,7 @@ public class MCATerrainChunk implements TerrainChunk {
@Override
public void setBiome(int x, int y, int z, Biome bio) {
- writer.setBiome(ox + x, y, oz + z, bio);
+ mcaChunk.setBiomeAt((ox + x) & 15, y, (oz + z) & 15, writer.getBiomeId(bio));
}
@Override
@@ -91,6 +92,11 @@ public class MCATerrainChunk implements TerrainChunk {
return;
}
+ if(blockData == null)
+ {
+ Iris.error("NULL BD");
+ }
+
mcaChunk.setBlockStateAt(xx, y, zz, NBTWorld.getCompound(blockData), false);
}
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 0a3e8e02b..e7defb9aa 100644
--- a/src/main/java/com/volmit/iris/engine/framework/Engine.java
+++ b/src/main/java/com/volmit/iris/engine/framework/Engine.java
@@ -243,7 +243,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
updateLighting(x, y, z, c);
}
}
- }, MantleFlag.UPDATE);
+ });
getMetrics().getUpdates().put(p.getMilliseconds());
}
@@ -434,13 +434,6 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
IrisDimension dim = getDimension();
dim.getAllBiomes(this).forEach((i) -> v.put(i.getLoadKey(), i));
- try {
- dim.getDimensionalComposite().forEach((m) -> getData().getDimensionLoader().load(m.getDimension()).getAllBiomes(this).forEach((i) -> v.put(i.getLoadKey(), i)));
- } catch (Throwable ignored) {
- Iris.reportError(ignored);
-
- }
-
return v.v();
}
diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java
index 77eae4f29..8460d8e3f 100644
--- a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java
+++ b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java
@@ -18,6 +18,7 @@
package com.volmit.iris.engine.framework;
+import com.volmit.iris.Iris;
import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.hunk.Hunk;
diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedComponent.java b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedComponent.java
index f00cdaca1..ca1f2f9d8 100644
--- a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedComponent.java
+++ b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedComponent.java
@@ -18,6 +18,7 @@
package com.volmit.iris.engine.framework;
+import com.volmit.iris.Iris;
import com.volmit.iris.util.math.RollingSequence;
import lombok.Data;
@@ -28,6 +29,7 @@ public class EngineAssignedComponent implements EngineComponent {
private final String name;
public EngineAssignedComponent(Engine engine, String name) {
+ Iris.debug("Engine: " + engine.getCacheID() + " Starting " + name);
this.engine = engine;
this.metrics = new RollingSequence(16);
this.name = name;
diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedModifier.java b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedModifier.java
index 6bcbd2267..e69648b80 100644
--- a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedModifier.java
+++ b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedModifier.java
@@ -18,6 +18,7 @@
package com.volmit.iris.engine.framework;
+import com.volmit.iris.Iris;
import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.hunk.Hunk;
diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java b/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java
index 250b343cb..7a7c18b4a 100644
--- a/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java
+++ b/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java
@@ -36,9 +36,7 @@ public class EngineTarget {
this.world = world;
this.dimension = dimension;
this.data = data;
- this.burster = new MultiBurst("Iris Engine " + dimension.getName(),
- IrisSettings.get().getConcurrency().getEngineThreadPriority(),
- IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getEngineThreadCount()));
+ this.burster = MultiBurst.burst;
}
public int getHeight() {
@@ -46,6 +44,6 @@ public class EngineTarget {
}
public void close() {
- burster.shutdownLater();
+
}
}
diff --git a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java
index 9983bbf0d..9cdaf127b 100644
--- a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java
+++ b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java
@@ -114,9 +114,26 @@ public class PlannedStructure {
int xx = i.getPosition().getX() + sx;
int zz = i.getPosition().getZ() + sz;
int offset = i.getPosition().getY() - startHeight;
- int height = (i.getStructure().getStructure().getLockY() != -1
- ? i.getStructure().getStructure().getLockY()
- : placer.getHighest(xx, zz, getData())) + offset + (v.getH() / 2);
+ int height = 0;
+
+ if(i.getStructure().getStructure().getLockY() == -1)
+ {
+ if(i.getStructure().getStructure().getOverrideYRange() != null)
+ {
+ height = (int)i.getStructure().getStructure().getOverrideYRange().get(rng, xx, zz, getData());
+ }
+
+ else
+ {
+ height = placer.getHighest(xx, zz, getData());
+ }
+ }
+
+ else{
+ height = i.getStructure().getStructure().getLockY();
+ }
+
+ height += offset + (v.getH() / 2);
if (options.getMode().equals(ObjectPlaceMode.PAINT) || options.isVacuum()) {
height = -1;
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 3046f8d3c..597012502 100644
--- a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java
+++ b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java
@@ -34,6 +34,7 @@ import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.mantle.Mantle;
import com.volmit.iris.util.mantle.MantleFlag;
+import com.volmit.iris.util.noise.CNG;
import com.volmit.iris.util.parallel.BurstExecutor;
import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
@@ -41,11 +42,8 @@ import org.bukkit.Chunk;
import org.bukkit.block.TileState;
import org.bukkit.block.data.BlockData;
-import java.util.Collections;
import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.ExecutionException;
+import java.util.concurrent.*;
import java.util.function.Consumer;
// TODO: MOVE PLACER OUT OF MATTER INTO ITS OWN THING
@@ -56,7 +54,7 @@ public interface EngineMantle extends IObjectPlacer {
Engine getEngine();
- CompletableFuture getRadius();
+ int getRadius();
KList getComponents();
@@ -171,15 +169,7 @@ public interface EngineMantle extends IObjectPlacer {
}
default int getRealRadius() {
- try {
- return (int) Math.ceil(getRadius().get() / 2D);
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (ExecutionException e) {
- e.printStackTrace();
- }
-
- return 0;
+ return (int) Math.ceil(getRadius() / 2D);
}
@@ -189,7 +179,6 @@ public interface EngineMantle extends IObjectPlacer {
return;
}
- PrecisionStopwatch p = PrecisionStopwatch.start();
KList post = new KList<>();
Consumer c = (i) -> {
synchronized (post)
@@ -198,15 +187,14 @@ public interface EngineMantle extends IObjectPlacer {
}
};
int s = getRealRadius();
- BurstExecutor burst = burst().burst();
- burst.setMulticore(multicore);
-
+ BurstExecutor burst = burst().burst(multicore);
+ MantleWriter writer = getMantle().write(this, x, z, s * 2);
for (int i = -s; i <= s; i++) {
- int xx = i + x;
for (int j = -s; j <= s; j++) {
+ int xx = i + x;
int zz = j + z;
burst.queue(() -> {
- getComponents().forEach((f) -> generateMantleComponent(xx, zz, f, c));
+ getComponents().forEach((f) -> generateMantleComponent(writer, xx, zz, f, c));
});
}
}
@@ -217,21 +205,12 @@ public interface EngineMantle extends IObjectPlacer {
{
KList px = post.copy();
post.clear();
-
- if(multicore)
- {
- burst().burst(px);
- }
-
- else
- {
- burst().sync(px);
- }
+ burst().burst(multicore, px);
}
}
- default void generateMantleComponent(int x, int z, MantleComponent c, Consumer post) {
- getMantle().raiseFlag(x, z, c.getFlag(), () -> c.generateLayer(x, z, post));
+ default void generateMantleComponent(MantleWriter writer, int x, int z, MantleComponent c, Consumer post) {
+ getMantle().raiseFlag(x, z, c.getFlag(), () -> c.generateLayer(writer, x, z, post));
}
@ChunkCoordinates
@@ -245,20 +224,23 @@ public interface EngineMantle extends IObjectPlacer {
@BlockCoordinates
default void updateBlock(int x, int y, int z) {
- getMantle().flag(x >> 4, z >> 4, MantleFlag.UPDATE, true);
getMantle().set(x, y, z, true);
}
@ChunkCoordinates
- default KList getFeaturesInChunk(Chunk c) {
+ default List getFeaturesInChunk(Chunk c) {
return getFeaturesInChunk(c.getX(), c.getZ());
}
@ChunkCoordinates
- default KList getFeaturesInChunk(int x, int z) {
- KList pos = new KList<>();
- getMantle().iterateChunk(x, z, IrisFeaturePositional.class, (a, b, c, f) -> pos.add(f), MantleFlag.FEATURE);
- return pos;
+ default List getFeaturesInChunk(int x, int z) {
+ return getMantle().getChunk(x, z).getFeatures();
+ }
+
+
+ @ChunkCoordinates
+ default KList forEachFeature(Chunk c) {
+ return forEachFeature((c.getX() << 4) + 8, (c.getZ() << 4) + 8);
}
@BlockCoordinates
@@ -283,7 +265,7 @@ public interface EngineMantle extends IObjectPlacer {
for (i = -s; i <= s; i++) {
for (j = -s; j <= s; j++) {
try {
- for (IrisFeaturePositional k : getFeaturesInChunk(i + cx, j + cx)) {
+ for (IrisFeaturePositional k : getFeaturesInChunk(i + cx, j + cz)) {
if (k.shouldFilter(x, z, getEngine().getComplex().getRng(), getData())) {
pos.add(k);
}
diff --git a/src/main/java/com/volmit/iris/engine/mantle/MantleComponent.java b/src/main/java/com/volmit/iris/engine/mantle/MantleComponent.java
index d2755f897..7a7444250 100644
--- a/src/main/java/com/volmit/iris/engine/mantle/MantleComponent.java
+++ b/src/main/java/com/volmit/iris/engine/mantle/MantleComponent.java
@@ -62,5 +62,5 @@ public interface MantleComponent {
MantleFlag getFlag();
@ChunkCoordinates
- void generateLayer(int x, int z, Consumer post);
+ void generateLayer(MantleWriter writer, int x, int z, Consumer post);
}
diff --git a/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java b/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java
new file mode 100644
index 000000000..c304c7e5d
--- /dev/null
+++ b/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java
@@ -0,0 +1,149 @@
+/*
+ * 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;
+
+import com.volmit.iris.Iris;
+import com.volmit.iris.core.project.loader.IrisData;
+import com.volmit.iris.engine.IrisEngineMantle;
+import com.volmit.iris.engine.data.cache.Cache;
+import com.volmit.iris.engine.object.common.IObjectPlacer;
+import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
+import com.volmit.iris.engine.object.tile.TileData;
+import com.volmit.iris.util.collection.KMap;
+import com.volmit.iris.util.mantle.Mantle;
+import com.volmit.iris.util.mantle.MantleChunk;
+import com.volmit.iris.util.matter.Matter;
+import lombok.Data;
+import org.bukkit.block.TileState;
+import org.bukkit.block.data.BlockData;
+
+@Data
+public class MantleWriter implements IObjectPlacer
+{
+ private final EngineMantle engineMantle;
+ private final Mantle mantle;
+ private final KMap cachedChunks;
+ private final int radius;
+ private final int x;
+ private final int z;
+
+ public MantleWriter(EngineMantle engineMantle, Mantle mantle, int x, int z, int radius)
+ {
+ this.engineMantle = engineMantle;
+ this.mantle = mantle;
+ this.cachedChunks = new KMap<>();
+ this.radius = radius;
+ this.x = x;
+ this.z = z;
+
+ for (int i = -radius; i <= radius; i++) {
+ for (int j = -radius; j <= radius; j++) {
+ cachedChunks.put(Cache.key(i + x, j + z), mantle.getChunk(i + x, j + z));
+ }
+ }
+ }
+
+ public void setData(int x, int y, int z, T t)
+ {
+ int cx = x >> 4;
+ int cz = z >> 4;
+
+ if (y < 0 || y >= mantle.getWorldHeight()) {
+ return;
+ }
+
+ if(cx >= this.x - radius && cx <= this.x + radius
+ && cz >= this.z - radius && cz <= this.z + radius)
+ {
+ MantleChunk chunk = cachedChunks.get(Cache.key(cx, cz));
+
+ if(chunk == null)
+ {
+ Iris.error("Mantle Writer Accessed " + cx + "," + cz + " and came up null (and yet within bounds!)");
+ return;
+ }
+
+ if(t instanceof IrisFeaturePositional)
+ {
+ chunk.addFeature((IrisFeaturePositional) t);
+ }
+
+ else
+ {
+ Matter matter = chunk.getOrCreate(y >> 4);
+ matter.slice(matter.getClass(t)).set(x & 15, y & 15, z & 15, t);
+ }
+ }
+
+ else
+ {
+ Iris.error("Mantle Writer[" + this.x + "," + this.z + ",R" + this.radius + "] Tried to access " + x + "," + y + "," + z + " (Chunk " + cx + "," + cz + ") which is OUT OF BOUNDS!");
+ }
+ }
+
+ @Override
+ public int getHighest(int x, int z, IrisData data) {
+ return engineMantle.getHighest(x, z, data);
+ }
+
+ @Override
+ public int getHighest(int x, int z, IrisData data, boolean ignoreFluid) {
+ return engineMantle.getHighest(x, z, data, ignoreFluid);
+ }
+
+ @Override
+ public void set(int x, int y, int z, BlockData d) {
+ setData(x, y, z, d);
+ }
+
+ @Override
+ public BlockData get(int x, int y, int z) {
+ return getEngineMantle().get(x, y, z);
+ }
+
+ @Override
+ public boolean isPreventingDecay() {
+ return getEngineMantle().isPreventingDecay();
+ }
+
+ @Override
+ public boolean isSolid(int x, int y, int z) {
+ return getEngineMantle().isSolid(x, y, z);
+ }
+
+ @Override
+ public boolean isUnderwater(int x, int z) {
+ return getEngineMantle().isUnderwater(x, z);
+ }
+
+ @Override
+ public int getFluidHeight() {
+ return getEngineMantle().getFluidHeight();
+ }
+
+ @Override
+ public boolean isDebugSmartBore() {
+ return getEngineMantle().isDebugSmartBore();
+ }
+
+ @Override
+ public void setTile(int xx, int yy, int zz, TileData extends TileState> tile) {
+ getEngineMantle().setTile(xx,yy,zz,tile);
+ }
+}
diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleFeatureComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleFeatureComponent.java
index 098e76ca8..eb7f29da5 100644
--- a/src/main/java/com/volmit/iris/engine/mantle/components/MantleFeatureComponent.java
+++ b/src/main/java/com/volmit/iris/engine/mantle/components/MantleFeatureComponent.java
@@ -21,6 +21,7 @@ package com.volmit.iris.engine.mantle.components;
import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.mantle.EngineMantle;
import com.volmit.iris.engine.mantle.IrisMantleComponent;
+import com.volmit.iris.engine.mantle.MantleWriter;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
import com.volmit.iris.engine.object.feature.IrisFeaturePotential;
@@ -38,34 +39,34 @@ public class MantleFeatureComponent extends IrisMantleComponent {
}
@Override
- public void generateLayer(int x, int z, Consumer post) {
+ public void generateLayer(MantleWriter writer, int x, int z, Consumer post) {
RNG rng = new RNG(Cache.key(x, z) + seed());
int xxx = 8 + (x << 4);
int zzz = 8 + (z << 4);
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz);
- generateFeatures(rng, x, z, region, biome);
+ generateFeatures(writer, rng, x, z, region, biome);
}
@ChunkCoordinates
- private void generateFeatures(RNG rng, int cx, int cz, IrisRegion region, IrisBiome biome) {
+ private void generateFeatures(MantleWriter writer, RNG rng, int cx, int cz, IrisRegion region, IrisBiome biome) {
for (IrisFeaturePotential i : getFeatures()) {
- placeZone(rng, cx, cz, i);
+ placeZone(writer, rng, cx, cz, i);
}
for (IrisFeaturePotential i : region.getFeatures()) {
- placeZone(rng, cx, cz, i);
+ placeZone(writer, rng, cx, cz, i);
}
for (IrisFeaturePotential i : biome.getFeatures()) {
- placeZone(rng, cx, cz, i);
+ placeZone(writer, rng, cx, cz, i);
}
}
- private void placeZone(RNG rng, int cx, int cz, IrisFeaturePotential i) {
+ private void placeZone(MantleWriter writer, RNG rng, int cx, int cz, IrisFeaturePotential i) {
int x = (cx << 4) + rng.nextInt(16);
int z = (cz << 4) + rng.nextInt(16);
- getMantle().set(x, 0, z, new IrisFeaturePositional(x, z, i.getZone()));
+ writer.setData(x, 0, z, new IrisFeaturePositional(x, z, i.getZone()));
}
private KList getFeatures() {
diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java
index 9462ca83a..2a946c845 100644
--- a/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java
+++ b/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java
@@ -18,42 +18,47 @@
package com.volmit.iris.engine.mantle.components;
-import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.jigsaw.PlannedStructure;
import com.volmit.iris.engine.mantle.EngineMantle;
import com.volmit.iris.engine.mantle.IrisMantleComponent;
+import com.volmit.iris.engine.mantle.MantleWriter;
import com.volmit.iris.engine.object.basic.IrisPosition;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure;
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement;
+import com.volmit.iris.engine.object.noise.NoiseStyle;
import com.volmit.iris.engine.object.regional.IrisRegion;
import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.mantle.MantleFlag;
import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.RNG;
+import com.volmit.iris.util.noise.CNG;
import java.util.List;
import java.util.function.Consumer;
public class MantleJigsawComponent extends IrisMantleComponent {
+ private final CNG cng;
+
public MantleJigsawComponent(EngineMantle engineMantle) {
super(engineMantle, MantleFlag.JIGSAW);
+ cng = NoiseStyle.STATIC.create(new RNG());
}
@Override
- public void generateLayer(int x, int z, Consumer post) {
- RNG rng = new RNG(Cache.key(x, z) + seed());
+ public void generateLayer(MantleWriter writer, int x, int z, Consumer post) {
+ RNG rng = new RNG(cng.fit(-Integer.MAX_VALUE, Integer.MAX_VALUE, x, z));
int xxx = 8 + (x << 4);
int zzz = 8 + (z << 4);
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz);
- generateJigsaw(rng, x, z, biome, region, post);
+ generateJigsaw(writer, rng, x, z, biome, region, post);
}
@ChunkCoordinates
- private void generateJigsaw(RNG rng, int x, int z, IrisBiome biome, IrisRegion region, Consumer post) {
+ private void generateJigsaw(MantleWriter writer, RNG rng, int x, int z, IrisBiome biome, IrisRegion region, Consumer post) {
boolean placed = false;
if (getDimension().getStronghold() != null) {
@@ -63,7 +68,7 @@ public class MantleJigsawComponent extends IrisMantleComponent {
for (Position2 pos : poss) {
if (x == pos.getX() >> 4 && z == pos.getZ() >> 4) {
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(getDimension().getStronghold());
- place(pos.toIris(), structure, rng, post);
+ place(writer, pos.toIris(), structure, rng, post);
placed = true;
}
}
@@ -75,7 +80,7 @@ public class MantleJigsawComponent extends IrisMantleComponent {
if (rng.nextInt(i.getRarity()) == 0) {
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
- place(position, structure, rng, post);
+ place(writer, position, structure, rng, post);
placed = true;
}
}
@@ -86,7 +91,7 @@ public class MantleJigsawComponent extends IrisMantleComponent {
if (rng.nextInt(i.getRarity()) == 0) {
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
- place(position, structure, rng, post);
+ place(writer, position, structure, rng, post);
placed = true;
}
}
@@ -97,23 +102,22 @@ public class MantleJigsawComponent extends IrisMantleComponent {
if (rng.nextInt(i.getRarity()) == 0) {
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
- place(position, structure, rng, post);
+ place(writer, position, structure, rng, post);
}
}
}
}
@BlockCoordinates
- private void place(IrisPosition position, IrisJigsawStructure structure, RNG rng, Consumer post) {
+ private void place(MantleWriter writer, IrisPosition position, IrisJigsawStructure structure, RNG rng, Consumer post) {
if (structure.getFeature() != null) {
if (structure.getFeature().getBlockRadius() == 32) {
structure.getFeature().setBlockRadius((double) structure.getMaxDimension() / 3);
}
-
- getMantle().set(position.getX(), 0, position.getZ(),
+ writer.setData(position.getX(), 0, position.getZ(),
new IrisFeaturePositional(position.getX(), position.getZ(), structure.getFeature()));
}
- post.accept(() -> new PlannedStructure(structure, position, rng).place(getEngineMantle(), getMantle(), post));
+ post.accept(() -> new PlannedStructure(structure, position, rng).place(writer, getMantle(), post));
}
}
diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleObjectComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleObjectComponent.java
index b0eb8b7b2..13f32ca9b 100644
--- a/src/main/java/com/volmit/iris/engine/mantle/components/MantleObjectComponent.java
+++ b/src/main/java/com/volmit/iris/engine/mantle/components/MantleObjectComponent.java
@@ -22,6 +22,7 @@ import com.volmit.iris.Iris;
import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.mantle.EngineMantle;
import com.volmit.iris.engine.mantle.IrisMantleComponent;
+import com.volmit.iris.engine.mantle.MantleWriter;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.feature.IrisFeature;
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
@@ -42,21 +43,21 @@ public class MantleObjectComponent extends IrisMantleComponent {
}
@Override
- public void generateLayer(int x, int z, Consumer post) {
+ public void generateLayer(MantleWriter writer, int x, int z, Consumer post) {
RNG rng = new RNG(Cache.key(x, z) + seed());
int xxx = 8 + (x << 4);
int zzz = 8 + (z << 4);
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz);
- placeObjects(rng, x, z, biome, region, post);
+ placeObjects(writer, rng, x, z, biome, region, post);
}
@ChunkCoordinates
- private void placeObjects(RNG rng, int x, int z, IrisBiome biome, IrisRegion region, Consumer post) {
+ private void placeObjects(MantleWriter writer, RNG rng, int x, int z, IrisBiome biome, IrisRegion region, Consumer post) {
for (IrisObjectPlacement i : biome.getSurfaceObjects()) {
if (rng.chance(i.getChance() + rng.d(-0.005, 0.005)) && rng.chance(getComplex().getObjectChanceStream().get(x << 4, z << 4))) {
try {
- placeObject(rng, x << 4, z << 4, i, post);
+ placeObject(writer, rng, x << 4, z << 4, i, post);
} catch (Throwable e) {
Iris.reportError(e);
Iris.error("Failed to place objects in the following biome: " + biome.getName());
@@ -70,7 +71,7 @@ public class MantleObjectComponent extends IrisMantleComponent {
for (IrisObjectPlacement i : region.getSurfaceObjects()) {
if (rng.chance(i.getChance() + rng.d(-0.005, 0.005)) && rng.chance(getComplex().getObjectChanceStream().get(x << 4, z << 4))) {
try {
- placeObject(rng, x << 4, z << 4, i, post);
+ placeObject(writer, rng, x << 4, z << 4, i, post);
} catch (Throwable e) {
Iris.reportError(e);
Iris.error("Failed to place objects in the following region: " + region.getName());
@@ -83,7 +84,7 @@ public class MantleObjectComponent extends IrisMantleComponent {
}
@BlockCoordinates
- private void placeObject(RNG rng, int x, int z, IrisObjectPlacement objectPlacement, Consumer post) {
+ private void placeObject(MantleWriter writer, RNG rng, int x, int z, IrisObjectPlacement objectPlacement, Consumer post) {
for (int i = 0; i < objectPlacement.getDensity(); i++) {
IrisObject v = objectPlacement.getScale().get(rng, objectPlacement.getObject(getComplex(), rng));
if (v == null) {
@@ -94,8 +95,8 @@ public class MantleObjectComponent extends IrisMantleComponent {
int id = rng.i(0, Integer.MAX_VALUE);
Runnable r = () -> {
- int h = v.place(xx, -1, zz, getEngineMantle(), objectPlacement, rng,
- (b) -> getMantle().set(b.getX(), b.getY(), b.getZ(),
+ int h = v.place(xx, -1, zz, writer, objectPlacement, rng,
+ (b) -> writer.setData(b.getX(), b.getY(), b.getZ(),
v.getLoadKey() + "@" + id), null, getData());
if (objectPlacement.usesFeatures()) {
@@ -108,12 +109,12 @@ public class MantleObjectComponent extends IrisMantleComponent {
f.setInterpolationRadius(objectPlacement.getVacuumInterpolationRadius());
f.setInterpolator(objectPlacement.getVacuumInterpolationMethod());
f.setStrength(1D);
- getMantle().set(xx, 0, zz, new IrisFeaturePositional(xx, zz, f));
+ writer.setData(xx, 0, zz, new IrisFeaturePositional(xx, zz, f));
}
for (IrisFeaturePotential j : objectPlacement.getAddFeatures()) {
if (j.hasZone(rng, xx >> 4, zz >> 4)) {
- getMantle().set(xx, 0, zz, new IrisFeaturePositional(xx, zz, j.getZone()));
+ writer.setData(xx, 0, zz, new IrisFeaturePositional(xx, zz, j.getZone()));
}
}
}
diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java
index 13ab2cd30..a4d6517f2 100644
--- a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java
+++ b/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java
@@ -55,20 +55,13 @@ public class IrisCaveModifier extends EngineAssignedModifier {
}
PrecisionStopwatch p = PrecisionStopwatch.start();
- if (multicore) {
- BurstExecutor e = getEngine().burst().burst(a.getWidth());
- for (int i = 0; i < a.getWidth(); i++) {
- int finalI = i;
- e.queue(() -> modifySliver(x, z, finalI, a));
- }
-
- e.complete();
- } else {
- for (int i = 0; i < a.getWidth(); i++) {
- modifySliver(x, z, i, a);
- }
+ BurstExecutor e = burst().burst(multicore);
+ for (int i = 0; i < a.getWidth(); i++) {
+ int finalI = i;
+ e.queue(() -> modifySliver(x, z, finalI, a));
}
+ e.complete();
getEngine().getMetrics().getCave().put(p.getMilliseconds());
}
@@ -244,7 +237,7 @@ public class IrisCaveModifier extends EngineAssignedModifier {
}
public boolean canAir(Material m, BlockData caveFluid) {
- return (B.isSolid(m) ||
+ return (m.isSolid() ||
(B.isDecorant(m.createBlockData())) || m.equals(Material.AIR)
|| m.equals(caveFluid.getMaterial()) ||
m.equals(B.getMaterial("CAVE_AIR")))
@@ -256,6 +249,6 @@ public class IrisCaveModifier extends EngineAssignedModifier {
}
public boolean can(Material m) {
- return B.isSolid(m) && !m.equals(Material.BEDROCK);
+ return m.isSolid() && !m.equals(Material.BEDROCK);
}
}
diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier2.java b/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier2.java
deleted file mode 100644
index bb496eaae..000000000
--- a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier2.java
+++ /dev/null
@@ -1,75 +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.modifier;
-
-import com.volmit.iris.engine.framework.Engine;
-import com.volmit.iris.engine.framework.EngineAssignedModifier;
-import com.volmit.iris.engine.object.common.CaveResult;
-import com.volmit.iris.util.collection.KList;
-import com.volmit.iris.util.data.B;
-import com.volmit.iris.util.hunk.Hunk;
-import com.volmit.iris.util.math.RNG;
-import com.volmit.iris.util.noise.FastNoiseDouble;
-import com.volmit.iris.util.parallel.BurstExecutor;
-import com.volmit.iris.util.scheduling.PrecisionStopwatch;
-import org.bukkit.block.data.BlockData;
-
-public class IrisCaveModifier2 extends EngineAssignedModifier {
- public static final BlockData CAVE_AIR = B.get("CAVE_AIR");
- public static final BlockData AIR = B.get("AIR");
- private static final KList EMPTY = new KList<>();
- private final FastNoiseDouble gg;
- private final RNG rng;
-
- public IrisCaveModifier2(Engine engine) {
- super(engine, "Cave");
- rng = new RNG(engine.getWorld().seed() + 28934555);
- gg = new FastNoiseDouble(324895L * rng.nextParallelRNG(49678).imax());
- }
-
- @Override
- public void onModify(int x, int z, Hunk a, boolean multicore) {
- if (!getDimension().isCaves()) {
- return;
- }
-
- PrecisionStopwatch p = PrecisionStopwatch.start();
- if (multicore) {
- BurstExecutor e = getEngine().burst().burst(a.getWidth());
- for (int i = 0; i < a.getWidth(); i++) {
- int finalI = i;
- e.queue(() -> modifySliver(x, z, finalI, a));
- }
-
- e.complete();
- } else {
- for (int i = 0; i < a.getWidth(); i++) {
- modifySliver(x, z, i, a);
- }
- }
-
- getEngine().getMetrics().getCave().put(p.getMilliseconds());
- }
-
- public void modifySliver(int x, int z, int finalI, Hunk a) {
- for (int j = 0; j < a.getDepth(); j++) {
-
- }
- }
-}
diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java
index c3402d5d6..3e2e7bb63 100644
--- a/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java
+++ b/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java
@@ -54,8 +54,8 @@ public class IrisDepositModifier extends EngineAssignedModifier {
RNG ro = rx.nextParallelRNG(x * x).nextParallelRNG(z * z);
IrisRegion region = getComplex().getRegionStream().get((x * 16) + 7, (z * 16) + 7);
IrisBiome biome = getComplex().getTrueBiomeStream().get((x * 16) + 7, (z * 16) + 7);
- BurstExecutor burst = burst().burst();
- burst.setMulticore(multicore);
+ BurstExecutor burst = burst().burst(multicore);
+
for (IrisDepositGenerator k : getDimension().getDeposits()) {
burst.queue(() -> generate(k, terrain, ro, x, z, false));
}
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 fee01f68a..5b772153a 100644
--- a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java
+++ b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java
@@ -64,20 +64,15 @@ public class IrisPostModifier extends EngineAssignedModifier {
PrecisionStopwatch p = PrecisionStopwatch.start();
AtomicInteger i = new AtomicInteger();
AtomicInteger j = new AtomicInteger();
- BurstExecutor burst = burst().burst();
- burst.setMulticore(multicore);
Hunk sync = output.synchronize();
for (i.set(0); i.get() < output.getWidth(); i.getAndIncrement()) {
- burst.queue(() -> {
- for (j.set(0); j.get() < output.getDepth(); j.getAndIncrement()) {
- int ii = i.get();
- int jj = j.get();
- post(ii, jj, sync, ii + x, jj + z);
- }
- });
+ for (j.set(0); j.get() < output.getDepth(); j.getAndIncrement()) {
+ int ii = i.get();
+ int jj = j.get();
+ post(ii, jj, sync, ii + x, jj + z);
+ }
}
- burst.complete();
getEngine().getMetrics().getPost().put(p.getMilliseconds());
}
diff --git a/src/main/java/com/volmit/iris/engine/object/basic/IrisPosition.java b/src/main/java/com/volmit/iris/engine/object/basic/IrisPosition.java
index fea93553f..e85f499b1 100644
--- a/src/main/java/com/volmit/iris/engine/object/basic/IrisPosition.java
+++ b/src/main/java/com/volmit/iris/engine/object/basic/IrisPosition.java
@@ -54,6 +54,10 @@ public class IrisPosition {
public IrisPosition(Vector v) {
this(v.getBlockX(), v.getBlockY(), v.getBlockZ());
}
+ public IrisPosition(double x, double y, double z) {
+ this((int)x,(int)y,(int)z);
+ }
+
public IrisPosition add(IrisPosition relativePosition) {
return new IrisPosition(relativePosition.x + x, relativePosition.y + y, relativePosition.z + z);
diff --git a/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java b/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java
index 4994393f9..e086f36cd 100644
--- a/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java
+++ b/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java
@@ -48,8 +48,10 @@ import com.volmit.iris.util.data.B;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.util.data.VanillaBiomeMap;
import com.volmit.iris.util.inventorygui.RandomColor;
+import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.noise.CNG;
+import com.volmit.iris.util.plugin.VolmitSender;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -696,4 +698,9 @@ public class IrisBiome extends IrisRegistrant implements IRare {
public String getTypeName() {
return "Biome";
}
+
+ @Override
+ public void scanForErrors(JSONObject p, VolmitSender sender) {
+
+ }
}
diff --git a/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java b/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java
index 28ec3d367..df29b7a01 100644
--- a/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java
+++ b/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java
@@ -26,6 +26,8 @@ import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.data.B;
+import com.volmit.iris.util.json.JSONObject;
+import com.volmit.iris.util.plugin.VolmitSender;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -193,17 +195,15 @@ public class IrisBlockData extends IrisRegistrant {
}
try {
- return Integer.valueOf(string);
- } catch (Throwable e) {
- Iris.reportError(e);
-
+ return Integer.parseInt(string);
+ } catch (Throwable ignored) {
+ // Checks
}
try {
return Double.valueOf(string).intValue();
- } catch (Throwable e) {
- Iris.reportError(e);
-
+ } catch (Throwable ignored) {
+ // Checks
}
return string;
@@ -218,4 +218,9 @@ public class IrisBlockData extends IrisRegistrant {
public String getTypeName() {
return "Block";
}
+
+ @Override
+ public void scanForErrors(JSONObject p, VolmitSender sender) {
+
+ }
}
diff --git a/src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java b/src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java
new file mode 100644
index 000000000..13483cd7d
--- /dev/null
+++ b/src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java
@@ -0,0 +1,66 @@
+/*
+ * 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.cave;
+
+import com.volmit.iris.core.project.loader.IrisData;
+import com.volmit.iris.core.project.loader.IrisRegistrant;
+import com.volmit.iris.engine.object.annotations.Desc;
+import com.volmit.iris.engine.object.noise.IrisWorm;
+import com.volmit.iris.util.collection.KList;
+import com.volmit.iris.util.data.B;
+import com.volmit.iris.util.json.JSONObject;
+import com.volmit.iris.util.mantle.Mantle;
+import com.volmit.iris.util.math.RNG;
+import com.volmit.iris.util.noise.Worm;
+import com.volmit.iris.util.noise.Worm3;
+import com.volmit.iris.util.noise.WormIterator3;
+import com.volmit.iris.util.plugin.VolmitSender;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.util.Vector;
+
+@EqualsAndHashCode(callSuper = true)
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+@Desc("Translate objects")
+@Data
+public class IrisCave extends IrisRegistrant {
+ @Desc("Define the shape of this cave")
+ private IrisWorm worm;
+
+ @Override
+ public String getFolderName() {
+ return "caves";
+ }
+
+ @Override
+ public String getTypeName() {
+ return "Cave";
+ }
+
+ @Override
+ public void scanForErrors(JSONObject p, VolmitSender sender) {
+
+ }
+}
diff --git a/src/main/java/com/volmit/iris/engine/object/cave/IrisCavePlacer.java b/src/main/java/com/volmit/iris/engine/object/cave/IrisCavePlacer.java
new file mode 100644
index 000000000..3f1ac227d
--- /dev/null
+++ b/src/main/java/com/volmit/iris/engine/object/cave/IrisCavePlacer.java
@@ -0,0 +1,108 @@
+/*
+ * 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.cave;
+
+import com.volmit.iris.Iris;
+import com.volmit.iris.core.project.loader.IrisData;
+import com.volmit.iris.engine.data.cache.AtomicCache;
+import com.volmit.iris.engine.object.annotations.Desc;
+import com.volmit.iris.engine.object.annotations.MinNumber;
+import com.volmit.iris.engine.object.annotations.RegistryListResource;
+import com.volmit.iris.engine.object.annotations.Required;
+import com.volmit.iris.engine.object.basic.IrisPosition;
+import com.volmit.iris.engine.object.common.IRare;
+import com.volmit.iris.util.collection.KList;
+import com.volmit.iris.util.data.B;
+import com.volmit.iris.util.mantle.Mantle;
+import com.volmit.iris.util.math.RNG;
+import com.volmit.iris.util.noise.Worm3;
+import com.volmit.iris.util.noise.WormIterator3;
+import com.volmit.iris.util.plugin.VolmitSender;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.util.BlockVector;
+import org.bukkit.util.Vector;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+@Desc("Translate objects")
+@Data
+public class IrisCavePlacer implements IRare {
+ private static final BlockData CAVE_AIR = B.get("CAVE_AIR");
+
+ @Required
+ @Desc("Typically a 1 in RARITY on a per chunk basis")
+ @MinNumber(1)
+ private int rarity = 15;
+
+ @MinNumber(1)
+ @Required
+ @Desc("The cave to place")
+ @RegistryListResource(IrisCave.class)
+ private String cave;
+
+ private transient final AtomicCache caveCache = new AtomicCache<>();
+ private transient final AtomicBoolean fail = new AtomicBoolean(false);
+
+ public IrisCave getRealCave(IrisData data)
+ {
+ return caveCache.aquire(() -> data.getCaveLoader().load(getCave()));
+ }
+
+ public void generateCave(Mantle mantle, RNG rng, IrisData data, int x, int y, int z)
+ {
+ if(fail.get())
+ {
+ return;
+ }
+
+ IrisCave cave = getRealCave(data);
+
+ if(cave == null)
+ {
+ Iris.warn("Unable to locate cave for generation!");
+ fail.set(true);
+ return;
+ }
+
+ WormIterator3 w = cave.getWorm().iterate3D(rng, data, x, y, z);
+ KList points = new KList<>();
+ int itr = 0;
+ while(w.hasNext())
+ {
+ itr++;
+ Worm3 wx = w.next();
+ points.add(new Vector(wx.getX().getPosition(), wx.getY().getPosition(), wx.getZ().getPosition()));
+ }
+
+
+ Iris.info(x + " " + y + " " + z + " /." + " POS: " + points.convert((i) -> "[" + i.getBlockX() + "," + i.getBlockY() + "," + i.getBlockZ() + "]").toString(", "));
+
+ mantle.setLine(points.convert(IrisPosition::new), cave.getWorm().getGirth().get(rng, x, z, data), true, CAVE_AIR);
+
+
+ // TODO decorate somehow
+ }
+}
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
index 413b488e9..0ad77ac6b 100644
--- a/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java
+++ b/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java
@@ -19,6 +19,8 @@
package com.volmit.iris.engine.object.common;
import com.volmit.iris.core.project.loader.IrisRegistrant;
+import com.volmit.iris.util.json.JSONObject;
+import com.volmit.iris.util.plugin.VolmitSender;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -48,4 +50,9 @@ public class IrisScript extends IrisRegistrant {
public String toString() {
return source;
}
+
+ @Override
+ public void scanForErrors(JSONObject p, VolmitSender sender) {
+
+ }
}
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 08050272d..0c9aa95eb 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
@@ -50,9 +50,11 @@ import com.volmit.iris.engine.object.villager.IrisVillagerOverride;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.util.io.IO;
+import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.noise.CNG;
+import com.volmit.iris.util.plugin.VolmitSender;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -81,13 +83,6 @@ public class IrisDimension extends IrisRegistrant {
@Desc("The human readable name of this dimension")
private String name = "A Dimension";
- @Desc("You can create mutliple dimensions on top of each other taking up less height of the same world. Such as the nether with a floor + ceiling.")
- @ArrayType(min = 1, type = IrisDimensionIndex.class)
- private KList dimensionalComposite = new KList<>();
-
- @Desc("Create an inverted dimension in the sky (like the nether)")
- private IrisDimension sky = null;
-
@RegistryListResource(IrisJigsawStructure.class)
@Desc("If defined, Iris will place the given jigsaw structure where minecraft should place the overworld stronghold.")
private String stronghold;
@@ -285,12 +280,6 @@ public class IrisDimension extends IrisRegistrant {
@Desc("Change the size of regions")
private double regionZoom = 1;
- @Desc("The terrain mode. NORMAL is normal... ISLANDS creates floating islands at varied heights")
- private IrisTerrainMode terrainMode = IrisTerrainMode.NORMAL;
-
- @Desc("The configuration for island mode dimensions")
- private IrisTerrainIsland islandMode = new IrisTerrainIsland();
-
@Desc("Disable this to stop placing objects, entities, features & updates")
private boolean useMantle = true;
@@ -358,10 +347,6 @@ public class IrisDimension extends IrisRegistrant {
});
}
- public boolean hasSky() {
- return getSky() != null;
- }
-
public CNG getCoordFracture(RNG rng, int signature) {
return coordFracture.aquire(() ->
{
@@ -560,4 +545,9 @@ public class IrisDimension extends IrisRegistrant {
public String getTypeName() {
return "Dimension";
}
+
+ @Override
+ public void scanForErrors(JSONObject p, VolmitSender sender) {
+
+ }
}
diff --git a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimensionIndex.java b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimensionIndex.java
deleted file mode 100644
index 570e325aa..000000000
--- a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimensionIndex.java
+++ /dev/null
@@ -1,54 +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.object.dimensional;
-
-import com.volmit.iris.engine.object.annotations.Desc;
-import com.volmit.iris.engine.object.annotations.MinNumber;
-import com.volmit.iris.engine.object.annotations.RegistryListResource;
-import com.volmit.iris.engine.object.annotations.Required;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-import lombok.experimental.Accessors;
-
-@SuppressWarnings("DefaultAnnotationParam")
-@Accessors(chain = true)
-@NoArgsConstructor
-@AllArgsConstructor
-@Desc("Represents an index for dimensions to take up vertical slots in the same world")
-@Data
-@EqualsAndHashCode(callSuper = false)
-public class IrisDimensionIndex {
- @Required
- @Desc("The weight of this dimension. If there are 2 dimensions, if the weight is the same on both, both dimensions will take up 128 blocks of height.")
- private double weight = 1D;
-
- @Desc("If inverted is set to true, the dimension will be updide down in the world")
- private boolean inverted = false;
-
- @Desc("Only one dimension layer should be set to primary. The primary dimension layer is where players spawn, and the biomes that the vanilla structure system uses to figure out what structures to place.")
- private boolean primary = false;
-
- @Required
- @RegistryListResource(IrisDimension.class)
- @MinNumber(1)
- @Desc("Name of dimension")
- private String dimension = "";
-}
diff --git a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisTerrainIsland.java b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisTerrainIsland.java
deleted file mode 100644
index 7b0df490f..000000000
--- a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisTerrainIsland.java
+++ /dev/null
@@ -1,50 +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.object.dimensional;
-
-import com.volmit.iris.engine.object.annotations.Desc;
-import com.volmit.iris.engine.object.annotations.MaxNumber;
-import com.volmit.iris.engine.object.annotations.MinNumber;
-import com.volmit.iris.engine.object.noise.IrisInterpolator;
-import com.volmit.iris.engine.object.noise.IrisStyledRange;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.Accessors;
-
-@Accessors(chain = true)
-@NoArgsConstructor
-@AllArgsConstructor
-@Desc("Translate objects")
-@Data
-public class IrisTerrainIsland {
- @Desc("The height range")
- private IrisStyledRange height = new IrisStyledRange().setMin(60).setMax(160);
-
- @Desc("How deep the island can get")
- private IrisStyledRange islandDepth = new IrisStyledRange().setMin(60).setMax(160);
-
- @MinNumber(1)
- @MaxNumber(10000)
- @Desc("How often are regions islands instead of nothing?")
- private double islandChance = 0.5;
-
- @Desc("Interpolate the edges of islands")
- private IrisInterpolator islandEdgeInterpolator = new IrisInterpolator();
-}
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 e9d10dd5f..b78044a1c 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
@@ -32,7 +32,9 @@ import com.volmit.iris.engine.object.meta.IrisEffect;
import com.volmit.iris.engine.object.spawners.IrisSurface;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.format.C;
+import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.math.RNG;
+import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import lombok.AllArgsConstructor;
@@ -380,4 +382,9 @@ public class IrisEntity extends IrisRegistrant {
public String getTypeName() {
return "Entity";
}
+
+ @Override
+ public void scanForErrors(JSONObject p, VolmitSender sender) {
+
+ }
}
diff --git a/src/main/java/com/volmit/iris/engine/object/feature/IrisFeaturePositional.java b/src/main/java/com/volmit/iris/engine/object/feature/IrisFeaturePositional.java
index dc686bb91..0edd0b49b 100644
--- a/src/main/java/com/volmit/iris/engine/object/feature/IrisFeaturePositional.java
+++ b/src/main/java/com/volmit/iris/engine/object/feature/IrisFeaturePositional.java
@@ -19,6 +19,7 @@
package com.volmit.iris.engine.object.feature;
import com.google.gson.Gson;
+import com.volmit.iris.Iris;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.object.annotations.Desc;
@@ -63,7 +64,18 @@ public class IrisFeaturePositional {
private static double BLOCK = 1D / 256D; // TODO: WARNING HEIGHT
public static IrisFeaturePositional read(DataInputStream s) throws IOException {
- return new Gson().fromJson(s.readUTF(), IrisFeaturePositional.class);
+ String sx = s.readUTF();
+ try
+ {
+ return new Gson().fromJson(sx, IrisFeaturePositional.class);
+ }
+
+ catch(Throwable e)
+ {
+ Iris.error(sx);
+ e.printStackTrace();
+ throw new IOException(e);
+ }
}
public void write(DataOutputStream s) throws IOException {
diff --git a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPiece.java b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPiece.java
index 87e9e2526..054db8418 100644
--- a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPiece.java
+++ b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPiece.java
@@ -30,6 +30,8 @@ import com.volmit.iris.engine.object.objects.IrisObject;
import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
import com.volmit.iris.engine.object.objects.ObjectPlaceMode;
import com.volmit.iris.util.collection.KList;
+import com.volmit.iris.util.json.JSONObject;
+import com.volmit.iris.util.plugin.VolmitSender;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -136,4 +138,9 @@ public class IrisJigsawPiece extends IrisRegistrant {
public String getTypeName() {
return "Jigsaw Piece";
}
+
+ @Override
+ public void scanForErrors(JSONObject p, VolmitSender sender) {
+
+ }
}
diff --git a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPool.java b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPool.java
index 35316d0ea..8dd1a8aeb 100644
--- a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPool.java
+++ b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPool.java
@@ -24,6 +24,8 @@ import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.RegistryListResource;
import com.volmit.iris.engine.object.annotations.Required;
import com.volmit.iris.util.collection.KList;
+import com.volmit.iris.util.json.JSONObject;
+import com.volmit.iris.util.plugin.VolmitSender;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -54,4 +56,9 @@ public class IrisJigsawPool extends IrisRegistrant {
public String getTypeName() {
return "Jigsaw Pool";
}
+
+ @Override
+ public void scanForErrors(JSONObject p, VolmitSender sender) {
+
+ }
}
diff --git a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawStructure.java b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawStructure.java
index af36ce9fa..f643b8567 100644
--- a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawStructure.java
+++ b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawStructure.java
@@ -23,7 +23,10 @@ import com.volmit.iris.core.project.loader.IrisRegistrant;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.engine.object.feature.IrisFeature;
+import com.volmit.iris.engine.object.noise.IrisStyledRange;
import com.volmit.iris.util.collection.KList;
+import com.volmit.iris.util.json.JSONObject;
+import com.volmit.iris.util.plugin.VolmitSender;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -59,7 +62,10 @@ public class IrisJigsawStructure extends IrisRegistrant {
@Desc("If set to true, iris will look for any pieces with only one connector in valid pools for edge connectors and attach them to 'terminate' the paths/piece connectors. Essentially it caps off ends. For example in a village, Iris would add houses to the ends of roads where possible. For terminators to be selected, they can only have one connector or they wont be chosen.")
private boolean terminate = true;
- @Desc("Set to lock the starting peice to a y coordinate, otherwise the surface will be used.")
+ @Desc("Override the y range instead of placing on the height map")
+ private IrisStyledRange overrideYRange = null;
+
+ @Desc("Force Y to a specific value")
private int lockY = -1;
private transient AtomicCache maxDimension = new AtomicCache<>();
@@ -144,4 +150,9 @@ public class IrisJigsawStructure extends IrisRegistrant {
public String getTypeName() {
return "Jigsaw Structure";
}
+
+ @Override
+ public void scanForErrors(JSONObject p, VolmitSender sender) {
+
+ }
}
diff --git a/src/main/java/com/volmit/iris/engine/object/loot/IrisLootTable.java b/src/main/java/com/volmit/iris/engine/object/loot/IrisLootTable.java
index 2f6a2656e..221781d44 100644
--- a/src/main/java/com/volmit/iris/engine/object/loot/IrisLootTable.java
+++ b/src/main/java/com/volmit/iris/engine/object/loot/IrisLootTable.java
@@ -25,7 +25,9 @@ import com.volmit.iris.engine.object.annotations.MinNumber;
import com.volmit.iris.engine.object.annotations.Required;
import com.volmit.iris.engine.object.meta.InventorySlotType;
import com.volmit.iris.util.collection.KList;
+import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.math.RNG;
+import com.volmit.iris.util.plugin.VolmitSender;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -96,4 +98,9 @@ public class IrisLootTable extends IrisRegistrant {
public String getTypeName() {
return "Loot";
}
+
+ @Override
+ public void scanForErrors(JSONObject p, VolmitSender sender) {
+
+ }
}
diff --git a/src/main/java/com/volmit/iris/engine/object/mods/IrisMod.java b/src/main/java/com/volmit/iris/engine/object/mods/IrisMod.java
index 0dc83583e..19d4d4476 100644
--- a/src/main/java/com/volmit/iris/engine/object/mods/IrisMod.java
+++ b/src/main/java/com/volmit/iris/engine/object/mods/IrisMod.java
@@ -25,6 +25,8 @@ import com.volmit.iris.engine.object.objects.IrisObject;
import com.volmit.iris.engine.object.objects.IrisObjectReplace;
import com.volmit.iris.engine.object.regional.IrisRegion;
import com.volmit.iris.util.collection.KList;
+import com.volmit.iris.util.json.JSONObject;
+import com.volmit.iris.util.plugin.VolmitSender;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -113,4 +115,9 @@ public class IrisMod extends IrisRegistrant {
public String getTypeName() {
return "Mod";
}
+
+ @Override
+ public void scanForErrors(JSONObject p, VolmitSender sender) {
+
+ }
}
diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisExpression.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisExpression.java
index 578070b1d..977cf1e4d 100644
--- a/src/main/java/com/volmit/iris/engine/object/noise/IrisExpression.java
+++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisExpression.java
@@ -28,7 +28,9 @@ import com.volmit.iris.engine.object.annotations.ArrayType;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.Required;
import com.volmit.iris.util.collection.KList;
+import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.math.RNG;
+import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.stream.ProceduralStream;
import com.volmit.iris.util.stream.interpolation.Interpolated;
import lombok.AllArgsConstructor;
@@ -128,4 +130,9 @@ public class IrisExpression extends IrisRegistrant {
public String getTypeName() {
return "Expression";
}
+
+ @Override
+ public void scanForErrors(JSONObject p, VolmitSender sender) {
+
+ }
}
diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisGenerator.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisGenerator.java
index 6a1c0d12c..f61c171db 100644
--- a/src/main/java/com/volmit/iris/engine/object/noise/IrisGenerator.java
+++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisGenerator.java
@@ -26,8 +26,10 @@ import com.volmit.iris.engine.object.common.IRare;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.context.IrisContext;
import com.volmit.iris.util.interpolation.IrisInterpolation;
+import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.noise.CellGenerator;
+import com.volmit.iris.util.plugin.VolmitSender;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -295,4 +297,9 @@ public class IrisGenerator extends IrisRegistrant {
public String getTypeName() {
return "Generator";
}
+
+ @Override
+ public void scanForErrors(JSONObject p, VolmitSender sender) {
+
+ }
}
diff --git a/src/main/java/com/volmit/iris/engine/object/cave/IrisWormGenerator.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java
similarity index 54%
rename from src/main/java/com/volmit/iris/engine/object/cave/IrisWormGenerator.java
rename to src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java
index 1717af527..97b862308 100644
--- a/src/main/java/com/volmit/iris/engine/object/cave/IrisWormGenerator.java
+++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java
@@ -16,8 +16,10 @@
* along with this program. If not, see .
*/
-package com.volmit.iris.engine.object.cave;
+package com.volmit.iris.engine.object.noise;
+import com.volmit.iris.core.project.loader.IrisData;
+import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.MinNumber;
import com.volmit.iris.engine.object.annotations.Required;
@@ -27,7 +29,11 @@ import com.volmit.iris.engine.object.noise.IrisGeneratorStyle;
import com.volmit.iris.engine.object.noise.IrisNoiseGenerator;
import com.volmit.iris.engine.object.noise.IrisStyledRange;
import com.volmit.iris.engine.object.noise.NoiseStyle;
+import com.volmit.iris.util.function.NoiseProvider;
+import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.noise.Worm;
+import com.volmit.iris.util.noise.WormIterator2;
+import com.volmit.iris.util.noise.WormIterator3;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -38,14 +44,9 @@ import lombok.experimental.Accessors;
@AllArgsConstructor
@Desc("Generate worms")
@Data
-public class IrisWormGenerator implements IRare {
- @Required
- @Desc("Typically a 1 in RARITY on a per chunk basis")
- @MinNumber(1)
- private int rarity = 15;
-
+public class IrisWorm {
@Desc("The style used to determine the curvature of this worm")
- private IrisGeneratorStyle angleStyle = new IrisGeneratorStyle();
+ private IrisGeneratorStyle angleStyle = new IrisGeneratorStyle(NoiseStyle.PERLIN);
@Desc("The max block distance this worm can travel from its start. This can have performance implications at ranges over 1,000 blocks but it's not too serious, test.")
private int maxDistance = 128;
@@ -53,7 +54,36 @@ public class IrisWormGenerator implements IRare {
@Desc("The max segments, or iterations this worm can execute on. Setting this to -1 will allow it to run up to the maxDistance's value of iterations (default)")
private int maxSegments = -1;
- @Desc("The thickness of the worm over distance")
- private IrisStyledRange girth = new IrisStyledRange().setMin(3).setMax(7)
- .setStyle(new IrisGeneratorStyle(NoiseStyle.SIMPLEX));
+ @Desc("The distance between segments")
+ private IrisStyledRange segmentDistance = new IrisStyledRange().setMin(4).setMax(7)
+ .setStyle(new IrisGeneratorStyle(NoiseStyle.PERLIN));
+
+ @Desc("The thickness of the worms. Each individual worm has the same thickness while traveling however, each spawned worm will vary in thickness.")
+ private IrisStyledRange girth = new IrisStyledRange().setMin(3).setMax(5)
+ .setStyle(new IrisGeneratorStyle(NoiseStyle.PERLIN));
+
+ private transient final AtomicCache angleProviderCache = new AtomicCache<>();
+
+ public NoiseProvider getAngleProvider(RNG rng, IrisData data)
+ {
+ return angleProviderCache.aquire(() -> (xx, zz) -> angleStyle.create(rng, data).fitDouble(-0.5, 0.5, xx, zz) * segmentDistance.get(rng, xx, zz, data));
+ }
+
+ public WormIterator2 iterate2D(RNG rng, IrisData data, int x, int z)
+ {
+ return WormIterator2.builder()
+ .maxDistance(maxDistance)
+ .maxIterations(maxSegments == -1 ? maxDistance : maxSegments)
+ .noise(getAngleProvider(rng, data)).x(x).z(z)
+ .build();
+ }
+
+ public WormIterator3 iterate3D(RNG rng, IrisData data, int x, int y, int z)
+ {
+ return WormIterator3.builder()
+ .maxDistance(maxDistance)
+ .maxIterations(maxSegments == -1 ? maxDistance : maxSegments)
+ .noise(getAngleProvider(rng, data)).x(x).z(z).y(y)
+ .build();
+ }
}
diff --git a/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java b/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java
index 16d591103..8c6ade3d5 100644
--- a/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java
+++ b/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java
@@ -31,10 +31,12 @@ import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.interpolation.IrisInterpolation;
+import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.math.AxisAlignedBB;
import com.volmit.iris.util.math.BlockPosition;
import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.RNG;
+import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.IrisLock;
import lombok.EqualsAndHashCode;
import lombok.Getter;
@@ -281,7 +283,7 @@ public class IrisObject extends IrisRegistrant {
this.h = din.readInt();
this.d = din.readInt();
if (!din.readUTF().equals("Iris V2 IOB;")) {
- throw new IOException("Not V2 Format");
+ return;
}
center = new BlockVector(w / 2, h / 2, d / 2);
int s = din.readShort();
@@ -994,4 +996,9 @@ public class IrisObject extends IrisRegistrant {
public String getTypeName() {
return "Object";
}
+
+ @Override
+ public void scanForErrors(JSONObject p, VolmitSender sender) {
+
+ }
}
diff --git a/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java b/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java
index c24ea2ab8..728d99c80 100644
--- a/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java
+++ b/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java
@@ -44,8 +44,10 @@ import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.util.data.VanillaBiomeMap;
import com.volmit.iris.util.inventorygui.RandomColor;
+import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.noise.CNG;
+import com.volmit.iris.util.plugin.VolmitSender;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -572,4 +574,9 @@ public class IrisRegion extends IrisRegistrant implements IRare {
public String getTypeName() {
return "Region";
}
+
+ @Override
+ public void scanForErrors(JSONObject p, VolmitSender sender) {
+
+ }
}
diff --git a/src/main/java/com/volmit/iris/engine/object/spawners/IrisSpawner.java b/src/main/java/com/volmit/iris/engine/object/spawners/IrisSpawner.java
index ece3c420c..2a0e98687 100644
--- a/src/main/java/com/volmit/iris/engine/object/spawners/IrisSpawner.java
+++ b/src/main/java/com/volmit/iris/engine/object/spawners/IrisSpawner.java
@@ -28,6 +28,8 @@ import com.volmit.iris.engine.object.basic.IrisWeather;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.entity.IrisEntitySpawn;
import com.volmit.iris.util.collection.KList;
+import com.volmit.iris.util.json.JSONObject;
+import com.volmit.iris.util.plugin.VolmitSender;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -106,4 +108,9 @@ public class IrisSpawner extends IrisRegistrant {
public String getTypeName() {
return "Spawner";
}
+
+ @Override
+ public void scanForErrors(JSONObject p, VolmitSender sender) {
+
+ }
}
diff --git a/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java b/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java
index 907dd6572..8547643db 100644
--- a/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java
+++ b/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java
@@ -188,7 +188,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
}
loadLock.acquire();
- PrecisionStopwatch ps = PrecisionStopwatch.start();
TerrainChunk tc = TerrainChunk.create(world, biome);
Hunk blocks = Hunk.view((ChunkData) tc);
Hunk biomes = Hunk.view((BiomeGrid) tc);
diff --git a/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java b/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java
index f3701efb2..82bd57971 100644
--- a/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java
+++ b/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java
@@ -34,6 +34,7 @@ import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.documentation.RegionCoordinates;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.math.Position2;
+import com.volmit.iris.util.nbt.mca.MCAFile;
import com.volmit.iris.util.nbt.mca.MCAUtil;
import com.volmit.iris.util.nbt.mca.NBTWorld;
import com.volmit.iris.util.nbt.tag.CompoundTag;
@@ -58,18 +59,17 @@ public class HeadlessGenerator implements PlatformChunkGenerator {
public HeadlessGenerator(HeadlessWorld world) {
this.world = world;
- burst = new MultiBurst("Iris Headless Generator", 9, IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount()));
+ burst = MultiBurst.burst;
writer = new NBTWorld(world.getWorld().worldFolder());
engine = new IrisEngine(new EngineTarget(world.getWorld(), world.getDimension(), world.getDimension().getLoader()), isStudio());
}
@ChunkCoordinates
- public void generateChunk(int x, int z) {
+ public void generateChunk(MCAFile file, int x, int z) {
try {
int ox = x << 4;
int oz = z << 4;
- com.volmit.iris.util.nbt.mca.Chunk chunk = writer.getChunk(x, z);
-
+ com.volmit.iris.util.nbt.mca.Chunk chunk = writer.getChunk(file, x, z);
TerrainChunk tc = MCATerrainChunk.builder()
.writer(writer).ox(ox).oz(oz).mcaChunk(chunk)
.minHeight(world.getWorld().minHeight()).maxHeight(world.getWorld().maxHeight())
@@ -102,11 +102,12 @@ public class HeadlessGenerator implements PlatformChunkGenerator {
@RegionCoordinates
public void generateRegion(int x, int z, PregenListener listener) {
BurstExecutor e = burst.burst(1024);
+ MCAFile f = writer.getMCA(x, x);
PregenTask.iterateRegion(x, z, (ii, jj) -> e.queue(() -> {
if (listener != null) {
listener.onChunkGenerating(ii, jj);
}
- generateChunk(ii, jj);
+ generateChunk(f, ii, jj);
if (listener != null) {
listener.onChunkGenerated(ii, jj);
}
@@ -131,7 +132,6 @@ public class HeadlessGenerator implements PlatformChunkGenerator {
}
public void close() {
- burst.shutdownAndAwait();
getEngine().close();
writer.close();
}
diff --git a/src/main/java/com/volmit/iris/util/data/B.java b/src/main/java/com/volmit/iris/util/data/B.java
index 25fc1b483..e072a5ab4 100644
--- a/src/main/java/com/volmit/iris/util/data/B.java
+++ b/src/main/java/com/volmit/iris/util/data/B.java
@@ -22,7 +22,10 @@ import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
-import com.volmit.iris.util.collection.KSet;
+import com.volmit.iris.util.scheduling.ChronoLatch;
+import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
+import it.unimi.dsi.fastutil.ints.IntSet;
+import it.unimi.dsi.fastutil.ints.IntSets;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
@@ -33,395 +36,201 @@ import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
+import static org.bukkit.Material.*;
+
public class B {
private static final Material AIR_MATERIAL = Material.AIR;
private static final BlockData AIR = AIR_MATERIAL.createBlockData();
- private static final KSet nullBlockDataCache = new KSet<>();
- private static final KSet nullMaterialCache = new KSet<>();
- private static final KMap solidCache = new KMap<>();
- private static final KMap updatableCache = new KMap<>();
- private static final KMap foliageCache = new KMap<>();
- private static final KMap litCache = new KMap<>();
- private static final KMap decorantCache = new KMap<>();
- private static final KMap storageCache = new KMap<>();
- private static final KMap storageChestCache = new KMap<>();
+ private static final IntSet foliageCache = buildFoliageCache();
+ private static final IntSet decorantCache = buildDecorantCache();
+ private static final IntSet storageCache = buildStorageCache();
+ private static final IntSet storageChestCache = buildStorageChestCache();
+ private static final IntSet litCache = buildLitCache();
private static final KMap blockDataCache = new KMap<>();
- private static final KMap materialCache = new KMap<>();
+ private static final ChronoLatch clw = new ChronoLatch(1000);
- public static boolean isWater(BlockData b) {
- return b.getMaterial().equals(Material.WATER);
+ private static IntSet buildFoliageCache() {
+ IntSet b = new IntOpenHashSet();
+ Arrays.stream(new Material[]{
+ POPPY,
+ DANDELION,
+ CORNFLOWER,
+ SWEET_BERRY_BUSH,
+ CRIMSON_ROOTS,
+ WARPED_ROOTS,
+ NETHER_SPROUTS,
+ ALLIUM,
+ AZURE_BLUET,
+ BLUE_ORCHID,
+ OXEYE_DAISY,
+ LILY_OF_THE_VALLEY,
+ WITHER_ROSE,
+ DARK_OAK_SAPLING,
+ ACACIA_SAPLING,
+ JUNGLE_SAPLING,
+ BIRCH_SAPLING,
+ SPRUCE_SAPLING,
+ OAK_SAPLING,
+ ORANGE_TULIP,
+ PINK_TULIP,
+ RED_TULIP,
+ WHITE_TULIP,
+ FERN,
+ LARGE_FERN,
+ GRASS,
+ TALL_GRASS
+ }).forEach((i) -> b.add(i.ordinal()));
+
+ return IntSets.unmodifiable(b);
}
- public static BlockData getAir() {
- return AIR;
+ private static IntSet buildDecorantCache() {
+ IntSet b = new IntOpenHashSet();
+ Arrays.stream(new Material[]{
+ GRASS,
+ TALL_GRASS,
+ FERN,
+ LARGE_FERN,
+ CORNFLOWER,
+ SUNFLOWER,
+ CHORUS_FLOWER,
+ POPPY,
+ DANDELION,
+ OXEYE_DAISY,
+ ORANGE_TULIP,
+ PINK_TULIP,
+ RED_TULIP,
+ WHITE_TULIP,
+ LILAC,
+ DEAD_BUSH,
+ SWEET_BERRY_BUSH,
+ ROSE_BUSH,
+ WITHER_ROSE,
+ ALLIUM,
+ BLUE_ORCHID,
+ LILY_OF_THE_VALLEY,
+ CRIMSON_FUNGUS,
+ WARPED_FUNGUS,
+ RED_MUSHROOM,
+ BROWN_MUSHROOM,
+ CRIMSON_ROOTS,
+ AZURE_BLUET,
+ WEEPING_VINES,
+ WEEPING_VINES_PLANT,
+ WARPED_ROOTS,
+ NETHER_SPROUTS,
+ TWISTING_VINES,
+ TWISTING_VINES_PLANT,
+ SUGAR_CANE,
+ WHEAT,
+ POTATOES,
+ CARROTS,
+ BEETROOTS,
+ NETHER_WART,
+ SEA_PICKLE,
+ SEAGRASS,
+ ACACIA_BUTTON,
+ BIRCH_BUTTON,
+ CRIMSON_BUTTON,
+ DARK_OAK_BUTTON,
+ JUNGLE_BUTTON,
+ OAK_BUTTON,
+ POLISHED_BLACKSTONE_BUTTON,
+ SPRUCE_BUTTON,
+ STONE_BUTTON,
+ WARPED_BUTTON,
+ TORCH,
+ SOUL_TORCH
+ }).forEach((i) -> b.add(i.ordinal()));
+ b.addAll(foliageCache);
+
+ return IntSets.unmodifiable(b);
}
- public static Material getMaterial(String bdx) {
- Material mat = getMaterialOrNull(bdx);
+ private static IntSet buildLitCache() {
+ IntSet b = new IntOpenHashSet();
+ Arrays.stream(new Material[]{
+ GLOWSTONE,
+ END_ROD,
+ SOUL_SAND,
+ TORCH,
+ REDSTONE_TORCH,
+ SOUL_TORCH,
+ REDSTONE_WALL_TORCH,
+ WALL_TORCH,
+ SOUL_WALL_TORCH,
+ LANTERN,
+ CANDLE,
+ JACK_O_LANTERN,
+ REDSTONE_LAMP,
+ MAGMA_BLOCK,
+ LIGHT,
+ SHROOMLIGHT,
+ SEA_LANTERN,
+ SOUL_LANTERN,
+ FIRE,
+ SOUL_FIRE,
+ SEA_PICKLE,
+ BREWING_STAND,
+ REDSTONE_ORE,
+ }).forEach((i) -> b.add(i.ordinal()));
- if (mat != null) {
- return mat;
- }
-
- return AIR_MATERIAL;
+ return IntSets.unmodifiable(b);
}
- public static Material getMaterialOrNull(String bdxx) {
- String bx = bdxx.trim().toUpperCase();
+ private static IntSet buildStorageCache() {
+ IntSet b = new IntOpenHashSet();
+ Arrays.stream(new Material[]{
+ CHEST,
+ SMOKER,
+ TRAPPED_CHEST,
+ SHULKER_BOX,
+ WHITE_SHULKER_BOX,
+ ORANGE_SHULKER_BOX,
+ MAGENTA_SHULKER_BOX,
+ LIGHT_BLUE_SHULKER_BOX,
+ YELLOW_SHULKER_BOX,
+ LIME_SHULKER_BOX,
+ PINK_SHULKER_BOX,
+ GRAY_SHULKER_BOX,
+ LIGHT_GRAY_SHULKER_BOX,
+ CYAN_SHULKER_BOX,
+ PURPLE_SHULKER_BOX,
+ BLUE_SHULKER_BOX,
+ BROWN_SHULKER_BOX,
+ GREEN_SHULKER_BOX,
+ RED_SHULKER_BOX,
+ BLACK_SHULKER_BOX,
+ BARREL,
+ DISPENSER,
+ DROPPER,
+ HOPPER,
+ FURNACE,
+ BLAST_FURNACE
+ }).forEach((i) -> b.add(i.ordinal()));
- if (nullMaterialCache.contains(bx)) {
- return null;
- }
-
- Material mat = materialCache.get(bx);
-
- if (mat != null) {
- return mat;
- }
-
- try {
- Material mm = Material.valueOf(bx);
- materialCache.put(bx, mm);
- return mm;
- } catch (Throwable e) {
- Iris.reportError(e);
- nullMaterialCache.add(bx);
- return null;
- }
+ return IntSets.unmodifiable(b);
}
- public static boolean isSolid(BlockData mat) {
- return isSolid(mat.getMaterial());
- }
+ private static IntSet buildStorageChestCache() {
+ IntSet b = new IntOpenHashSet(storageCache);
+ b.remove(SMOKER.ordinal());
+ b.remove(FURNACE.ordinal());
+ b.remove(BLAST_FURNACE.ordinal());
- public static boolean isSolid(Material mat) {
- Boolean solid = solidCache.get(mat);
-
- if (solid != null) {
- return solid;
- }
-
- solid = mat.isSolid();
- solidCache.put(mat, solid);
-
- return solid;
- }
-
- public static BlockData getOrNull(String bdxf) {
- try {
- String bd = bdxf.trim();
- BlockData bdx = parseBlockData(bd);
-
- if (bdx == null) {
- Iris.warn("Unknown Block Data '" + bd + "'");
- return AIR;
- }
-
- return bdx;
- } catch (Throwable e) {
- Iris.reportError(e);
- Iris.warn("Unknown Block Data '" + bdxf + "'");
- }
-
- return null;
- }
-
- public static BlockData get(String bdxf) {
- BlockData bd = getOrNull(bdxf);
-
- if (bd != null) {
- return bd;
- }
-
- return AIR;
- }
-
- private static BlockData parseBlockDataOrNull(String ix) {
- if (nullBlockDataCache.contains(ix)) {
- return null;
- }
-
- try {
- BlockData bb = blockDataCache.get(ix);
-
- if (bb != null) {
- return bb;
- }
- BlockData bx = null;
-
- if (ix.startsWith("oraxen:") && Iris.linkOraxen.supported()) {
- bx = Iris.linkOraxen.getBlockDataFor(ix.split("\\Q:\\E")[1]);
- }
-
- if (bx == null) {
- bx = Bukkit.createBlockData(ix);
- }
-
- if (bx instanceof Leaves && IrisSettings.get().getGenerator().preventLeafDecay) {
- ((Leaves) bx).setPersistent(true);
- } else if (bx instanceof Leaves) {
- ((Leaves) bx).setPersistent(false);
- }
-
- blockDataCache.put(ix, bx);
- return bx;
- } catch (Exception e) {
- //Iris.reportError(e);
- Iris.debug("Failed to load block \"" + ix + "\"");
-
- String block = ix.contains(":") ? ix.split(":")[1].toLowerCase() : ix.toLowerCase();
- String state = block.contains("[") ? block.split("\\[")[1].split("\\]")[0] : "";
- Map stateMap = new HashMap<>();
- if (!state.equals("")) {
- Arrays.stream(state.split(",")).forEach(s -> {
- stateMap.put(s.split("=")[0], s.split("=")[1]);
- });
- }
- block = block.split("\\[")[0];
-
- switch (block) {
- case "cauldron" -> block = "water_cauldron"; //Would fail to load if it has a level parameter
- case "grass_path" -> block = "dirt_path";
- case "concrete" -> block = "white_concrete";
- case "wool" -> block = "white_wool";
- case "beetroots" -> {
- if (stateMap.containsKey("age")) {
- String updated = stateMap.get("age");
- switch (updated) {
- case "7" -> updated = "3";
- case "3", "4", "5" -> updated = "2";
- case "1", "2" -> updated = "1";
- }
- stateMap.put("age", updated);
- }
- }
- }
-
- Map newStates = new HashMap<>();
- for (String key : stateMap.keySet()) { //Iterate through every state and check if its valid
- try {
- String newState = block + "[" + key + "=" + stateMap.get(key) + "]";
- Bukkit.createBlockData(newState);
-
- //If we get to here, the state is okay so we can use it
- newStates.put(key, stateMap.get(key));
-
- } catch (IllegalArgumentException ignored) {
- }
- }
-
- //Combine all the "good" states again
- state = newStates.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).collect(Collectors.joining(","));
- if (!state.equals("")) state = "[" + state + "]";
- String newBlock = block + state;
- Iris.debug("Converting " + ix + " to " + newBlock);
-
- try {
- BlockData bd = Bukkit.createBlockData(newBlock);
- blockDataCache.put(ix, bd);
- return bd;
- } catch (Throwable e1) {
- Iris.reportError(e1);
- }
-
- nullBlockDataCache.add(ix);
- return null;
- }
- }
-
- private static BlockData parseBlockData(String ix) {
- BlockData bd = parseBlockDataOrNull(ix);
-
- if (bd != null) {
- return bd;
- }
-
- Iris.warn("Unknown Block Data: " + ix);
-
- return AIR;
- }
-
- public static boolean isStorage(BlockData mat) {
- Material mm = mat.getMaterial();
- Boolean f = storageCache.get(mm);
-
- if (f != null) {
- return f;
- }
-
- f = mm.equals(B.getMaterial("CHEST"))
- || mm.equals(B.getMaterial("TRAPPED_CHEST"))
- || mm.equals(B.getMaterial("SHULKER_BOX"))
- || mm.equals(B.getMaterial("WHITE_SHULKER_BOX"))
- || mm.equals(B.getMaterial("ORANGE_SHULKER_BOX"))
- || mm.equals(B.getMaterial("MAGENTA_SHULKER_BOX"))
- || mm.equals(B.getMaterial("LIGHT_BLUE_SHULKER_BOX"))
- || mm.equals(B.getMaterial("YELLOW_SHULKER_BOX"))
- || mm.equals(B.getMaterial("LIME_SHULKER_BOX"))
- || mm.equals(B.getMaterial("PINK_SHULKER_BOX"))
- || mm.equals(B.getMaterial("GRAY_SHULKER_BOX"))
- || mm.equals(B.getMaterial("LIGHT_GRAY_SHULKER_BOX"))
- || mm.equals(B.getMaterial("CYAN_SHULKER_BOX"))
- || mm.equals(B.getMaterial("PURPLE_SHULKER_BOX"))
- || mm.equals(B.getMaterial("BLUE_SHULKER_BOX"))
- || mm.equals(B.getMaterial("BROWN_SHULKER_BOX"))
- || mm.equals(B.getMaterial("GREEN_SHULKER_BOX"))
- || mm.equals(B.getMaterial("RED_SHULKER_BOX"))
- || mm.equals(B.getMaterial("BLACK_SHULKER_BOX"))
- || mm.equals(B.getMaterial("BARREL"))
- || mm.equals(B.getMaterial("DISPENSER"))
- || mm.equals(B.getMaterial("DROPPER"))
- || mm.equals(B.getMaterial("HOPPER"))
- || mm.equals(B.getMaterial("FURNACE"))
- || mm.equals(B.getMaterial("BLAST_FURNACE"))
- || mm.equals(B.getMaterial("SMOKER"));
- storageCache.put(mm, f);
- return f;
- }
-
- public static boolean isStorageChest(BlockData mat) {
- if (!isStorage(mat)) {
- return false;
- }
-
- Material mm = mat.getMaterial();
- Boolean f = storageChestCache.get(mm);
-
- if (f != null) {
- return f;
- }
-
- f = mm.equals(B.getMaterial("CHEST"))
- || mm.equals(B.getMaterial("TRAPPED_CHEST"))
- || mm.equals(B.getMaterial("SHULKER_BOX"))
- || mm.equals(B.getMaterial("WHITE_SHULKER_BOX"))
- || mm.equals(B.getMaterial("ORANGE_SHULKER_BOX"))
- || mm.equals(B.getMaterial("MAGENTA_SHULKER_BOX"))
- || mm.equals(B.getMaterial("LIGHT_BLUE_SHULKER_BOX"))
- || mm.equals(B.getMaterial("YELLOW_SHULKER_BOX"))
- || mm.equals(B.getMaterial("LIME_SHULKER_BOX"))
- || mm.equals(B.getMaterial("PINK_SHULKER_BOX"))
- || mm.equals(B.getMaterial("GRAY_SHULKER_BOX"))
- || mm.equals(B.getMaterial("LIGHT_GRAY_SHULKER_BOX"))
- || mm.equals(B.getMaterial("CYAN_SHULKER_BOX"))
- || mm.equals(B.getMaterial("PURPLE_SHULKER_BOX"))
- || mm.equals(B.getMaterial("BLUE_SHULKER_BOX"))
- || mm.equals(B.getMaterial("BROWN_SHULKER_BOX"))
- || mm.equals(B.getMaterial("GREEN_SHULKER_BOX"))
- || mm.equals(B.getMaterial("RED_SHULKER_BOX"))
- || mm.equals(B.getMaterial("BLACK_SHULKER_BOX"))
- || mm.equals(B.getMaterial("BARREL"))
- || mm.equals(B.getMaterial("DISPENSER"))
- || mm.equals(B.getMaterial("DROPPER"))
- || mm.equals(B.getMaterial("HOPPER"));
- storageChestCache.put(mm, f);
- return f;
- }
-
- public static boolean isLit(BlockData mat) {
- Material mm = mat.getMaterial();
- Boolean f = litCache.get(mm);
-
- if (f != null) {
- return f;
- }
-
- f = mm.equals(B.getMaterial("GLOWSTONE"))
- || mm.equals(B.getMaterial("END_ROD"))
- || mm.equals(B.getMaterial("SOUL_SAND"))
- || mm.equals(B.getMaterial("TORCH"))
- || mm.equals(Material.REDSTONE_TORCH)
- || mm.equals(B.getMaterial("SOUL_TORCH"))
- || mm.equals(Material.REDSTONE_WALL_TORCH)
- || mm.equals(Material.WALL_TORCH)
- || mm.equals(B.getMaterial("SOUL_WALL_TORCH"))
- || mm.equals(B.getMaterial("LANTERN"))
- || mm.equals(Material.JACK_O_LANTERN)
- || mm.equals(Material.REDSTONE_LAMP)
- || mm.equals(Material.MAGMA_BLOCK)
- || mm.equals(B.getMaterial("SHROOMLIGHT"))
- || mm.equals(B.getMaterial("SEA_LANTERN"))
- || mm.equals(B.getMaterial("SOUL_LANTERN"))
- || mm.equals(Material.FIRE)
- || mm.equals(B.getMaterial("SOUL_FIRE"))
- || mm.equals(B.getMaterial("SEA_PICKLE"))
- || mm.equals(Material.BREWING_STAND)
- || mm.equals(Material.REDSTONE_ORE);
- litCache.put(mm, f);
- return f;
- }
-
- public static boolean isUpdatable(BlockData mat) {
- Boolean u = updatableCache.get(mat.getMaterial());
-
- if (u != null) {
- return u;
- }
-
- u = isLit(mat) || isStorage(mat);
- updatableCache.put(mat.getMaterial(), u);
- return u;
- }
-
- public static boolean isFoliage(Material d) {
- return isFoliage(d.createBlockData());
- }
-
- public static boolean isFoliage(BlockData d) {
- Boolean f = foliageCache.get(d.getMaterial());
- if (f != null) {
- return f;
- }
-
- if (isFluid(d) || isAir(d) || isSolid(d)) {
- foliageCache.put(d.getMaterial(), false);
- return false;
- }
-
- Material mat = d.getMaterial();
- f = mat.equals(Material.POPPY)
- || mat.equals(Material.DANDELION)
- || mat.equals(B.getMaterial("CORNFLOWER"))
- || mat.equals(B.getMaterial("SWEET_BERRY_BUSH"))
- || mat.equals(B.getMaterial("CRIMSON_ROOTS"))
- || mat.equals(B.getMaterial("WARPED_ROOTS"))
- || mat.equals(B.getMaterial("NETHER_SPROUTS"))
- || mat.equals(B.getMaterial("ALLIUM"))
- || mat.equals(B.getMaterial("AZURE_BLUET"))
- || mat.equals(B.getMaterial("BLUE_ORCHID"))
- || mat.equals(B.getMaterial("POPPY"))
- || mat.equals(B.getMaterial("DANDELION"))
- || mat.equals(B.getMaterial("OXEYE_DAISY"))
- || mat.equals(B.getMaterial("LILY_OF_THE_VALLEY"))
- || mat.equals(B.getMaterial("WITHER_ROSE"))
- || mat.equals(Material.DARK_OAK_SAPLING)
- || mat.equals(Material.ACACIA_SAPLING)
- || mat.equals(Material.JUNGLE_SAPLING)
- || mat.equals(Material.BIRCH_SAPLING)
- || mat.equals(Material.SPRUCE_SAPLING)
- || mat.equals(Material.OAK_SAPLING)
- || mat.equals(Material.ORANGE_TULIP)
- || mat.equals(Material.PINK_TULIP)
- || mat.equals(Material.RED_TULIP)
- || mat.equals(Material.WHITE_TULIP)
- || mat.equals(Material.FERN)
- || mat.equals(Material.LARGE_FERN)
- || mat.equals(Material.GRASS)
- || mat.equals(Material.TALL_GRASS);
- foliageCache.put(d.getMaterial(), f);
- return f;
+ return IntSets.unmodifiable(b);
}
public static boolean canPlaceOnto(Material mat, Material onto) {
- String key = mat.name() + "" + onto.name();
-
if (isFoliage(mat)) {
if (!isFoliagePlantable(onto)) {
return false;
}
}
- if (onto.equals(Material.AIR) || onto.equals(B.getMaterial("CAVE_AIR")) || onto.equals(B.getMaterial("VOID_AIR"))) {
+ if (onto.equals(Material.AIR) ||
+ onto.equals(B.getMaterial("CAVE_AIR"))
+ || onto.equals(B.getMaterial("VOID_AIR"))) {
return false;
}
@@ -447,86 +256,6 @@ public class B {
return true;
}
- public static boolean isDecorant(BlockData m) {
- Material mm = m.getMaterial();
- Boolean f = decorantCache.get(mm);
-
- if (f != null) {
- return f;
- }
-
- f = mm.equals(Material.GRASS)
- || mm.equals(Material.TALL_GRASS)
- || mm.equals(Material.FERN)
- || mm.equals(Material.LARGE_FERN)
- || mm.equals(B.getMaterial("CORNFLOWER"))
- || mm.equals(Material.SUNFLOWER)
- || mm.equals(Material.CHORUS_FLOWER)
- || mm.equals(Material.POPPY)
- || mm.equals(Material.DANDELION)
- || mm.equals(Material.OXEYE_DAISY)
- || mm.equals(Material.ORANGE_TULIP)
- || mm.equals(Material.PINK_TULIP)
- || mm.equals(Material.RED_TULIP)
- || mm.equals(Material.WHITE_TULIP)
- || mm.equals(Material.LILAC)
- || mm.equals(Material.DEAD_BUSH)
- || mm.equals(B.getMaterial("SWEET_BERRY_BUSH"))
- || mm.equals(Material.ROSE_BUSH)
- || mm.equals(B.getMaterial("WITHER_ROSE"))
- || mm.equals(Material.ALLIUM)
- || mm.equals(Material.BLUE_ORCHID)
- || mm.equals(B.getMaterial("LILY_OF_THE_VALLEY"))
- || mm.equals(B.getMaterial("CRIMSON_FUNGUS"))
- || mm.equals(B.getMaterial("WARPED_FUNGUS"))
- || mm.equals(Material.RED_MUSHROOM)
- || mm.equals(Material.BROWN_MUSHROOM)
- || mm.equals(B.getMaterial("CRIMSON_ROOTS"))
- || mm.equals(B.getMaterial("AZURE_BLUET"))
- || mm.equals(B.getMaterial("WEEPING_VINES"))
- || mm.equals(B.getMaterial("WEEPING_VINES_PLANT"))
- || mm.equals(B.getMaterial("WARPED_ROOTS"))
- || mm.equals(B.getMaterial("NETHER_SPROUTS"))
- || mm.equals(B.getMaterial("TWISTING_VINES"))
- || mm.equals(B.getMaterial("TWISTING_VINES_PLANT"))
- || mm.equals(Material.SUGAR_CANE)
- || mm.equals(Material.WHEAT)
- || mm.equals(Material.POTATOES)
- || mm.equals(Material.CARROTS)
- || mm.equals(Material.BEETROOTS)
- || mm.equals(Material.NETHER_WART)
- || mm.equals(B.getMaterial("SEA_PICKLE"))
- || mm.equals(B.getMaterial("SEAGRASS"))
- || mm.equals(B.getMaterial("ACACIA_BUTTON"))
- || mm.equals(B.getMaterial("BIRCH_BUTTON"))
- || mm.equals(B.getMaterial("CRIMSON_BUTTON"))
- || mm.equals(B.getMaterial("DARK_OAK_BUTTON"))
- || mm.equals(B.getMaterial("JUNGLE_BUTTON"))
- || mm.equals(B.getMaterial("OAK_BUTTON"))
- || mm.equals(B.getMaterial("POLISHED_BLACKSTONE_BUTTON"))
- || mm.equals(B.getMaterial("SPRUCE_BUTTON"))
- || mm.equals(B.getMaterial("STONE_BUTTON"))
- || mm.equals(B.getMaterial("WARPED_BUTTON"))
- || mm.equals(Material.TORCH)
- || mm.equals(B.getMaterial("SOUL_TORCH"));
- decorantCache.put(mm, f);
- return f;
- }
-
- public static KList get(KList find) {
- KList b = new KList<>();
-
- for (String i : find) {
- BlockData bd = get(i);
-
- if (bd != null) {
- b.add(bd);
- }
- }
-
- return b;
- }
-
public static boolean isFoliagePlantable(BlockData d) {
return d.getMaterial().equals(Material.GRASS_BLOCK)
|| d.getMaterial().equals(Material.ROOTED_DIRT)
@@ -543,6 +272,207 @@ public class B {
|| d.equals(Material.PODZOL);
}
+ public static boolean isWater(BlockData b) {
+ return b.getMaterial().equals(Material.WATER);
+ }
+
+ public static BlockData getAir() {
+ return AIR;
+ }
+
+ public static Material getMaterialOrNull(String bdx) {
+ try {
+ return Material.valueOf(bdx.trim().toUpperCase());
+ } catch (Throwable e) {
+ Iris.reportError(e);
+ if(clw.flip())
+ {
+ Iris.warn("Unknown Material: " + bdx);
+ }
+ return null;
+ }
+ }
+
+ public static Material getMaterial(String bdx) {
+ Material m = getMaterialOrNull(bdx);
+
+ if(m == null)
+ {
+ return AIR_MATERIAL;
+ }
+
+ return m;
+ }
+
+ public static boolean isSolid(BlockData mat) {
+ return mat.getMaterial().isSolid();
+ }
+
+ public static BlockData getOrNull(String bdxf) {
+ try {
+ String bd = bdxf.trim();
+ BlockData bdx = parseBlockData(bd);
+
+ if (bdx == null) {
+ if(clw.flip())
+ {
+ Iris.warn("Unknown Block Data '" + bd + "'");
+ }
+ return AIR;
+ }
+
+ return bdx;
+ } catch (Throwable e) {
+ Iris.reportError(e);
+
+ if(clw.flip())
+ {
+ Iris.warn("Unknown Block Data '" + bdxf + "'");
+ }
+ }
+
+ return null;
+ }
+
+ public static BlockData get(String bdxf) {
+ BlockData bd = getOrNull(bdxf);
+
+ if (bd != null) {
+ return bd;
+ }
+
+ return AIR;
+ }
+
+ private static BlockData parseBlockData(String ix) {
+ try {
+ BlockData bb = blockDataCache.get(ix);
+
+ if (bb != null) {
+ return bb;
+ }
+
+ BlockData bx = null;
+
+ if (ix.startsWith("oraxen:") && Iris.linkOraxen.supported()) {
+ bx = Iris.linkOraxen.getBlockDataFor(ix.split("\\Q:\\E")[1]);
+ }
+
+ if (bx == null) {
+ bx = Bukkit.createBlockData(ix);
+ }
+
+ if (bx instanceof Leaves && IrisSettings.get().getGenerator().preventLeafDecay) {
+ ((Leaves) bx).setPersistent(true);
+ } else if (bx instanceof Leaves) {
+ ((Leaves) bx).setPersistent(false);
+ }
+
+ blockDataCache.put(ix, bx);
+ return bx;
+ } catch (Throwable e) {
+ if(clw.flip())
+ {
+ Iris.warn("Unknown Block Data: " + ix);
+ }
+
+ String block = ix.contains(":") ? ix.split(":")[1].toLowerCase() : ix.toLowerCase();
+ String state = block.contains("[") ? block.split("\\Q[\\E")[1].split("\\Q]\\E")[0] : "";
+ Map stateMap = new HashMap<>();
+ if (!state.equals("")) {
+ Arrays.stream(state.split(",")).forEach(s -> stateMap.put(s.split("=")[0], s.split("=")[1]));
+ }
+ block = block.split("\\Q[\\E")[0];
+
+ switch (block) {
+ case "cauldron" -> block = "water_cauldron";
+ case "grass_path" -> block = "dirt_path";
+ case "concrete" -> block = "white_concrete";
+ case "wool" -> block = "white_wool";
+ case "beetroots" -> {
+ if (stateMap.containsKey("age")) {
+ String updated = stateMap.get("age");
+ switch (updated) {
+ case "7" -> updated = "3";
+ case "3", "4", "5" -> updated = "2";
+ case "1", "2" -> updated = "1";
+ }
+ stateMap.put("age", updated);
+ }
+ }
+ }
+
+ Map newStates = new HashMap<>();
+ for (String key : stateMap.keySet()) { //Iterate through every state and check if its valid
+ try {
+ String newState = block + "[" + key + "=" + stateMap.get(key) + "]";
+ Bukkit.createBlockData(newState);
+ newStates.put(key, stateMap.get(key));
+
+ } catch (IllegalArgumentException ignored) {
+ }
+ }
+
+ //Combine all the "good" states again
+ state = newStates.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).collect(Collectors.joining(","));
+ if (!state.equals("")) state = "[" + state + "]";
+ String newBlock = block + state;
+ Iris.debug("Converting " + ix + " to " + newBlock);
+
+ try {
+ BlockData bd = Bukkit.createBlockData(newBlock);
+ blockDataCache.put(ix, bd);
+ return bd;
+ } catch (Throwable e1) {
+ Iris.reportError(e1);
+ }
+
+ return null;
+ }
+ }
+
+ public static boolean isStorage(BlockData mat) {
+ return storageCache.contains(mat.getMaterial().ordinal());
+ }
+
+ public static boolean isStorageChest(BlockData mat) {
+ return storageChestCache.contains(mat.getMaterial().ordinal());
+ }
+
+ public static boolean isLit(BlockData mat) {
+ return litCache.contains(mat.getMaterial().ordinal());
+ }
+
+ public static boolean isUpdatable(BlockData mat) {
+ return isLit(mat) || isStorage(mat);
+ }
+
+ public static boolean isFoliage(Material d) {
+ return foliageCache.contains(d.ordinal());
+ }
+
+ public static boolean isFoliage(BlockData d) {
+ return isFoliage(d.getMaterial());
+ }
+
+ public static boolean isDecorant(BlockData m) {
+ return decorantCache.contains(m.getMaterial().ordinal());
+ }
+
+ public static KList get(KList find) {
+ KList b = new KList<>();
+
+ for (String i : find) {
+ BlockData bd = get(i);
+
+ if (bd != null) {
+ b.add(bd);
+ }
+ }
+
+ return b;
+ }
+
public static boolean isFluid(BlockData d) {
return d.getMaterial().equals(Material.WATER) || d.getMaterial().equals(Material.LAVA);
}
diff --git a/src/main/java/com/volmit/iris/util/hunk/storage/MappedSyncHunk.java b/src/main/java/com/volmit/iris/util/hunk/storage/MappedSyncHunk.java
new file mode 100644
index 000000000..ee2a79228
--- /dev/null
+++ b/src/main/java/com/volmit/iris/util/hunk/storage/MappedSyncHunk.java
@@ -0,0 +1,123 @@
+/*
+ * 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.hunk.storage;
+
+import com.volmit.iris.util.collection.KMap;
+import com.volmit.iris.util.function.Consumer4;
+import com.volmit.iris.util.function.Consumer4IO;
+import com.volmit.iris.util.hunk.Hunk;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+@SuppressWarnings({"DefaultAnnotationParam", "Lombok"})
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class MappedSyncHunk extends StorageHunk implements Hunk {
+ private final Map data;
+
+ public MappedSyncHunk(int w, int h, int d) {
+ super(w, h, d);
+ data = new HashMap<>();
+ }
+
+ public int getEntryCount() {
+ return data.size();
+ }
+
+ public boolean isMapped() {
+ return true;
+ }
+
+ public boolean isEmpty() {
+ synchronized(data)
+ {
+ return data.isEmpty();
+ }
+ }
+
+ @Override
+ public void setRaw(int x, int y, int z, T t) {
+ synchronized(data) {
+ if (t == null) {
+ data.remove(index(x, y, z));
+ return;
+ }
+
+ data.put(index(x, y, z), t);
+ }
+ }
+
+ private Integer index(int x, int y, int z) {
+ return (z * getWidth() * getHeight()) + (y * getWidth()) + x;
+ }
+
+ @Override
+ public synchronized Hunk iterateSync(Consumer4 c) {
+ synchronized(data)
+ {
+ int idx, z;
+
+ for (Map.Entry g : data.entrySet()) {
+ idx = g.getKey();
+ z = idx / (getWidth() * getHeight());
+ idx -= (z * getWidth() * getHeight());
+ c.accept(idx % getWidth(), idx / getWidth(), z, g.getValue());
+ }
+
+ return this;
+ }
+ }
+
+ @Override
+ public synchronized Hunk iterateSyncIO(Consumer4IO c) throws IOException {
+ synchronized(data)
+ {
+ int idx, z;
+
+ for (Map.Entry g : data.entrySet()) {
+ idx = g.getKey();
+ z = idx / (getWidth() * getHeight());
+ idx -= (z * getWidth() * getHeight());
+ c.accept(idx % getWidth(), idx / getWidth(), z, g.getValue());
+ }
+
+ return this;
+ }
+ }
+
+ @Override
+ public void empty(T b) {
+ synchronized(data)
+ {
+ data.clear();
+ }
+ }
+
+ @Override
+ public T getRaw(int x, int y, int z) {
+ synchronized(data)
+ {
+ return data.get(index(x, y, z));
+ }
+ }
+}
diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java
index e17ae0b32..9c5dd7501 100644
--- a/src/main/java/com/volmit/iris/util/mantle/Mantle.java
+++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java
@@ -18,8 +18,13 @@
package com.volmit.iris.util.mantle;
+import com.google.common.collect.ImmutableList;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.data.cache.Cache;
+import com.volmit.iris.engine.mantle.EngineMantle;
+import com.volmit.iris.engine.mantle.MantleWriter;
+import com.volmit.iris.engine.object.basic.IrisPosition;
+import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.documentation.BlockCoordinates;
@@ -28,19 +33,23 @@ import com.volmit.iris.util.documentation.RegionCoordinates;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.function.Consumer4;
+import com.volmit.iris.util.math.INode;
+import com.volmit.iris.util.math.KochanekBartelsInterpolation;
import com.volmit.iris.util.math.M;
+import com.volmit.iris.util.math.PathInterpolation;
import com.volmit.iris.util.matter.Matter;
import com.volmit.iris.util.parallel.BurstExecutor;
import com.volmit.iris.util.parallel.HyperLock;
import com.volmit.iris.util.parallel.MultiBurst;
+import org.bukkit.util.Vector;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
-import java.util.Map;
-import java.util.UUID;
+import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -75,10 +84,17 @@ public class Mantle {
unload = new KSet<>();
loadedRegions = new KMap<>();
lastUse = new KMap<>();
- ioBurst = new MultiBurst("Iris Mantle[" + dataFolder.hashCode() + "]", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors() / 2);
+ ioBurst = MultiBurst.burst;
Iris.debug("Opened The Mantle " + C.DARK_AQUA + dataFolder.getAbsolutePath());
}
+ /**
+ * Raise a flag if it is lowered currently, If the flag was raised, execute the runnable
+ * @param x the chunk x
+ * @param z the chunk z
+ * @param flag the flag to raise
+ * @param r the runnable to fire if the flag is now raised (and was previously lowered)
+ */
@ChunkCoordinates
public void raiseFlag(int x, int z, MantleFlag flag, Runnable r) {
if (!hasFlag(x, z, flag)) {
@@ -87,6 +103,27 @@ public class Mantle {
}
}
+ /**
+ * Obtain a cached writer which only contains cached chunks.
+ * This avoids locking on regions when writing to lots of chunks
+ * @param x the x chunk
+ * @param z the z chunk
+ * @param radius the radius chunks
+ * @return the writer
+ */
+ @ChunkCoordinates
+ public MantleWriter write(EngineMantle engineMantle, int x, int z, int radius)
+ {
+ return new MantleWriter(engineMantle, this, x, z, radius);
+ }
+
+ /**
+ * Lower a flag if it is raised. If the flag was lowered (meaning it was previously raised), execute the runnable
+ * @param x the chunk x
+ * @param z the chunk z
+ * @param flag the flag to lower
+ * @param r the runnable that is fired if the flag was raised but is now lowered
+ */
@ChunkCoordinates
public void lowerFlag(int x, int z, MantleFlag flag, Runnable r) {
if (hasFlag(x, z, flag)) {
@@ -95,35 +132,69 @@ public class Mantle {
}
}
+ @ChunkCoordinates
+ public MantleChunk getChunk(int x, int z)
+ {
+ return get(x>>5, z>>5).getOrCreate(x & 31, z & 31);
+ }
+
+ /**
+ * Flag or unflag a chunk
+ * @param x the chunk x
+ * @param z the chunk z
+ * @param flag the flag
+ * @param flagged should it be set to flagged or not
+ */
@ChunkCoordinates
public void flag(int x, int z, MantleFlag flag, boolean flagged) {
get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).flag(flag, flagged);
}
+ /**
+ * Check very quickly if a tectonic plate exists via cached or the file system
+ * @param x the x region coordinate
+ * @param z the z region coordinate
+ * @return true if it exists
+ */
+ @RegionCoordinates
+ public boolean hasTectonicPlate(int x, int z)
+ {
+ Long k = key(x, z);
+ return loadedRegions.containsKey(k) || fileForRegion(dataFolder, k).exists();
+ }
+
+ /**
+ * Iterate data in a chunk
+ * @param x the chunk x
+ * @param z the chunk z
+ * @param type the type of data to iterate
+ * @param iterator the iterator (x,y,z,data) -> do stuff
+ * @param the type of data to iterate
+ */
@ChunkCoordinates
- public void iterateChunk(int x, int z, Class type, Consumer4 iterator, MantleFlag... requiredFlags) {
- for (MantleFlag i : requiredFlags) {
- if (!hasFlag(x, z, i)) {
- return;
- }
+ public void iterateChunk(int x, int z, Class type, Consumer4 iterator) {
+ if(!hasTectonicPlate(x >> 5, z >> 5))
+ {
+ return;
}
get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).iterate(type, iterator);
}
- @ChunkCoordinates
- public void iterateChunk(int x, int z, Class type, Consumer4 iterator, BurstExecutor e, MantleFlag... requiredFlags) {
- for (MantleFlag i : requiredFlags) {
- if (!hasFlag(x, z, i)) {
- return;
- }
- }
-
- get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).iterate(type, iterator, e);
- }
-
+ /**
+ * Does this chunk have a flag on it?
+ * @param x the x
+ * @param z the z
+ * @param flag the flag to test
+ * @return true if it's flagged
+ */
@ChunkCoordinates
public boolean hasFlag(int x, int z, MantleFlag flag) {
+ if(!hasTectonicPlate(x >> 5, z >> 5))
+ {
+ return false;
+ }
+
return get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).isFlagged(flag);
}
@@ -151,11 +222,20 @@ public class Mantle {
return;
}
- Matter matter = get((x >> 4) >> 5, (z >> 4) >> 5)
- .getOrCreate((x >> 4) & 31, (z >> 4) & 31)
- .getOrCreate(y >> 4);
- matter.slice(matter.getClass(t))
- .set(x & 15, y & 15, z & 15, t);
+ if(t instanceof IrisFeaturePositional)
+ {
+ get((x >> 4) >> 5, (z >> 4) >> 5)
+ .getOrCreate((x >> 4) & 31, (z >> 4) & 31).addFeature((IrisFeaturePositional) t);
+ }
+
+ else
+ {
+ Matter matter = get((x >> 4) >> 5, (z >> 4) >> 5)
+ .getOrCreate((x >> 4) & 31, (z >> 4) & 31)
+ .getOrCreate(y >> 4);
+ matter.slice(matter.getClass(t))
+ .set(x & 15, y & 15, z & 15, t);
+ }
}
/**
@@ -180,7 +260,12 @@ public class Mantle {
throw new RuntimeException("The Mantle is closed");
}
- if (y < 0) {
+ if(!hasTectonicPlate((x >> 4) >> 5, (z >> 4) >> 5))
+ {
+ return null;
+ }
+
+ if (y < 0 || y >= worldHeight) {
return null;
}
@@ -190,6 +275,10 @@ public class Mantle {
.get(x & 15, y & 15, z & 15);
}
+ /**
+ * Is this mantle closed
+ * @return true if it is
+ */
public boolean isClosed()
{
return closed.get();
@@ -228,7 +317,6 @@ public class Mantle {
Iris.reportError(e);
}
- ioBurst.shutdownNow();
Iris.debug("The Mantle has Closed " + C.DARK_AQUA + dataFolder.getAbsolutePath());
}
@@ -324,7 +412,7 @@ public class Mantle {
* @return the future of a tectonic plate.
*/
@RegionCoordinates
- private CompletableFuture getSafe(int x, int z) {
+ private Future getSafe(int x, int z) {
Long k = key(x, z);
TectonicPlate p = loadedRegions.get(k);
@@ -367,17 +455,39 @@ public class Mantle {
}));
}
+ /**
+ * Get the file for a region
+ * @param folder the folder
+ * @param x the x coord
+ * @param z the z coord
+ * @return the file
+ */
public static File fileForRegion(File folder, int x, int z) {
return fileForRegion(folder, key(x, z));
}
+ /**
+ * Get the file for the given region
+ * @param folder the data folder
+ * @param key the region key
+ * @return the file
+ */
public static File fileForRegion(File folder, Long key) {
String id = UUID.nameUUIDFromBytes(("TectonicPlate:" + key).getBytes(StandardCharsets.UTF_8)).toString();
File f = new File(folder, id.substring(0, 2) + "/" + id.split("\\Q-\\E")[3] + "/" + id + ".ttp");
- f.getParentFile().mkdirs();
+ if(!f.getParentFile().exists())
+ {
+ f.getParentFile().mkdirs();
+ }
return f;
}
+ /**
+ * Get the long value representing a chunk or region coordinate
+ * @param x the x
+ * @param z the z
+ * @return the value
+ */
public static Long key(int x, int z) {
return Cache.key(x, z);
}
@@ -385,4 +495,440 @@ public class Mantle {
public void saveAll() {
}
+
+ /**
+ * Set a sphere into the mantle
+ * @param cx the center x
+ * @param cy the center y
+ * @param cz the center z
+ * @param radius the radius of this sphere
+ * @param fill should it be filled? or just the outer shell?
+ * @param data the data to set
+ * @param the type of data to apply to the mantle
+ */
+ public void setSphere(int cx, int cy, int cz, double radius, boolean fill, T data)
+ {
+ setElipsoid(cx, cy, cz, radius, radius, radius, fill, data);
+ }
+
+ /**
+ * Set an elipsoid into the mantle
+ * @param cx the center x
+ * @param cy the center y
+ * @param cz the center z
+ * @param rx the x radius
+ * @param ry the y radius
+ * @param rz the z radius
+ * @param fill should it be filled or just the outer shell?
+ * @param data the data to set
+ * @param the type of data to apply to the mantle
+ */
+ public void setElipsoid(int cx, int cy, int cz, double rx, double ry, double rz, boolean fill, T data)
+ {
+ rx += 0.5;
+ ry += 0.5;
+ rz += 0.5;
+ final double invRadiusX = 1 / rx;
+ final double invRadiusY = 1 / ry;
+ final double invRadiusZ = 1 / rz;
+ final int ceilRadiusX = (int) Math.ceil(rx);
+ final int ceilRadiusY = (int) Math.ceil(ry);
+ final int ceilRadiusZ = (int) Math.ceil(rz);
+ double nextXn = 0;
+
+ forX: for (int x = 0; x <= ceilRadiusX; ++x) {
+ final double xn = nextXn;
+ nextXn = (x + 1) * invRadiusX;
+ double nextYn = 0;
+ forY: for (int y = 0; y <= ceilRadiusY; ++y) {
+ final double yn = nextYn;
+ nextYn = (y + 1) * invRadiusY;
+ double nextZn = 0;
+ for (int z = 0; z <= ceilRadiusZ; ++z) {
+ final double zn = nextZn;
+ nextZn = (z + 1) * invRadiusZ;
+
+ double distanceSq = lengthSq(xn, yn, zn);
+ if (distanceSq > 1) {
+ if (z == 0) {
+ if (y == 0) {
+ break forX;
+ }
+ break forY;
+ }
+ break;
+ }
+
+ if (!fill) {
+ if (lengthSq(nextXn, yn, zn) <= 1 && lengthSq(xn, nextYn, zn) <= 1 && lengthSq(xn, yn, nextZn) <= 1) {
+ continue;
+ }
+ }
+
+ set(x + cx,y + cy,z + cz, data);
+ set(-x + cx,y + cy,z + cz, data);
+ set(x + cx,-y + cy,z + cz, data);
+ set(x + cx,y + cy,-z + cz, data);
+ set(-x + cx,y + cy,-z + cz, data);
+ set(-x + cx,-y + cy,z + cz, data);
+ set(x + cx,-y + cy,-z + cz, data);
+ set(-x + cx,y + cy,-z + cz, data);
+ set(-x + cx,-y + cy,-z + cz, data);
+ }
+ }
+ }
+ }
+
+ /**
+ * Set a cuboid of data in the mantle
+ * @param x1 the min x
+ * @param y1 the min y
+ * @param z1 the min z
+ * @param x2 the max x
+ * @param y2 the max y
+ * @param z2 the max z
+ * @param data the data to set
+ * @param the type of data to apply to the mantle
+ */
+ public void setCuboid(int x1, int y1, int z1, int x2, int y2, int z2, T data)
+ {
+ int j,k;
+
+ for(int i = x1; i <= x2; i++)
+ {
+ for(j = x1; j <= x2; j++)
+ {
+ for(k = x1; k <= x2; k++)
+ {
+ set(i,j,k,data);
+ }
+ }
+ }
+ }
+
+ /**
+ * Set a pyramid of data in the mantle
+ * @param cx the center x
+ * @param cy the base y
+ * @param cz the center z
+ * @param data the data to set
+ * @param size the size of the pyramid (width of base & height)
+ * @param filled should it be filled or hollow
+ * @param the type of data to apply to the mantle
+ */
+ @SuppressWarnings("ConstantConditions")
+ public void setPyramid(int cx, int cy, int cz, T data, int size, boolean filled) {
+ int height = size;
+
+ for (int y = 0; y <= height; ++y) {
+ size--;
+ for (int x = 0; x <= size; ++x) {
+ for (int z = 0; z <= size; ++z) {
+ if ((filled && z <= size && x <= size) || z == size || x == size) {
+ set(x + cx, y + cy, z + cz, data);
+ set(-x + cx, y + cy, z + cz, data);
+ set(x + cx, y + cy, -z + cz, data);
+ set(-x + cx, y + cy, -z + cz, data);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Set a 3d tube spline interpolated with Kochanek Bartels
+ * @param nodevectors the vector points
+ * @param radius the radius
+ * @param filled if it should be filled or hollow
+ * @param data the data to set
+ */
+ public void setSpline(List nodevectors, double radius, boolean filled, T data) {
+ setSpline(nodevectors, 0, 0, 0, 10, radius, filled, data);
+ }
+
+ /**
+ * Set a 3d tube spline interpolated with Kochanek Bartels
+ * @param nodevectors the spline points
+ * @param tension the tension 0
+ * @param bias the bias 0
+ * @param continuity the continuity 0
+ * @param quality the quality 10
+ * @param radius the radius
+ * @param filled filled or hollow
+ * @param data the data to set
+ * @param the type of data to apply to the mantle
+ */
+ public void setSpline(List nodevectors, double tension, double bias, double continuity, double quality, double radius, boolean filled, T data) {
+ Set vset = new KSet<>();
+ List nodes = new ArrayList<>(nodevectors.size());
+ PathInterpolation interpol = new KochanekBartelsInterpolation();
+
+ for (Vector nodevector : nodevectors) {
+ INode n = new INode(nodevector);
+ n.setTension(tension);
+ n.setBias(bias);
+ n.setContinuity(continuity);
+ nodes.add(n);
+ }
+
+ interpol.setNodes(nodes);
+ double splinelength = interpol.arcLength(0, 1);
+ for (double loop = 0; loop <= 1; loop += 1D / splinelength / quality) {
+ Vector tipv = interpol.getPosition(loop);
+ vset.add(new IrisPosition(tipv.toBlockVector()));
+ }
+
+ vset = getBallooned(vset, radius);
+ if (!filled) {
+ vset = getHollowed(vset);
+ }
+
+ set(vset, data);
+ }
+
+ /**
+ * Set a 3d line
+ * @param a the first point
+ * @param b the second point
+ * @param radius the radius
+ * @param filled hollow or filled?
+ * @param data the data
+ * @param the type of data to apply to the mantle
+ */
+ public void setLine(IrisPosition a, IrisPosition b, double radius, boolean filled, T data)
+ {
+ setLine(ImmutableList.of(a, b), radius, filled, data);
+ }
+
+ /**
+ * Set lines for points
+ * @param vectors the points
+ * @param radius the radius
+ * @param filled hollow or filled?
+ * @param data the data to set
+ * @param the type of data to apply to the mantle
+ */
+ public void setLine(List vectors, double radius, boolean filled, T data) {
+ Set vset = new KSet<>();
+
+ for (int i = 0; vectors.size() != 0 && i < vectors.size() - 1; i++) {
+ IrisPosition pos1 = vectors.get(i);
+ IrisPosition pos2 = vectors.get(i + 1);
+ int x1 = pos1.getX();
+ int y1 = pos1.getY();
+ int z1 = pos1.getZ();
+ int x2 = pos2.getX();
+ int y2 = pos2.getY();
+ int z2 = pos2.getZ();
+ int tipx = x1;
+ int tipy = y1;
+ int tipz = z1;
+ int dx = Math.abs(x2 - x1);
+ int dy = Math.abs(y2 - y1);
+ int dz = Math.abs(z2 - z1);
+
+ if (dx + dy + dz == 0) {
+ vset.add(new IrisPosition(tipx, tipy, tipz));
+ continue;
+ }
+
+ int dMax = Math.max(Math.max(dx, dy), dz);
+ if (dMax == dx) {
+ for (int domstep = 0; domstep <= dx; domstep++) {
+ tipx = x1 + domstep * (x2 - x1 > 0 ? 1 : -1);
+ tipy = (int) Math.round(y1 + domstep * ((double) dy) / ((double) dx) * (y2 - y1 > 0 ? 1 : -1));
+ tipz = (int) Math.round(z1 + domstep * ((double) dz) / ((double) dx) * (z2 - z1 > 0 ? 1 : -1));
+
+ vset.add(new IrisPosition(tipx, tipy, tipz));
+ }
+ } else if (dMax == dy) {
+ for (int domstep = 0; domstep <= dy; domstep++) {
+ tipy = y1 + domstep * (y2 - y1 > 0 ? 1 : -1);
+ tipx = (int) Math.round(x1 + domstep * ((double) dx) / ((double) dy) * (x2 - x1 > 0 ? 1 : -1));
+ tipz = (int) Math.round(z1 + domstep * ((double) dz) / ((double) dy) * (z2 - z1 > 0 ? 1 : -1));
+
+ vset.add(new IrisPosition(tipx, tipy, tipz));
+ }
+ } else /* if (dMax == dz) */ {
+ for (int domstep = 0; domstep <= dz; domstep++) {
+ tipz = z1 + domstep * (z2 - z1 > 0 ? 1 : -1);
+ tipy = (int) Math.round(y1 + domstep * ((double) dy) / ((double) dz) * (y2 - y1 > 0 ? 1 : -1));
+ tipx = (int) Math.round(x1 + domstep * ((double) dx) / ((double) dz) * (x2 - x1 > 0 ? 1 : -1));
+
+ vset.add(new IrisPosition(tipx, tipy, tipz));
+ }
+ }
+ }
+
+ vset = getBallooned(vset, radius);
+
+ if (!filled) {
+ vset = getHollowed(vset);
+ }
+
+ set(vset, data);
+ }
+
+ /**
+ * Set a cylinder in the mantle
+ * @param cx the center x
+ * @param cy the base y
+ * @param cz the center z
+ * @param data the data to set
+ * @param radius the radius
+ * @param height the height of the cyl
+ * @param filled filled or not
+ */
+ public void setCylinder(int cx, int cy, int cz, T data, double radius, int height, boolean filled){
+ setCylinder(cx, cy, cz, data, radius, radius, height, filled);
+ }
+
+ /**
+ * Set a cylinder in the mantle
+ * @param cx the center x
+ * @param cy the base y
+ * @param cz the center z
+ * @param data the data to set
+ * @param radiusX the x radius
+ * @param radiusZ the z radius
+ * @param height the height of this cyl
+ * @param filled filled or hollow?
+ */
+ public void setCylinder(int cx, int cy, int cz, T data, double radiusX, double radiusZ, int height, boolean filled) {
+ int affected = 0;
+ radiusX += 0.5;
+ radiusZ += 0.5;
+
+ if (height == 0) {
+ return;
+ } else if (height < 0) {
+ height = -height;
+ cy = cy - height;
+ }
+
+ if (cy < 0) {
+ cy = 0;
+ } else if (cy + height - 1 > worldHeight) {
+ height = worldHeight - cy + 1;
+ }
+
+ final double invRadiusX = 1 / radiusX;
+ final double invRadiusZ = 1 / radiusZ;
+ final int ceilRadiusX = (int) Math.ceil(radiusX);
+ final int ceilRadiusZ = (int) Math.ceil(radiusZ);
+ double nextXn = 0;
+
+ forX: for (int x = 0; x <= ceilRadiusX; ++x) {
+ final double xn = nextXn;
+ nextXn = (x + 1) * invRadiusX;
+ double nextZn = 0;
+ for (int z = 0; z <= ceilRadiusZ; ++z) {
+ final double zn = nextZn;
+ nextZn = (z + 1) * invRadiusZ;
+ double distanceSq = lengthSq(xn, zn);
+
+ if (distanceSq > 1) {
+ if (z == 0) {
+ break forX;
+ }
+
+ break;
+ }
+
+ if (!filled) {
+ if (lengthSq(nextXn, zn) <= 1 && lengthSq(xn, nextZn) <= 1) {
+ continue;
+ }
+ }
+
+ for (int y = 0; y < height; ++y) {
+ set(cx + x, cy + y, cz + z, data);
+ set(cx + -x, cy + y, cz + z, data);
+ set(cx + x, cy + y, cz + -z, data);
+ set(cx + -x, cy + y, cz + -z, data);
+ }
+ }
+ }
+ }
+
+ public void set(IrisPosition pos, T data)
+ {
+ set(pos.getX(), pos.getY(), pos.getZ(), data);
+ }
+
+ public void set(List positions, T data)
+ {
+ for(IrisPosition i : positions)
+ {
+ set(i, data);
+ }
+ }
+
+ public void set(Set positions, T data)
+ {
+ for(IrisPosition i : positions)
+ {
+ set(i, data);
+ }
+ }
+
+ private static Set getBallooned(Set vset, double radius) {
+ Set returnset = new HashSet<>();
+ int ceilrad = (int) Math.ceil(radius);
+
+ for (IrisPosition v : vset) {
+ int tipx = v.getX();
+ int tipy = v.getY();
+ int tipz = v.getZ();
+
+ for (int loopx = tipx - ceilrad; loopx <= tipx + ceilrad; loopx++) {
+ for (int loopy = tipy - ceilrad; loopy <= tipy + ceilrad; loopy++) {
+ for (int loopz = tipz - ceilrad; loopz <= tipz + ceilrad; loopz++) {
+ if (hypot(loopx - tipx, loopy - tipy, loopz - tipz) <= radius) {
+ returnset.add(new IrisPosition(loopx, loopy, loopz));
+ }
+ }
+ }
+ }
+ }
+ return returnset;
+ }
+
+ private static Set getHollowed(Set vset) {
+ Set returnset = new KSet<>();
+ for (IrisPosition v : vset) {
+ double x = v.getX();
+ double y = v.getY();
+ double z = v.getZ();
+ if (!(vset.contains(new IrisPosition(x + 1, y, z))
+ && vset.contains(new IrisPosition(x - 1, y, z))
+ && vset.contains(new IrisPosition(x, y + 1, z))
+ && vset.contains(new IrisPosition(x, y - 1, z))
+ && vset.contains(new IrisPosition(x, y, z + 1))
+ && vset.contains(new IrisPosition(x, y, z - 1)))) {
+ returnset.add(v);
+ }
+ }
+ return returnset;
+ }
+
+ private static double hypot(double... pars) {
+ double sum = 0;
+ for (double d : pars) {
+ sum += Math.pow(d, 2);
+ }
+ return Math.sqrt(sum);
+ }
+
+ private static double lengthSq(double x, double y, double z) {
+ return (x * x) + (y * y) + (z * z);
+ }
+
+ private static double lengthSq(double x, double z) {
+ return (x * x) + (z * z);
+ }
+
+ public int getWorldHeight() {
+ return worldHeight;
+ }
}
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 85d248508..7675d78cc 100644
--- a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java
+++ b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java
@@ -18,17 +18,22 @@
package com.volmit.iris.util.mantle;
+import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
+import com.volmit.iris.util.data.Varint;
import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.function.Consumer4;
import com.volmit.iris.util.matter.IrisMatter;
import com.volmit.iris.util.matter.Matter;
import com.volmit.iris.util.matter.MatterSlice;
+import com.volmit.iris.util.matter.slices.ZoneMatter;
import com.volmit.iris.util.parallel.BurstExecutor;
import com.volmit.iris.util.parallel.MultiBurst;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.concurrent.atomic.AtomicReferenceArray;
@@ -37,8 +42,10 @@ import java.util.concurrent.atomic.AtomicReferenceArray;
* Mantle Chunks are fully atomic & thread safe
*/
public class MantleChunk {
+ private static final ZoneMatter zm = new ZoneMatter();
private final AtomicIntegerArray flags;
private final AtomicReferenceArray sections;
+ private final CopyOnWriteArrayList features;
/**
* Create a mantle chunk
@@ -49,6 +56,7 @@ public class MantleChunk {
public MantleChunk(int sectionHeight) {
sections = new AtomicReferenceArray<>(sectionHeight);
flags = new AtomicIntegerArray(MantleFlag.values().length);
+ features = new CopyOnWriteArrayList<>();
for (int i = 0; i < flags.length(); i++) {
flags.set(i, 0);
@@ -76,6 +84,13 @@ public class MantleChunk {
sections.set(i, Matter.read(din));
}
}
+
+ short v = din.readShort();
+
+ for(int i = 0; i < v; i++)
+ {
+ features.add(zm.readNode(din));
+ }
}
public void flag(MantleFlag flag, boolean f) {
@@ -169,6 +184,13 @@ public class MantleChunk {
dos.writeBoolean(false);
}
}
+
+ dos.writeShort(features.size());
+
+ for(IrisFeaturePositional i : features)
+ {
+ zm.writeNode(i, dos);
+ }
}
private void trimSlice(int i) {
@@ -186,26 +208,6 @@ public class MantleChunk {
}
}
- public void iterate(Class type, Consumer4 iterator, BurstExecutor burst) {
- for (int i = 0; i < sections.length(); i++) {
- int finalI = i;
- burst.queue(() -> {
- int bs = (finalI << 4);
- Matter matter = get(finalI);
-
- if (matter != null) {
- MatterSlice t = matter.getSlice(type);
-
- if (t != null) {
- t.iterateSync((a, b, c, f) -> iterator.accept(a, b + bs, c, f));
- }
- }
- });
- }
-
- burst.complete();
- }
-
public void iterate(Class type, Consumer4 iterator) {
for (int i = 0; i < sections.length(); i++) {
int bs = (i << 4);
@@ -220,4 +222,12 @@ public class MantleChunk {
}
}
}
+
+ public void addFeature(IrisFeaturePositional t) {
+ features.add(t);
+ }
+
+ public List getFeatures() {
+ return features;
+ }
}
diff --git a/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java b/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java
index b78a32f2f..6df695c21 100644
--- a/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java
+++ b/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java
@@ -19,9 +19,11 @@
package com.volmit.iris.util.mantle;
import com.volmit.iris.Iris;
+import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form;
+import com.volmit.iris.util.hunk.storage.ArrayHunk;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import java.io.*;
@@ -140,7 +142,7 @@ public class TectonicPlate {
@ChunkCoordinates
private int index(int x, int z) {
- return (x & 0x1F) + (z & 0x1F) * 32;
+ return Cache.to1D(x, z, 0, 32, 32);
}
/**
diff --git a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisTerrainMode.java b/src/main/java/com/volmit/iris/util/math/INode.java
similarity index 57%
rename from src/main/java/com/volmit/iris/engine/object/dimensional/IrisTerrainMode.java
rename to src/main/java/com/volmit/iris/util/math/INode.java
index 8c9a162b0..cb831d5b0 100644
--- a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisTerrainMode.java
+++ b/src/main/java/com/volmit/iris/util/math/INode.java
@@ -16,14 +16,32 @@
* along with this program. If not, see .
*/
-package com.volmit.iris.engine.object.dimensional;
+package com.volmit.iris.util.math;
-import com.volmit.iris.engine.object.annotations.Desc;
+import lombok.Data;
+import org.bukkit.util.Vector;
-@Desc("Terrain modes are used to decide the generator type currently used")
-public enum IrisTerrainMode {
- @Desc("Normal terrain, similar to the vanilla overworld")
- NORMAL,
- @Desc("Island terrain, more similar to the end, but endless possibilities!")
- ISLANDS
-}
+@Data
+public class INode {
+
+ private Vector position;
+ private double tension;
+ private double bias;
+ private double continuity;
+
+ public INode() {
+ this(new Vector(0,0,0));
+ }
+
+ public INode(INode other) {
+ this.position = other.position;
+
+ this.tension = other.tension;
+ this.bias = other.bias;
+ this.continuity = other.continuity;
+ }
+
+ public INode(Vector position) {
+ this.position = position;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/volmit/iris/util/math/KochanekBartelsInterpolation.java b/src/main/java/com/volmit/iris/util/math/KochanekBartelsInterpolation.java
new file mode 100644
index 000000000..75a01b205
--- /dev/null
+++ b/src/main/java/com/volmit/iris/util/math/KochanekBartelsInterpolation.java
@@ -0,0 +1,248 @@
+/*
+ * 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.math;
+
+import org.bukkit.util.Vector;
+
+import java.util.Collections;
+import java.util.List;
+
+public class KochanekBartelsInterpolation implements PathInterpolation {
+
+ private List nodes;
+ private Vector[] coeffA;
+ private Vector[] coeffB;
+ private Vector[] coeffC;
+ private Vector[] coeffD;
+ private double scaling;
+
+ public KochanekBartelsInterpolation() {
+ setNodes(Collections.emptyList());
+ }
+
+ @Override
+ public void setNodes(List nodes) {
+ this.nodes = nodes;
+ recalc();
+ }
+
+ private void recalc() {
+ final int nNodes = nodes.size();
+ coeffA = new Vector[nNodes];
+ coeffB = new Vector[nNodes];
+ coeffC = new Vector[nNodes];
+ coeffD = new Vector[nNodes];
+
+ if (nNodes == 0) {
+ return;
+ }
+
+ INode nodeB = nodes.get(0);
+ double tensionB = nodeB.getTension();
+ double biasB = nodeB.getBias();
+ double continuityB = nodeB.getContinuity();
+ for (int i = 0; i < nNodes; ++i) {
+ final double tensionA = tensionB;
+ final double biasA = biasB;
+ final double continuityA = continuityB;
+
+ if (i + 1 < nNodes) {
+ nodeB = nodes.get(i + 1);
+ tensionB = nodeB.getTension();
+ biasB = nodeB.getBias();
+ continuityB = nodeB.getContinuity();
+ }
+
+ // Kochanek-Bartels tangent coefficients
+ final double ta = (1 - tensionA) * (1 + biasA) * (1 + continuityA) / 2; // Factor for lhs of d[i]
+ final double tb = (1 - tensionA) * (1 - biasA) * (1 - continuityA) / 2; // Factor for rhs of d[i]
+ final double tc = (1 - tensionB) * (1 + biasB) * (1 - continuityB) / 2; // Factor for lhs of d[i+1]
+ final double td = (1 - tensionB) * (1 - biasB) * (1 + continuityB) / 2; // Factor for rhs of d[i+1]
+
+ coeffA[i] = linearCombination(i, -ta, ta - tb - tc + 2, tb + tc - td - 2, td);
+ coeffB[i] = linearCombination(i, 2 * ta, -2 * ta + 2 * tb + tc - 3, -2 * tb - tc + td + 3, -td);
+ coeffC[i] = linearCombination(i, -ta, ta - tb, tb, 0);
+ //coeffD[i] = linearCombination(i, 0, 1, 0, 0);
+ coeffD[i] = retrieve(i); // this is an optimization
+ }
+
+ scaling = nodes.size() - 1;
+ }
+
+ /**
+ * Returns the linear combination of the given coefficients with the nodes adjacent to baseIndex.
+ *
+ * @param baseIndex node index
+ * @param f1 coefficient for baseIndex-1
+ * @param f2 coefficient for baseIndex
+ * @param f3 coefficient for baseIndex+1
+ * @param f4 coefficient for baseIndex+2
+ * @return linear combination of nodes[n-1..n+2] with f1..4
+ */
+ private Vector linearCombination(int baseIndex, double f1, double f2, double f3, double f4) {
+ final Vector r1 = retrieve(baseIndex - 1).multiply(f1);
+ final Vector r2 = retrieve(baseIndex ).multiply(f2);
+ final Vector r3 = retrieve(baseIndex + 1).multiply(f3);
+ final Vector r4 = retrieve(baseIndex + 2).multiply(f4);
+
+ return r1.add(r2).add(r3).add(r4);
+ }
+
+ /**
+ * Retrieves a node. Indexes are clamped to the valid range.
+ *
+ * @param index node index to retrieve
+ * @return nodes[clamp(0, nodes.length-1)]
+ */
+ private Vector retrieve(int index) {
+ if (index < 0) {
+ return fastRetrieve(0);
+ }
+
+ if (index >= nodes.size()) {
+ return fastRetrieve(nodes.size() - 1);
+ }
+
+ return fastRetrieve(index);
+ }
+
+ private Vector fastRetrieve(int index) {
+ return nodes.get(index).getPosition();
+ }
+
+ @Override
+ public Vector getPosition(double position) {
+ if (coeffA == null) {
+ throw new IllegalStateException("Must call setNodes first.");
+ }
+
+ if (position > 1) {
+ return null;
+ }
+
+ position *= scaling;
+
+ final int index = (int) Math.floor(position);
+ final double remainder = position - index;
+
+ final Vector a = coeffA[index];
+ final Vector b = coeffB[index];
+ final Vector c = coeffC[index];
+ final Vector d = coeffD[index];
+
+ return a.multiply(remainder).add(b).multiply(remainder).add(c).multiply(remainder).add(d);
+ }
+
+ @Override
+ public Vector get1stDerivative(double position) {
+ if (coeffA == null) {
+ throw new IllegalStateException("Must call setNodes first.");
+ }
+
+ if (position > 1) {
+ return null;
+ }
+
+ position *= scaling;
+
+ final int index = (int) Math.floor(position);
+ //final double remainder = position - index;
+
+ final Vector a = coeffA[index];
+ final Vector b = coeffB[index];
+ final Vector c = coeffC[index];
+
+ return a.multiply(1.5 * position - 3.0 * index).add(b).multiply(2.0 * position).add(a.multiply(1.5 * index).subtract(b).multiply(2.0 * index)).add(c).multiply(scaling);
+ }
+
+ @Override
+ public double arcLength(double positionA, double positionB) {
+ if (coeffA == null) {
+ throw new IllegalStateException("Must call setNodes first.");
+ }
+
+ if (positionA > positionB) {
+ return arcLength(positionB, positionA);
+ }
+
+ positionA *= scaling;
+ positionB *= scaling;
+
+ final int indexA = (int) Math.floor(positionA);
+ final double remainderA = positionA - indexA;
+
+ final int indexB = (int) Math.floor(positionB);
+ final double remainderB = positionB - indexB;
+
+ return arcLengthRecursive(indexA, remainderA, indexB, remainderB);
+ }
+
+ /**
+ * Assumes a < b.
+ */
+ private double arcLengthRecursive(int indexLeft, double remainderLeft, int indexRight, double remainderRight) {
+ switch (indexRight - indexLeft) {
+ case 0:
+ return arcLengthRecursive(indexLeft, remainderLeft, remainderRight);
+
+ case 1:
+ // This case is merely a speed-up for a very common case
+ return arcLengthRecursive(indexLeft, remainderLeft, 1.0)
+ + arcLengthRecursive(indexRight, 0.0, remainderRight);
+
+ default:
+ return arcLengthRecursive(indexLeft, remainderLeft, indexRight - 1, 1.0)
+ + arcLengthRecursive(indexRight, 0.0, remainderRight);
+ }
+ }
+
+ private double arcLengthRecursive(int index, double remainderLeft, double remainderRight) {
+ final Vector a = coeffA[index].multiply(3.0);
+ final Vector b = coeffB[index].multiply(2.0);
+ final Vector c = coeffC[index];
+
+ final int nPoints = 8;
+
+ double accum = a.multiply(remainderLeft).add(b).multiply(remainderLeft).add(c).length() / 2.0;
+ for (int i = 1; i < nPoints - 1; ++i) {
+ double t = ((double) i) / nPoints;
+ t = (remainderRight - remainderLeft) * t + remainderLeft;
+ accum += a.multiply(t).add(b).multiply(t).add(c).length();
+ }
+
+ accum += a.multiply(remainderRight).add(b).multiply(remainderRight).add(c).length() / 2.0;
+ return accum * (remainderRight - remainderLeft) / nPoints;
+ }
+
+ @Override
+ public int getSegment(double position) {
+ if (coeffA == null) {
+ throw new IllegalStateException("Must call setNodes first.");
+ }
+
+ if (position > 1) {
+ return Integer.MAX_VALUE;
+ }
+
+ position *= scaling;
+
+ return (int) Math.floor(position);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/volmit/iris/util/math/PathInterpolation.java b/src/main/java/com/volmit/iris/util/math/PathInterpolation.java
new file mode 100644
index 000000000..b352230bf
--- /dev/null
+++ b/src/main/java/com/volmit/iris/util/math/PathInterpolation.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.util.math;
+
+import org.bukkit.util.Vector;
+
+import java.util.List;
+
+public interface PathInterpolation {
+
+ /**
+ * Sets nodes to be used by subsequent calls to
+ * {@link #getPosition(double)} and the other methods.
+ *
+ * @param nodes the nodes
+ */
+ void setNodes(List nodes);
+
+ /**
+ * Gets the result of f(position).
+ *
+ * @param position the position to interpolate
+ * @return the result
+ */
+ Vector getPosition(double position);
+
+ /**
+ * Gets the result of f'(position).
+ *
+ * @param position the position to interpolate
+ * @return the result
+ */
+ Vector get1stDerivative(double position);
+
+ /**
+ * Gets the result of ∫ab|f'(t)| dt.
+ * That means it calculates the arc length (in meters) between positionA
+ * and positionB.
+ *
+ * @param positionA lower limit
+ * @param positionB upper limit
+ * @return the arc length
+ */
+ double arcLength(double positionA, double positionB);
+
+ /**
+ * Get the segment position.
+ *
+ * @param position the position
+ * @return the segment position
+ */
+ int getSegment(double position);
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/volmit/iris/util/matter/Matter.java b/src/main/java/com/volmit/iris/util/matter/Matter.java
index 621ced544..421c9fb3f 100644
--- a/src/main/java/com/volmit/iris/util/matter/Matter.java
+++ b/src/main/java/com/volmit/iris/util/matter/Matter.java
@@ -27,6 +27,7 @@ import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.math.BlockPosition;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
+import org.bukkit.craftbukkit.v1_17_R1.block.data.type.CraftLeaves;
import org.bukkit.entity.Entity;
import java.io.*;
@@ -189,7 +190,16 @@ public interface Matter {
slice = (MatterSlice) createSlice(c, this);
if (slice == null) {
- Iris.error("Unable to find a slice for class " + C.DARK_RED + c.getCanonicalName());
+ try
+ {
+ throw new RuntimeException("Bad slice " + c.getCanonicalName());
+ }
+
+ catch(Throwable e)
+ {
+ e.printStackTrace();
+ }
+
return null;
}
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
index 6201b08f1..652ac391f 100644
--- a/src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java
+++ b/src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java
@@ -18,6 +18,7 @@
package com.volmit.iris.util.matter.slices;
+import com.volmit.iris.Iris;
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
import com.volmit.iris.util.matter.Sliced;
diff --git a/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java b/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java
index 3d91dc202..04125982e 100644
--- a/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java
+++ b/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java
@@ -225,7 +225,7 @@ public class Chunk {
* @param blockZ The z-coordinate of the block.
* @return The biome id or -1 if the biomes are not correctly initialized.
*/
- public int getBiomeAt(int blockX, int blockY, int blockZ) {
+ public synchronized int getBiomeAt(int blockX, int blockY, int blockZ) {
if (dataVersion < 2202) {
if (biomes == null || biomes.length != 256) {
return -1;
@@ -244,7 +244,7 @@ public class Chunk {
}
@Deprecated
- public void setBiomeAt(int blockX, int blockZ, int biomeID) {
+ public synchronized void setBiomeAt(int blockX, int blockZ, int biomeID) {
if (dataVersion < 2202) {
if (biomes == null || biomes.length != 256) {
biomes = new int[256];
@@ -275,7 +275,7 @@ public class Chunk {
* @param biomeID The biome id to be set.
* When set to a negative number, Minecraft will replace it with the block column's default biome.
*/
- public void setBiomeAt(int blockX, int blockY, int blockZ, int biomeID) {
+ public synchronized void setBiomeAt(int blockX, int blockY, int blockZ, int biomeID) {
if (dataVersion < 2202) {
if (biomes == null || biomes.length != 256) {
biomes = new int[256];
diff --git a/src/main/java/com/volmit/iris/util/nbt/mca/NBTWorld.java b/src/main/java/com/volmit/iris/util/nbt/mca/NBTWorld.java
index 3c278c14e..a2b858f86 100644
--- a/src/main/java/com/volmit/iris/util/nbt/mca/NBTWorld.java
+++ b/src/main/java/com/volmit/iris/util/nbt/mca/NBTWorld.java
@@ -27,6 +27,7 @@ import com.volmit.iris.util.format.C;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.nbt.tag.CompoundTag;
import com.volmit.iris.util.nbt.tag.StringTag;
+import com.volmit.iris.util.parallel.HyperLock;
import com.volmit.iris.util.scheduling.IrisLock;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Biome;
@@ -43,8 +44,8 @@ public class NBTWorld {
private static final BlockData AIR = B.get("AIR");
private static final Map blockDataCache = new KMap<>();
private static final Map biomeIds = computeBiomeIDs();
- private final IrisLock regionLock = new IrisLock("Region");
private final KMap loadedRegions;
+ private final HyperLock hyperLock = new HyperLock();
private final KMap lastUse;
private final File worldFolder;
private final ExecutorService saveQueue;
@@ -62,13 +63,11 @@ public class NBTWorld {
}
public void close() {
- regionLock.lock();
for (Long i : loadedRegions.k()) {
queueSaveUnload(Cache.keyX(i), Cache.keyZ(i));
}
- regionLock.unlock();
saveQueue.shutdown();
try {
while (!saveQueue.awaitTermination(3, TimeUnit.SECONDS)) {
@@ -80,13 +79,9 @@ public class NBTWorld {
}
public void flushNow() {
- regionLock.lock();
-
for (Long i : loadedRegions.k()) {
doSaveUnload(Cache.keyX(i), Cache.keyZ(i));
}
-
- regionLock.unlock();
}
public void queueSaveUnload(int x, int z) {
@@ -103,8 +98,6 @@ public class NBTWorld {
}
public void save() {
- regionLock.lock();
-
boolean saving = true;
for (Long i : loadedRegions.k()) {
@@ -121,8 +114,6 @@ public class NBTWorld {
}
Iris.debug("Regions: " + C.GOLD + loadedRegions.size() + C.LIGHT_PURPLE);
-
- regionLock.unlock();
}
public void queueSave() {
@@ -131,10 +122,8 @@ public class NBTWorld {
public synchronized void unloadRegion(int x, int z) {
long key = Cache.key(x, z);
- regionLock.lock();
loadedRegions.remove(key);
lastUse.remove(key);
- regionLock.unlock();
Iris.debug("Unloaded Region " + C.GOLD + x + " " + z);
}
@@ -249,6 +238,11 @@ public class NBTWorld {
getChunkSection(x >> 4, y >> 4, z >> 4).setBlockStateAt(x & 15, y & 15, z & 15, getCompound(data), false);
}
+ public int getBiomeId(Biome b)
+ {
+ return biomeIds.get(b);
+ }
+
public void setBiome(int x, int y, int z, Biome biome) {
getChunk(x >> 4, z >> 4).setBiomeAt(x & 15, y, z & 15, biomeIds.get(biome));
}
@@ -265,8 +259,12 @@ public class NBTWorld {
return s;
}
- public synchronized Chunk getChunk(int x, int z) {
- MCAFile mca = getMCA(x >> 5, z >> 5);
+ public Chunk getChunk(int x, int z)
+ {
+ return getChunk(getMCA(x >> 5, z >> 5), x, z);
+ }
+
+ public Chunk getChunk(MCAFile mca, int x, int z) {
Chunk c = mca.getChunk(x & 31, z & 31);
if (c == null) {
@@ -278,41 +276,40 @@ public class NBTWorld {
}
public long getIdleDuration(int x, int z) {
- Long l = lastUse.get(Cache.key(x, z));
-
- return l == null ? 0 : (M.ms() - l);
+ return hyperLock.withResult(x, z, () -> {
+ Long l = lastUse.get(Cache.key(x, z));
+ return l == null ? 0 : (M.ms() - l);
+ });
}
public MCAFile getMCA(int x, int z) {
long key = Cache.key(x, z);
- regionLock.lock();
- lastUse.put(key, M.ms());
- MCAFile mcaf = loadedRegions.get(key);
- regionLock.unlock();
+ return hyperLock.withResult(x, z, () -> {
+ lastUse.put(key, M.ms());
- if (mcaf == null) {
- mcaf = new MCAFile(x, z);
- regionLock.lock();
- loadedRegions.put(key, mcaf);
- regionLock.unlock();
- }
+ MCAFile mcaf = loadedRegions.get(key);
- return mcaf;
+ if (mcaf == null) {
+ mcaf = new MCAFile(x, z);
+ loadedRegions.put(key, mcaf);
+ }
+
+ return mcaf;
+ });
}
public MCAFile getMCAOrNull(int x, int z) {
long key = Cache.key(x, z);
- MCAFile ff = null;
- regionLock.lock();
- if (loadedRegions.containsKey(key)) {
- lastUse.put(key, M.ms());
- ff = loadedRegions.get(key);
- }
+ return hyperLock.withResult(x, z, () -> {
+ if (loadedRegions.containsKey(key)) {
+ lastUse.put(key, M.ms());
+ return loadedRegions.get(key);
+ }
- regionLock.unlock();
- return ff;
+ return null;
+ });
}
public int size() {
diff --git a/src/main/java/com/volmit/iris/util/nbt/mca/Section.java b/src/main/java/com/volmit/iris/util/nbt/mca/Section.java
index 901de03af..89ce29962 100644
--- a/src/main/java/com/volmit/iris/util/nbt/mca/Section.java
+++ b/src/main/java/com/volmit/iris/util/nbt/mca/Section.java
@@ -24,6 +24,7 @@ import com.volmit.iris.util.nbt.tag.ByteArrayTag;
import com.volmit.iris.util.nbt.tag.CompoundTag;
import com.volmit.iris.util.nbt.tag.ListTag;
import com.volmit.iris.util.nbt.tag.LongArrayTag;
+import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import java.util.ArrayList;
import java.util.HashMap;
@@ -170,7 +171,7 @@ public class Section {
* This option should only be used moderately to avoid unnecessary recalculation of the palette indices.
* Recalculating the Palette should only be executed once right before saving the Section to file.
*/
- public void setBlockStateAt(int blockX, int blockY, int blockZ, CompoundTag state, boolean cleanup) {
+ public synchronized void setBlockStateAt(int blockX, int blockY, int blockZ, CompoundTag state, boolean cleanup) {
int paletteSizeBefore = palette.size();
int paletteIndex = addToPalette(state);
//power of 2 --> bits must increase, but only if the palette size changed
@@ -223,7 +224,7 @@ public class Section {
* @param paletteIndex The block state to be set (index of block data in the palette).
* @param blockStates The block states to be updated.
*/
- public void setPaletteIndex(int blockIndex, int paletteIndex, AtomicLongArray blockStates) {
+ public synchronized void setPaletteIndex(int blockIndex, int paletteIndex, AtomicLongArray blockStates) {
int bits = blockStates.length() >> 6;
if (dataVersion < 2527) {
@@ -253,7 +254,7 @@ public class Section {
return palette;
}
- int addToPalette(CompoundTag data) {
+ synchronized int addToPalette(CompoundTag data) {
PaletteIndex index;
if ((index = getValueIndexedPalette(data)) != null) {
return index.index;
@@ -283,14 +284,14 @@ public class Section {
* This should only be used moderately to avoid unnecessary recalculation of the palette indices.
* Recalculating the Palette should only be executed once right before saving the Section to file.
*/
- public void cleanupPaletteAndBlockStates() {
+ public synchronized void cleanupPaletteAndBlockStates() {
Map oldToNewMapping = cleanupPalette();
adjustBlockStateBits(oldToNewMapping, blockStates);
}
- private Map cleanupPalette() {
+ private synchronized Map cleanupPalette() {
//create index - palette mapping
- Map allIndices = new HashMap<>();
+ Map allIndices = new Int2IntOpenHashMap();
for (int i = 0; i < 4096; i++) {
int paletteIndex = getPaletteIndex(i);
allIndices.put(paletteIndex, paletteIndex);
@@ -314,7 +315,7 @@ public class Section {
return allIndices;
}
- void adjustBlockStateBits(Map oldToNewMapping, AtomicLongArray blockStates) {
+ synchronized void adjustBlockStateBits(Map oldToNewMapping, AtomicLongArray blockStates) {
//increases or decreases the amount of bits used per BlockState
//based on the size of the palette. oldToNewMapping can be used to update indices
//if the palette had been cleaned up before using MCAFile#cleanupPalette().
@@ -376,7 +377,7 @@ public class Section {
* @throws NullPointerException If blockStates
is null
* @throws IllegalArgumentException When blockStates
' length is < 256 or > 4096 and is not a multiple of 64
*/
- public void setBlockStates(AtomicLongArray blockStates) {
+ public synchronized void setBlockStates(AtomicLongArray blockStates) {
if (blockStates == null) {
throw new NullPointerException("BlockStates cannot be null");
} else if (blockStates.length() % 64 != 0 || blockStates.length() < 256 || blockStates.length() > 4096) {
diff --git a/src/main/java/com/volmit/iris/util/noise/WormIterator2.java b/src/main/java/com/volmit/iris/util/noise/WormIterator2.java
index 9c229472c..69655fde8 100644
--- a/src/main/java/com/volmit/iris/util/noise/WormIterator2.java
+++ b/src/main/java/com/volmit/iris/util/noise/WormIterator2.java
@@ -26,6 +26,7 @@ import lombok.Data;
@Data
public class WormIterator2 {
private transient Worm2 worm;
+ private transient NoiseProvider noise;
private int x;
private int z;
private int maxDistance;
@@ -39,13 +40,18 @@ public class WormIterator2 {
+ ((z * z) - (worm.getZ().getPosition() * worm.getZ().getPosition())) < dist * dist;
}
- public Worm2 next(NoiseProvider p)
+ public Worm2 next()
{
if(worm == null)
{
worm = new Worm2(x, z, 0, 0);
+ return worm;
}
-
+
+ worm.getX().setVelocity(noise.noise(worm.getX().getPosition(), 0));
+ worm.getZ().setVelocity(noise.noise(worm.getZ().getPosition(), 0));
+ worm.step();
+
return worm;
}
}
diff --git a/src/main/java/com/volmit/iris/util/noise/WormIterator3.java b/src/main/java/com/volmit/iris/util/noise/WormIterator3.java
new file mode 100644
index 000000000..dfe2b7e00
--- /dev/null
+++ b/src/main/java/com/volmit/iris/util/noise/WormIterator3.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.util.noise;
+
+import com.volmit.iris.Iris;
+import com.volmit.iris.util.function.NoiseProvider;
+import lombok.Builder;
+import lombok.Data;
+
+@Builder
+@Data
+public class WormIterator3 {
+ private transient Worm3 worm;
+ private int x;
+ private int y;
+ private int z;
+ private transient NoiseProvider noise;
+ private int maxDistance;
+ private int maxIterations;
+
+ public boolean hasNext()
+ {
+ if(worm == null)
+ {
+ return true;
+ }
+
+ double dist = maxDistance - (Math.max(Math.max(Math.abs(worm.getX().getVelocity()),
+ Math.abs(worm.getZ().getVelocity())),
+ Math.abs(worm.getY().getVelocity())) + 1);
+
+ return maxIterations > 0 &&
+ ((x * x) - (worm.getX().getPosition() * worm.getX().getPosition()))
+ + ((y * y) - (worm.getY().getPosition() * worm.getY().getPosition()))
+ + ((z * z) - (worm.getZ().getPosition() * worm.getZ().getPosition())) < dist * dist;
+ }
+
+ public Worm3 next()
+ {
+ maxIterations--;
+ if(worm == null)
+ {
+ worm = new Worm3(x, y, z, 0, 0, 0);
+ return worm;
+ }
+
+ worm.getX().setVelocity(worm.getX().getVelocity() + noise.noise(worm.getX().getPosition() + 10000, 0));
+ worm.getY().setVelocity(worm.getY().getVelocity() + noise.noise(worm.getY().getPosition() + 1000, 0));
+ worm.getZ().setVelocity(worm.getZ().getVelocity() + noise.noise(worm.getZ().getPosition() - 10000, 0));
+ worm.step();
+
+ return worm;
+ }
+}
diff --git a/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java b/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java
index ef6935a97..c81e47f77 100644
--- a/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java
+++ b/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java
@@ -28,25 +28,20 @@ import java.util.concurrent.*;
@SuppressWarnings("ALL")
public class BurstExecutor {
private final ExecutorService executor;
- private final KList> futures;
+ private final KList> futures;
@Setter
private boolean multicore = true;
public BurstExecutor(ExecutorService executor, int burstSizeEstimate) {
this.executor = executor;
- futures = new KList>(burstSizeEstimate);
+ futures = new KList>(burstSizeEstimate);
}
@SuppressWarnings("UnusedReturnValue")
- public CompletableFuture queue(Runnable r) {
- if(!multicore)
- {
- r.run();
- return null;
- }
-
+ public Future> queue(Runnable r) {
synchronized (futures) {
- CompletableFuture c = CompletableFuture.runAsync(r, executor);
+
+ Future> c = executor.submit(r);
futures.add(c);
return c;
}
@@ -55,7 +50,7 @@ public class BurstExecutor {
public BurstExecutor queue(List r) {
if(!multicore)
{
- for(Runnable i : r)
+ for(Runnable i : new KList<>(r))
{
i.run();
}
@@ -65,8 +60,7 @@ public class BurstExecutor {
synchronized (futures) {
for (Runnable i : new KList<>(r)) {
- CompletableFuture c = CompletableFuture.runAsync(i, executor);
- futures.add(c);
+ queue(i);
}
}
@@ -76,7 +70,7 @@ public class BurstExecutor {
public BurstExecutor queue(Runnable[] r) {
if(!multicore)
{
- for(Runnable i : r)
+ for(Runnable i : new KList<>(r))
{
i.run();
}
@@ -86,8 +80,7 @@ public class BurstExecutor {
synchronized (futures) {
for (Runnable i : r) {
- CompletableFuture c = CompletableFuture.runAsync(i, executor);
- futures.add(c);
+ queue(i);
}
}
@@ -106,38 +99,15 @@ public class BurstExecutor {
}
try {
- CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get();
- futures.clear();
- } catch (InterruptedException | ExecutionException e) {
- Iris.reportError(e);
- }
- }
- }
-
- public boolean complete(long maxDur) {
- if(!multicore)
- {
- return true;
- }
-
- synchronized (futures) {
- if (futures.isEmpty()) {
- return true;
- }
-
- try {
- try {
- CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get(maxDur, TimeUnit.MILLISECONDS);
- } catch (TimeoutException e) {
- return false;
+ for(Future> i : futures)
+ {
+ i.get();
}
+
futures.clear();
} catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
Iris.reportError(e);
}
}
-
- return false;
}
}
diff --git a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java
index 92a07825e..ce21c64f7 100644
--- a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java
+++ b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java
@@ -22,10 +22,8 @@ import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.service.PreservationSVC;
import com.volmit.iris.util.collection.KList;
-import com.volmit.iris.util.io.InstanceState;
import com.volmit.iris.util.math.M;
-import com.volmit.iris.util.scheduling.J;
-import com.volmit.iris.util.scheduling.Looper;
+import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.concurrent.*;
@@ -33,66 +31,39 @@ import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Supplier;
public class MultiBurst {
- public static final MultiBurst burst = new MultiBurst("Iris", IrisSettings.get().getConcurrency().getMiscThreadPriority(), IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getMiscThreadCount()));
+ public static final MultiBurst burst = new MultiBurst();
private ExecutorService service;
- private final Looper heartbeat;
private final AtomicLong last;
- private int tid;
private final String name;
- private final int tc;
private final int priority;
- private final int instance;
- public MultiBurst(int tc) {
- this("Iris", 6, tc);
+ public MultiBurst() {
+ this("Iris", Thread.MIN_PRIORITY);
}
- public MultiBurst(String name, int priority, int tc) {
+ public MultiBurst(String name, int priority) {
this.name = name;
this.priority = priority;
- this.tc = tc;
- instance = InstanceState.getInstanceId();
last = new AtomicLong(M.ms());
- heartbeat = new Looper() {
- @Override
- protected long loop() {
- if (instance != InstanceState.getInstanceId()) {
- shutdownNow();
- return -1;
- }
-
- if (M.ms() - last.get() > TimeUnit.MINUTES.toMillis(1) && service != null) {
- service.shutdown();
- service = null;
- Iris.debug("Shutting down MultiBurst Pool " + getName() + " to conserve resources.");
- }
-
- return 30000;
- }
- };
- heartbeat.setName(name + " Monitor");
- heartbeat.start();
Iris.service(PreservationSVC.class).register(this);
}
private synchronized ExecutorService getService() {
last.set(M.ms());
if (service == null || service.isShutdown()) {
- service = Executors.newFixedThreadPool(Math.max(tc, 1), r -> {
- tid++;
- Thread t = new Thread(r);
- t.setName(name + " " + tid);
- t.setPriority(priority);
- t.setUncaughtExceptionHandler((et, e) ->
- {
- Iris.info("Exception encountered in " + et.getName());
- e.printStackTrace();
- });
+ service = new ForkJoinPool(IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getParallelism()),
+ new ForkJoinPool.ForkJoinWorkerThreadFactory() {
+ int m = 0;
- return t;
- });
- Iris.service(PreservationSVC.class).register(service);
- Iris.debug("Started MultiBurst Pool " + name + " with " + tc + " threads at " + priority + " priority.");
+ @Override
+ public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
+ final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
+ worker.setPriority(priority);
+ worker.setName(name + " " + ++m);
+ return worker;
+ }
+ },
+ (t, e) -> e.printStackTrace(), true);
}
return service;
@@ -102,10 +73,40 @@ public class MultiBurst {
burst(r.length).queue(r).complete();
}
+ public void burst(boolean multicore, Runnable... r) {
+ if(multicore)
+ {
+ burst(r);
+ }
+
+ else
+ {
+ sync(r);
+ }
+ }
+
public void burst(List r) {
burst(r.size()).queue(r).complete();
}
+ public void burst(boolean multicore, List r) {
+ if(multicore)
+ {
+ burst(r);
+ }
+
+ else {
+ sync(r);
+ }
+ }
+
+ private void sync(List r) {
+ for(Runnable i : new KList<>(r))
+ {
+ i.run();
+ }
+ }
+
public void sync(Runnable... r) {
for (Runnable i : r) {
i.run();
@@ -126,6 +127,12 @@ public class MultiBurst {
return burst(16);
}
+ public BurstExecutor burst(boolean multicore) {
+ BurstExecutor b = burst();
+ b.setMulticore(multicore);
+ return b;
+ }
+
public Future lazySubmit(Callable o) {
return getService().submit(o);
}
@@ -138,64 +145,15 @@ public class MultiBurst {
return getService().submit(o);
}
- public CompletableFuture> complete(Runnable o) {
- return CompletableFuture.runAsync(o, getService());
+ public Future> complete(Runnable o) {
+ return getService().submit(o);
}
- public CompletableFuture completeValue(Supplier o) {
- return CompletableFuture.supplyAsync(o, getService());
+ public Future completeValue(Callable o) {
+ return getService().submit(o);
}
- public void shutdownNow() {
- Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + ".");
- heartbeat.interrupt();
-
- if (service != null) {
- service.shutdownNow().forEach(Runnable::run);
- }
- }
-
- public void shutdown() {
- Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + ".");
- heartbeat.interrupt();
-
- if (service != null) {
- service.shutdown();
- }
- }
-
- public void shutdownLater() {
- if (service != null) {
- try
- {
- service.submit(() -> {
- J.sleep(3000);
- Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + ".");
-
- if (service != null) {
- service.shutdown();
- }
- });
-
- heartbeat.interrupt();
- }
-
- catch(Throwable e)
- {
- Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + ".");
-
- if (service != null) {
- service.shutdown();
- }
-
- heartbeat.interrupt();
- }
- }
- }
-
- public void shutdownAndAwait() {
- Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + ".");
- heartbeat.interrupt();
+ public void close() {
if (service != null) {
service.shutdown();
try {
diff --git a/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java b/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java
index 9110d849f..9b71d0aad 100644
--- a/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java
+++ b/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java
@@ -311,6 +311,9 @@ public class VolmitSender implements CommandSender {
}
}
+ public void sendMessageBasic(String message) {
+ s.sendMessage(C.translateAlternateColorCodes('&', getTag() + message));
+ }
public void sendMessageRaw(String message) {
if (message.contains("")) {
diff --git a/src/main/java/com/volmit/iris/util/scheduling/J.java b/src/main/java/com/volmit/iris/util/scheduling/J.java
index 0394dbd60..b5a38442e 100644
--- a/src/main/java/com/volmit/iris/util/scheduling/J.java
+++ b/src/main/java/com/volmit/iris/util/scheduling/J.java
@@ -129,7 +129,6 @@ public class J {
try {
r.run();
} catch (Throwable e) {
- Iris.reportError(e);
return e;
}
diff --git a/src/main/java/com/volmit/iris/util/scheduling/jobs/ParallelQueueJob.java b/src/main/java/com/volmit/iris/util/scheduling/jobs/ParallelQueueJob.java
new file mode 100644
index 000000000..579b5303d
--- /dev/null
+++ b/src/main/java/com/volmit/iris/util/scheduling/jobs/ParallelQueueJob.java
@@ -0,0 +1,42 @@
+/*
+ * 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