mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-19 02:36:59 +00:00
Merge remote-tracking branch 'upstream/master' into DecreeCommands
This commit is contained in:
commit
2dd6db352f
25
.github/workflows/gradlebuild.yml
vendored
Normal file
25
.github/workflows/gradlebuild.yml
vendored
Normal file
@ -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
|
@ -32,7 +32,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group 'com.volmit.iris'
|
group 'com.volmit.iris'
|
||||||
version '1.7.4'
|
version '1.7.8'
|
||||||
def apiVersion = '1.17'
|
def apiVersion = '1.17'
|
||||||
def name = getRootProject().getName() // See settings.gradle
|
def name = getRootProject().getName() // See settings.gradle
|
||||||
def main = 'com.volmit.iris.Iris'
|
def main = 'com.volmit.iris.Iris'
|
||||||
@ -187,6 +187,7 @@ dependencies {
|
|||||||
implementation 'net.kyori:adventure-api:4.8.1'
|
implementation 'net.kyori:adventure-api:4.8.1'
|
||||||
|
|
||||||
// Dynamically Loaded
|
// Dynamically Loaded
|
||||||
|
implementation 'io.timeandspace:smoothie-map:2.0.2'
|
||||||
implementation 'it.unimi.dsi:fastutil:8.5.4'
|
implementation 'it.unimi.dsi:fastutil:8.5.4'
|
||||||
implementation 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2'
|
implementation 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2'
|
||||||
implementation 'org.zeroturnaround:zt-zip:1.14'
|
implementation 'org.zeroturnaround:zt-zip:1.14'
|
||||||
@ -195,4 +196,5 @@ dependencies {
|
|||||||
implementation 'com.google.guava:guava:30.1.1-jre'
|
implementation 'com.google.guava:guava:30.1.1-jre'
|
||||||
implementation 'bsf:bsf:2.4.0'
|
implementation 'bsf:bsf:2.4.0'
|
||||||
implementation 'rhino:js:1.7R2'
|
implementation 'rhino:js:1.7R2'
|
||||||
|
implementation 'com.github.ben-manes.caffeine:caffeine:3.0.3'
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,5 @@ libraries:
|
|||||||
commands:
|
commands:
|
||||||
iris:
|
iris:
|
||||||
aliases: [ ir, irs ]
|
aliases: [ ir, irs ]
|
||||||
irisd:
|
|
||||||
aliases: [ ird, irsd ]
|
|
||||||
api-version: ${apiversion}
|
api-version: ${apiversion}
|
||||||
hotload-dependencies: false
|
hotload-dependencies: false
|
@ -27,11 +27,11 @@ import com.volmit.iris.core.link.MultiverseCoreLink;
|
|||||||
import com.volmit.iris.core.link.MythicMobsLink;
|
import com.volmit.iris.core.link.MythicMobsLink;
|
||||||
import com.volmit.iris.core.link.OraxenLink;
|
import com.volmit.iris.core.link.OraxenLink;
|
||||||
import com.volmit.iris.core.nms.INMS;
|
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.project.loader.IrisData;
|
||||||
import com.volmit.iris.core.service.StudioSVC;
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
import com.volmit.iris.engine.object.biome.IrisBiome;
|
import com.volmit.iris.engine.object.biome.IrisBiome;
|
||||||
import com.volmit.iris.engine.object.biome.IrisBiomeCustom;
|
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.common.IrisWorld;
|
||||||
import com.volmit.iris.engine.object.compat.IrisCompat;
|
import com.volmit.iris.engine.object.compat.IrisCompat;
|
||||||
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
||||||
@ -116,12 +116,10 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
sender.setTag(getTag());
|
sender.setTag(getTag());
|
||||||
instance = this;
|
instance = this;
|
||||||
compat = IrisCompat.configured(getDataFile("compat.json"));
|
compat = IrisCompat.configured(getDataFile("compat.json"));
|
||||||
|
|
||||||
linkMultiverseCore = new MultiverseCoreLink();
|
linkMultiverseCore = new MultiverseCoreLink();
|
||||||
linkOraxen = new OraxenLink();
|
linkOraxen = new OraxenLink();
|
||||||
linkMythicMobs = new MythicMobsLink();
|
linkMythicMobs = new MythicMobsLink();
|
||||||
configWatcher = new FileWatcher(getDataFile("settings.json"));
|
configWatcher = new FileWatcher(getDataFile("settings.json"));
|
||||||
|
|
||||||
services.values().forEach(IrisService::onEnable);
|
services.values().forEach(IrisService::onEnable);
|
||||||
services.values().forEach(this::registerListener);
|
services.values().forEach(this::registerListener);
|
||||||
}
|
}
|
||||||
@ -165,6 +163,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
HandlerList.unregisterAll((Plugin) this);
|
HandlerList.unregisterAll((Plugin) this);
|
||||||
postShutdown.forEach(Runnable::run);
|
postShutdown.forEach(Runnable::run);
|
||||||
services.clear();
|
services.clear();
|
||||||
|
MultiBurst.burst.close();
|
||||||
super.onDisable();
|
super.onDisable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -604,14 +603,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void verbose(String string) {
|
public static void verbose(String string) {
|
||||||
try {
|
debug(string);
|
||||||
if (IrisSettings.get().getGeneral().isVerbose()) {
|
|
||||||
msg(C.GRAY + string);
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
msg(C.GRAY + string);
|
|
||||||
Iris.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void success(String string) {
|
public static void success(String string) {
|
||||||
@ -683,7 +675,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMCA() {
|
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) {
|
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()) {
|
if (IrisSettings.get().getGeneral().isDebug()) {
|
||||||
String n = e.getClass().getCanonicalName() + "-" + e.getStackTrace()[0].getClassName() + "-" + e.getStackTrace()[0].getLineNumber();
|
String n = e.getClass().getCanonicalName() + "-" + e.getStackTrace()[0].getClassName() + "-" + e.getStackTrace()[0].getLineNumber();
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ package com.volmit.iris.core;
|
|||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.volmit.iris.Iris;
|
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.collection.KSet;
|
||||||
import com.volmit.iris.util.io.IO;
|
import com.volmit.iris.util.io.IO;
|
||||||
import com.volmit.iris.util.json.JSONException;
|
import com.volmit.iris.util.json.JSONException;
|
||||||
@ -56,6 +57,11 @@ public class IrisSettings {
|
|||||||
return getParallax().getParallaxRegionEvictionMS();
|
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) {
|
public static int getThreadCount(int c) {
|
||||||
if (c < 2 && c >= 0) {
|
if (c < 2 && c >= 0) {
|
||||||
return 2;
|
return 2;
|
||||||
@ -82,13 +88,7 @@ public class IrisSettings {
|
|||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class IrisSettingsConcurrency {
|
public static class IrisSettingsConcurrency {
|
||||||
public int engineThreadCount = -1;
|
public int parallelism = -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@ -101,7 +101,6 @@ public class IrisSettings {
|
|||||||
public static class IrisSettingsGeneral {
|
public static class IrisSettingsGeneral {
|
||||||
public boolean commandSounds = true;
|
public boolean commandSounds = true;
|
||||||
public boolean debug = false;
|
public boolean debug = false;
|
||||||
public boolean verbose = false;
|
|
||||||
public boolean ignoreWorldEdit = false;
|
public boolean ignoreWorldEdit = false;
|
||||||
public boolean disableNMS = false;
|
public boolean disableNMS = false;
|
||||||
public boolean keepProductionOnReload = false;
|
public boolean keepProductionOnReload = false;
|
||||||
@ -115,7 +114,6 @@ public class IrisSettings {
|
|||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class IrisSettingsGUI {
|
public static class IrisSettingsGUI {
|
||||||
|
|
||||||
public boolean useServerLaunchedGuis = true;
|
public boolean useServerLaunchedGuis = true;
|
||||||
public boolean maximumPregenGuiFPS = false;
|
public boolean maximumPregenGuiFPS = false;
|
||||||
public boolean localPregenGui = true;
|
public boolean localPregenGui = true;
|
||||||
@ -124,10 +122,8 @@ public class IrisSettings {
|
|||||||
@Data
|
@Data
|
||||||
public static class IrisSettingsGenerator {
|
public static class IrisSettingsGenerator {
|
||||||
public String defaultWorldType = "overworld";
|
public String defaultWorldType = "overworld";
|
||||||
public boolean disableMCA = false;
|
public boolean headlessPregeneration = false;
|
||||||
public boolean systemEffects = true;
|
public boolean systemEffects = true;
|
||||||
public boolean systemEntitySpawnOverrides = true;
|
|
||||||
public boolean systemEntityInitialSpawns = true;
|
|
||||||
public int maxBiomeChildDepth = 4;
|
public int maxBiomeChildDepth = 4;
|
||||||
public boolean preventLeafDecay = true;
|
public boolean preventLeafDecay = true;
|
||||||
}
|
}
|
||||||
@ -162,65 +158,14 @@ public class IrisSettings {
|
|||||||
try {
|
try {
|
||||||
String ss = IO.readAll(s);
|
String ss = IO.readAll(s);
|
||||||
settings = new Gson().fromJson(ss, IrisSettings.class);
|
settings = new Gson().fromJson(ss, IrisSettings.class);
|
||||||
|
|
||||||
J.a(() ->
|
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
JSONObject j = new JSONObject(ss);
|
IO.writeAll(s, new JSONObject(new Gson().toJson(settings)).toString(4));
|
||||||
boolean u = false;
|
} catch (IOException e) {
|
||||||
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();
|
e.printStackTrace();
|
||||||
Iris.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (Throwable ee) {
|
} catch (Throwable ee) {
|
||||||
Iris.reportError(ee);
|
Iris.reportError(ee);
|
||||||
Iris.error("Configuration Error in settings.json! " + ee.getClass().getSimpleName() + ": " + ee.getMessage());
|
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!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} 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!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,9 @@ public class CommandIrisStudio extends MortarCommand {
|
|||||||
@Command
|
@Command
|
||||||
private CommandIrisStudioExecute execute;
|
private CommandIrisStudioExecute execute;
|
||||||
|
|
||||||
|
@Command
|
||||||
|
private CommandIrisStudioCompile compile;
|
||||||
|
|
||||||
@Command
|
@Command
|
||||||
private CommandIrisStudioOpen open;
|
private CommandIrisStudioOpen open;
|
||||||
|
|
||||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<String> 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]";
|
||||||
|
}
|
||||||
|
}
|
@ -66,7 +66,7 @@ public class CommandIrisStudioUpdate extends MortarCommand {
|
|||||||
IrisData data = IrisData.get(Iris.service(StudioSVC.class).getWorkspaceFolder(args[0]));
|
IrisData data = IrisData.get(Iris.service(StudioSVC.class).getWorkspaceFolder(args[0]));
|
||||||
int t = data.getObjectLoader().getPossibleKeys().length;
|
int t = data.getObjectLoader().getPossibleKeys().length;
|
||||||
ChronoLatch cl = new ChronoLatch(250, false);
|
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();
|
BurstExecutor b = bx.burst();
|
||||||
int g = 0;
|
int g = 0;
|
||||||
for (String f : data.getObjectLoader().getPossibleKeys()) {
|
for (String f : data.getObjectLoader().getPossibleKeys()) {
|
||||||
@ -102,7 +102,6 @@ public class CommandIrisStudioUpdate extends MortarCommand {
|
|||||||
int finalG = g;
|
int finalG = g;
|
||||||
J.a(() -> {
|
J.a(() -> {
|
||||||
b.complete();
|
b.complete();
|
||||||
bx.shutdownNow();
|
|
||||||
sender.sendMessage("Done! Rewrote " + Form.f(finalG) + " Objects!");
|
sender.sendMessage("Done! Rewrote " + Form.f(finalG) + " Objects!");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,7 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@Decree(name = "studio", aliases = {"std", "s"}, description = "Studio Commands", studio = true)
|
@Decree(name = "studio", aliases = {"std", "s"}, description = "Studio Commands", studio = true)
|
||||||
@ -133,7 +134,7 @@ public class DecStudio implements DecreeExecutor {
|
|||||||
KList<Job> jobs = new KList<>();
|
KList<Job> jobs = new KList<>();
|
||||||
KList<File> files = new KList<File>();
|
KList<File> files = new KList<File>();
|
||||||
files(Iris.instance.getDataFolder("packs", project.getLoadKey()), files);
|
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", () -> {
|
jobs.add(new SingleJob("Updating Workspace", () -> {
|
||||||
if (!new IrisProject(Iris.service(StudioSVC.class).getWorkspaceFolder(project.getLoadKey())).updateWorkspace()) {
|
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()));
|
IrisData data = IrisData.get(Iris.service(StudioSVC.class).getWorkspaceFolder(project.getLoadKey()));
|
||||||
for (String f : data.getObjectLoader().getPossibleKeys()) {
|
for (String f : data.getObjectLoader().getPossibleKeys()) {
|
||||||
CompletableFuture<?> gg = burst.complete(() -> {
|
Future<?> gg = burst.complete(() -> {
|
||||||
File ff = data.getObjectLoader().findFile(f);
|
File ff = data.getObjectLoader().findFile(f);
|
||||||
IrisObject oo = new IrisObject(0, 0, 0);
|
IrisObject oo = new IrisObject(0, 0, 0);
|
||||||
try {
|
try {
|
||||||
@ -237,8 +238,6 @@ public class DecStudio implements DecreeExecutor {
|
|||||||
jobs.add(q);
|
jobs.add(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
jobs.add(new SingleJob("Finishing Up", burst::shutdownNow));
|
|
||||||
|
|
||||||
new JobCollection("Cleaning", jobs).execute(sender());
|
new JobCollection("Cleaning", jobs).execute(sender());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List
|
|||||||
static double ascale = 10;
|
static double ascale = 10;
|
||||||
CNG cng = NoiseStyle.STATIC.create(new RNG(RNG.r.nextLong()));
|
CNG cng = NoiseStyle.STATIC.create(new RNG(RNG.r.nextLong()));
|
||||||
@SuppressWarnings("CanBeFinal")
|
@SuppressWarnings("CanBeFinal")
|
||||||
MultiBurst gx = new MultiBurst("Iris Noise Renderer", Thread.MAX_PRIORITY, Runtime.getRuntime().availableProcessors());
|
MultiBurst gx = MultiBurst.burst;
|
||||||
ReentrantLock l = new ReentrantLock();
|
ReentrantLock l = new ReentrantLock();
|
||||||
BufferedImage img;
|
BufferedImage img;
|
||||||
int w = 0;
|
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);
|
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() {
|
frame.addWindowListener(new java.awt.event.WindowAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
|
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
|
||||||
nv.gx.shutdownLater();
|
|
||||||
Iris.instance.unregisterListener(nv);
|
Iris.instance.unregisterListener(nv);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -29,11 +29,12 @@ import org.bukkit.Chunk;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public class AsyncPregenMethod implements PregeneratorMethod {
|
public class AsyncPregenMethod implements PregeneratorMethod {
|
||||||
private final World world;
|
private final World world;
|
||||||
private final MultiBurst burst;
|
private final MultiBurst burst;
|
||||||
private final KList<CompletableFuture<?>> future;
|
private final KList<Future<?>> future;
|
||||||
|
|
||||||
public AsyncPregenMethod(World world, int threads) {
|
public AsyncPregenMethod(World world, int threads) {
|
||||||
if (!PaperLib.isPaper()) {
|
if (!PaperLib.isPaper()) {
|
||||||
@ -41,7 +42,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.world = world;
|
this.world = world;
|
||||||
burst = new MultiBurst("Iris Async Pregenerator", IrisSettings.get().getConcurrency().getPregenThreadPriority(), threads);
|
burst = MultiBurst.burst;
|
||||||
future = new KList<>(1024);
|
future = new KList<>(1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +70,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void waitForChunks() {
|
private void waitForChunks() {
|
||||||
for (CompletableFuture<?> i : future.copy()) {
|
for (Future<?> i : future.copy()) {
|
||||||
try {
|
try {
|
||||||
i.get();
|
i.get();
|
||||||
future.remove(i);
|
future.remove(i);
|
||||||
@ -92,7 +93,6 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
waitForChunks();
|
waitForChunks();
|
||||||
burst.shutdownAndAwait();
|
|
||||||
unloadAndSaveAllChunks();
|
unloadAndSaveAllChunks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateChunk(int x, int z, PregenListener listener) {
|
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();
|
waitForChunks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ public class HybridPregenMethod implements PregeneratorMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean supportsHeadless(World world) {
|
private boolean supportsHeadless(World world) {
|
||||||
return IrisToolbelt.access(world) != null && !IrisSettings.get().getGenerator().isDisableMCA();
|
return IrisToolbelt.access(world) != null && IrisSettings.get().getGenerator().isHeadlessPregeneration();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -95,7 +95,7 @@ public class MedievalPregenMethod implements PregeneratorMethod {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateChunk(int x, int z, PregenListener listener) {
|
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();
|
waitForChunks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import com.google.gson.Gson;
|
|||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.IrisSettings;
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.project.loader.IrisData;
|
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.project.loader.ResourceLoader;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
import com.volmit.iris.engine.object.biome.IrisBiome;
|
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.entity.IrisEntity;
|
||||||
import com.volmit.iris.engine.object.loot.IrisLootTable;
|
import com.volmit.iris.engine.object.loot.IrisLootTable;
|
||||||
import com.volmit.iris.engine.object.noise.IrisGenerator;
|
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.objects.IrisObjectPlacement;
|
||||||
import com.volmit.iris.engine.object.regional.IrisRegion;
|
import com.volmit.iris.engine.object.regional.IrisRegion;
|
||||||
import com.volmit.iris.engine.object.spawners.IrisSpawner;
|
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.KList;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.collection.KSet;
|
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.exceptions.IrisException;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
import com.volmit.iris.util.io.IO;
|
import com.volmit.iris.util.io.IO;
|
||||||
import com.volmit.iris.util.json.JSONArray;
|
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.J;
|
||||||
import com.volmit.iris.util.scheduling.O;
|
import com.volmit.iris.util.scheduling.O;
|
||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
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 lombok.Data;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
@ -443,7 +451,6 @@ public class IrisProject {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static int clean(VolmitSender s, File clean) {
|
public static int clean(VolmitSender s, File clean) {
|
||||||
int c = 0;
|
int c = 0;
|
||||||
if (clean.isDirectory()) {
|
if (clean.isDirectory()) {
|
||||||
@ -499,4 +506,153 @@ public class IrisProject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void compile(VolmitSender sender) {
|
||||||
|
IrisData data = IrisData.get(getPath());
|
||||||
|
KList<Job> jobs = new KList<Job>();
|
||||||
|
KList<File> files = new KList<File>();
|
||||||
|
KList<File> objects = new KList<File>();
|
||||||
|
files(getPath(), files);
|
||||||
|
filesObjects(getPath(), objects);
|
||||||
|
|
||||||
|
jobs.add(new ParallelQueueJob<File>() {
|
||||||
|
@Override
|
||||||
|
public void execute(File f) {
|
||||||
|
try {
|
||||||
|
IrisObject o = new IrisObject(0,0,0);
|
||||||
|
o.read(f);
|
||||||
|
|
||||||
|
if(o.getBlocks().isEmpty())
|
||||||
|
{
|
||||||
|
sender.sendMessageRaw("<hover:show_text:'Error:\n" +
|
||||||
|
"<yellow>" + f.getPath() +
|
||||||
|
"'><red>- IOB " + f.getName() + " has 0 blocks!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(o.getW() == 0 || o.getH() == 0 || o.getD() == 0)
|
||||||
|
{
|
||||||
|
sender.sendMessageRaw("<hover:show_text:'Error:\n" +
|
||||||
|
"<yellow>" + f.getPath() + "\n<red>The width height or depth has a zero in it (bad format)" +
|
||||||
|
"'><red>- IOB " + f.getName() + " is not 3D!");
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "IOB";
|
||||||
|
}
|
||||||
|
}.queue(objects));
|
||||||
|
|
||||||
|
jobs.add(new ParallelQueueJob<File>() {
|
||||||
|
@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("<hover:show_text:'Error:\n" +
|
||||||
|
"<yellow>" + f.getPath() +
|
||||||
|
"\n<red>" +e.getMessage() +
|
||||||
|
"'><red>- 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<String> path)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Object o = c.getClass().getConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
catch(Throwable e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void files(File clean, KList<File> 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<File> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import org.bukkit.enchantments.Enchantment;
|
|||||||
import org.bukkit.potion.PotionEffectType;
|
import org.bukkit.potion.PotionEffectType;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.lang.reflect.AccessibleObject;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -536,8 +537,8 @@ public class SchemaBuilder {
|
|||||||
d.add("* Default Value is " + value);
|
d.add("* Default Value is " + value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable ignored) {
|
||||||
Iris.reportError(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
description.forEach((g) -> d.add(g.trim()));
|
description.forEach((g) -> d.add(g.trim()));
|
||||||
|
@ -19,9 +19,11 @@
|
|||||||
package com.volmit.iris.core.project.loader;
|
package com.volmit.iris.core.project.loader;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.biome.IrisBiome;
|
import com.volmit.iris.engine.object.biome.IrisBiome;
|
||||||
import com.volmit.iris.engine.object.block.IrisBlockData;
|
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.common.IrisScript;
|
||||||
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
||||||
import com.volmit.iris.engine.object.entity.IrisEntity;
|
import com.volmit.iris.engine.object.entity.IrisEntity;
|
||||||
@ -42,8 +44,9 @@ import com.volmit.iris.util.math.RNG;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Objects;
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class IrisData {
|
public class IrisData {
|
||||||
@ -63,6 +66,7 @@ public class IrisData {
|
|||||||
private ResourceLoader<IrisExpression> expressionLoader;
|
private ResourceLoader<IrisExpression> expressionLoader;
|
||||||
private ResourceLoader<IrisObject> objectLoader;
|
private ResourceLoader<IrisObject> objectLoader;
|
||||||
private ResourceLoader<IrisScript> scriptLoader;
|
private ResourceLoader<IrisScript> scriptLoader;
|
||||||
|
private ResourceLoader<IrisCave> caveLoader;
|
||||||
private KMap<Class<? extends IrisRegistrant>, ResourceLoader<? extends IrisRegistrant>> loaders = new KMap<>();
|
private KMap<Class<? extends IrisRegistrant>, ResourceLoader<? extends IrisRegistrant>> loaders = new KMap<>();
|
||||||
private boolean closed;
|
private boolean closed;
|
||||||
private final File dataFolder;
|
private final File dataFolder;
|
||||||
@ -87,6 +91,23 @@ public class IrisData {
|
|||||||
dataLoaders.v().forEach(IrisData::cleanupEngine);
|
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()
|
public void cleanupEngine()
|
||||||
{
|
{
|
||||||
if(engine != null && engine.isClosed())
|
if(engine != null && engine.isClosed())
|
||||||
@ -199,6 +220,7 @@ public class IrisData {
|
|||||||
this.jigsawStructureLoader = registerLoader(IrisJigsawStructure.class);
|
this.jigsawStructureLoader = registerLoader(IrisJigsawStructure.class);
|
||||||
this.jigsawPieceLoader = registerLoader(IrisJigsawPiece.class);
|
this.jigsawPieceLoader = registerLoader(IrisJigsawPiece.class);
|
||||||
this.generatorLoader = registerLoader(IrisGenerator.class);
|
this.generatorLoader = registerLoader(IrisGenerator.class);
|
||||||
|
this.caveLoader = registerLoader(IrisCave.class);
|
||||||
this.blockLoader = registerLoader(IrisBlockData.class);
|
this.blockLoader = registerLoader(IrisBlockData.class);
|
||||||
this.expressionLoader = registerLoader(IrisExpression.class);
|
this.expressionLoader = registerLoader(IrisExpression.class);
|
||||||
this.objectLoader = registerLoader(IrisObject.class);
|
this.objectLoader = registerLoader(IrisObject.class);
|
||||||
@ -273,6 +295,10 @@ public class IrisData {
|
|||||||
return loadAny(key, (dm) -> dm.getRegionLoader().load(key, false));
|
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) {
|
public static IrisDimension loadAnyDimension(String key) {
|
||||||
return loadAny(key, (dm) -> dm.getDimensionLoader().load(key, false));
|
return loadAny(key, (dm) -> dm.getDimensionLoader().load(key, false));
|
||||||
}
|
}
|
||||||
@ -304,4 +330,39 @@ public class IrisData {
|
|||||||
|
|
||||||
return null;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
@ -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.RegistryListResource;
|
||||||
import com.volmit.iris.engine.object.common.IrisScript;
|
import com.volmit.iris.engine.object.common.IrisScript;
|
||||||
import com.volmit.iris.util.collection.KList;
|
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 lombok.Data;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
@ -55,4 +57,6 @@ public abstract class IrisRegistrant {
|
|||||||
|
|
||||||
return getLoadFile();
|
return getLoadFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract void scanForErrors(JSONObject p, VolmitSender sender);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ import com.volmit.iris.util.plugin.IrisService;
|
|||||||
public class CommandSVC implements IrisService, DecreeSystem {
|
public class CommandSVC implements IrisService, DecreeSystem {
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
Iris.instance.getCommand("irisd").setExecutor(this);
|
// TODO Iris.instance.getCommand("irisd").setExecutor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -31,7 +31,6 @@ import java.util.concurrent.ExecutorService;
|
|||||||
public class PreservationSVC implements IrisService
|
public class PreservationSVC implements IrisService
|
||||||
{
|
{
|
||||||
private KList<Thread> threads = new KList<>();
|
private KList<Thread> threads = new KList<>();
|
||||||
private KList<MultiBurst> bursts = new KList<>();
|
|
||||||
private KList<ExecutorService> services = new KList<>();
|
private KList<ExecutorService> services = new KList<>();
|
||||||
private Looper dereferencer;
|
private Looper dereferencer;
|
||||||
|
|
||||||
@ -42,7 +41,7 @@ public class PreservationSVC implements IrisService
|
|||||||
|
|
||||||
public void register(MultiBurst burst)
|
public void register(MultiBurst burst)
|
||||||
{
|
{
|
||||||
bursts.add(burst);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void register(ExecutorService service)
|
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)
|
for(ExecutorService i : services)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -82,18 +82,6 @@ public class StudioSVC implements IrisService {
|
|||||||
IrisToolbelt.evacuate(i);
|
IrisToolbelt.evacuate(i);
|
||||||
IrisToolbelt.access(i).close();
|
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ public class IrisToolbelt {
|
|||||||
return pregenerate(task, new HeadlessPregenMethod(((HeadlessGenerator) gen).getWorld(), (HeadlessGenerator) gen));
|
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, 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())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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.common.CaveResult;
|
||||||
import com.volmit.iris.engine.object.decoration.IrisDecorationPart;
|
import com.volmit.iris.engine.object.decoration.IrisDecorationPart;
|
||||||
import com.volmit.iris.engine.object.decoration.IrisDecorator;
|
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.feature.IrisFeaturePositional;
|
||||||
import com.volmit.iris.engine.object.noise.IrisGenerator;
|
import com.volmit.iris.engine.object.noise.IrisGenerator;
|
||||||
import com.volmit.iris.engine.object.noise.IrisInterpolator;
|
import com.volmit.iris.engine.object.noise.IrisInterpolator;
|
||||||
@ -65,9 +64,6 @@ public class IrisComplex implements DataProvider {
|
|||||||
private ProceduralStream<Double> regionStyleStream;
|
private ProceduralStream<Double> regionStyleStream;
|
||||||
private ProceduralStream<Double> regionIdentityStream;
|
private ProceduralStream<Double> regionIdentityStream;
|
||||||
private ProceduralStream<UUID> regionIDStream;
|
private ProceduralStream<UUID> regionIDStream;
|
||||||
private ProceduralStream<Boolean> islandStream;
|
|
||||||
private ProceduralStream<Double> islandHeightStream;
|
|
||||||
private ProceduralStream<Double> islandDepthStream;
|
|
||||||
private ProceduralStream<InferredType> bridgeStream;
|
private ProceduralStream<InferredType> bridgeStream;
|
||||||
private ProceduralStream<IrisBiome> landBiomeStream;
|
private ProceduralStream<IrisBiome> landBiomeStream;
|
||||||
private ProceduralStream<IrisBiome> caveBiomeStream;
|
private ProceduralStream<IrisBiome> caveBiomeStream;
|
||||||
@ -86,8 +82,6 @@ public class IrisComplex implements DataProvider {
|
|||||||
private ProceduralStream<Double> heightFluidStream;
|
private ProceduralStream<Double> heightFluidStream;
|
||||||
private ProceduralStream<Integer> trueHeightStream;
|
private ProceduralStream<Integer> trueHeightStream;
|
||||||
private ProceduralStream<Double> slopeStream;
|
private ProceduralStream<Double> slopeStream;
|
||||||
private ProceduralStream<Integer> islandTopStream;
|
|
||||||
private ProceduralStream<Integer> islandBottomStream;
|
|
||||||
private ProceduralStream<Integer> topSurfaceStream;
|
private ProceduralStream<Integer> topSurfaceStream;
|
||||||
private ProceduralStream<RNG> rngStream;
|
private ProceduralStream<RNG> rngStream;
|
||||||
private ProceduralStream<RNG> chunkRngStream;
|
private ProceduralStream<RNG> chunkRngStream;
|
||||||
@ -167,11 +161,6 @@ public class IrisComplex implements DataProvider {
|
|||||||
: regionStyleStream
|
: regionStyleStream
|
||||||
.selectRarity(engine.getDimension().getRegions(), (i) -> data.getRegionLoader().load(i))
|
.selectRarity(engine.getDimension().getRegions(), (i) -> data.getRegionLoader().load(i))
|
||||||
.convertCached((s) -> data.getRegionLoader().load(s)).cache2D(cacheSize);
|
.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));
|
regionIDStream = regionIdentityStream.convertCached((i) -> new UUID(Double.doubleToLongBits(i), String.valueOf(i * 38445).hashCode() * 3245556666L));
|
||||||
caveBiomeStream = regionStream.convert((r)
|
caveBiomeStream = regionStream.convert((r)
|
||||||
-> engine.getDimension().getCaveBiomeStyle().create(rng.nextParallelRNG(InferredType.CAVE.ordinal()), getData()).stream()
|
-> engine.getDimension().getCaveBiomeStyle().create(rng.nextParallelRNG(InferredType.CAVE.ordinal()), getData()).stream()
|
||||||
@ -334,7 +323,6 @@ public class IrisComplex implements DataProvider {
|
|||||||
int heightf = (int) Math.round(getHeightStream().get(rx, rz));
|
int heightf = (int) Math.round(getHeightStream().get(rx, rz));
|
||||||
int m = heightf;
|
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)) {
|
if (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) {
|
||||||
m--;
|
m--;
|
||||||
|
|
||||||
@ -342,7 +330,6 @@ public class IrisComplex implements DataProvider {
|
|||||||
m--;
|
m--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (engine.getDimension().isCaves()) {
|
if (engine.getDimension().isCaves()) {
|
||||||
KList<CaveResult> caves = ((IrisCaveModifier) engine.getCaveModifier()).genCaves(rx, rz, 0, 0, null);
|
KList<CaveResult> caves = ((IrisCaveModifier) engine.getCaveModifier()).genCaves(rx, rz, 0, 0, null);
|
||||||
@ -367,27 +354,9 @@ public class IrisComplex implements DataProvider {
|
|||||||
d.hashCode());
|
d.hashCode());
|
||||||
})
|
})
|
||||||
.cache2D(cacheSize);
|
.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
|
//@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) {
|
private IrisRegion findRegion(IrisBiome focus, Engine engine) {
|
||||||
for (IrisRegion i : engine.getDimension().getAllRegions(engine)) {
|
for (IrisRegion i : engine.getDimension().getAllRegions(engine)) {
|
||||||
if (i.getAllBiomeIds().contains(focus.getLoadKey())) {
|
if (i.getAllBiomeIds().contains(focus.getLoadKey())) {
|
||||||
|
@ -26,7 +26,6 @@ import com.volmit.iris.core.events.IrisEngineHotloadEvent;
|
|||||||
import com.volmit.iris.core.service.PreservationSVC;
|
import com.volmit.iris.core.service.PreservationSVC;
|
||||||
import com.volmit.iris.engine.actuator.IrisBiomeActuator;
|
import com.volmit.iris.engine.actuator.IrisBiomeActuator;
|
||||||
import com.volmit.iris.engine.actuator.IrisDecorantActuator;
|
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.actuator.IrisTerrainNormalActuator;
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
import com.volmit.iris.engine.framework.*;
|
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.io.IO;
|
||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.math.RNG;
|
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.ChronoLatch;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
@ -96,8 +96,7 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
private double maxBiomeLayerDensity;
|
private double maxBiomeLayerDensity;
|
||||||
private double maxBiomeDecoratorDensity;
|
private double maxBiomeDecoratorDensity;
|
||||||
private IrisComplex complex;
|
private IrisComplex complex;
|
||||||
private EngineActuator<BlockData> terrainNormalActuator;
|
private EngineActuator<BlockData> terrainActuator;
|
||||||
private EngineActuator<BlockData> terrainIslandActuator;
|
|
||||||
private EngineActuator<BlockData> decorantActuator;
|
private EngineActuator<BlockData> decorantActuator;
|
||||||
private EngineActuator<Biome> biomeActuator;
|
private EngineActuator<Biome> biomeActuator;
|
||||||
private EngineModifier<BlockData> depositModifier;
|
private EngineModifier<BlockData> depositModifier;
|
||||||
@ -132,6 +131,7 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
closed = false;
|
closed = false;
|
||||||
art = J.ar(this::tickRandomPlayer, 0);
|
art = J.ar(this::tickRandomPlayer, 0);
|
||||||
setupEngine();
|
setupEngine();
|
||||||
|
Iris.debug("Engine Initialized " + getCacheID());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tickRandomPlayer() {
|
private void tickRandomPlayer() {
|
||||||
@ -145,8 +145,7 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
worldManager.close();
|
worldManager.close();
|
||||||
complex.close();
|
complex.close();
|
||||||
execution.close();
|
execution.close();
|
||||||
terrainNormalActuator.close();
|
terrainActuator.close();
|
||||||
terrainIslandActuator.close();
|
|
||||||
decorantActuator.close();
|
decorantActuator.close();
|
||||||
biomeActuator.close();
|
biomeActuator.close();
|
||||||
depositModifier.close();
|
depositModifier.close();
|
||||||
@ -158,12 +157,14 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
|
|
||||||
private void setupEngine()
|
private void setupEngine()
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Iris.debug("Setup Engine " + getCacheID());
|
||||||
cacheId = RNG.r.nextInt();
|
cacheId = RNG.r.nextInt();
|
||||||
worldManager = new IrisWorldManager(this);
|
worldManager = new IrisWorldManager(this);
|
||||||
complex = new IrisComplex(this);
|
complex = new IrisComplex(this);
|
||||||
execution = new IrisExecutionEnvironment(this);
|
execution = new IrisExecutionEnvironment(this);
|
||||||
terrainNormalActuator = new IrisTerrainNormalActuator(this);
|
terrainActuator = new IrisTerrainNormalActuator(this);
|
||||||
terrainIslandActuator = new IrisTerrainIslandActuator(this);
|
|
||||||
decorantActuator = new IrisDecorantActuator(this);
|
decorantActuator = new IrisDecorantActuator(this);
|
||||||
biomeActuator = new IrisBiomeActuator(this);
|
biomeActuator = new IrisBiomeActuator(this);
|
||||||
depositModifier = new IrisDepositModifier(this);
|
depositModifier = new IrisDepositModifier(this);
|
||||||
@ -174,6 +175,15 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
J.a(this::computeBiomeMaxes);
|
J.a(this::computeBiomeMaxes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
catch(Throwable e)
|
||||||
|
{
|
||||||
|
Iris.error("FAILED TO SETUP ENGINE!");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
Iris.debug("Engine Setup Complete " + getCacheID());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void hotload() {
|
public void hotload() {
|
||||||
getData().dump();
|
getData().dump();
|
||||||
@ -374,13 +384,6 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public EngineActuator<BlockData> getTerrainActuator() {
|
|
||||||
return switch (getDimension().getTerrainMode()) {
|
|
||||||
case NORMAL -> getTerrainNormalActuator();
|
|
||||||
case ISLANDS -> getTerrainIslandActuator();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
@Override
|
@Override
|
||||||
public double modifyX(double x) {
|
public double modifyX(double x) {
|
||||||
@ -406,23 +409,24 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
try {
|
try {
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
Hunk<BlockData> blocks = vblocks.listen((xx, y, zz, t) -> catchBlockUpdates(x + xx, y + getMinHeight(), z + zz, t));
|
Hunk<BlockData> blocks = vblocks.listen((xx, y, zz, t) -> catchBlockUpdates(x + xx, y + getMinHeight(), z + zz, t));
|
||||||
|
|
||||||
switch (getDimension().getTerrainMode()) {
|
|
||||||
case NORMAL -> {
|
|
||||||
getMantle().generateMatter(x >> 4, z >> 4, multicore);
|
getMantle().generateMatter(x >> 4, z >> 4, multicore);
|
||||||
getTerrainActuator().actuate(x, z, vblocks, multicore);
|
|
||||||
getBiomeActuator().actuate(x, z, vbiomes, multicore);
|
burst().burst(multicore,
|
||||||
getCaveModifier().modify(x, z, vblocks, multicore);
|
() -> getTerrainActuator().actuate(x, z, vblocks, multicore),
|
||||||
getRavineModifier().modify(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);
|
getPostModifier().modify(x, z, vblocks, multicore);
|
||||||
getDecorantActuator().actuate(x, z, blocks, multicore);
|
|
||||||
getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore);
|
burst().burst(multicore,
|
||||||
getDepositModifier().modify(x, z, blocks, multicore);
|
() -> getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore),
|
||||||
}
|
() -> getDepositModifier().modify(x, z, vblocks, multicore)
|
||||||
case ISLANDS -> {
|
);
|
||||||
getTerrainActuator().actuate(x, z, vblocks, multicore);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getMetrics().getTotal().put(p.getMilliseconds());
|
getMetrics().getTotal().put(p.getMilliseconds());
|
||||||
generated.incrementAndGet();
|
generated.incrementAndGet();
|
||||||
|
@ -18,7 +18,9 @@
|
|||||||
|
|
||||||
package com.volmit.iris.engine;
|
package com.volmit.iris.engine;
|
||||||
|
|
||||||
|
import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
|
||||||
import com.volmit.iris.Iris;
|
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.framework.Engine;
|
||||||
import com.volmit.iris.engine.mantle.EngineMantle;
|
import com.volmit.iris.engine.mantle.EngineMantle;
|
||||||
import com.volmit.iris.engine.mantle.MantleComponent;
|
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.mantle.components.MantleObjectComponent;
|
||||||
import com.volmit.iris.engine.object.biome.IrisBiome;
|
import com.volmit.iris.engine.object.biome.IrisBiome;
|
||||||
import com.volmit.iris.engine.object.deposits.IrisDepositGenerator;
|
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.feature.IrisFeaturePotential;
|
||||||
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement;
|
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement;
|
||||||
import com.volmit.iris.engine.object.objects.IrisObject;
|
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.KList;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.collection.KSet;
|
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.format.Form;
|
||||||
import com.volmit.iris.util.mantle.Mantle;
|
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.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 lombok.Data;
|
||||||
import org.bukkit.util.BlockVector;
|
import org.bukkit.util.BlockVector;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@ -53,12 +62,13 @@ public class IrisEngineMantle implements EngineMantle {
|
|||||||
private final Engine engine;
|
private final Engine engine;
|
||||||
private final Mantle mantle;
|
private final Mantle mantle;
|
||||||
private final KList<MantleComponent> components;
|
private final KList<MantleComponent> components;
|
||||||
private final CompletableFuture<Integer> radius;
|
private final int radius;
|
||||||
|
private final AtomicCache<Integer> radCache = new AtomicCache<>();
|
||||||
|
|
||||||
public IrisEngineMantle(Engine engine) {
|
public IrisEngineMantle(Engine engine) {
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
this.mantle = new Mantle(new File(engine.getWorld().worldFolder(), "mantle"), engine.getTarget().getHeight());
|
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<>();
|
components = new KList<>();
|
||||||
registerComponent(new MantleFeatureComponent(this));
|
registerComponent(new MantleFeatureComponent(this));
|
||||||
registerComponent(new MantleJigsawComponent(this));
|
registerComponent(new MantleJigsawComponent(this));
|
||||||
|
@ -211,7 +211,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
.shuffleCopy(RNG.r).stream()
|
.shuffleCopy(RNG.r).stream()
|
||||||
.filter(this::canSpawn),
|
.filter(this::canSpawn),
|
||||||
getData().getSpawnerLoader().streamAll(getEngine().getMantle()
|
getData().getSpawnerLoader().streamAll(getEngine().getMantle()
|
||||||
.getFeaturesInChunk(c).stream()
|
.forEachFeature(c).stream()
|
||||||
.flatMap((o) -> o.getFeature().getEntitySpawners().stream()))
|
.flatMap((o) -> o.getFeature().getEntitySpawners().stream()))
|
||||||
.filter(this::canSpawn))
|
.filter(this::canSpawn))
|
||||||
.filter((i) -> i.isValid(biome))
|
.filter((i) -> i.isValid(biome))
|
||||||
@ -294,6 +294,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
private KList<IrisEntitySpawn> spawnRandomly(List<IrisEntitySpawn> types) {
|
private KList<IrisEntitySpawn> spawnRandomly(List<IrisEntitySpawn> types) {
|
||||||
KList<IrisEntitySpawn> rarityTypes = new KList<>();
|
KList<IrisEntitySpawn> rarityTypes = new KList<>();
|
||||||
int totalRarity = 0;
|
int totalRarity = 0;
|
||||||
|
|
||||||
for (IrisEntitySpawn i : types) {
|
for (IrisEntitySpawn i : types) {
|
||||||
totalRarity += IRare.get(i);
|
totalRarity += IRare.get(i);
|
||||||
}
|
}
|
||||||
@ -344,7 +345,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
public void onChunkLoad(Chunk e, boolean generated) {
|
public void onChunkLoad(Chunk e, boolean generated) {
|
||||||
if (generated) {
|
if (generated) {
|
||||||
energy += 1.2;
|
energy += 1.2;
|
||||||
spawnIn(e, true);
|
J.a(() -> spawnIn(e, true), RNG.r.i(5, 50));
|
||||||
} else {
|
} else {
|
||||||
energy += 0.3;
|
energy += 0.3;
|
||||||
}
|
}
|
||||||
|
@ -68,8 +68,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator<Biome> {
|
|||||||
@Override
|
@Override
|
||||||
public void onActuate(int x, int z, Hunk<Biome> h, boolean multicore) {
|
public void onActuate(int x, int z, Hunk<Biome> h, boolean multicore) {
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
BurstExecutor burst = burst().burst();
|
BurstExecutor burst = burst().burst(multicore);
|
||||||
burst.setMulticore(multicore);
|
|
||||||
|
|
||||||
for (int xf = 0; xf < h.getWidth(); xf++) {
|
for (int xf = 0; xf < h.getWidth(); xf++) {
|
||||||
int finalXf = xf;
|
int finalXf = xf;
|
||||||
|
@ -90,8 +90,7 @@ public class IrisDecorantActuator extends EngineAssignedActuator<BlockData> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
BurstExecutor burst = burst().burst();
|
BurstExecutor burst = burst().burst(multicore);
|
||||||
burst.setMulticore(multicore);
|
|
||||||
|
|
||||||
for (int i = 0; i < output.getWidth(); i++) {
|
for (int i = 0; i < output.getWidth(); i++) {
|
||||||
int finalI = i;
|
int finalI = i;
|
||||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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<BlockData> {
|
|
||||||
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<BlockData> h, boolean multicore) {
|
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
|
||||||
int i, zf, depth, surface, realX, realZ;
|
|
||||||
IrisBiome biome;
|
|
||||||
KList<BlockData> 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());
|
|
||||||
}
|
|
||||||
}
|
|
@ -55,8 +55,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<BlockData>
|
|||||||
public void onActuate(int x, int z, Hunk<BlockData> h, boolean multicore) {
|
public void onActuate(int x, int z, Hunk<BlockData> h, boolean multicore) {
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
|
|
||||||
BurstExecutor e = getEngine().burst().burst(h.getWidth());
|
BurstExecutor e = burst().burst(multicore);
|
||||||
e.setMulticore(multicore);
|
|
||||||
for (int xf = 0; xf < h.getWidth(); xf++) {
|
for (int xf = 0; xf < h.getWidth(); xf++) {
|
||||||
int finalXf = xf;
|
int finalXf = xf;
|
||||||
e.queue(() -> terrainSliver(x, z, finalXf, h));
|
e.queue(() -> terrainSliver(x, z, finalXf, h));
|
||||||
@ -67,70 +66,6 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<BlockData>
|
|||||||
getEngine().getMetrics().getTerrain().put(p.getMilliseconds());
|
getEngine().getMetrics().getTerrain().put(p.getMilliseconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateGround(int realX, int realZ, int xf, int zf, Hunk<BlockData> h, int surface, int bottom, int height, int fluidOrHeight, IrisBiome biome)
|
|
||||||
{
|
|
||||||
if(surface == bottom || surface-1 == bottom)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
KList<BlockData> blocks = null;
|
|
||||||
KList<BlockData> 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)
|
private int fluidOrHeight(int height)
|
||||||
{
|
{
|
||||||
return Math.max(getDimension().getFluidHeight(), height);
|
return Math.max(getDimension().getFluidHeight(), height);
|
||||||
@ -146,12 +81,12 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<BlockData>
|
|||||||
*/
|
*/
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
public void terrainSliver(int x, int z, int xf, Hunk<BlockData> h) {
|
public void terrainSliver(int x, int z, int xf, Hunk<BlockData> h) {
|
||||||
int i, realX, realZ, hf, he;
|
int zf, realX, realZ, hf, he;
|
||||||
IrisBiome biome;
|
IrisBiome biome;
|
||||||
|
|
||||||
for (i = 0; i < h.getDepth(); i++) {
|
for (zf = 0; zf < h.getDepth(); zf++) {
|
||||||
realX = (int) modX(xf + x);
|
realX = (int) modX(xf + x);
|
||||||
realZ = (int) modZ(i + z);
|
realZ = (int) modZ(zf + z);
|
||||||
biome = getComplex().getTrueBiomeStream().get(realX, realZ);
|
biome = getComplex().getTrueBiomeStream().get(realX, realZ);
|
||||||
he = (int) Math.round(Math.min(h.getHeight(), getComplex().getHeightStream().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));
|
hf = Math.round(Math.max(Math.min(h.getHeight(), getDimension().getFluidHeight()), he));
|
||||||
@ -160,7 +95,65 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<BlockData>
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
generateGround(realX, realZ, xf, i, h, hf, 0, he, hf, biome);
|
KList<BlockData> blocks = null;
|
||||||
|
KList<BlockData> 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package com.volmit.iris.engine.data.chunk;
|
package com.volmit.iris.engine.data.chunk;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.nms.BiomeBaseInjector;
|
import com.volmit.iris.core.nms.BiomeBaseInjector;
|
||||||
import com.volmit.iris.util.nbt.mca.Chunk;
|
import com.volmit.iris.util.nbt.mca.Chunk;
|
||||||
import com.volmit.iris.util.nbt.mca.NBTWorld;
|
import com.volmit.iris.util.nbt.mca.NBTWorld;
|
||||||
@ -69,7 +70,7 @@ public class MCATerrainChunk implements TerrainChunk {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBiome(int x, int y, int z, Biome bio) {
|
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
|
@Override
|
||||||
@ -91,6 +92,11 @@ public class MCATerrainChunk implements TerrainChunk {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(blockData == null)
|
||||||
|
{
|
||||||
|
Iris.error("NULL BD");
|
||||||
|
}
|
||||||
|
|
||||||
mcaChunk.setBlockStateAt(xx, y, zz, NBTWorld.getCompound(blockData), false);
|
mcaChunk.setBlockStateAt(xx, y, zz, NBTWorld.getCompound(blockData), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
|||||||
updateLighting(x, y, z, c);
|
updateLighting(x, y, z, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, MantleFlag.UPDATE);
|
});
|
||||||
getMetrics().getUpdates().put(p.getMilliseconds());
|
getMetrics().getUpdates().put(p.getMilliseconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,13 +434,6 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
|||||||
IrisDimension dim = getDimension();
|
IrisDimension dim = getDimension();
|
||||||
dim.getAllBiomes(this).forEach((i) -> v.put(i.getLoadKey(), i));
|
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();
|
return v.v();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package com.volmit.iris.engine.framework;
|
package com.volmit.iris.engine.framework;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.util.documentation.BlockCoordinates;
|
import com.volmit.iris.util.documentation.BlockCoordinates;
|
||||||
import com.volmit.iris.util.hunk.Hunk;
|
import com.volmit.iris.util.hunk.Hunk;
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package com.volmit.iris.engine.framework;
|
package com.volmit.iris.engine.framework;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.util.math.RollingSequence;
|
import com.volmit.iris.util.math.RollingSequence;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@ -28,6 +29,7 @@ public class EngineAssignedComponent implements EngineComponent {
|
|||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
public EngineAssignedComponent(Engine engine, String name) {
|
public EngineAssignedComponent(Engine engine, String name) {
|
||||||
|
Iris.debug("Engine: " + engine.getCacheID() + " Starting " + name);
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
this.metrics = new RollingSequence(16);
|
this.metrics = new RollingSequence(16);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package com.volmit.iris.engine.framework;
|
package com.volmit.iris.engine.framework;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.util.documentation.BlockCoordinates;
|
import com.volmit.iris.util.documentation.BlockCoordinates;
|
||||||
import com.volmit.iris.util.hunk.Hunk;
|
import com.volmit.iris.util.hunk.Hunk;
|
||||||
|
|
||||||
|
@ -36,9 +36,7 @@ public class EngineTarget {
|
|||||||
this.world = world;
|
this.world = world;
|
||||||
this.dimension = dimension;
|
this.dimension = dimension;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.burster = new MultiBurst("Iris Engine " + dimension.getName(),
|
this.burster = MultiBurst.burst;
|
||||||
IrisSettings.get().getConcurrency().getEngineThreadPriority(),
|
|
||||||
IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getEngineThreadCount()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHeight() {
|
public int getHeight() {
|
||||||
@ -46,6 +44,6 @@ public class EngineTarget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
burster.shutdownLater();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,9 +114,26 @@ public class PlannedStructure {
|
|||||||
int xx = i.getPosition().getX() + sx;
|
int xx = i.getPosition().getX() + sx;
|
||||||
int zz = i.getPosition().getZ() + sz;
|
int zz = i.getPosition().getZ() + sz;
|
||||||
int offset = i.getPosition().getY() - startHeight;
|
int offset = i.getPosition().getY() - startHeight;
|
||||||
int height = (i.getStructure().getStructure().getLockY() != -1
|
int height = 0;
|
||||||
? i.getStructure().getStructure().getLockY()
|
|
||||||
: placer.getHighest(xx, zz, getData())) + offset + (v.getH() / 2);
|
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()) {
|
if (options.getMode().equals(ObjectPlaceMode.PAINT) || options.isVacuum()) {
|
||||||
height = -1;
|
height = -1;
|
||||||
|
@ -34,6 +34,7 @@ import com.volmit.iris.util.documentation.ChunkCoordinates;
|
|||||||
import com.volmit.iris.util.hunk.Hunk;
|
import com.volmit.iris.util.hunk.Hunk;
|
||||||
import com.volmit.iris.util.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
import com.volmit.iris.util.mantle.MantleFlag;
|
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.BurstExecutor;
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
@ -41,11 +42,8 @@ import org.bukkit.Chunk;
|
|||||||
import org.bukkit.block.TileState;
|
import org.bukkit.block.TileState;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
// TODO: MOVE PLACER OUT OF MATTER INTO ITS OWN THING
|
// TODO: MOVE PLACER OUT OF MATTER INTO ITS OWN THING
|
||||||
@ -56,7 +54,7 @@ public interface EngineMantle extends IObjectPlacer {
|
|||||||
|
|
||||||
Engine getEngine();
|
Engine getEngine();
|
||||||
|
|
||||||
CompletableFuture<Integer> getRadius();
|
int getRadius();
|
||||||
|
|
||||||
KList<MantleComponent> getComponents();
|
KList<MantleComponent> getComponents();
|
||||||
|
|
||||||
@ -171,15 +169,7 @@ public interface EngineMantle extends IObjectPlacer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default int getRealRadius() {
|
default int getRealRadius() {
|
||||||
try {
|
return (int) Math.ceil(getRadius() / 2D);
|
||||||
return (int) Math.ceil(getRadius().get() / 2D);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -189,7 +179,6 @@ public interface EngineMantle extends IObjectPlacer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
|
||||||
KList<Runnable> post = new KList<>();
|
KList<Runnable> post = new KList<>();
|
||||||
Consumer<Runnable> c = (i) -> {
|
Consumer<Runnable> c = (i) -> {
|
||||||
synchronized (post)
|
synchronized (post)
|
||||||
@ -198,15 +187,14 @@ public interface EngineMantle extends IObjectPlacer {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
int s = getRealRadius();
|
int s = getRealRadius();
|
||||||
BurstExecutor burst = burst().burst();
|
BurstExecutor burst = burst().burst(multicore);
|
||||||
burst.setMulticore(multicore);
|
MantleWriter writer = getMantle().write(this, x, z, s * 2);
|
||||||
|
|
||||||
for (int i = -s; i <= s; i++) {
|
for (int i = -s; i <= s; i++) {
|
||||||
int xx = i + x;
|
|
||||||
for (int j = -s; j <= s; j++) {
|
for (int j = -s; j <= s; j++) {
|
||||||
|
int xx = i + x;
|
||||||
int zz = j + z;
|
int zz = j + z;
|
||||||
burst.queue(() -> {
|
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<Runnable> px = post.copy();
|
KList<Runnable> px = post.copy();
|
||||||
post.clear();
|
post.clear();
|
||||||
|
burst().burst(multicore, px);
|
||||||
if(multicore)
|
|
||||||
{
|
|
||||||
burst().burst(px);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
burst().sync(px);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default void generateMantleComponent(int x, int z, MantleComponent c, Consumer<Runnable> post) {
|
default void generateMantleComponent(MantleWriter writer, int x, int z, MantleComponent c, Consumer<Runnable> post) {
|
||||||
getMantle().raiseFlag(x, z, c.getFlag(), () -> c.generateLayer(x, z, post));
|
getMantle().raiseFlag(x, z, c.getFlag(), () -> c.generateLayer(writer, x, z, post));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
@ -245,20 +224,23 @@ public interface EngineMantle extends IObjectPlacer {
|
|||||||
|
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
default void updateBlock(int x, int y, int z) {
|
default void updateBlock(int x, int y, int z) {
|
||||||
getMantle().flag(x >> 4, z >> 4, MantleFlag.UPDATE, true);
|
|
||||||
getMantle().set(x, y, z, true);
|
getMantle().set(x, y, z, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
default KList<IrisFeaturePositional> getFeaturesInChunk(Chunk c) {
|
default List<IrisFeaturePositional> getFeaturesInChunk(Chunk c) {
|
||||||
return getFeaturesInChunk(c.getX(), c.getZ());
|
return getFeaturesInChunk(c.getX(), c.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
default KList<IrisFeaturePositional> getFeaturesInChunk(int x, int z) {
|
default List<IrisFeaturePositional> getFeaturesInChunk(int x, int z) {
|
||||||
KList<IrisFeaturePositional> pos = new KList<>();
|
return getMantle().getChunk(x, z).getFeatures();
|
||||||
getMantle().iterateChunk(x, z, IrisFeaturePositional.class, (a, b, c, f) -> pos.add(f), MantleFlag.FEATURE);
|
}
|
||||||
return pos;
|
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
default KList<IrisFeaturePositional> forEachFeature(Chunk c) {
|
||||||
|
return forEachFeature((c.getX() << 4) + 8, (c.getZ() << 4) + 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
@ -283,7 +265,7 @@ public interface EngineMantle extends IObjectPlacer {
|
|||||||
for (i = -s; i <= s; i++) {
|
for (i = -s; i <= s; i++) {
|
||||||
for (j = -s; j <= s; j++) {
|
for (j = -s; j <= s; j++) {
|
||||||
try {
|
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())) {
|
if (k.shouldFilter(x, z, getEngine().getComplex().getRng(), getData())) {
|
||||||
pos.add(k);
|
pos.add(k);
|
||||||
}
|
}
|
||||||
|
@ -62,5 +62,5 @@ public interface MantleComponent {
|
|||||||
MantleFlag getFlag();
|
MantleFlag getFlag();
|
||||||
|
|
||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
void generateLayer(int x, int z, Consumer<Runnable> post);
|
void generateLayer(MantleWriter writer, int x, int z, Consumer<Runnable> post);
|
||||||
}
|
}
|
||||||
|
149
src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java
Normal file
149
src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<Long, MantleChunk> 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 <T> 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);
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@ package com.volmit.iris.engine.mantle.components;
|
|||||||
import com.volmit.iris.engine.data.cache.Cache;
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
import com.volmit.iris.engine.mantle.EngineMantle;
|
import com.volmit.iris.engine.mantle.EngineMantle;
|
||||||
import com.volmit.iris.engine.mantle.IrisMantleComponent;
|
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.biome.IrisBiome;
|
||||||
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
|
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
|
||||||
import com.volmit.iris.engine.object.feature.IrisFeaturePotential;
|
import com.volmit.iris.engine.object.feature.IrisFeaturePotential;
|
||||||
@ -38,34 +39,34 @@ public class MantleFeatureComponent extends IrisMantleComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateLayer(int x, int z, Consumer<Runnable> post) {
|
public void generateLayer(MantleWriter writer, int x, int z, Consumer<Runnable> post) {
|
||||||
RNG rng = new RNG(Cache.key(x, z) + seed());
|
RNG rng = new RNG(Cache.key(x, z) + seed());
|
||||||
int xxx = 8 + (x << 4);
|
int xxx = 8 + (x << 4);
|
||||||
int zzz = 8 + (z << 4);
|
int zzz = 8 + (z << 4);
|
||||||
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
|
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
|
||||||
IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz);
|
IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz);
|
||||||
generateFeatures(rng, x, z, region, biome);
|
generateFeatures(writer, rng, x, z, region, biome);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ChunkCoordinates
|
@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()) {
|
for (IrisFeaturePotential i : getFeatures()) {
|
||||||
placeZone(rng, cx, cz, i);
|
placeZone(writer, rng, cx, cz, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IrisFeaturePotential i : region.getFeatures()) {
|
for (IrisFeaturePotential i : region.getFeatures()) {
|
||||||
placeZone(rng, cx, cz, i);
|
placeZone(writer, rng, cx, cz, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IrisFeaturePotential i : biome.getFeatures()) {
|
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 x = (cx << 4) + rng.nextInt(16);
|
||||||
int z = (cz << 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<IrisFeaturePotential> getFeatures() {
|
private KList<IrisFeaturePotential> getFeatures() {
|
||||||
|
@ -18,42 +18,47 @@
|
|||||||
|
|
||||||
package com.volmit.iris.engine.mantle.components;
|
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.jigsaw.PlannedStructure;
|
||||||
import com.volmit.iris.engine.mantle.EngineMantle;
|
import com.volmit.iris.engine.mantle.EngineMantle;
|
||||||
import com.volmit.iris.engine.mantle.IrisMantleComponent;
|
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.basic.IrisPosition;
|
||||||
import com.volmit.iris.engine.object.biome.IrisBiome;
|
import com.volmit.iris.engine.object.biome.IrisBiome;
|
||||||
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
|
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
|
||||||
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure;
|
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure;
|
||||||
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement;
|
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.engine.object.regional.IrisRegion;
|
||||||
import com.volmit.iris.util.documentation.BlockCoordinates;
|
import com.volmit.iris.util.documentation.BlockCoordinates;
|
||||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
import com.volmit.iris.util.mantle.MantleFlag;
|
import com.volmit.iris.util.mantle.MantleFlag;
|
||||||
import com.volmit.iris.util.math.Position2;
|
import com.volmit.iris.util.math.Position2;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
|
import com.volmit.iris.util.noise.CNG;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class MantleJigsawComponent extends IrisMantleComponent {
|
public class MantleJigsawComponent extends IrisMantleComponent {
|
||||||
|
private final CNG cng;
|
||||||
|
|
||||||
public MantleJigsawComponent(EngineMantle engineMantle) {
|
public MantleJigsawComponent(EngineMantle engineMantle) {
|
||||||
super(engineMantle, MantleFlag.JIGSAW);
|
super(engineMantle, MantleFlag.JIGSAW);
|
||||||
|
cng = NoiseStyle.STATIC.create(new RNG());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateLayer(int x, int z, Consumer<Runnable> post) {
|
public void generateLayer(MantleWriter writer, int x, int z, Consumer<Runnable> post) {
|
||||||
RNG rng = new RNG(Cache.key(x, z) + seed());
|
RNG rng = new RNG(cng.fit(-Integer.MAX_VALUE, Integer.MAX_VALUE, x, z));
|
||||||
int xxx = 8 + (x << 4);
|
int xxx = 8 + (x << 4);
|
||||||
int zzz = 8 + (z << 4);
|
int zzz = 8 + (z << 4);
|
||||||
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
|
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
|
||||||
IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().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
|
@ChunkCoordinates
|
||||||
private void generateJigsaw(RNG rng, int x, int z, IrisBiome biome, IrisRegion region, Consumer<Runnable> post) {
|
private void generateJigsaw(MantleWriter writer, RNG rng, int x, int z, IrisBiome biome, IrisRegion region, Consumer<Runnable> post) {
|
||||||
boolean placed = false;
|
boolean placed = false;
|
||||||
|
|
||||||
if (getDimension().getStronghold() != null) {
|
if (getDimension().getStronghold() != null) {
|
||||||
@ -63,7 +68,7 @@ public class MantleJigsawComponent extends IrisMantleComponent {
|
|||||||
for (Position2 pos : poss) {
|
for (Position2 pos : poss) {
|
||||||
if (x == pos.getX() >> 4 && z == pos.getZ() >> 4) {
|
if (x == pos.getX() >> 4 && z == pos.getZ() >> 4) {
|
||||||
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(getDimension().getStronghold());
|
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(getDimension().getStronghold());
|
||||||
place(pos.toIris(), structure, rng, post);
|
place(writer, pos.toIris(), structure, rng, post);
|
||||||
placed = true;
|
placed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +80,7 @@ public class MantleJigsawComponent extends IrisMantleComponent {
|
|||||||
if (rng.nextInt(i.getRarity()) == 0) {
|
if (rng.nextInt(i.getRarity()) == 0) {
|
||||||
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
|
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
|
||||||
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
|
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
|
||||||
place(position, structure, rng, post);
|
place(writer, position, structure, rng, post);
|
||||||
placed = true;
|
placed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,7 +91,7 @@ public class MantleJigsawComponent extends IrisMantleComponent {
|
|||||||
if (rng.nextInt(i.getRarity()) == 0) {
|
if (rng.nextInt(i.getRarity()) == 0) {
|
||||||
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
|
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
|
||||||
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
|
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
|
||||||
place(position, structure, rng, post);
|
place(writer, position, structure, rng, post);
|
||||||
placed = true;
|
placed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,23 +102,22 @@ public class MantleJigsawComponent extends IrisMantleComponent {
|
|||||||
if (rng.nextInt(i.getRarity()) == 0) {
|
if (rng.nextInt(i.getRarity()) == 0) {
|
||||||
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
|
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
|
||||||
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
|
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
|
||||||
place(position, structure, rng, post);
|
place(writer, position, structure, rng, post);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
private void place(IrisPosition position, IrisJigsawStructure structure, RNG rng, Consumer<Runnable> post) {
|
private void place(MantleWriter writer, IrisPosition position, IrisJigsawStructure structure, RNG rng, Consumer<Runnable> post) {
|
||||||
if (structure.getFeature() != null) {
|
if (structure.getFeature() != null) {
|
||||||
if (structure.getFeature().getBlockRadius() == 32) {
|
if (structure.getFeature().getBlockRadius() == 32) {
|
||||||
structure.getFeature().setBlockRadius((double) structure.getMaxDimension() / 3);
|
structure.getFeature().setBlockRadius((double) structure.getMaxDimension() / 3);
|
||||||
}
|
}
|
||||||
|
writer.setData(position.getX(), 0, position.getZ(),
|
||||||
getMantle().set(position.getX(), 0, position.getZ(),
|
|
||||||
new IrisFeaturePositional(position.getX(), position.getZ(), structure.getFeature()));
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.engine.data.cache.Cache;
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
import com.volmit.iris.engine.mantle.EngineMantle;
|
import com.volmit.iris.engine.mantle.EngineMantle;
|
||||||
import com.volmit.iris.engine.mantle.IrisMantleComponent;
|
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.biome.IrisBiome;
|
||||||
import com.volmit.iris.engine.object.feature.IrisFeature;
|
import com.volmit.iris.engine.object.feature.IrisFeature;
|
||||||
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
|
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
|
||||||
@ -42,21 +43,21 @@ public class MantleObjectComponent extends IrisMantleComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateLayer(int x, int z, Consumer<Runnable> post) {
|
public void generateLayer(MantleWriter writer, int x, int z, Consumer<Runnable> post) {
|
||||||
RNG rng = new RNG(Cache.key(x, z) + seed());
|
RNG rng = new RNG(Cache.key(x, z) + seed());
|
||||||
int xxx = 8 + (x << 4);
|
int xxx = 8 + (x << 4);
|
||||||
int zzz = 8 + (z << 4);
|
int zzz = 8 + (z << 4);
|
||||||
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
|
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
|
||||||
IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().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
|
@ChunkCoordinates
|
||||||
private void placeObjects(RNG rng, int x, int z, IrisBiome biome, IrisRegion region, Consumer<Runnable> post) {
|
private void placeObjects(MantleWriter writer, RNG rng, int x, int z, IrisBiome biome, IrisRegion region, Consumer<Runnable> post) {
|
||||||
for (IrisObjectPlacement i : biome.getSurfaceObjects()) {
|
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))) {
|
if (rng.chance(i.getChance() + rng.d(-0.005, 0.005)) && rng.chance(getComplex().getObjectChanceStream().get(x << 4, z << 4))) {
|
||||||
try {
|
try {
|
||||||
placeObject(rng, x << 4, z << 4, i, post);
|
placeObject(writer, rng, x << 4, z << 4, i, post);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
Iris.error("Failed to place objects in the following biome: " + biome.getName());
|
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()) {
|
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))) {
|
if (rng.chance(i.getChance() + rng.d(-0.005, 0.005)) && rng.chance(getComplex().getObjectChanceStream().get(x << 4, z << 4))) {
|
||||||
try {
|
try {
|
||||||
placeObject(rng, x << 4, z << 4, i, post);
|
placeObject(writer, rng, x << 4, z << 4, i, post);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
Iris.error("Failed to place objects in the following region: " + region.getName());
|
Iris.error("Failed to place objects in the following region: " + region.getName());
|
||||||
@ -83,7 +84,7 @@ public class MantleObjectComponent extends IrisMantleComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
private void placeObject(RNG rng, int x, int z, IrisObjectPlacement objectPlacement, Consumer<Runnable> post) {
|
private void placeObject(MantleWriter writer, RNG rng, int x, int z, IrisObjectPlacement objectPlacement, Consumer<Runnable> post) {
|
||||||
for (int i = 0; i < objectPlacement.getDensity(); i++) {
|
for (int i = 0; i < objectPlacement.getDensity(); i++) {
|
||||||
IrisObject v = objectPlacement.getScale().get(rng, objectPlacement.getObject(getComplex(), rng));
|
IrisObject v = objectPlacement.getScale().get(rng, objectPlacement.getObject(getComplex(), rng));
|
||||||
if (v == null) {
|
if (v == null) {
|
||||||
@ -94,8 +95,8 @@ public class MantleObjectComponent extends IrisMantleComponent {
|
|||||||
int id = rng.i(0, Integer.MAX_VALUE);
|
int id = rng.i(0, Integer.MAX_VALUE);
|
||||||
|
|
||||||
Runnable r = () -> {
|
Runnable r = () -> {
|
||||||
int h = v.place(xx, -1, zz, getEngineMantle(), objectPlacement, rng,
|
int h = v.place(xx, -1, zz, writer, objectPlacement, rng,
|
||||||
(b) -> getMantle().set(b.getX(), b.getY(), b.getZ(),
|
(b) -> writer.setData(b.getX(), b.getY(), b.getZ(),
|
||||||
v.getLoadKey() + "@" + id), null, getData());
|
v.getLoadKey() + "@" + id), null, getData());
|
||||||
|
|
||||||
if (objectPlacement.usesFeatures()) {
|
if (objectPlacement.usesFeatures()) {
|
||||||
@ -108,12 +109,12 @@ public class MantleObjectComponent extends IrisMantleComponent {
|
|||||||
f.setInterpolationRadius(objectPlacement.getVacuumInterpolationRadius());
|
f.setInterpolationRadius(objectPlacement.getVacuumInterpolationRadius());
|
||||||
f.setInterpolator(objectPlacement.getVacuumInterpolationMethod());
|
f.setInterpolator(objectPlacement.getVacuumInterpolationMethod());
|
||||||
f.setStrength(1D);
|
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()) {
|
for (IrisFeaturePotential j : objectPlacement.getAddFeatures()) {
|
||||||
if (j.hasZone(rng, xx >> 4, zz >> 4)) {
|
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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,20 +55,13 @@ public class IrisCaveModifier extends EngineAssignedModifier<BlockData> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
if (multicore) {
|
BurstExecutor e = burst().burst(multicore);
|
||||||
BurstExecutor e = getEngine().burst().burst(a.getWidth());
|
|
||||||
for (int i = 0; i < a.getWidth(); i++) {
|
for (int i = 0; i < a.getWidth(); i++) {
|
||||||
int finalI = i;
|
int finalI = i;
|
||||||
e.queue(() -> modifySliver(x, z, finalI, a));
|
e.queue(() -> modifySliver(x, z, finalI, a));
|
||||||
}
|
}
|
||||||
|
|
||||||
e.complete();
|
e.complete();
|
||||||
} else {
|
|
||||||
for (int i = 0; i < a.getWidth(); i++) {
|
|
||||||
modifySliver(x, z, i, a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getEngine().getMetrics().getCave().put(p.getMilliseconds());
|
getEngine().getMetrics().getCave().put(p.getMilliseconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +237,7 @@ public class IrisCaveModifier extends EngineAssignedModifier<BlockData> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean canAir(Material m, BlockData caveFluid) {
|
public boolean canAir(Material m, BlockData caveFluid) {
|
||||||
return (B.isSolid(m) ||
|
return (m.isSolid() ||
|
||||||
(B.isDecorant(m.createBlockData())) || m.equals(Material.AIR)
|
(B.isDecorant(m.createBlockData())) || m.equals(Material.AIR)
|
||||||
|| m.equals(caveFluid.getMaterial()) ||
|
|| m.equals(caveFluid.getMaterial()) ||
|
||||||
m.equals(B.getMaterial("CAVE_AIR")))
|
m.equals(B.getMaterial("CAVE_AIR")))
|
||||||
@ -256,6 +249,6 @@ public class IrisCaveModifier extends EngineAssignedModifier<BlockData> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean can(Material m) {
|
public boolean can(Material m) {
|
||||||
return B.isSolid(m) && !m.equals(Material.BEDROCK);
|
return m.isSolid() && !m.equals(Material.BEDROCK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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<BlockData> {
|
|
||||||
public static final BlockData CAVE_AIR = B.get("CAVE_AIR");
|
|
||||||
public static final BlockData AIR = B.get("AIR");
|
|
||||||
private static final KList<CaveResult> 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<BlockData> 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<BlockData> a) {
|
|
||||||
for (int j = 0; j < a.getDepth(); j++) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -54,8 +54,8 @@ public class IrisDepositModifier extends EngineAssignedModifier<BlockData> {
|
|||||||
RNG ro = rx.nextParallelRNG(x * x).nextParallelRNG(z * z);
|
RNG ro = rx.nextParallelRNG(x * x).nextParallelRNG(z * z);
|
||||||
IrisRegion region = getComplex().getRegionStream().get((x * 16) + 7, (z * 16) + 7);
|
IrisRegion region = getComplex().getRegionStream().get((x * 16) + 7, (z * 16) + 7);
|
||||||
IrisBiome biome = getComplex().getTrueBiomeStream().get((x * 16) + 7, (z * 16) + 7);
|
IrisBiome biome = getComplex().getTrueBiomeStream().get((x * 16) + 7, (z * 16) + 7);
|
||||||
BurstExecutor burst = burst().burst();
|
BurstExecutor burst = burst().burst(multicore);
|
||||||
burst.setMulticore(multicore);
|
|
||||||
for (IrisDepositGenerator k : getDimension().getDeposits()) {
|
for (IrisDepositGenerator k : getDimension().getDeposits()) {
|
||||||
burst.queue(() -> generate(k, terrain, ro, x, z, false));
|
burst.queue(() -> generate(k, terrain, ro, x, z, false));
|
||||||
}
|
}
|
||||||
|
@ -64,20 +64,15 @@ public class IrisPostModifier extends EngineAssignedModifier<BlockData> {
|
|||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
AtomicInteger i = new AtomicInteger();
|
AtomicInteger i = new AtomicInteger();
|
||||||
AtomicInteger j = new AtomicInteger();
|
AtomicInteger j = new AtomicInteger();
|
||||||
BurstExecutor burst = burst().burst();
|
|
||||||
burst.setMulticore(multicore);
|
|
||||||
Hunk<BlockData> sync = output.synchronize();
|
Hunk<BlockData> sync = output.synchronize();
|
||||||
for (i.set(0); i.get() < output.getWidth(); i.getAndIncrement()) {
|
for (i.set(0); i.get() < output.getWidth(); i.getAndIncrement()) {
|
||||||
burst.queue(() -> {
|
|
||||||
for (j.set(0); j.get() < output.getDepth(); j.getAndIncrement()) {
|
for (j.set(0); j.get() < output.getDepth(); j.getAndIncrement()) {
|
||||||
int ii = i.get();
|
int ii = i.get();
|
||||||
int jj = j.get();
|
int jj = j.get();
|
||||||
post(ii, jj, sync, ii + x, jj + z);
|
post(ii, jj, sync, ii + x, jj + z);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
burst.complete();
|
|
||||||
getEngine().getMetrics().getPost().put(p.getMilliseconds());
|
getEngine().getMetrics().getPost().put(p.getMilliseconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +54,10 @@ public class IrisPosition {
|
|||||||
public IrisPosition(Vector v) {
|
public IrisPosition(Vector v) {
|
||||||
this(v.getBlockX(), v.getBlockY(), v.getBlockZ());
|
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) {
|
public IrisPosition add(IrisPosition relativePosition) {
|
||||||
return new IrisPosition(relativePosition.x + x, relativePosition.y + y, relativePosition.z + z);
|
return new IrisPosition(relativePosition.x + x, relativePosition.y + y, relativePosition.z + z);
|
||||||
|
@ -48,8 +48,10 @@ import com.volmit.iris.util.data.B;
|
|||||||
import com.volmit.iris.util.data.DataProvider;
|
import com.volmit.iris.util.data.DataProvider;
|
||||||
import com.volmit.iris.util.data.VanillaBiomeMap;
|
import com.volmit.iris.util.data.VanillaBiomeMap;
|
||||||
import com.volmit.iris.util.inventorygui.RandomColor;
|
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.math.RNG;
|
||||||
import com.volmit.iris.util.noise.CNG;
|
import com.volmit.iris.util.noise.CNG;
|
||||||
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@ -696,4 +698,9 @@ public class IrisBiome extends IrisRegistrant implements IRare {
|
|||||||
public String getTypeName() {
|
public String getTypeName() {
|
||||||
return "Biome";
|
return "Biome";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanForErrors(JSONObject p, VolmitSender sender) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,8 @@ import com.volmit.iris.engine.object.annotations.*;
|
|||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.data.B;
|
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.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@ -193,17 +195,15 @@ public class IrisBlockData extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Integer.valueOf(string);
|
return Integer.parseInt(string);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable ignored) {
|
||||||
Iris.reportError(e);
|
// Checks
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Double.valueOf(string).intValue();
|
return Double.valueOf(string).intValue();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable ignored) {
|
||||||
Iris.reportError(e);
|
// Checks
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return string;
|
return string;
|
||||||
@ -218,4 +218,9 @@ public class IrisBlockData extends IrisRegistrant {
|
|||||||
public String getTypeName() {
|
public String getTypeName() {
|
||||||
return "Block";
|
return "Block";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanForErrors(JSONObject p, VolmitSender sender) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<IrisCave> 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<Vector> 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
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,8 @@
|
|||||||
package com.volmit.iris.engine.object.common;
|
package com.volmit.iris.engine.object.common;
|
||||||
|
|
||||||
import com.volmit.iris.core.project.loader.IrisRegistrant;
|
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.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
@ -48,4 +50,9 @@ public class IrisScript extends IrisRegistrant {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanForErrors(JSONObject p, VolmitSender sender) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,9 +50,11 @@ import com.volmit.iris.engine.object.villager.IrisVillagerOverride;
|
|||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.data.DataProvider;
|
import com.volmit.iris.util.data.DataProvider;
|
||||||
import com.volmit.iris.util.io.IO;
|
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.Position2;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import com.volmit.iris.util.noise.CNG;
|
import com.volmit.iris.util.noise.CNG;
|
||||||
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@ -81,13 +83,6 @@ public class IrisDimension extends IrisRegistrant {
|
|||||||
@Desc("The human readable name of this dimension")
|
@Desc("The human readable name of this dimension")
|
||||||
private String name = "A 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<IrisDimensionIndex> dimensionalComposite = new KList<>();
|
|
||||||
|
|
||||||
@Desc("Create an inverted dimension in the sky (like the nether)")
|
|
||||||
private IrisDimension sky = null;
|
|
||||||
|
|
||||||
@RegistryListResource(IrisJigsawStructure.class)
|
@RegistryListResource(IrisJigsawStructure.class)
|
||||||
@Desc("If defined, Iris will place the given jigsaw structure where minecraft should place the overworld stronghold.")
|
@Desc("If defined, Iris will place the given jigsaw structure where minecraft should place the overworld stronghold.")
|
||||||
private String stronghold;
|
private String stronghold;
|
||||||
@ -285,12 +280,6 @@ public class IrisDimension extends IrisRegistrant {
|
|||||||
@Desc("Change the size of regions")
|
@Desc("Change the size of regions")
|
||||||
private double regionZoom = 1;
|
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")
|
@Desc("Disable this to stop placing objects, entities, features & updates")
|
||||||
private boolean useMantle = true;
|
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) {
|
public CNG getCoordFracture(RNG rng, int signature) {
|
||||||
return coordFracture.aquire(() ->
|
return coordFracture.aquire(() ->
|
||||||
{
|
{
|
||||||
@ -560,4 +545,9 @@ public class IrisDimension extends IrisRegistrant {
|
|||||||
public String getTypeName() {
|
public String getTypeName() {
|
||||||
return "Dimension";
|
return "Dimension";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanForErrors(JSONObject p, VolmitSender sender) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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 = "";
|
|
||||||
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
@ -32,7 +32,9 @@ import com.volmit.iris.engine.object.meta.IrisEffect;
|
|||||||
import com.volmit.iris.engine.object.spawners.IrisSurface;
|
import com.volmit.iris.engine.object.spawners.IrisSurface;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.format.C;
|
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.math.RNG;
|
||||||
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
@ -380,4 +382,9 @@ public class IrisEntity extends IrisRegistrant {
|
|||||||
public String getTypeName() {
|
public String getTypeName() {
|
||||||
return "Entity";
|
return "Entity";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanForErrors(JSONObject p, VolmitSender sender) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
package com.volmit.iris.engine.object.feature;
|
package com.volmit.iris.engine.object.feature;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.project.loader.IrisData;
|
import com.volmit.iris.core.project.loader.IrisData;
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
import com.volmit.iris.engine.object.annotations.Desc;
|
import com.volmit.iris.engine.object.annotations.Desc;
|
||||||
@ -63,7 +64,18 @@ public class IrisFeaturePositional {
|
|||||||
private static double BLOCK = 1D / 256D; // TODO: WARNING HEIGHT
|
private static double BLOCK = 1D / 256D; // TODO: WARNING HEIGHT
|
||||||
|
|
||||||
public static IrisFeaturePositional read(DataInputStream s) throws IOException {
|
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 {
|
public void write(DataOutputStream s) throws IOException {
|
||||||
|
@ -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.IrisObjectPlacement;
|
||||||
import com.volmit.iris.engine.object.objects.ObjectPlaceMode;
|
import com.volmit.iris.engine.object.objects.ObjectPlaceMode;
|
||||||
import com.volmit.iris.util.collection.KList;
|
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.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@ -136,4 +138,9 @@ public class IrisJigsawPiece extends IrisRegistrant {
|
|||||||
public String getTypeName() {
|
public String getTypeName() {
|
||||||
return "Jigsaw Piece";
|
return "Jigsaw Piece";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanForErrors(JSONObject p, VolmitSender sender) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.RegistryListResource;
|
||||||
import com.volmit.iris.engine.object.annotations.Required;
|
import com.volmit.iris.engine.object.annotations.Required;
|
||||||
import com.volmit.iris.util.collection.KList;
|
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.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@ -54,4 +56,9 @@ public class IrisJigsawPool extends IrisRegistrant {
|
|||||||
public String getTypeName() {
|
public String getTypeName() {
|
||||||
return "Jigsaw Pool";
|
return "Jigsaw Pool";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanForErrors(JSONObject p, VolmitSender sender) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.data.cache.AtomicCache;
|
||||||
import com.volmit.iris.engine.object.annotations.*;
|
import com.volmit.iris.engine.object.annotations.*;
|
||||||
import com.volmit.iris.engine.object.feature.IrisFeature;
|
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.collection.KList;
|
||||||
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
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.")
|
@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;
|
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 int lockY = -1;
|
||||||
|
|
||||||
private transient AtomicCache<Integer> maxDimension = new AtomicCache<>();
|
private transient AtomicCache<Integer> maxDimension = new AtomicCache<>();
|
||||||
@ -144,4 +150,9 @@ public class IrisJigsawStructure extends IrisRegistrant {
|
|||||||
public String getTypeName() {
|
public String getTypeName() {
|
||||||
return "Jigsaw Structure";
|
return "Jigsaw Structure";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanForErrors(JSONObject p, VolmitSender sender) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.annotations.Required;
|
||||||
import com.volmit.iris.engine.object.meta.InventorySlotType;
|
import com.volmit.iris.engine.object.meta.InventorySlotType;
|
||||||
import com.volmit.iris.util.collection.KList;
|
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.math.RNG;
|
||||||
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@ -96,4 +98,9 @@ public class IrisLootTable extends IrisRegistrant {
|
|||||||
public String getTypeName() {
|
public String getTypeName() {
|
||||||
return "Loot";
|
return "Loot";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanForErrors(JSONObject p, VolmitSender sender) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.objects.IrisObjectReplace;
|
||||||
import com.volmit.iris.engine.object.regional.IrisRegion;
|
import com.volmit.iris.engine.object.regional.IrisRegion;
|
||||||
import com.volmit.iris.util.collection.KList;
|
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.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@ -113,4 +115,9 @@ public class IrisMod extends IrisRegistrant {
|
|||||||
public String getTypeName() {
|
public String getTypeName() {
|
||||||
return "Mod";
|
return "Mod";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanForErrors(JSONObject p, VolmitSender sender) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.Desc;
|
||||||
import com.volmit.iris.engine.object.annotations.Required;
|
import com.volmit.iris.engine.object.annotations.Required;
|
||||||
import com.volmit.iris.util.collection.KList;
|
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.math.RNG;
|
||||||
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.stream.ProceduralStream;
|
import com.volmit.iris.util.stream.ProceduralStream;
|
||||||
import com.volmit.iris.util.stream.interpolation.Interpolated;
|
import com.volmit.iris.util.stream.interpolation.Interpolated;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
@ -128,4 +130,9 @@ public class IrisExpression extends IrisRegistrant {
|
|||||||
public String getTypeName() {
|
public String getTypeName() {
|
||||||
return "Expression";
|
return "Expression";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanForErrors(JSONObject p, VolmitSender sender) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,10 @@ import com.volmit.iris.engine.object.common.IRare;
|
|||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.context.IrisContext;
|
import com.volmit.iris.util.context.IrisContext;
|
||||||
import com.volmit.iris.util.interpolation.IrisInterpolation;
|
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.math.RNG;
|
||||||
import com.volmit.iris.util.noise.CellGenerator;
|
import com.volmit.iris.util.noise.CellGenerator;
|
||||||
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@ -295,4 +297,9 @@ public class IrisGenerator extends IrisRegistrant {
|
|||||||
public String getTypeName() {
|
public String getTypeName() {
|
||||||
return "Generator";
|
return "Generator";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanForErrors(JSONObject p, VolmitSender sender) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,10 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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.Desc;
|
||||||
import com.volmit.iris.engine.object.annotations.MinNumber;
|
import com.volmit.iris.engine.object.annotations.MinNumber;
|
||||||
import com.volmit.iris.engine.object.annotations.Required;
|
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.IrisNoiseGenerator;
|
||||||
import com.volmit.iris.engine.object.noise.IrisStyledRange;
|
import com.volmit.iris.engine.object.noise.IrisStyledRange;
|
||||||
import com.volmit.iris.engine.object.noise.NoiseStyle;
|
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.Worm;
|
||||||
|
import com.volmit.iris.util.noise.WormIterator2;
|
||||||
|
import com.volmit.iris.util.noise.WormIterator3;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@ -38,14 +44,9 @@ import lombok.experimental.Accessors;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Desc("Generate worms")
|
@Desc("Generate worms")
|
||||||
@Data
|
@Data
|
||||||
public class IrisWormGenerator implements IRare {
|
public class IrisWorm {
|
||||||
@Required
|
|
||||||
@Desc("Typically a 1 in RARITY on a per chunk basis")
|
|
||||||
@MinNumber(1)
|
|
||||||
private int rarity = 15;
|
|
||||||
|
|
||||||
@Desc("The style used to determine the curvature of this worm")
|
@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.")
|
@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;
|
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)")
|
@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;
|
private int maxSegments = -1;
|
||||||
|
|
||||||
@Desc("The thickness of the worm over distance")
|
@Desc("The distance between segments")
|
||||||
private IrisStyledRange girth = new IrisStyledRange().setMin(3).setMax(7)
|
private IrisStyledRange segmentDistance = new IrisStyledRange().setMin(4).setMax(7)
|
||||||
.setStyle(new IrisGeneratorStyle(NoiseStyle.SIMPLEX));
|
.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<NoiseProvider> 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();
|
||||||
|
}
|
||||||
}
|
}
|
@ -31,10 +31,12 @@ import com.volmit.iris.util.collection.KList;
|
|||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.data.B;
|
import com.volmit.iris.util.data.B;
|
||||||
import com.volmit.iris.util.interpolation.IrisInterpolation;
|
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.AxisAlignedBB;
|
||||||
import com.volmit.iris.util.math.BlockPosition;
|
import com.volmit.iris.util.math.BlockPosition;
|
||||||
import com.volmit.iris.util.math.Position2;
|
import com.volmit.iris.util.math.Position2;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.scheduling.IrisLock;
|
import com.volmit.iris.util.scheduling.IrisLock;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -281,7 +283,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
this.h = din.readInt();
|
this.h = din.readInt();
|
||||||
this.d = din.readInt();
|
this.d = din.readInt();
|
||||||
if (!din.readUTF().equals("Iris V2 IOB;")) {
|
if (!din.readUTF().equals("Iris V2 IOB;")) {
|
||||||
throw new IOException("Not V2 Format");
|
return;
|
||||||
}
|
}
|
||||||
center = new BlockVector(w / 2, h / 2, d / 2);
|
center = new BlockVector(w / 2, h / 2, d / 2);
|
||||||
int s = din.readShort();
|
int s = din.readShort();
|
||||||
@ -994,4 +996,9 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
public String getTypeName() {
|
public String getTypeName() {
|
||||||
return "Object";
|
return "Object";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanForErrors(JSONObject p, VolmitSender sender) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,10 @@ import com.volmit.iris.util.collection.KSet;
|
|||||||
import com.volmit.iris.util.data.DataProvider;
|
import com.volmit.iris.util.data.DataProvider;
|
||||||
import com.volmit.iris.util.data.VanillaBiomeMap;
|
import com.volmit.iris.util.data.VanillaBiomeMap;
|
||||||
import com.volmit.iris.util.inventorygui.RandomColor;
|
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.math.RNG;
|
||||||
import com.volmit.iris.util.noise.CNG;
|
import com.volmit.iris.util.noise.CNG;
|
||||||
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@ -572,4 +574,9 @@ public class IrisRegion extends IrisRegistrant implements IRare {
|
|||||||
public String getTypeName() {
|
public String getTypeName() {
|
||||||
return "Region";
|
return "Region";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanForErrors(JSONObject p, VolmitSender sender) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.biome.IrisBiome;
|
||||||
import com.volmit.iris.engine.object.entity.IrisEntitySpawn;
|
import com.volmit.iris.engine.object.entity.IrisEntitySpawn;
|
||||||
import com.volmit.iris.util.collection.KList;
|
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.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@ -106,4 +108,9 @@ public class IrisSpawner extends IrisRegistrant {
|
|||||||
public String getTypeName() {
|
public String getTypeName() {
|
||||||
return "Spawner";
|
return "Spawner";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanForErrors(JSONObject p, VolmitSender sender) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadLock.acquire();
|
loadLock.acquire();
|
||||||
PrecisionStopwatch ps = PrecisionStopwatch.start();
|
|
||||||
TerrainChunk tc = TerrainChunk.create(world, biome);
|
TerrainChunk tc = TerrainChunk.create(world, biome);
|
||||||
Hunk<BlockData> blocks = Hunk.view((ChunkData) tc);
|
Hunk<BlockData> blocks = Hunk.view((ChunkData) tc);
|
||||||
Hunk<Biome> biomes = Hunk.view((BiomeGrid) tc);
|
Hunk<Biome> biomes = Hunk.view((BiomeGrid) tc);
|
||||||
|
@ -34,6 +34,7 @@ import com.volmit.iris.util.documentation.ChunkCoordinates;
|
|||||||
import com.volmit.iris.util.documentation.RegionCoordinates;
|
import com.volmit.iris.util.documentation.RegionCoordinates;
|
||||||
import com.volmit.iris.util.hunk.Hunk;
|
import com.volmit.iris.util.hunk.Hunk;
|
||||||
import com.volmit.iris.util.math.Position2;
|
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.MCAUtil;
|
||||||
import com.volmit.iris.util.nbt.mca.NBTWorld;
|
import com.volmit.iris.util.nbt.mca.NBTWorld;
|
||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||||
@ -58,18 +59,17 @@ public class HeadlessGenerator implements PlatformChunkGenerator {
|
|||||||
|
|
||||||
public HeadlessGenerator(HeadlessWorld world) {
|
public HeadlessGenerator(HeadlessWorld world) {
|
||||||
this.world = 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());
|
writer = new NBTWorld(world.getWorld().worldFolder());
|
||||||
engine = new IrisEngine(new EngineTarget(world.getWorld(), world.getDimension(), world.getDimension().getLoader()), isStudio());
|
engine = new IrisEngine(new EngineTarget(world.getWorld(), world.getDimension(), world.getDimension().getLoader()), isStudio());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
public void generateChunk(int x, int z) {
|
public void generateChunk(MCAFile file, int x, int z) {
|
||||||
try {
|
try {
|
||||||
int ox = x << 4;
|
int ox = x << 4;
|
||||||
int oz = z << 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()
|
TerrainChunk tc = MCATerrainChunk.builder()
|
||||||
.writer(writer).ox(ox).oz(oz).mcaChunk(chunk)
|
.writer(writer).ox(ox).oz(oz).mcaChunk(chunk)
|
||||||
.minHeight(world.getWorld().minHeight()).maxHeight(world.getWorld().maxHeight())
|
.minHeight(world.getWorld().minHeight()).maxHeight(world.getWorld().maxHeight())
|
||||||
@ -102,11 +102,12 @@ public class HeadlessGenerator implements PlatformChunkGenerator {
|
|||||||
@RegionCoordinates
|
@RegionCoordinates
|
||||||
public void generateRegion(int x, int z, PregenListener listener) {
|
public void generateRegion(int x, int z, PregenListener listener) {
|
||||||
BurstExecutor e = burst.burst(1024);
|
BurstExecutor e = burst.burst(1024);
|
||||||
|
MCAFile f = writer.getMCA(x, x);
|
||||||
PregenTask.iterateRegion(x, z, (ii, jj) -> e.queue(() -> {
|
PregenTask.iterateRegion(x, z, (ii, jj) -> e.queue(() -> {
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.onChunkGenerating(ii, jj);
|
listener.onChunkGenerating(ii, jj);
|
||||||
}
|
}
|
||||||
generateChunk(ii, jj);
|
generateChunk(f, ii, jj);
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.onChunkGenerated(ii, jj);
|
listener.onChunkGenerated(ii, jj);
|
||||||
}
|
}
|
||||||
@ -131,7 +132,6 @@ public class HeadlessGenerator implements PlatformChunkGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
burst.shutdownAndAwait();
|
|
||||||
getEngine().close();
|
getEngine().close();
|
||||||
writer.close();
|
writer.close();
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,10 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.core.IrisSettings;
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
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.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
@ -33,395 +36,201 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.bukkit.Material.*;
|
||||||
|
|
||||||
public class B {
|
public class B {
|
||||||
private static final Material AIR_MATERIAL = Material.AIR;
|
private static final Material AIR_MATERIAL = Material.AIR;
|
||||||
private static final BlockData AIR = AIR_MATERIAL.createBlockData();
|
private static final BlockData AIR = AIR_MATERIAL.createBlockData();
|
||||||
private static final KSet<String> nullBlockDataCache = new KSet<>();
|
private static final IntSet foliageCache = buildFoliageCache();
|
||||||
private static final KSet<String> nullMaterialCache = new KSet<>();
|
private static final IntSet decorantCache = buildDecorantCache();
|
||||||
private static final KMap<Material, Boolean> solidCache = new KMap<>();
|
private static final IntSet storageCache = buildStorageCache();
|
||||||
private static final KMap<Material, Boolean> updatableCache = new KMap<>();
|
private static final IntSet storageChestCache = buildStorageChestCache();
|
||||||
private static final KMap<Material, Boolean> foliageCache = new KMap<>();
|
private static final IntSet litCache = buildLitCache();
|
||||||
private static final KMap<Material, Boolean> litCache = new KMap<>();
|
|
||||||
private static final KMap<Material, Boolean> decorantCache = new KMap<>();
|
|
||||||
private static final KMap<Material, Boolean> storageCache = new KMap<>();
|
|
||||||
private static final KMap<Material, Boolean> storageChestCache = new KMap<>();
|
|
||||||
private static final KMap<String, BlockData> blockDataCache = new KMap<>();
|
private static final KMap<String, BlockData> blockDataCache = new KMap<>();
|
||||||
private static final KMap<String, Material> materialCache = new KMap<>();
|
private static final ChronoLatch clw = new ChronoLatch(1000);
|
||||||
|
|
||||||
public static boolean isWater(BlockData b) {
|
private static IntSet buildFoliageCache() {
|
||||||
return b.getMaterial().equals(Material.WATER);
|
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() {
|
private static IntSet buildDecorantCache() {
|
||||||
return AIR;
|
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) {
|
private static IntSet buildLitCache() {
|
||||||
Material mat = getMaterialOrNull(bdx);
|
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 IntSets.unmodifiable(b);
|
||||||
return mat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return AIR_MATERIAL;
|
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()));
|
||||||
|
|
||||||
|
return IntSets.unmodifiable(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Material getMaterialOrNull(String bdxx) {
|
private static IntSet buildStorageChestCache() {
|
||||||
String bx = bdxx.trim().toUpperCase();
|
IntSet b = new IntOpenHashSet(storageCache);
|
||||||
|
b.remove(SMOKER.ordinal());
|
||||||
|
b.remove(FURNACE.ordinal());
|
||||||
|
b.remove(BLAST_FURNACE.ordinal());
|
||||||
|
|
||||||
if (nullMaterialCache.contains(bx)) {
|
return IntSets.unmodifiable(b);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSolid(BlockData mat) {
|
|
||||||
return isSolid(mat.getMaterial());
|
|
||||||
}
|
|
||||||
|
|
||||||
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<String, String> 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<String, String> 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean canPlaceOnto(Material mat, Material onto) {
|
public static boolean canPlaceOnto(Material mat, Material onto) {
|
||||||
String key = mat.name() + "" + onto.name();
|
|
||||||
|
|
||||||
if (isFoliage(mat)) {
|
if (isFoliage(mat)) {
|
||||||
if (!isFoliagePlantable(onto)) {
|
if (!isFoliagePlantable(onto)) {
|
||||||
return false;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,86 +256,6 @@ public class B {
|
|||||||
return true;
|
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<BlockData> get(KList<String> find) {
|
|
||||||
KList<BlockData> 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) {
|
public static boolean isFoliagePlantable(BlockData d) {
|
||||||
return d.getMaterial().equals(Material.GRASS_BLOCK)
|
return d.getMaterial().equals(Material.GRASS_BLOCK)
|
||||||
|| d.getMaterial().equals(Material.ROOTED_DIRT)
|
|| d.getMaterial().equals(Material.ROOTED_DIRT)
|
||||||
@ -543,6 +272,207 @@ public class B {
|
|||||||
|| d.equals(Material.PODZOL);
|
|| 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<String, String> 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<String, String> 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<BlockData> get(KList<String> find) {
|
||||||
|
KList<BlockData> 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) {
|
public static boolean isFluid(BlockData d) {
|
||||||
return d.getMaterial().equals(Material.WATER) || d.getMaterial().equals(Material.LAVA);
|
return d.getMaterial().equals(Material.WATER) || d.getMaterial().equals(Material.LAVA);
|
||||||
}
|
}
|
||||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<T> extends StorageHunk<T> implements Hunk<T> {
|
||||||
|
private final Map<Integer, T> 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<T> iterateSync(Consumer4<Integer, Integer, Integer, T> c) {
|
||||||
|
synchronized(data)
|
||||||
|
{
|
||||||
|
int idx, z;
|
||||||
|
|
||||||
|
for (Map.Entry<Integer, T> 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<T> iterateSyncIO(Consumer4IO<Integer, Integer, Integer, T> c) throws IOException {
|
||||||
|
synchronized(data)
|
||||||
|
{
|
||||||
|
int idx, z;
|
||||||
|
|
||||||
|
for (Map.Entry<Integer, T> 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,8 +18,13 @@
|
|||||||
|
|
||||||
package com.volmit.iris.util.mantle;
|
package com.volmit.iris.util.mantle;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.engine.data.cache.Cache;
|
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.KMap;
|
||||||
import com.volmit.iris.util.collection.KSet;
|
import com.volmit.iris.util.collection.KSet;
|
||||||
import com.volmit.iris.util.documentation.BlockCoordinates;
|
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.C;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
import com.volmit.iris.util.function.Consumer4;
|
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.M;
|
||||||
|
import com.volmit.iris.util.math.PathInterpolation;
|
||||||
import com.volmit.iris.util.matter.Matter;
|
import com.volmit.iris.util.matter.Matter;
|
||||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||||
import com.volmit.iris.util.parallel.HyperLock;
|
import com.volmit.iris.util.parallel.HyperLock;
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Map;
|
import java.util.*;
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,10 +84,17 @@ public class Mantle {
|
|||||||
unload = new KSet<>();
|
unload = new KSet<>();
|
||||||
loadedRegions = new KMap<>();
|
loadedRegions = new KMap<>();
|
||||||
lastUse = 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());
|
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
|
@ChunkCoordinates
|
||||||
public void raiseFlag(int x, int z, MantleFlag flag, Runnable r) {
|
public void raiseFlag(int x, int z, MantleFlag flag, Runnable r) {
|
||||||
if (!hasFlag(x, z, flag)) {
|
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
|
@ChunkCoordinates
|
||||||
public void lowerFlag(int x, int z, MantleFlag flag, Runnable r) {
|
public void lowerFlag(int x, int z, MantleFlag flag, Runnable r) {
|
||||||
if (hasFlag(x, z, flag)) {
|
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
|
@ChunkCoordinates
|
||||||
public void flag(int x, int z, MantleFlag flag, boolean flagged) {
|
public void flag(int x, int z, MantleFlag flag, boolean flagged) {
|
||||||
get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).flag(flag, flagged);
|
get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).flag(flag, flagged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ChunkCoordinates
|
/**
|
||||||
public <T> void iterateChunk(int x, int z, Class<T> type, Consumer4<Integer, Integer, Integer, T> iterator, MantleFlag... requiredFlags) {
|
* Check very quickly if a tectonic plate exists via cached or the file system
|
||||||
for (MantleFlag i : requiredFlags) {
|
* @param x the x region coordinate
|
||||||
if (!hasFlag(x, z, i)) {
|
* @param z the z region coordinate
|
||||||
return;
|
* @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 <T> the type of data to iterate
|
||||||
|
*/
|
||||||
|
@ChunkCoordinates
|
||||||
|
public <T> void iterateChunk(int x, int z, Class<T> type, Consumer4<Integer, Integer, Integer, T> iterator) {
|
||||||
|
if(!hasTectonicPlate(x >> 5, z >> 5))
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).iterate(type, iterator);
|
get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).iterate(type, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ChunkCoordinates
|
/**
|
||||||
public <T> void iterateChunk(int x, int z, Class<T> type, Consumer4<Integer, Integer, Integer, T> iterator, BurstExecutor e, MantleFlag... requiredFlags) {
|
* Does this chunk have a flag on it?
|
||||||
for (MantleFlag i : requiredFlags) {
|
* @param x the x
|
||||||
if (!hasFlag(x, z, i)) {
|
* @param z the z
|
||||||
return;
|
* @param flag the flag to test
|
||||||
}
|
* @return true if it's flagged
|
||||||
}
|
*/
|
||||||
|
|
||||||
get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).iterate(type, iterator, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
public boolean hasFlag(int x, int z, MantleFlag flag) {
|
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);
|
return get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).isFlagged(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,12 +222,21 @@ public class Mantle {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
Matter matter = get((x >> 4) >> 5, (z >> 4) >> 5)
|
||||||
.getOrCreate((x >> 4) & 31, (z >> 4) & 31)
|
.getOrCreate((x >> 4) & 31, (z >> 4) & 31)
|
||||||
.getOrCreate(y >> 4);
|
.getOrCreate(y >> 4);
|
||||||
matter.slice(matter.getClass(t))
|
matter.slice(matter.getClass(t))
|
||||||
.set(x & 15, y & 15, z & 15, t);
|
.set(x & 15, y & 15, z & 15, t);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the data tat the current block position This method will attempt to find a
|
* Gets the data tat the current block position This method will attempt to find a
|
||||||
@ -180,7 +260,12 @@ public class Mantle {
|
|||||||
throw new RuntimeException("The Mantle is closed");
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,6 +275,10 @@ public class Mantle {
|
|||||||
.get(x & 15, y & 15, z & 15);
|
.get(x & 15, y & 15, z & 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this mantle closed
|
||||||
|
* @return true if it is
|
||||||
|
*/
|
||||||
public boolean isClosed()
|
public boolean isClosed()
|
||||||
{
|
{
|
||||||
return closed.get();
|
return closed.get();
|
||||||
@ -228,7 +317,6 @@ public class Mantle {
|
|||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
ioBurst.shutdownNow();
|
|
||||||
Iris.debug("The Mantle has Closed " + C.DARK_AQUA + dataFolder.getAbsolutePath());
|
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.
|
* @return the future of a tectonic plate.
|
||||||
*/
|
*/
|
||||||
@RegionCoordinates
|
@RegionCoordinates
|
||||||
private CompletableFuture<TectonicPlate> getSafe(int x, int z) {
|
private Future<TectonicPlate> getSafe(int x, int z) {
|
||||||
Long k = key(x, z);
|
Long k = key(x, z);
|
||||||
TectonicPlate p = loadedRegions.get(k);
|
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) {
|
public static File fileForRegion(File folder, int x, int z) {
|
||||||
return fileForRegion(folder, key(x, 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) {
|
public static File fileForRegion(File folder, Long key) {
|
||||||
String id = UUID.nameUUIDFromBytes(("TectonicPlate:" + key).getBytes(StandardCharsets.UTF_8)).toString();
|
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");
|
File f = new File(folder, id.substring(0, 2) + "/" + id.split("\\Q-\\E")[3] + "/" + id + ".ttp");
|
||||||
|
if(!f.getParentFile().exists())
|
||||||
|
{
|
||||||
f.getParentFile().mkdirs();
|
f.getParentFile().mkdirs();
|
||||||
|
}
|
||||||
return f;
|
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) {
|
public static Long key(int x, int z) {
|
||||||
return Cache.key(x, z);
|
return Cache.key(x, z);
|
||||||
}
|
}
|
||||||
@ -385,4 +495,440 @@ public class Mantle {
|
|||||||
public void saveAll() {
|
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 <T> the type of data to apply to the mantle
|
||||||
|
*/
|
||||||
|
public <T> 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 <T> the type of data to apply to the mantle
|
||||||
|
*/
|
||||||
|
public <T> 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 <T> the type of data to apply to the mantle
|
||||||
|
*/
|
||||||
|
public <T> 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 <T> the type of data to apply to the mantle
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
public <T> 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 <T> void setSpline(List<Vector> 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 <T> the type of data to apply to the mantle
|
||||||
|
*/
|
||||||
|
public <T> void setSpline(List<Vector> nodevectors, double tension, double bias, double continuity, double quality, double radius, boolean filled, T data) {
|
||||||
|
Set<IrisPosition> vset = new KSet<>();
|
||||||
|
List<INode> 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 <T> the type of data to apply to the mantle
|
||||||
|
*/
|
||||||
|
public <T> 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 <T> the type of data to apply to the mantle
|
||||||
|
*/
|
||||||
|
public <T> void setLine(List<IrisPosition> vectors, double radius, boolean filled, T data) {
|
||||||
|
Set<IrisPosition> 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 <T> 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 <T> 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 <T> void set(IrisPosition pos, T data)
|
||||||
|
{
|
||||||
|
set(pos.getX(), pos.getY(), pos.getZ(), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> void set(List<IrisPosition> positions, T data)
|
||||||
|
{
|
||||||
|
for(IrisPosition i : positions)
|
||||||
|
{
|
||||||
|
set(i, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> void set(Set<IrisPosition> positions, T data)
|
||||||
|
{
|
||||||
|
for(IrisPosition i : positions)
|
||||||
|
{
|
||||||
|
set(i, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<IrisPosition> getBallooned(Set<IrisPosition> vset, double radius) {
|
||||||
|
Set<IrisPosition> 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<IrisPosition> getHollowed(Set<IrisPosition> vset) {
|
||||||
|
Set<IrisPosition> 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,17 +18,22 @@
|
|||||||
|
|
||||||
package com.volmit.iris.util.mantle;
|
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.documentation.ChunkCoordinates;
|
||||||
import com.volmit.iris.util.function.Consumer4;
|
import com.volmit.iris.util.function.Consumer4;
|
||||||
import com.volmit.iris.util.matter.IrisMatter;
|
import com.volmit.iris.util.matter.IrisMatter;
|
||||||
import com.volmit.iris.util.matter.Matter;
|
import com.volmit.iris.util.matter.Matter;
|
||||||
import com.volmit.iris.util.matter.MatterSlice;
|
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.BurstExecutor;
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.atomic.AtomicIntegerArray;
|
import java.util.concurrent.atomic.AtomicIntegerArray;
|
||||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||||
|
|
||||||
@ -37,8 +42,10 @@ import java.util.concurrent.atomic.AtomicReferenceArray;
|
|||||||
* Mantle Chunks are fully atomic & thread safe
|
* Mantle Chunks are fully atomic & thread safe
|
||||||
*/
|
*/
|
||||||
public class MantleChunk {
|
public class MantleChunk {
|
||||||
|
private static final ZoneMatter zm = new ZoneMatter();
|
||||||
private final AtomicIntegerArray flags;
|
private final AtomicIntegerArray flags;
|
||||||
private final AtomicReferenceArray<Matter> sections;
|
private final AtomicReferenceArray<Matter> sections;
|
||||||
|
private final CopyOnWriteArrayList<IrisFeaturePositional> features;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a mantle chunk
|
* Create a mantle chunk
|
||||||
@ -49,6 +56,7 @@ public class MantleChunk {
|
|||||||
public MantleChunk(int sectionHeight) {
|
public MantleChunk(int sectionHeight) {
|
||||||
sections = new AtomicReferenceArray<>(sectionHeight);
|
sections = new AtomicReferenceArray<>(sectionHeight);
|
||||||
flags = new AtomicIntegerArray(MantleFlag.values().length);
|
flags = new AtomicIntegerArray(MantleFlag.values().length);
|
||||||
|
features = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
for (int i = 0; i < flags.length(); i++) {
|
for (int i = 0; i < flags.length(); i++) {
|
||||||
flags.set(i, 0);
|
flags.set(i, 0);
|
||||||
@ -76,6 +84,13 @@ public class MantleChunk {
|
|||||||
sections.set(i, Matter.read(din));
|
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) {
|
public void flag(MantleFlag flag, boolean f) {
|
||||||
@ -169,6 +184,13 @@ public class MantleChunk {
|
|||||||
dos.writeBoolean(false);
|
dos.writeBoolean(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dos.writeShort(features.size());
|
||||||
|
|
||||||
|
for(IrisFeaturePositional i : features)
|
||||||
|
{
|
||||||
|
zm.writeNode(i, dos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void trimSlice(int i) {
|
private void trimSlice(int i) {
|
||||||
@ -186,26 +208,6 @@ public class MantleChunk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void iterate(Class<T> type, Consumer4<Integer, Integer, Integer, T> 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> t = matter.getSlice(type);
|
|
||||||
|
|
||||||
if (t != null) {
|
|
||||||
t.iterateSync((a, b, c, f) -> iterator.accept(a, b + bs, c, f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
burst.complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> void iterate(Class<T> type, Consumer4<Integer, Integer, Integer, T> iterator) {
|
public <T> void iterate(Class<T> type, Consumer4<Integer, Integer, Integer, T> iterator) {
|
||||||
for (int i = 0; i < sections.length(); i++) {
|
for (int i = 0; i < sections.length(); i++) {
|
||||||
int bs = (i << 4);
|
int bs = (i << 4);
|
||||||
@ -220,4 +222,12 @@ public class MantleChunk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addFeature(IrisFeaturePositional t) {
|
||||||
|
features.add(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IrisFeaturePositional> getFeatures() {
|
||||||
|
return features;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,11 @@
|
|||||||
package com.volmit.iris.util.mantle;
|
package com.volmit.iris.util.mantle;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
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.documentation.ChunkCoordinates;
|
||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
|
import com.volmit.iris.util.hunk.storage.ArrayHunk;
|
||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
@ -140,7 +142,7 @@ public class TectonicPlate {
|
|||||||
|
|
||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
private int index(int x, int z) {
|
private int index(int x, int z) {
|
||||||
return (x & 0x1F) + (z & 0x1F) * 32;
|
return Cache.to1D(x, z, 0, 32, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,14 +16,32 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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")
|
@Data
|
||||||
public enum IrisTerrainMode {
|
public class INode {
|
||||||
@Desc("Normal terrain, similar to the vanilla overworld")
|
|
||||||
NORMAL,
|
private Vector position;
|
||||||
@Desc("Island terrain, more similar to the end, but endless possibilities!")
|
private double tension;
|
||||||
ISLANDS
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<INode> 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<INode> 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<INode> 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 ∫<sub>a</sub><sup style="position: relative; left: -1ex">b</sup>|f'(t)| dt.<br />
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
}
|
@ -27,6 +27,7 @@ import com.volmit.iris.util.hunk.Hunk;
|
|||||||
import com.volmit.iris.util.math.BlockPosition;
|
import com.volmit.iris.util.math.BlockPosition;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.craftbukkit.v1_17_R1.block.data.type.CraftLeaves;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
@ -189,7 +190,16 @@ public interface Matter {
|
|||||||
slice = (MatterSlice<T>) createSlice(c, this);
|
slice = (MatterSlice<T>) createSlice(c, this);
|
||||||
|
|
||||||
if (slice == null) {
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package com.volmit.iris.util.matter.slices;
|
package com.volmit.iris.util.matter.slices;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
|
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
|
||||||
import com.volmit.iris.util.matter.Sliced;
|
import com.volmit.iris.util.matter.Sliced;
|
||||||
|
|
||||||
|
@ -225,7 +225,7 @@ public class Chunk {
|
|||||||
* @param blockZ The z-coordinate of the block.
|
* @param blockZ The z-coordinate of the block.
|
||||||
* @return The biome id or -1 if the biomes are not correctly initialized.
|
* @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 (dataVersion < 2202) {
|
||||||
if (biomes == null || biomes.length != 256) {
|
if (biomes == null || biomes.length != 256) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -244,7 +244,7 @@ public class Chunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void setBiomeAt(int blockX, int blockZ, int biomeID) {
|
public synchronized void setBiomeAt(int blockX, int blockZ, int biomeID) {
|
||||||
if (dataVersion < 2202) {
|
if (dataVersion < 2202) {
|
||||||
if (biomes == null || biomes.length != 256) {
|
if (biomes == null || biomes.length != 256) {
|
||||||
biomes = new int[256];
|
biomes = new int[256];
|
||||||
@ -275,7 +275,7 @@ public class Chunk {
|
|||||||
* @param biomeID The biome id to be set.
|
* @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.
|
* 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 (dataVersion < 2202) {
|
||||||
if (biomes == null || biomes.length != 256) {
|
if (biomes == null || biomes.length != 256) {
|
||||||
biomes = new int[256];
|
biomes = new int[256];
|
||||||
|
@ -27,6 +27,7 @@ import com.volmit.iris.util.format.C;
|
|||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||||
import com.volmit.iris.util.nbt.tag.StringTag;
|
import com.volmit.iris.util.nbt.tag.StringTag;
|
||||||
|
import com.volmit.iris.util.parallel.HyperLock;
|
||||||
import com.volmit.iris.util.scheduling.IrisLock;
|
import com.volmit.iris.util.scheduling.IrisLock;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
@ -43,8 +44,8 @@ public class NBTWorld {
|
|||||||
private static final BlockData AIR = B.get("AIR");
|
private static final BlockData AIR = B.get("AIR");
|
||||||
private static final Map<String, CompoundTag> blockDataCache = new KMap<>();
|
private static final Map<String, CompoundTag> blockDataCache = new KMap<>();
|
||||||
private static final Map<Biome, Integer> biomeIds = computeBiomeIDs();
|
private static final Map<Biome, Integer> biomeIds = computeBiomeIDs();
|
||||||
private final IrisLock regionLock = new IrisLock("Region");
|
|
||||||
private final KMap<Long, MCAFile> loadedRegions;
|
private final KMap<Long, MCAFile> loadedRegions;
|
||||||
|
private final HyperLock hyperLock = new HyperLock();
|
||||||
private final KMap<Long, Long> lastUse;
|
private final KMap<Long, Long> lastUse;
|
||||||
private final File worldFolder;
|
private final File worldFolder;
|
||||||
private final ExecutorService saveQueue;
|
private final ExecutorService saveQueue;
|
||||||
@ -62,13 +63,11 @@ public class NBTWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
regionLock.lock();
|
|
||||||
|
|
||||||
for (Long i : loadedRegions.k()) {
|
for (Long i : loadedRegions.k()) {
|
||||||
queueSaveUnload(Cache.keyX(i), Cache.keyZ(i));
|
queueSaveUnload(Cache.keyX(i), Cache.keyZ(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
regionLock.unlock();
|
|
||||||
saveQueue.shutdown();
|
saveQueue.shutdown();
|
||||||
try {
|
try {
|
||||||
while (!saveQueue.awaitTermination(3, TimeUnit.SECONDS)) {
|
while (!saveQueue.awaitTermination(3, TimeUnit.SECONDS)) {
|
||||||
@ -80,13 +79,9 @@ public class NBTWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void flushNow() {
|
public void flushNow() {
|
||||||
regionLock.lock();
|
|
||||||
|
|
||||||
for (Long i : loadedRegions.k()) {
|
for (Long i : loadedRegions.k()) {
|
||||||
doSaveUnload(Cache.keyX(i), Cache.keyZ(i));
|
doSaveUnload(Cache.keyX(i), Cache.keyZ(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
regionLock.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void queueSaveUnload(int x, int z) {
|
public void queueSaveUnload(int x, int z) {
|
||||||
@ -103,8 +98,6 @@ public class NBTWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
public void save() {
|
||||||
regionLock.lock();
|
|
||||||
|
|
||||||
boolean saving = true;
|
boolean saving = true;
|
||||||
|
|
||||||
for (Long i : loadedRegions.k()) {
|
for (Long i : loadedRegions.k()) {
|
||||||
@ -121,8 +114,6 @@ public class NBTWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Iris.debug("Regions: " + C.GOLD + loadedRegions.size() + C.LIGHT_PURPLE);
|
Iris.debug("Regions: " + C.GOLD + loadedRegions.size() + C.LIGHT_PURPLE);
|
||||||
|
|
||||||
regionLock.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void queueSave() {
|
public void queueSave() {
|
||||||
@ -131,10 +122,8 @@ public class NBTWorld {
|
|||||||
|
|
||||||
public synchronized void unloadRegion(int x, int z) {
|
public synchronized void unloadRegion(int x, int z) {
|
||||||
long key = Cache.key(x, z);
|
long key = Cache.key(x, z);
|
||||||
regionLock.lock();
|
|
||||||
loadedRegions.remove(key);
|
loadedRegions.remove(key);
|
||||||
lastUse.remove(key);
|
lastUse.remove(key);
|
||||||
regionLock.unlock();
|
|
||||||
Iris.debug("Unloaded Region " + C.GOLD + x + " " + z);
|
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);
|
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) {
|
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));
|
getChunk(x >> 4, z >> 4).setBiomeAt(x & 15, y, z & 15, biomeIds.get(biome));
|
||||||
}
|
}
|
||||||
@ -265,8 +259,12 @@ public class NBTWorld {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Chunk getChunk(int x, int z) {
|
public Chunk getChunk(int x, int z)
|
||||||
MCAFile mca = getMCA(x >> 5, z >> 5);
|
{
|
||||||
|
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);
|
Chunk c = mca.getChunk(x & 31, z & 31);
|
||||||
|
|
||||||
if (c == null) {
|
if (c == null) {
|
||||||
@ -278,41 +276,40 @@ public class NBTWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public long getIdleDuration(int x, int z) {
|
public long getIdleDuration(int x, int z) {
|
||||||
|
return hyperLock.withResult(x, z, () -> {
|
||||||
Long l = lastUse.get(Cache.key(x, z));
|
Long l = lastUse.get(Cache.key(x, z));
|
||||||
|
|
||||||
return l == null ? 0 : (M.ms() - l);
|
return l == null ? 0 : (M.ms() - l);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public MCAFile getMCA(int x, int z) {
|
public MCAFile getMCA(int x, int z) {
|
||||||
long key = Cache.key(x, z);
|
long key = Cache.key(x, z);
|
||||||
|
|
||||||
regionLock.lock();
|
return hyperLock.withResult(x, z, () -> {
|
||||||
lastUse.put(key, M.ms());
|
lastUse.put(key, M.ms());
|
||||||
|
|
||||||
MCAFile mcaf = loadedRegions.get(key);
|
MCAFile mcaf = loadedRegions.get(key);
|
||||||
regionLock.unlock();
|
|
||||||
|
|
||||||
if (mcaf == null) {
|
if (mcaf == null) {
|
||||||
mcaf = new MCAFile(x, z);
|
mcaf = new MCAFile(x, z);
|
||||||
regionLock.lock();
|
|
||||||
loadedRegions.put(key, mcaf);
|
loadedRegions.put(key, mcaf);
|
||||||
regionLock.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mcaf;
|
return mcaf;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public MCAFile getMCAOrNull(int x, int z) {
|
public MCAFile getMCAOrNull(int x, int z) {
|
||||||
long key = Cache.key(x, z);
|
long key = Cache.key(x, z);
|
||||||
MCAFile ff = null;
|
|
||||||
regionLock.lock();
|
|
||||||
|
|
||||||
|
return hyperLock.withResult(x, z, () -> {
|
||||||
if (loadedRegions.containsKey(key)) {
|
if (loadedRegions.containsKey(key)) {
|
||||||
lastUse.put(key, M.ms());
|
lastUse.put(key, M.ms());
|
||||||
ff = loadedRegions.get(key);
|
return loadedRegions.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
regionLock.unlock();
|
return null;
|
||||||
return ff;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
|
@ -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.CompoundTag;
|
||||||
import com.volmit.iris.util.nbt.tag.ListTag;
|
import com.volmit.iris.util.nbt.tag.ListTag;
|
||||||
import com.volmit.iris.util.nbt.tag.LongArrayTag;
|
import com.volmit.iris.util.nbt.tag.LongArrayTag;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
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.
|
* 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.
|
* 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 paletteSizeBefore = palette.size();
|
||||||
int paletteIndex = addToPalette(state);
|
int paletteIndex = addToPalette(state);
|
||||||
//power of 2 --> bits must increase, but only if the palette size changed
|
//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 paletteIndex The block state to be set (index of block data in the palette).
|
||||||
* @param blockStates The block states to be updated.
|
* @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;
|
int bits = blockStates.length() >> 6;
|
||||||
|
|
||||||
if (dataVersion < 2527) {
|
if (dataVersion < 2527) {
|
||||||
@ -253,7 +254,7 @@ public class Section {
|
|||||||
return palette;
|
return palette;
|
||||||
}
|
}
|
||||||
|
|
||||||
int addToPalette(CompoundTag data) {
|
synchronized int addToPalette(CompoundTag data) {
|
||||||
PaletteIndex index;
|
PaletteIndex index;
|
||||||
if ((index = getValueIndexedPalette(data)) != null) {
|
if ((index = getValueIndexedPalette(data)) != null) {
|
||||||
return index.index;
|
return index.index;
|
||||||
@ -283,14 +284,14 @@ public class Section {
|
|||||||
* This should only be used moderately to avoid unnecessary recalculation of the palette indices.
|
* 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.
|
* Recalculating the Palette should only be executed once right before saving the Section to file.
|
||||||
*/
|
*/
|
||||||
public void cleanupPaletteAndBlockStates() {
|
public synchronized void cleanupPaletteAndBlockStates() {
|
||||||
Map<Integer, Integer> oldToNewMapping = cleanupPalette();
|
Map<Integer, Integer> oldToNewMapping = cleanupPalette();
|
||||||
adjustBlockStateBits(oldToNewMapping, blockStates);
|
adjustBlockStateBits(oldToNewMapping, blockStates);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Integer, Integer> cleanupPalette() {
|
private synchronized Map<Integer, Integer> cleanupPalette() {
|
||||||
//create index - palette mapping
|
//create index - palette mapping
|
||||||
Map<Integer, Integer> allIndices = new HashMap<>();
|
Map<Integer, Integer> allIndices = new Int2IntOpenHashMap();
|
||||||
for (int i = 0; i < 4096; i++) {
|
for (int i = 0; i < 4096; i++) {
|
||||||
int paletteIndex = getPaletteIndex(i);
|
int paletteIndex = getPaletteIndex(i);
|
||||||
allIndices.put(paletteIndex, paletteIndex);
|
allIndices.put(paletteIndex, paletteIndex);
|
||||||
@ -314,7 +315,7 @@ public class Section {
|
|||||||
return allIndices;
|
return allIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
void adjustBlockStateBits(Map<Integer, Integer> oldToNewMapping, AtomicLongArray blockStates) {
|
synchronized void adjustBlockStateBits(Map<Integer, Integer> oldToNewMapping, AtomicLongArray blockStates) {
|
||||||
//increases or decreases the amount of bits used per BlockState
|
//increases or decreases the amount of bits used per BlockState
|
||||||
//based on the size of the palette. oldToNewMapping can be used to update indices
|
//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().
|
//if the palette had been cleaned up before using MCAFile#cleanupPalette().
|
||||||
@ -376,7 +377,7 @@ public class Section {
|
|||||||
* @throws NullPointerException If <code>blockStates</code> is <code>null</code>
|
* @throws NullPointerException If <code>blockStates</code> is <code>null</code>
|
||||||
* @throws IllegalArgumentException When <code>blockStates</code>' length is < 256 or > 4096 and is not a multiple of 64
|
* @throws IllegalArgumentException When <code>blockStates</code>' 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) {
|
if (blockStates == null) {
|
||||||
throw new NullPointerException("BlockStates cannot be null");
|
throw new NullPointerException("BlockStates cannot be null");
|
||||||
} else if (blockStates.length() % 64 != 0 || blockStates.length() < 256 || blockStates.length() > 4096) {
|
} else if (blockStates.length() % 64 != 0 || blockStates.length() < 256 || blockStates.length() > 4096) {
|
||||||
|
@ -26,6 +26,7 @@ import lombok.Data;
|
|||||||
@Data
|
@Data
|
||||||
public class WormIterator2 {
|
public class WormIterator2 {
|
||||||
private transient Worm2 worm;
|
private transient Worm2 worm;
|
||||||
|
private transient NoiseProvider noise;
|
||||||
private int x;
|
private int x;
|
||||||
private int z;
|
private int z;
|
||||||
private int maxDistance;
|
private int maxDistance;
|
||||||
@ -39,13 +40,18 @@ public class WormIterator2 {
|
|||||||
+ ((z * z) - (worm.getZ().getPosition() * worm.getZ().getPosition())) < dist * dist;
|
+ ((z * z) - (worm.getZ().getPosition() * worm.getZ().getPosition())) < dist * dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Worm2 next(NoiseProvider p)
|
public Worm2 next()
|
||||||
{
|
{
|
||||||
if(worm == null)
|
if(worm == null)
|
||||||
{
|
{
|
||||||
worm = new Worm2(x, z, 0, 0);
|
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;
|
return worm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
70
src/main/java/com/volmit/iris/util/noise/WormIterator3.java
Normal file
70
src/main/java/com/volmit/iris/util/noise/WormIterator3.java
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -28,25 +28,20 @@ import java.util.concurrent.*;
|
|||||||
@SuppressWarnings("ALL")
|
@SuppressWarnings("ALL")
|
||||||
public class BurstExecutor {
|
public class BurstExecutor {
|
||||||
private final ExecutorService executor;
|
private final ExecutorService executor;
|
||||||
private final KList<CompletableFuture<Void>> futures;
|
private final KList<Future<?>> futures;
|
||||||
@Setter
|
@Setter
|
||||||
private boolean multicore = true;
|
private boolean multicore = true;
|
||||||
|
|
||||||
public BurstExecutor(ExecutorService executor, int burstSizeEstimate) {
|
public BurstExecutor(ExecutorService executor, int burstSizeEstimate) {
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
futures = new KList<CompletableFuture<Void>>(burstSizeEstimate);
|
futures = new KList<Future<?>>(burstSizeEstimate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("UnusedReturnValue")
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
public CompletableFuture<Void> queue(Runnable r) {
|
public Future<?> queue(Runnable r) {
|
||||||
if(!multicore)
|
|
||||||
{
|
|
||||||
r.run();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (futures) {
|
synchronized (futures) {
|
||||||
CompletableFuture<Void> c = CompletableFuture.runAsync(r, executor);
|
|
||||||
|
Future<?> c = executor.submit(r);
|
||||||
futures.add(c);
|
futures.add(c);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@ -55,7 +50,7 @@ public class BurstExecutor {
|
|||||||
public BurstExecutor queue(List<Runnable> r) {
|
public BurstExecutor queue(List<Runnable> r) {
|
||||||
if(!multicore)
|
if(!multicore)
|
||||||
{
|
{
|
||||||
for(Runnable i : r)
|
for(Runnable i : new KList<>(r))
|
||||||
{
|
{
|
||||||
i.run();
|
i.run();
|
||||||
}
|
}
|
||||||
@ -65,8 +60,7 @@ public class BurstExecutor {
|
|||||||
|
|
||||||
synchronized (futures) {
|
synchronized (futures) {
|
||||||
for (Runnable i : new KList<>(r)) {
|
for (Runnable i : new KList<>(r)) {
|
||||||
CompletableFuture<Void> c = CompletableFuture.runAsync(i, executor);
|
queue(i);
|
||||||
futures.add(c);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +70,7 @@ public class BurstExecutor {
|
|||||||
public BurstExecutor queue(Runnable[] r) {
|
public BurstExecutor queue(Runnable[] r) {
|
||||||
if(!multicore)
|
if(!multicore)
|
||||||
{
|
{
|
||||||
for(Runnable i : r)
|
for(Runnable i : new KList<>(r))
|
||||||
{
|
{
|
||||||
i.run();
|
i.run();
|
||||||
}
|
}
|
||||||
@ -86,8 +80,7 @@ public class BurstExecutor {
|
|||||||
|
|
||||||
synchronized (futures) {
|
synchronized (futures) {
|
||||||
for (Runnable i : r) {
|
for (Runnable i : r) {
|
||||||
CompletableFuture<Void> c = CompletableFuture.runAsync(i, executor);
|
queue(i);
|
||||||
futures.add(c);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,38 +99,15 @@ public class BurstExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get();
|
for(Future<?> i : futures)
|
||||||
futures.clear();
|
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean complete(long maxDur) {
|
|
||||||
if(!multicore)
|
|
||||||
{
|
{
|
||||||
return true;
|
i.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
futures.clear();
|
futures.clear();
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
e.printStackTrace();
|
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,8 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.core.IrisSettings;
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.service.PreservationSVC;
|
import com.volmit.iris.core.service.PreservationSVC;
|
||||||
import com.volmit.iris.util.collection.KList;
|
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.math.M;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import com.volmit.iris.util.scheduling.Looper;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
@ -33,66 +31,39 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class MultiBurst {
|
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 ExecutorService service;
|
||||||
private final Looper heartbeat;
|
|
||||||
private final AtomicLong last;
|
private final AtomicLong last;
|
||||||
private int tid;
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final int tc;
|
|
||||||
private final int priority;
|
private final int priority;
|
||||||
private final int instance;
|
|
||||||
|
|
||||||
public MultiBurst(int tc) {
|
public MultiBurst() {
|
||||||
this("Iris", 6, tc);
|
this("Iris", Thread.MIN_PRIORITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MultiBurst(String name, int priority, int tc) {
|
public MultiBurst(String name, int priority) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
this.tc = tc;
|
|
||||||
instance = InstanceState.getInstanceId();
|
|
||||||
last = new AtomicLong(M.ms());
|
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);
|
Iris.service(PreservationSVC.class).register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized ExecutorService getService() {
|
private synchronized ExecutorService getService() {
|
||||||
last.set(M.ms());
|
last.set(M.ms());
|
||||||
if (service == null || service.isShutdown()) {
|
if (service == null || service.isShutdown()) {
|
||||||
service = Executors.newFixedThreadPool(Math.max(tc, 1), r -> {
|
service = new ForkJoinPool(IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getParallelism()),
|
||||||
tid++;
|
new ForkJoinPool.ForkJoinWorkerThreadFactory() {
|
||||||
Thread t = new Thread(r);
|
int m = 0;
|
||||||
t.setName(name + " " + tid);
|
|
||||||
t.setPriority(priority);
|
|
||||||
t.setUncaughtExceptionHandler((et, e) ->
|
|
||||||
{
|
|
||||||
Iris.info("Exception encountered in " + et.getName());
|
|
||||||
e.printStackTrace();
|
|
||||||
});
|
|
||||||
|
|
||||||
return t;
|
@Override
|
||||||
});
|
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
|
||||||
Iris.service(PreservationSVC.class).register(service);
|
final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
|
||||||
Iris.debug("Started MultiBurst Pool " + name + " with " + tc + " threads at " + priority + " priority.");
|
worker.setPriority(priority);
|
||||||
|
worker.setName(name + " " + ++m);
|
||||||
|
return worker;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(t, e) -> e.printStackTrace(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return service;
|
return service;
|
||||||
@ -102,10 +73,40 @@ public class MultiBurst {
|
|||||||
burst(r.length).queue(r).complete();
|
burst(r.length).queue(r).complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void burst(boolean multicore, Runnable... r) {
|
||||||
|
if(multicore)
|
||||||
|
{
|
||||||
|
burst(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sync(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void burst(List<Runnable> r) {
|
public void burst(List<Runnable> r) {
|
||||||
burst(r.size()).queue(r).complete();
|
burst(r.size()).queue(r).complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void burst(boolean multicore, List<Runnable> r) {
|
||||||
|
if(multicore)
|
||||||
|
{
|
||||||
|
burst(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
sync(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sync(List<Runnable> r) {
|
||||||
|
for(Runnable i : new KList<>(r))
|
||||||
|
{
|
||||||
|
i.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void sync(Runnable... r) {
|
public void sync(Runnable... r) {
|
||||||
for (Runnable i : r) {
|
for (Runnable i : r) {
|
||||||
i.run();
|
i.run();
|
||||||
@ -126,6 +127,12 @@ public class MultiBurst {
|
|||||||
return burst(16);
|
return burst(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BurstExecutor burst(boolean multicore) {
|
||||||
|
BurstExecutor b = burst();
|
||||||
|
b.setMulticore(multicore);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
public <T> Future<T> lazySubmit(Callable<T> o) {
|
public <T> Future<T> lazySubmit(Callable<T> o) {
|
||||||
return getService().submit(o);
|
return getService().submit(o);
|
||||||
}
|
}
|
||||||
@ -138,64 +145,15 @@ public class MultiBurst {
|
|||||||
return getService().submit(o);
|
return getService().submit(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<?> complete(Runnable o) {
|
public Future<?> complete(Runnable o) {
|
||||||
return CompletableFuture.runAsync(o, getService());
|
return getService().submit(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> CompletableFuture<T> completeValue(Supplier<T> o) {
|
public <T> Future<T> completeValue(Callable<T> o) {
|
||||||
return CompletableFuture.supplyAsync(o, getService());
|
return getService().submit(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shutdownNow() {
|
public void close() {
|
||||||
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();
|
|
||||||
if (service != null) {
|
if (service != null) {
|
||||||
service.shutdown();
|
service.shutdown();
|
||||||
try {
|
try {
|
||||||
|
@ -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) {
|
public void sendMessageRaw(String message) {
|
||||||
if (message.contains("<NOMINI>")) {
|
if (message.contains("<NOMINI>")) {
|
||||||
|
@ -129,7 +129,6 @@ public class J {
|
|||||||
try {
|
try {
|
||||||
r.run();
|
r.run();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.volmit.iris.util.scheduling.jobs;
|
||||||
|
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||||
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
|
|
||||||
|
public abstract class ParallelQueueJob<T> extends QueueJob<T> {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
while (queue.isNotEmpty()) {
|
||||||
|
BurstExecutor b = MultiBurst.burst.burst(queue.size());
|
||||||
|
KList<T> q = queue.copy();
|
||||||
|
queue.clear();
|
||||||
|
for(T i : q)
|
||||||
|
{
|
||||||
|
b.queue(() -> {
|
||||||
|
execute(i);
|
||||||
|
completeWork();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
b.complete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,27 +18,32 @@
|
|||||||
|
|
||||||
package com.volmit.iris.util.scheduling.jobs;
|
package com.volmit.iris.util.scheduling.jobs;
|
||||||
|
|
||||||
|
import com.sun.jna.platform.unix.X11;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public abstract class QueueJob<T> implements Job {
|
public abstract class QueueJob<T> implements Job {
|
||||||
private final KList<T> queue;
|
final KList<T> queue;
|
||||||
private int totalWork;
|
protected int totalWork;
|
||||||
private int completed;
|
private AtomicInteger completed;
|
||||||
|
|
||||||
public QueueJob() {
|
public QueueJob() {
|
||||||
totalWork = 0;
|
totalWork = 0;
|
||||||
completed = 0;
|
completed = new AtomicInteger(0);
|
||||||
queue = new KList<>();
|
queue = new KList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void queue(T t) {
|
public QueueJob queue(T t) {
|
||||||
queue.add(t);
|
queue.add(t);
|
||||||
totalWork++;
|
totalWork++;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void queue(KList<T> f) {
|
public QueueJob queue(KList<T> f) {
|
||||||
queue.addAll(f);
|
queue.addAll(f);
|
||||||
totalWork += f.size();
|
totalWork += f.size();
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void execute(T t);
|
public abstract void execute(T t);
|
||||||
@ -54,7 +59,7 @@ public abstract class QueueJob<T> implements Job {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void completeWork() {
|
public void completeWork() {
|
||||||
completed++;
|
completed.incrementAndGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -64,6 +69,6 @@ public abstract class QueueJob<T> implements Job {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getWorkCompleted() {
|
public int getWorkCompleted() {
|
||||||
return completed;
|
return completed.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,18 +6,18 @@ authors: [ cyberpwn, NextdoorPsycho ]
|
|||||||
website: volmit.com
|
website: volmit.com
|
||||||
description: More than a Dimension!
|
description: More than a Dimension!
|
||||||
libraries:
|
libraries:
|
||||||
- org.zeroturnaround:zt-zip:1.14
|
|
||||||
- com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2
|
- com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2
|
||||||
- org.ow2.asm:asm:9.2
|
- com.github.ben-manes.caffeine:caffeine:3.0.3
|
||||||
- com.google.code.gson:gson:2.8.7
|
- io.timeandspace:smoothie-map:2.0.2
|
||||||
- it.unimi.dsi:fastutil:8.5.4
|
|
||||||
- com.google.guava:guava:30.1.1-jre
|
- com.google.guava:guava:30.1.1-jre
|
||||||
- bsf:bsf:2.4.0
|
- com.google.code.gson:gson:2.8.7
|
||||||
|
- org.zeroturnaround:zt-zip:1.14
|
||||||
|
- it.unimi.dsi:fastutil:8.5.4
|
||||||
|
- org.ow2.asm:asm:9.2
|
||||||
- rhino:js:1.7R2
|
- rhino:js:1.7R2
|
||||||
|
- bsf:bsf:2.4.0
|
||||||
commands:
|
commands:
|
||||||
iris:
|
iris:
|
||||||
aliases: [ ir, irs ]
|
aliases: [ ir, irs ]
|
||||||
irisd:
|
|
||||||
aliases: [ ird, irsd ]
|
|
||||||
api-version: ${apiversion}
|
api-version: ${apiversion}
|
||||||
hotload-dependencies: false
|
hotload-dependencies: false
|
Loading…
x
Reference in New Issue
Block a user