mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-28 11:39:07 +00:00
Compare commits
75 Commits
fix/deco-f
...
feat/exclu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf41364da7 | ||
|
|
f6033d9c1b | ||
|
|
f42bf07d4e | ||
|
|
289813b044 | ||
|
|
b209f69bba | ||
|
|
790fde02a8 | ||
|
|
eddc0c81f2 | ||
|
|
d8c3fd8e6c | ||
|
|
984d294bab | ||
|
|
96b0db309a | ||
|
|
b5da0dd33f | ||
|
|
1ac482ff49 | ||
|
|
fb0bc112e3 | ||
|
|
407e51378c | ||
|
|
c468eb1ab1 | ||
|
|
bdb7cc61e5 | ||
|
|
e8f9e841c4 | ||
|
|
1b1b9d97b7 | ||
|
|
24355064ff | ||
|
|
06a45056d9 | ||
|
|
dfe4894be7 | ||
|
|
8eb2287ec0 | ||
|
|
c4f0722614 | ||
|
|
7fa1484b21 | ||
|
|
1c5eb8b910 | ||
|
|
94bf530d93 | ||
|
|
686ae57b5b | ||
|
|
a911685aaf | ||
|
|
6899761ca9 | ||
|
|
a58958fd62 | ||
|
|
307f3c9158 | ||
|
|
4f275c2e06 | ||
|
|
7e4e3f3cd8 | ||
|
|
84e5add564 | ||
|
|
4d4adbb76f | ||
|
|
ff2f285784 | ||
|
|
8b1636e78a | ||
|
|
3bdad10562 | ||
|
|
ac03a977aa | ||
|
|
d7270f66e1 | ||
|
|
b220b1bffa | ||
|
|
4796fe98cb | ||
|
|
ece905ec6e | ||
|
|
53c9e7c04c | ||
|
|
29f6f52443 | ||
|
|
a778cc51a6 | ||
|
|
c6963d0cd3 | ||
|
|
489844f61b | ||
|
|
4d1b0246ca | ||
|
|
13f3511fa8 | ||
|
|
f6f2766315 | ||
|
|
56530a1245 | ||
|
|
210a1f29a7 | ||
|
|
847bf972ae | ||
|
|
e5d21fdf7e | ||
|
|
0b2fd3b358 | ||
|
|
10484d1226 | ||
|
|
ce0092c52a | ||
|
|
474e033c2b | ||
|
|
62aad1f497 | ||
|
|
32b5157682 | ||
|
|
70717ea282 | ||
|
|
15975f108c | ||
|
|
66c66e82c1 | ||
|
|
4f6da95d8e | ||
|
|
b37ccbdf01 | ||
|
|
30dbe0881a | ||
|
|
20ad4657a9 | ||
|
|
d4986f42a6 | ||
|
|
8df15c0c2d | ||
|
|
24e1c578c8 | ||
|
|
1c3bff7559 | ||
|
|
a09657b4d0 | ||
|
|
910220d3ca | ||
|
|
fc05c24e3a |
@@ -15,17 +15,17 @@ Consider supporting our development by buying Iris on spigot! We work hard to ma
|
|||||||
|
|
||||||
### Command Line Builds
|
### Command Line Builds
|
||||||
|
|
||||||
1. Install [Java JDK 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
|
1. Install [Java JDK 21](https://www.oracle.com/java/technologies/javase/jdk21-archive-downloads.html)
|
||||||
2. Set the JDK installation path to `JAVA_HOME` as an environment variable.
|
2. Set the JDK installation path to `JAVA_HOME` as an environment variable.
|
||||||
* Windows
|
* Windows
|
||||||
1. Start > Type `env` and press Enter
|
1. Start > Type `env` and press Enter
|
||||||
2. Advanced > Environment Variables
|
2. Advanced > Environment Variables
|
||||||
3. Under System Variables, click `New...`
|
3. Under System Variables, click `New...`
|
||||||
4. Variable Name: `JAVA_HOME`
|
4. Variable Name: `JAVA_HOME`
|
||||||
5. Variable Value: `C:\Program Files\Java\jdk-17.0.1` (verify this exists after installing java don't just copy
|
5. Variable Value: `C:\Program Files\Java\jdk-21.0.1` (verify this exists after installing java don't just copy
|
||||||
the example text)
|
the example text)
|
||||||
* MacOS
|
* MacOS
|
||||||
1. Run `/usr/libexec/java_home -V` and look for Java 17
|
1. Run `/usr/libexec/java_home -V` and look for Java 21
|
||||||
2. Run `sudo nano ~/.zshenv`
|
2. Run `sudo nano ~/.zshenv`
|
||||||
3. Add `export JAVA_HOME=$(/usr/libexec/java_home)` as a new line
|
3. Add `export JAVA_HOME=$(/usr/libexec/java_home)` as a new line
|
||||||
4. Use `CTRL + X`, then Press `Y`, Then `ENTER`
|
4. Use `CTRL + X`, then Press `Y`, Then `ENTER`
|
||||||
@@ -35,7 +35,7 @@ Consider supporting our development by buying Iris on spigot! We work hard to ma
|
|||||||
|
|
||||||
### IDE Builds (for development)
|
### IDE Builds (for development)
|
||||||
|
|
||||||
* Configure ITJ Gradle to use JDK 17 (in settings, search for gradle)
|
* Configure ITJ Gradle to use JDK 21 (in settings, search for gradle)
|
||||||
* Add a build line in the build.gradle for your own build task to directly compile Iris into your plugins folder if you
|
* Add a build line in the build.gradle for your own build task to directly compile Iris into your plugins folder if you
|
||||||
prefer.
|
prefer.
|
||||||
* Resync the project & run your newly created task (under the development folder in gradle tasks!)
|
* Resync the project & run your newly created task (under the development folder in gradle tasks!)
|
||||||
|
|||||||
11
build.gradle
11
build.gradle
@@ -32,7 +32,8 @@ plugins {
|
|||||||
id "de.undercouch.download" version "5.0.1"
|
id "de.undercouch.download" version "5.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
version '3.5.2-1.19.2-1.21.3'
|
|
||||||
|
version '3.6.5-1.20.1-1.21.4'
|
||||||
|
|
||||||
// ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED
|
// ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED
|
||||||
// ======================== WINDOWS =============================
|
// ======================== WINDOWS =============================
|
||||||
@@ -44,7 +45,7 @@ registerCustomOutputTask('Strange', 'D://Servers/1.17 Test Server/plugins')
|
|||||||
registerCustomOutputTask('Vatuu', 'D://Minecraft/Servers/1.19.4/plugins')
|
registerCustomOutputTask('Vatuu', 'D://Minecraft/Servers/1.19.4/plugins')
|
||||||
registerCustomOutputTask('CrazyDev22', 'C://Users/Julian/Desktop/server/plugins')
|
registerCustomOutputTask('CrazyDev22', 'C://Users/Julian/Desktop/server/plugins')
|
||||||
registerCustomOutputTask('PixelFury', 'C://Users/repix/workplace/Iris/1.21.3 - Development-Public-v3/plugins')
|
registerCustomOutputTask('PixelFury', 'C://Users/repix/workplace/Iris/1.21.3 - Development-Public-v3/plugins')
|
||||||
registerCustomOutputTask('PixelFuryDev', 'C://Users/repix/workplace/Iris/1.21 - Development-v3/plugins')
|
registerCustomOutputTask('PixelFuryDev', 'C://Users/repix/workplace/Iris/1.21.4 - Development-v3/plugins')
|
||||||
// ========================== UNIX ==============================
|
// ========================== UNIX ==============================
|
||||||
registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins')
|
registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins')
|
||||||
registerCustomOutputTaskUnix('PsychoLT', '/Users/brianfopiano/Developer/RemoteGit/Server/plugins')
|
registerCustomOutputTaskUnix('PsychoLT', '/Users/brianfopiano/Developer/RemoteGit/Server/plugins')
|
||||||
@@ -53,15 +54,13 @@ registerCustomOutputTaskUnix('CrazyDev22LT', '/home/julian/Desktop/server/plugin
|
|||||||
// ==============================================================
|
// ==============================================================
|
||||||
|
|
||||||
def NMS_BINDINGS = Map.of(
|
def NMS_BINDINGS = Map.of(
|
||||||
|
"v1_21_R3", "1.21.4-R0.1-SNAPSHOT",
|
||||||
"v1_21_R2", "1.21.3-R0.1-SNAPSHOT",
|
"v1_21_R2", "1.21.3-R0.1-SNAPSHOT",
|
||||||
"v1_21_R1", "1.21.1-R0.1-SNAPSHOT",
|
"v1_21_R1", "1.21.1-R0.1-SNAPSHOT",
|
||||||
"v1_20_R4", "1.20.6-R0.1-SNAPSHOT",
|
"v1_20_R4", "1.20.6-R0.1-SNAPSHOT",
|
||||||
"v1_20_R3", "1.20.4-R0.1-SNAPSHOT",
|
"v1_20_R3", "1.20.4-R0.1-SNAPSHOT",
|
||||||
"v1_20_R2", "1.20.2-R0.1-SNAPSHOT",
|
"v1_20_R2", "1.20.2-R0.1-SNAPSHOT",
|
||||||
"v1_20_R1", "1.20.1-R0.1-SNAPSHOT",
|
"v1_20_R1", "1.20.1-R0.1-SNAPSHOT",
|
||||||
"v1_19_R3", "1.19.4-R0.1-SNAPSHOT",
|
|
||||||
"v1_19_R2", "1.19.3-R0.1-SNAPSHOT",
|
|
||||||
"v1_19_R1", "1.19.2-R0.1-SNAPSHOT"
|
|
||||||
)
|
)
|
||||||
def JVM_VERSION = Map.of()
|
def JVM_VERSION = Map.of()
|
||||||
NMS_BINDINGS.each { nms ->
|
NMS_BINDINGS.each { nms ->
|
||||||
@@ -129,7 +128,7 @@ allprojects {
|
|||||||
annotationProcessor 'org.projectlombok:lombok:1.18.36'
|
annotationProcessor 'org.projectlombok:lombok:1.18.36'
|
||||||
|
|
||||||
// Shaded
|
// Shaded
|
||||||
implementation 'com.dfsek:Paralithic:0.4.0'
|
implementation 'com.dfsek:paralithic:0.8.1'
|
||||||
implementation 'io.papermc:paperlib:1.0.5'
|
implementation 'io.papermc:paperlib:1.0.5'
|
||||||
implementation "net.kyori:adventure-text-minimessage:4.17.0"
|
implementation "net.kyori:adventure-text-minimessage:4.17.0"
|
||||||
implementation 'net.kyori:adventure-platform-bukkit:4.3.4'
|
implementation 'net.kyori:adventure-platform-bukkit:4.3.4'
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ dependencies {
|
|||||||
|
|
||||||
// Third Party Integrations
|
// Third Party Integrations
|
||||||
compileOnly 'com.ticxo.playeranimator:PlayerAnimator:R1.2.7'
|
compileOnly 'com.ticxo.playeranimator:PlayerAnimator:R1.2.7'
|
||||||
compileOnly 'com.nexomc:nexo:0.6.0-dev.0'
|
compileOnly 'com.nexomc:nexo:1.0.0-dev.38'
|
||||||
compileOnly 'com.github.LoneDev6:api-itemsadder:3.4.1-r4'
|
compileOnly 'com.github.LoneDev6:api-itemsadder:3.4.1-r4'
|
||||||
compileOnly 'com.github.PlaceholderAPI:placeholderapi:2.11.3'
|
compileOnly 'com.github.PlaceholderAPI:placeholderapi:2.11.3'
|
||||||
compileOnly 'com.github.Ssomar-Developement:SCore:4.23.10.8'
|
compileOnly 'com.github.Ssomar-Developement:SCore:4.23.10.8'
|
||||||
|
|||||||
@@ -32,8 +32,10 @@ import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
|||||||
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
||||||
import com.volmit.iris.core.service.StudioSVC;
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
|
import com.volmit.iris.core.tools.IrisWorldCreator;
|
||||||
import com.volmit.iris.engine.EnginePanic;
|
import com.volmit.iris.engine.EnginePanic;
|
||||||
import com.volmit.iris.engine.object.IrisCompat;
|
import com.volmit.iris.engine.object.IrisCompat;
|
||||||
|
import com.volmit.iris.engine.object.IrisContextInjector;
|
||||||
import com.volmit.iris.engine.object.IrisDimension;
|
import com.volmit.iris.engine.object.IrisDimension;
|
||||||
import com.volmit.iris.engine.object.IrisWorld;
|
import com.volmit.iris.engine.object.IrisWorld;
|
||||||
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
||||||
@@ -101,8 +103,6 @@ import static com.volmit.iris.core.safeguard.ServerBootSFG.passedserversoftware;
|
|||||||
|
|
||||||
@SuppressWarnings("CanBeFinal")
|
@SuppressWarnings("CanBeFinal")
|
||||||
public class Iris extends VolmitPlugin implements Listener {
|
public class Iris extends VolmitPlugin implements Listener {
|
||||||
public static final String OVERWORLD_TAG = "31000";
|
|
||||||
|
|
||||||
private static final Queue<Runnable> syncJobs = new ShurikenQueue<>();
|
private static final Queue<Runnable> syncJobs = new ShurikenQueue<>();
|
||||||
|
|
||||||
public static Iris instance;
|
public static Iris instance;
|
||||||
@@ -459,9 +459,12 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
initialize("com.volmit.iris.core.service").forEach((i) -> services.put((Class<? extends IrisService>) i.getClass(), (IrisService) i));
|
initialize("com.volmit.iris.core.service").forEach((i) -> services.put((Class<? extends IrisService>) i.getClass(), (IrisService) i));
|
||||||
INMS.get();
|
INMS.get();
|
||||||
IO.delete(new File("iris"));
|
IO.delete(new File("iris"));
|
||||||
|
compat = IrisCompat.configured(getDataFile("compat.json"));
|
||||||
|
ServerConfigurator.configure();
|
||||||
|
new IrisContextInjector();
|
||||||
IrisSafeguard.IrisSafeguardSystem();
|
IrisSafeguard.IrisSafeguardSystem();
|
||||||
getSender().setTag(getTag());
|
getSender().setTag(getTag());
|
||||||
compat = IrisCompat.configured(getDataFile("compat.json"));
|
IrisSafeguard.earlySplash();
|
||||||
linkMultiverseCore = new MultiverseCoreLink();
|
linkMultiverseCore = new MultiverseCoreLink();
|
||||||
linkMythicMobs = new MythicMobsLink();
|
linkMythicMobs = new MythicMobsLink();
|
||||||
configWatcher = new FileWatcher(getDataFile("settings.json"));
|
configWatcher = new FileWatcher(getDataFile("settings.json"));
|
||||||
@@ -516,10 +519,10 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
Iris.info("Loading World: %s | Generator: %s", s, generator);
|
Iris.info("Loading World: %s | Generator: %s", s, generator);
|
||||||
|
|
||||||
Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "...");
|
Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "...");
|
||||||
new WorldCreator(s)
|
WorldCreator c = new WorldCreator(s)
|
||||||
.generator(getDefaultWorldGenerator(s, generator))
|
.generator(getDefaultWorldGenerator(s, generator))
|
||||||
.environment(IrisData.loadAnyDimension(generator).getEnvironment())
|
.environment(IrisData.loadAnyDimension(generator).getEnvironment());
|
||||||
.createWorld();
|
INMS.get().createWorld(c);
|
||||||
Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!");
|
Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!");
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@@ -672,10 +675,12 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
metrics.addCustomChart(new DrilldownPie("used_packs", () -> Bukkit.getWorlds().stream()
|
metrics.addCustomChart(new DrilldownPie("used_packs", () -> Bukkit.getWorlds().stream()
|
||||||
.map(IrisToolbelt::access)
|
.map(IrisToolbelt::access)
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.map(PlatformChunkGenerator::getTarget)
|
.map(PlatformChunkGenerator::getEngine)
|
||||||
.collect(Collectors.toMap(target -> target.getDimension().getLoadKey(), target -> {
|
.collect(Collectors.toMap(engine -> engine.getDimension().getLoadKey(), engine -> {
|
||||||
int version = target.getDimension().getVersion();
|
var hash32 = engine.getHash32().getNow(null);
|
||||||
String checksum = IO.hashRecursive(target.getData().getDataFolder());
|
if (hash32 == null) return Map.of();
|
||||||
|
int version = engine.getDimension().getVersion();
|
||||||
|
String checksum = Long.toHexString(hash32);
|
||||||
|
|
||||||
return Map.of("v" + version + " (" + checksum + ")", 1);
|
return Map.of("v" + version + " (" + checksum + ")", 1);
|
||||||
}, (a, b) -> {
|
}, (a, b) -> {
|
||||||
@@ -777,7 +782,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
service(StudioSVC.class).installIntoWorld(getSender(), dim.getLoadKey(), w.worldFolder());
|
service(StudioSVC.class).installIntoWorld(getSender(), dim.getLoadKey(), w.worldFolder());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey(), false);
|
return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void splash() {
|
public void splash() {
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import com.volmit.iris.util.io.IO;
|
|||||||
import com.volmit.iris.util.json.JSONException;
|
import com.volmit.iris.util.json.JSONException;
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@@ -135,6 +134,11 @@ public class IrisSettings {
|
|||||||
@Data
|
@Data
|
||||||
public static class IrisSettingsConcurrency {
|
public static class IrisSettingsConcurrency {
|
||||||
public int parallelism = -1;
|
public int parallelism = -1;
|
||||||
|
public int worldGenParallelism = -1;
|
||||||
|
|
||||||
|
public int getWorldGenThreads() {
|
||||||
|
return getThreadCount(worldGenParallelism);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@@ -181,6 +185,7 @@ public class IrisSettings {
|
|||||||
public boolean splashLogoStartup = true;
|
public boolean splashLogoStartup = true;
|
||||||
public boolean useConsoleCustomColors = true;
|
public boolean useConsoleCustomColors = true;
|
||||||
public boolean useCustomColorsIngame = true;
|
public boolean useCustomColorsIngame = true;
|
||||||
|
public boolean adjustVanillaHeight = false;
|
||||||
public String forceMainWorld = "";
|
public String forceMainWorld = "";
|
||||||
public int spinh = -20;
|
public int spinh = -20;
|
||||||
public int spins = 7;
|
public int spins = 7;
|
||||||
|
|||||||
@@ -28,20 +28,28 @@ import com.volmit.iris.engine.object.IrisBiomeCustom;
|
|||||||
import com.volmit.iris.engine.object.IrisDimension;
|
import com.volmit.iris.engine.object.IrisDimension;
|
||||||
import com.volmit.iris.engine.object.IrisRange;
|
import com.volmit.iris.engine.object.IrisRange;
|
||||||
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.KSet;
|
import com.volmit.iris.util.collection.KSet;
|
||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
|
import com.volmit.iris.util.misc.ServerProperties;
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NonNull;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static com.volmit.iris.core.nms.datapack.IDataFixer.Dimension.*;
|
||||||
|
|
||||||
public class ServerConfigurator {
|
public class ServerConfigurator {
|
||||||
public static void configure() {
|
public static void configure() {
|
||||||
@@ -84,12 +92,13 @@ public class ServerConfigurator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<File> getDatapacksFolder() {
|
private static KList<File> getDatapacksFolder() {
|
||||||
if (!IrisSettings.get().getGeneral().forceMainWorld.isEmpty()) {
|
if (!IrisSettings.get().getGeneral().forceMainWorld.isEmpty()) {
|
||||||
return new KList<File>().qadd(new File(Bukkit.getWorldContainer(), IrisSettings.get().getGeneral().forceMainWorld + "/datapacks"));
|
return new KList<File>().qadd(new File(Bukkit.getWorldContainer(), IrisSettings.get().getGeneral().forceMainWorld + "/datapacks"));
|
||||||
}
|
}
|
||||||
KList<File> worlds = new KList<>();
|
KList<File> worlds = new KList<>();
|
||||||
Bukkit.getServer().getWorlds().forEach(w -> worlds.add(new File(w.getWorldFolder(), "datapacks")));
|
Bukkit.getServer().getWorlds().forEach(w -> worlds.add(new File(w.getWorldFolder(), "datapacks")));
|
||||||
|
if (worlds.isEmpty()) worlds.add(new File(Bukkit.getWorldContainer(), ServerProperties.LEVEL_NAME + "/datapacks"));
|
||||||
return worlds;
|
return worlds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,57 +108,17 @@ public class ServerConfigurator {
|
|||||||
|
|
||||||
public static void installDataPacks(IDataFixer fixer, boolean fullInstall) {
|
public static void installDataPacks(IDataFixer fixer, boolean fullInstall) {
|
||||||
Iris.info("Checking Data Packs...");
|
Iris.info("Checking Data Packs...");
|
||||||
File packs = new File("plugins/Iris/packs");
|
DimensionHeight height = new DimensionHeight(fixer);
|
||||||
double ultimateMaxHeight = 0;
|
KList<File> folders = getDatapacksFolder();
|
||||||
double ultimateMinHeight = 0;
|
KMap<String, KSet<String>> biomes = new KMap<>();
|
||||||
if (packs.exists() && packs.isDirectory()) {
|
|
||||||
for (File pack : packs.listFiles()) {
|
|
||||||
IrisData data = IrisData.get(pack);
|
|
||||||
if (pack.isDirectory()) {
|
|
||||||
File dimensionsFolder = new File(pack, "dimensions");
|
|
||||||
if (dimensionsFolder.exists() && dimensionsFolder.isDirectory()) {
|
|
||||||
for (File file : dimensionsFolder.listFiles()) {
|
|
||||||
if (file.isFile() && file.getName().endsWith(".json")) {
|
|
||||||
IrisDimension dim = data.getDimensionLoader().load(file.getName().split("\\Q.\\E")[0]);
|
|
||||||
if (ultimateMaxHeight < dim.getDimensionHeight().getMax()) {
|
|
||||||
ultimateMaxHeight = dim.getDimensionHeight().getMax();
|
|
||||||
}
|
|
||||||
if (ultimateMinHeight > dim.getDimensionHeight().getMin()) {
|
|
||||||
ultimateMinHeight = dim.getDimensionHeight().getMin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (packs.exists()) {
|
allPacks().flatMap(height::merge)
|
||||||
for (File i : packs.listFiles()) {
|
.parallel()
|
||||||
if (i.isDirectory()) {
|
.forEach(dim -> {
|
||||||
Iris.verbose("Checking Pack: " + i.getPath());
|
Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath());
|
||||||
IrisData data = IrisData.get(i);
|
dim.installBiomes(fixer, dim::getLoader, folders, biomes.computeIfAbsent(dim.getLoadKey(), k -> new KSet<>()));
|
||||||
File dims = new File(i, "dimensions");
|
});
|
||||||
|
IrisDimension.writeShared(folders, height);
|
||||||
if (dims.exists()) {
|
|
||||||
for (File j : dims.listFiles()) {
|
|
||||||
if (j.getName().endsWith(".json")) {
|
|
||||||
IrisDimension dim = data.getDimensionLoader().load(j.getName().split("\\Q.\\E")[0]);
|
|
||||||
|
|
||||||
if (dim == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath());
|
|
||||||
for (File dpack : getDatapacksFolder()) {
|
|
||||||
dim.installDataPack(fixer, () -> data, dpack, ultimateMaxHeight, ultimateMinHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Iris.info("Data Packs Setup!");
|
Iris.info("Data Packs Setup!");
|
||||||
|
|
||||||
@@ -158,57 +127,40 @@ public class ServerConfigurator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void verifyDataPacksPost(boolean allowRestarting) {
|
private static void verifyDataPacksPost(boolean allowRestarting) {
|
||||||
File packs = new File("plugins/Iris/packs");
|
boolean bad = allPacks()
|
||||||
|
.map(data -> {
|
||||||
|
Iris.verbose("Checking Pack: " + data.getDataFolder().getPath());
|
||||||
|
var loader = data.getDimensionLoader();
|
||||||
|
return loader.loadAll(loader.getPossibleKeys())
|
||||||
|
.stream()
|
||||||
|
.map(ServerConfigurator::verifyDataPackInstalled)
|
||||||
|
.toList()
|
||||||
|
.contains(false);
|
||||||
|
})
|
||||||
|
.toList()
|
||||||
|
.contains(true);
|
||||||
|
if (!bad) return;
|
||||||
|
|
||||||
boolean bad = false;
|
|
||||||
if (packs.exists()) {
|
|
||||||
for (File i : packs.listFiles()) {
|
|
||||||
if (i.isDirectory()) {
|
|
||||||
Iris.verbose("Checking Pack: " + i.getPath());
|
|
||||||
IrisData data = IrisData.get(i);
|
|
||||||
File dims = new File(i, "dimensions");
|
|
||||||
|
|
||||||
if (dims.exists()) {
|
if (allowRestarting) {
|
||||||
for (File j : dims.listFiles()) {
|
restart();
|
||||||
if (j.getName().endsWith(".json")) {
|
} else if (INMS.get().supportsDataPacks()) {
|
||||||
IrisDimension dim = data.getDimensionLoader().load(j.getName().split("\\Q.\\E")[0]);
|
Iris.error("============================================================================");
|
||||||
|
Iris.error(C.ITALIC + "You need to restart your server to properly generate custom biomes.");
|
||||||
|
Iris.error(C.ITALIC + "By continuing, Iris will use backup biomes in place of the custom biomes.");
|
||||||
|
Iris.error("----------------------------------------------------------------------------");
|
||||||
|
Iris.error(C.UNDERLINE + "IT IS HIGHLY RECOMMENDED YOU RESTART THE SERVER BEFORE GENERATING!");
|
||||||
|
Iris.error("============================================================================");
|
||||||
|
|
||||||
if (dim == null) {
|
for (Player i : Bukkit.getOnlinePlayers()) {
|
||||||
Iris.error("Failed to load " + j.getPath() + " ");
|
if (i.isOp() || i.hasPermission("iris.all")) {
|
||||||
continue;
|
VolmitSender sender = new VolmitSender(i, Iris.instance.getTag("WARNING"));
|
||||||
}
|
sender.sendMessage("There are some Iris Packs that have custom biomes in them");
|
||||||
|
sender.sendMessage("You need to restart your server to use these packs.");
|
||||||
if (!verifyDataPackInstalled(dim)) {
|
|
||||||
bad = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (bad) {
|
J.sleep(3000);
|
||||||
if (allowRestarting) {
|
|
||||||
restart();
|
|
||||||
} else if (INMS.get().supportsDataPacks()) {
|
|
||||||
Iris.error("============================================================================");
|
|
||||||
Iris.error(C.ITALIC + "You need to restart your server to properly generate custom biomes.");
|
|
||||||
Iris.error(C.ITALIC + "By continuing, Iris will use backup biomes in place of the custom biomes.");
|
|
||||||
Iris.error("----------------------------------------------------------------------------");
|
|
||||||
Iris.error(C.UNDERLINE + "IT IS HIGHLY RECOMMENDED YOU RESTART THE SERVER BEFORE GENERATING!");
|
|
||||||
Iris.error("============================================================================");
|
|
||||||
|
|
||||||
for (Player i : Bukkit.getOnlinePlayers()) {
|
|
||||||
if (i.isOp() || i.hasPermission("iris.all")) {
|
|
||||||
VolmitSender sender = new VolmitSender(i, Iris.instance.getTag("WARNING"));
|
|
||||||
sender.sendMessage("There are some Iris Packs that have custom biomes in them");
|
|
||||||
sender.sendMessage("You need to restart your server to use these packs.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
J.sleep(3000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,7 +170,7 @@ public class ServerConfigurator {
|
|||||||
Iris.warn("This will only happen when your pack changes (updates/first time setup)");
|
Iris.warn("This will only happen when your pack changes (updates/first time setup)");
|
||||||
Iris.warn("(You can disable this auto restart in iris settings)");
|
Iris.warn("(You can disable this auto restart in iris settings)");
|
||||||
J.s(() -> {
|
J.s(() -> {
|
||||||
Iris.warn("Looks like the restart command diddn't work. Stopping the server instead!");
|
Iris.warn("Looks like the restart command didn't work. Stopping the server instead!");
|
||||||
Bukkit.shutdown();
|
Bukkit.shutdown();
|
||||||
}, 100);
|
}, 100);
|
||||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "restart");
|
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "restart");
|
||||||
@@ -226,22 +178,24 @@ public class ServerConfigurator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean verifyDataPackInstalled(IrisDimension dimension) {
|
public static boolean verifyDataPackInstalled(IrisDimension dimension) {
|
||||||
IrisData idm = IrisData.get(Iris.instance.getDataFolder("packs", dimension.getLoadKey()));
|
|
||||||
KSet<String> keys = new KSet<>();
|
KSet<String> keys = new KSet<>();
|
||||||
boolean warn = false;
|
boolean warn = false;
|
||||||
|
|
||||||
for (IrisBiome i : dimension.getAllBiomes(() -> idm)) {
|
for (IrisBiome i : dimension.getAllBiomes(dimension::getLoader)) {
|
||||||
if (i.isCustom()) {
|
if (i.isCustom()) {
|
||||||
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
||||||
keys.add(dimension.getLoadKey() + ":" + j.getId());
|
keys.add(dimension.getLoadKey() + ":" + j.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
String key = getWorld(dimension.getLoader());
|
||||||
|
if (key == null) key = dimension.getLoadKey();
|
||||||
|
else key += "/" + dimension.getLoadKey();
|
||||||
|
|
||||||
if (!INMS.get().supportsDataPacks()) {
|
if (!INMS.get().supportsDataPacks()) {
|
||||||
if (!keys.isEmpty()) {
|
if (!keys.isEmpty()) {
|
||||||
Iris.warn("===================================================================================");
|
Iris.warn("===================================================================================");
|
||||||
Iris.warn("Pack " + dimension.getLoadKey() + " has " + keys.size() + " custom biome(s). ");
|
Iris.warn("Pack " + key + " has " + keys.size() + " custom biome(s). ");
|
||||||
Iris.warn("Your server version does not yet support datapacks for iris.");
|
Iris.warn("Your server version does not yet support datapacks for iris.");
|
||||||
Iris.warn("The world will generate these biomes as backup biomes.");
|
Iris.warn("The world will generate these biomes as backup biomes.");
|
||||||
Iris.warn("====================================================================================");
|
Iris.warn("====================================================================================");
|
||||||
@@ -260,10 +214,74 @@ public class ServerConfigurator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (warn) {
|
if (warn) {
|
||||||
Iris.error("The Pack " + dimension.getLoadKey() + " is INCAPABLE of generating custom biomes");
|
Iris.error("The Pack " + key + " is INCAPABLE of generating custom biomes");
|
||||||
Iris.error("If not done automatically, restart your server before generating with this pack!");
|
Iris.error("If not done automatically, restart your server before generating with this pack!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return !warn;
|
return !warn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Stream<IrisData> allPacks() {
|
||||||
|
return Stream.concat(listFiles(new File("plugins/Iris/packs")),
|
||||||
|
listFiles(Bukkit.getWorldContainer()).map(w -> new File(w, "iris/pack")))
|
||||||
|
.filter(File::isDirectory)
|
||||||
|
.map(IrisData::get);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static String getWorld(@NonNull IrisData data) {
|
||||||
|
String worldContainer = Bukkit.getWorldContainer().getAbsolutePath();
|
||||||
|
if (!worldContainer.endsWith(File.separator)) worldContainer += File.separator;
|
||||||
|
|
||||||
|
String path = data.getDataFolder().getAbsolutePath();
|
||||||
|
if (!path.startsWith(worldContainer)) return null;
|
||||||
|
int l = path.endsWith(File.separator) ? 11 : 10;
|
||||||
|
return path.substring(worldContainer.length(), path.length() - l);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<File> listFiles(File parent) {
|
||||||
|
var files = parent.listFiles();
|
||||||
|
return files == null ? Stream.empty() : Arrays.stream(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class DimensionHeight {
|
||||||
|
private final IDataFixer fixer;
|
||||||
|
private IrisRange overworld = new IrisRange();
|
||||||
|
private IrisRange nether = new IrisRange();
|
||||||
|
private IrisRange end = new IrisRange();
|
||||||
|
private int logicalOverworld = 0;
|
||||||
|
private int logicalNether = 0;
|
||||||
|
private int logicalEnd = 0;
|
||||||
|
|
||||||
|
public Stream<IrisDimension> merge(IrisData data) {
|
||||||
|
Iris.verbose("Checking Pack: " + data.getDataFolder().getPath());
|
||||||
|
var loader = data.getDimensionLoader();
|
||||||
|
return loader.loadAll(loader.getPossibleKeys())
|
||||||
|
.stream()
|
||||||
|
.peek(this::merge);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void merge(IrisDimension dimension) {
|
||||||
|
overworld.merge(dimension.getDimensionHeight());
|
||||||
|
nether.merge(dimension.getDimensionHeight());
|
||||||
|
end.merge(dimension.getDimensionHeight());
|
||||||
|
|
||||||
|
logicalOverworld = Math.max(logicalOverworld, dimension.getLogicalHeight());
|
||||||
|
logicalNether = Math.max(logicalNether, dimension.getLogicalHeightNether());
|
||||||
|
logicalEnd = Math.max(logicalEnd, dimension.getLogicalHeightEnd());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String overworldType() {
|
||||||
|
return fixer.createDimension(OVERRWORLD, overworld, logicalOverworld).toString(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String netherType() {
|
||||||
|
return fixer.createDimension(NETHER, nether, logicalNether).toString(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String endType() {
|
||||||
|
return fixer.createDimension(THE_END, end, logicalEnd).toString(4);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ public class CommandDeveloper implements DecreeExecutor {
|
|||||||
public void packBenchmark(
|
public void packBenchmark(
|
||||||
@Param(description = "The pack to bench", aliases = {"pack"}, defaultValue = "overworld")
|
@Param(description = "The pack to bench", aliases = {"pack"}, defaultValue = "overworld")
|
||||||
IrisDimension dimension,
|
IrisDimension dimension,
|
||||||
@Param(description = "Radius in regions", defaultValue = "5")
|
@Param(description = "Radius in regions", defaultValue = "2048")
|
||||||
int radius,
|
int radius,
|
||||||
@Param(description = "Open GUI while benchmarking", defaultValue = "false")
|
@Param(description = "Open GUI while benchmarking", defaultValue = "false")
|
||||||
boolean gui
|
boolean gui
|
||||||
|
|||||||
@@ -19,13 +19,17 @@
|
|||||||
package com.volmit.iris.core.commands;
|
package com.volmit.iris.core.commands;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.core.service.StudioSVC;
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
import com.volmit.iris.engine.object.*;
|
import com.volmit.iris.engine.object.*;
|
||||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||||
import com.volmit.iris.util.decree.DecreeOrigin;
|
import com.volmit.iris.util.decree.DecreeOrigin;
|
||||||
import com.volmit.iris.util.decree.annotations.Decree;
|
import com.volmit.iris.util.decree.annotations.Decree;
|
||||||
import com.volmit.iris.util.decree.annotations.Param;
|
import com.volmit.iris.util.decree.annotations.Param;
|
||||||
|
import com.volmit.iris.util.decree.specialhandlers.NullableBiomeHandler;
|
||||||
|
import com.volmit.iris.util.decree.specialhandlers.NullableRegionHandler;
|
||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
|
import org.bukkit.block.Biome;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
@@ -51,12 +55,31 @@ public class CommandEdit implements DecreeExecutor {
|
|||||||
|
|
||||||
|
|
||||||
@Decree(description = "Edit the biome you specified", aliases = {"b"}, origin = DecreeOrigin.PLAYER)
|
@Decree(description = "Edit the biome you specified", aliases = {"b"}, origin = DecreeOrigin.PLAYER)
|
||||||
public void biome(@Param(contextual = false, description = "The biome to edit") IrisBiome biome) {
|
public void biome(@Param(contextual = false, description = "The biome to edit", defaultValue = "---", customHandler = NullableBiomeHandler.class) IrisBiome biome) {
|
||||||
if (noStudio()) {
|
if (noStudio()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (biome == null) {
|
||||||
|
try {
|
||||||
|
IrisBiome b = engine().getBiome(player().getLocation().getBlockX(), player().getLocation().getBlockY() - player().getWorld().getMinHeight(), player().getLocation().getBlockZ());
|
||||||
|
Desktop.getDesktop().open(b.getLoadFile());
|
||||||
|
sender().sendMessage(C.GREEN + "Opening " + b.getTypeName() + " " + b.getLoadFile().getName().split("\\Q.\\E")[0] + " in VSCode! ");
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
sender().sendMessage("Non-Iris Biome: " + player().getLocation().getBlock().getBiome().name());
|
||||||
|
if (player().getLocation().getBlock().getBiome().equals(Biome.CUSTOM)) {
|
||||||
|
try {
|
||||||
|
sender().sendMessage("Data Pack Biome: " + INMS.get().getTrueBiomeBaseKey(player().getLocation()) + " (ID: " + INMS.get().getTrueBiomeBaseId(INMS.get().getTrueBiomeBase(player().getLocation())) + ")");
|
||||||
|
} catch (Throwable ee) {
|
||||||
|
Iris.reportError(ee);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (biome == null || biome.getLoadFile() == null) {
|
if (biome.getLoadFile() == null) {
|
||||||
sender().sendMessage(C.GOLD + "Cannot find the file; Perhaps it was not loaded directly from a file?");
|
sender().sendMessage(C.GOLD + "Cannot find the file; Perhaps it was not loaded directly from a file?");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -69,10 +92,20 @@ public class CommandEdit implements DecreeExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Edit the region you specified", aliases = {"r"}, origin = DecreeOrigin.PLAYER)
|
@Decree(description = "Edit the region you specified", aliases = {"r"}, origin = DecreeOrigin.PLAYER)
|
||||||
public void region(@Param(contextual = false, description = "The region to edit") IrisRegion region) {
|
public void region(@Param(contextual = false, description = "The region to edit", defaultValue = "---", customHandler = NullableRegionHandler.class) IrisRegion region) {
|
||||||
if (noStudio()) {
|
if (noStudio()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (region == null) {
|
||||||
|
try {
|
||||||
|
IrisRegion r = engine().getRegion(player().getLocation().getBlockX(), player().getLocation().getBlockZ());
|
||||||
|
Desktop.getDesktop().open(r.getLoadFile());
|
||||||
|
sender().sendMessage(C.GREEN + "Opening " + r.getTypeName() + " " + r.getLoadFile().getName().split("\\Q.\\E")[0] + " in VSCode! ");
|
||||||
|
} catch (Throwable e) {
|
||||||
|
sender().sendMessage(C.RED + "Failed to get region.");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (region == null || region.getLoadFile() == null) {
|
if (region == null || region.getLoadFile() == null) {
|
||||||
sender().sendMessage(C.GOLD + "Cannot find the file; Perhaps it was not loaded directly from a file?");
|
sender().sendMessage(C.GOLD + "Cannot find the file; Perhaps it was not loaded directly from a file?");
|
||||||
|
|||||||
@@ -20,9 +20,8 @@ package com.volmit.iris.core.commands;
|
|||||||
|
|
||||||
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.ServerConfigurator;
|
|
||||||
import com.volmit.iris.core.loader.IrisData;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
import com.volmit.iris.core.nms.datapack.DataVersion;
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.core.pregenerator.ChunkUpdater;
|
import com.volmit.iris.core.pregenerator.ChunkUpdater;
|
||||||
import com.volmit.iris.core.service.StudioSVC;
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
import com.volmit.iris.core.tools.IrisBenchmarking;
|
import com.volmit.iris.core.tools.IrisBenchmarking;
|
||||||
@@ -43,9 +42,7 @@ 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.plugin.VolmitSender;
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import lombok.Getter;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Difficulty;
|
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.WorldCreator;
|
import org.bukkit.WorldCreator;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
@@ -55,10 +52,8 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
import java.io.Console;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -94,9 +89,7 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
@Param(aliases = "dimension", description = "The dimension type to create the world with", defaultValue = "default")
|
@Param(aliases = "dimension", description = "The dimension type to create the world with", defaultValue = "default")
|
||||||
IrisDimension type,
|
IrisDimension type,
|
||||||
@Param(description = "The seed to generate the world with", defaultValue = "1337")
|
@Param(description = "The seed to generate the world with", defaultValue = "1337")
|
||||||
long seed,
|
long seed
|
||||||
@Param(description = "If it should convert the dimension to match the vanilla height system.", defaultValue = "false")
|
|
||||||
boolean vanillaheight
|
|
||||||
) {
|
) {
|
||||||
if(sender() instanceof Player) {
|
if(sender() instanceof Player) {
|
||||||
if (incompatibilities.get("Multiverse-Core")) {
|
if (incompatibilities.get("Multiverse-Core")) {
|
||||||
@@ -140,7 +133,6 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
.seed(seed)
|
.seed(seed)
|
||||||
.sender(sender())
|
.sender(sender())
|
||||||
.studio(false)
|
.studio(false)
|
||||||
.smartVanillaHeight(vanillaheight)
|
|
||||||
.create();
|
.create();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
sender().sendMessage(C.RED + "Exception raised during creation. See the console for more details.");
|
sender().sendMessage(C.RED + "Exception raised during creation. See the console for more details.");
|
||||||
@@ -274,6 +266,17 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sender().sendMessage(C.GREEN + "Removing world: " + world.getName());
|
sender().sendMessage(C.GREEN + "Removing world: " + world.getName());
|
||||||
|
|
||||||
|
if (!IrisToolbelt.evacuate(world)) {
|
||||||
|
sender().sendMessage(C.RED + "Failed to evacuate world: " + world.getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Bukkit.unloadWorld(world, false)) {
|
||||||
|
sender().sendMessage(C.RED + "Failed to unload world: " + world.getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (IrisToolbelt.removeWorld(world)) {
|
if (IrisToolbelt.removeWorld(world)) {
|
||||||
sender().sendMessage(C.GREEN + "Successfully removed " + world.getName() + " from bukkit.yml");
|
sender().sendMessage(C.GREEN + "Successfully removed " + world.getName() + " from bukkit.yml");
|
||||||
@@ -286,27 +289,32 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
}
|
}
|
||||||
IrisToolbelt.evacuate(world, "Deleting world");
|
IrisToolbelt.evacuate(world, "Deleting world");
|
||||||
deletingWorld = true;
|
deletingWorld = true;
|
||||||
Bukkit.unloadWorld(world, false);
|
if (!delete) {
|
||||||
int retries = 12;
|
deletingWorld = false;
|
||||||
if (delete) {
|
return;
|
||||||
|
}
|
||||||
|
VolmitSender sender = sender();
|
||||||
|
J.a(() -> {
|
||||||
|
int retries = 12;
|
||||||
|
|
||||||
if (deleteDirectory(world.getWorldFolder())) {
|
if (deleteDirectory(world.getWorldFolder())) {
|
||||||
sender().sendMessage(C.GREEN + "Successfully removed world folder");
|
sender.sendMessage(C.GREEN + "Successfully removed world folder");
|
||||||
} else {
|
} else {
|
||||||
while(true){
|
while(true){
|
||||||
if (deleteDirectory(world.getWorldFolder())){
|
if (deleteDirectory(world.getWorldFolder())){
|
||||||
sender().sendMessage(C.GREEN + "Successfully removed world folder");
|
sender.sendMessage(C.GREEN + "Successfully removed world folder");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
retries--;
|
retries--;
|
||||||
if (retries == 0){
|
if (retries == 0){
|
||||||
sender().sendMessage(C.RED + "Failed to remove world folder");
|
sender.sendMessage(C.RED + "Failed to remove world folder");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
J.sleep(3000);
|
J.sleep(3000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
deletingWorld = false;
|
||||||
deletingWorld = false;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean deleteDirectory(File dir) {
|
public static boolean deleteDirectory(File dir) {
|
||||||
@@ -405,7 +413,7 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
) {
|
) {
|
||||||
sender().sendMessage(C.GREEN + "Downloading pack: " + pack + "/" + branch + (trim ? " trimmed" : "") + (overwrite ? " overwriting" : ""));
|
sender().sendMessage(C.GREEN + "Downloading pack: " + pack + "/" + branch + (trim ? " trimmed" : "") + (overwrite ? " overwriting" : ""));
|
||||||
if (pack.equals("overworld")) {
|
if (pack.equals("overworld")) {
|
||||||
String url = "https://github.com/IrisDimensions/overworld/releases/download/" + Iris.OVERWORLD_TAG + "/overworld.zip";
|
String url = "https://github.com/IrisDimensions/overworld/releases/download/" + INMS.OVERWORLD_TAG + "/overworld.zip";
|
||||||
Iris.service(StudioSVC.class).downloadRelease(sender(), url, trim, overwrite);
|
Iris.service(StudioSVC.class).downloadRelease(sender(), url, trim, overwrite);
|
||||||
} else {
|
} else {
|
||||||
Iris.service(StudioSVC.class).downloadSearch(sender(), "IrisDimensions/" + pack + "/" + branch, trim, overwrite);
|
Iris.service(StudioSVC.class).downloadSearch(sender(), "IrisDimensions/" + pack + "/" + branch, trim, overwrite);
|
||||||
@@ -591,10 +599,10 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "...");
|
Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "...");
|
||||||
new WorldCreator(s)
|
WorldCreator c = new WorldCreator(s)
|
||||||
.generator(getDefaultWorldGenerator(s, generator))
|
.generator(getDefaultWorldGenerator(s, generator))
|
||||||
.environment(IrisData.loadAnyDimension(generator).getEnvironment())
|
.environment(IrisData.loadAnyDimension(generator).getEnvironment());
|
||||||
.createWorld();
|
INMS.get().createWorld(c);
|
||||||
Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!");
|
Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!");
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@@ -649,6 +657,6 @@ public class CommandIris implements DecreeExecutor {
|
|||||||
ff.mkdirs();
|
ff.mkdirs();
|
||||||
service(StudioSVC.class).installIntoWorld(sender, dim.getLoadKey(), ff.getParentFile());
|
service(StudioSVC.class).installIntoWorld(sender, dim.getLoadKey(), ff.getParentFile());
|
||||||
}
|
}
|
||||||
return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey(), false);
|
return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ import com.volmit.iris.core.tools.IrisConverter;
|
|||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.*;
|
import com.volmit.iris.engine.object.*;
|
||||||
import com.volmit.iris.util.data.Cuboid;
|
import com.volmit.iris.util.data.Cuboid;
|
||||||
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
|
import com.volmit.iris.util.data.registry.Materials;
|
||||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||||
import com.volmit.iris.util.decree.DecreeOrigin;
|
import com.volmit.iris.util.decree.DecreeOrigin;
|
||||||
import com.volmit.iris.util.decree.annotations.Decree;
|
import com.volmit.iris.util.decree.annotations.Decree;
|
||||||
@@ -36,12 +38,9 @@ import com.volmit.iris.util.decree.specialhandlers.ObjectHandler;
|
|||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.math.Direction;
|
import com.volmit.iris.util.math.Direction;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import com.volmit.iris.util.misc.E;
|
|
||||||
import com.volmit.iris.util.scheduling.Queue;
|
import com.volmit.iris.util.scheduling.Queue;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockState;
|
|
||||||
import org.bukkit.block.TileState;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
@@ -54,7 +53,7 @@ import java.util.*;
|
|||||||
@Decree(name = "object", aliases = "o", origin = DecreeOrigin.PLAYER, studio = true, description = "Iris object manipulation")
|
@Decree(name = "object", aliases = "o", origin = DecreeOrigin.PLAYER, studio = true, description = "Iris object manipulation")
|
||||||
public class CommandObject implements DecreeExecutor {
|
public class CommandObject implements DecreeExecutor {
|
||||||
|
|
||||||
private static final Set<Material> skipBlocks = Set.of(E.getOrDefault(Material.class, "GRASS", "SHORT_GRASS"), Material.SNOW, Material.VINE, Material.TORCH, Material.DEAD_BUSH,
|
private static final Set<Material> skipBlocks = Set.of(Materials.GRASS, Material.SNOW, Material.VINE, Material.TORCH, Material.DEAD_BUSH,
|
||||||
Material.POPPY, Material.DANDELION);
|
Material.POPPY, Material.DANDELION);
|
||||||
|
|
||||||
public static IObjectPlacer createPlacer(World world, Map<Block, BlockData> futureBlockChanges) {
|
public static IObjectPlacer createPlacer(World world, Map<Block, BlockData> futureBlockChanges) {
|
||||||
@@ -79,7 +78,10 @@ public class CommandObject implements DecreeExecutor {
|
|||||||
|
|
||||||
futureBlockChanges.put(block, block.getBlockData());
|
futureBlockChanges.put(block, block.getBlockData());
|
||||||
|
|
||||||
block.setBlockData(d);
|
if (d instanceof IrisCustomData data) {
|
||||||
|
block.setBlockData(data.getBase());
|
||||||
|
Iris.warn("Tried to place custom block at " + x + ", " + y + ", " + z + " which is not supported!");
|
||||||
|
} else block.setBlockData(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -19,9 +19,7 @@
|
|||||||
package com.volmit.iris.core.commands;
|
package com.volmit.iris.core.commands;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.IrisSettings;
|
|
||||||
import com.volmit.iris.core.gui.PregeneratorJob;
|
import com.volmit.iris.core.gui.PregeneratorJob;
|
||||||
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
|
||||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||||
@@ -29,12 +27,9 @@ import com.volmit.iris.util.decree.annotations.Decree;
|
|||||||
import com.volmit.iris.util.decree.annotations.Param;
|
import com.volmit.iris.util.decree.annotations.Param;
|
||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.math.Position2;
|
import com.volmit.iris.util.math.Position2;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
@Decree(name = "pregen", aliases = "pregenerate", description = "Pregenerate your Iris worlds!")
|
@Decree(name = "pregen", aliases = "pregenerate", description = "Pregenerate your Iris worlds!")
|
||||||
public class CommandPregen implements DecreeExecutor {
|
public class CommandPregen implements DecreeExecutor {
|
||||||
@Decree(description = "Pregenerate a world")
|
@Decree(description = "Pregenerate a world")
|
||||||
@@ -52,13 +47,12 @@ public class CommandPregen implements DecreeExecutor {
|
|||||||
sender().sendMessage(C.RED + "Please make sure the world is loaded & the engine is initialized. Generate a new chunk, for example.");
|
sender().sendMessage(C.RED + "Please make sure the world is loaded & the engine is initialized. Generate a new chunk, for example.");
|
||||||
}
|
}
|
||||||
radius = Math.max(radius, 1024);
|
radius = Math.max(radius, 1024);
|
||||||
int w = (radius >> 9 + 1) * 2;
|
|
||||||
IrisToolbelt.pregenerate(PregenTask
|
IrisToolbelt.pregenerate(PregenTask
|
||||||
.builder()
|
.builder()
|
||||||
.center(new Position2(center.getBlockX() >> 9, center.getBlockZ() >> 9))
|
.center(new Position2(center.getBlockX(), center.getBlockZ()))
|
||||||
.gui(true)
|
.gui(true)
|
||||||
.width(w)
|
.radiusX(radius)
|
||||||
.height(w)
|
.radiusZ(radius)
|
||||||
.build(), world);
|
.build(), world);
|
||||||
String msg = C.GREEN + "Pregen started in " + C.GOLD + world.getName() + C.GREEN + " of " + C.GOLD + (radius * 2) + C.GREEN + " by " + C.GOLD + (radius * 2) + C.GREEN + " blocks from " + C.GOLD + center.getX() + "," + center.getZ();
|
String msg = C.GREEN + "Pregen started in " + C.GOLD + world.getName() + C.GREEN + " of " + C.GOLD + (radius * 2) + C.GREEN + " by " + C.GOLD + (radius * 2) + C.GREEN + " blocks from " + C.GOLD + center.getX() + "," + center.getZ();
|
||||||
sender().sendMessage(msg);
|
sender().sendMessage(msg);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.core.IrisSettings;
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.gui.NoiseExplorerGUI;
|
import com.volmit.iris.core.gui.NoiseExplorerGUI;
|
||||||
import com.volmit.iris.core.gui.VisionGUI;
|
import com.volmit.iris.core.gui.VisionGUI;
|
||||||
|
import com.volmit.iris.core.gui.components.IrisRenderer;
|
||||||
import com.volmit.iris.core.loader.IrisData;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
import com.volmit.iris.core.project.IrisProject;
|
import com.volmit.iris.core.project.IrisProject;
|
||||||
import com.volmit.iris.core.service.ConversionSVC;
|
import com.volmit.iris.core.service.ConversionSVC;
|
||||||
@@ -65,6 +66,9 @@ import org.bukkit.inventory.Inventory;
|
|||||||
import org.bukkit.util.BlockVector;
|
import org.bukkit.util.BlockVector;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -156,6 +160,37 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
sender().sendMessage(C.GREEN + "The \"" + dimension.getName() + "\" pack has version: " + dimension.getVersion());
|
sender().sendMessage(C.GREEN + "The \"" + dimension.getName() + "\" pack has version: " + dimension.getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Debug image")
|
||||||
|
public void printImageChannel(
|
||||||
|
@Param(name = "image", description = "Image found in the image folder inside the project")
|
||||||
|
String image,
|
||||||
|
@Param(name = "channel", description = "Image channel")
|
||||||
|
IrisImageChannel channel
|
||||||
|
) {
|
||||||
|
if (noStudio()) return;
|
||||||
|
try {
|
||||||
|
File file = new File(access().getEngine().getComplex().getData().getDataFolder(), "images/" + image);
|
||||||
|
if (!file.exists()) {
|
||||||
|
sender().sendMessage(C.RED + "The image \"" + image + "\" does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BufferedImage buffer = ImageIO.read(file);
|
||||||
|
IrisImage irisImage = new IrisImage(buffer);
|
||||||
|
File at = new File(file.getParentFile(), "debug-see-" + file.getName());
|
||||||
|
BufferedImage b = new BufferedImage(buffer.getWidth(), buffer.getHeight(), BufferedImage.TYPE_INT_RGB);
|
||||||
|
for (int i = 0; i < buffer.getWidth(); i++) {
|
||||||
|
for (int j = 0; j < buffer.getHeight(); j++) {
|
||||||
|
b.setRGB(i, j, Color.getHSBColor(0, 0, (float) irisImage.getValue(channel, i, j)).getRGB());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImageIO.write(b, "png", at);
|
||||||
|
sender().sendMessage(C.IRIS + "Debug image written to ./images for channel " + channel.name());
|
||||||
|
} catch (Exception e) {
|
||||||
|
sender().sendMessage(C.RED + "Something went wrong.. ");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Decree(name = "regen", description = "Regenerate nearby chunks.", aliases = "rg", sync = true, origin = DecreeOrigin.PLAYER)
|
@Decree(name = "regen", description = "Regenerate nearby chunks.", aliases = "rg", sync = true, origin = DecreeOrigin.PLAYER)
|
||||||
public void regen(
|
public void regen(
|
||||||
@Param(name = "radius", description = "The radius of nearby cunks", defaultValue = "5")
|
@Param(name = "radius", description = "The radius of nearby cunks", defaultValue = "5")
|
||||||
@@ -404,9 +439,16 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
@Param(name = "world", description = "The world to open the generator for", contextual = true)
|
@Param(name = "world", description = "The world to open the generator for", contextual = true)
|
||||||
World world
|
World world
|
||||||
) {
|
) {
|
||||||
if (noGUI()) return;
|
if (noGUI()) {
|
||||||
|
sender().sendMessage(C.GOLD + "GUI Support isn't enabled or supported on this server.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!IrisToolbelt.isIrisWorld(world)) {
|
if (world == null) {
|
||||||
|
if (noStudio()) return;
|
||||||
|
world = player().getWorld();
|
||||||
|
}
|
||||||
|
else if (!IrisToolbelt.isIrisWorld(world)) {
|
||||||
sender().sendMessage(C.RED + "You need to be in or specify an Iris-generated world!");
|
sender().sendMessage(C.RED + "You need to be in or specify an Iris-generated world!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -842,7 +884,7 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
sender().sendMessage(C.RED + "No studio world is open!");
|
sender().sendMessage(C.RED + "No studio world is open!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!engine().isStudio()) {
|
if (engine() == null || !engine().isStudio()) {
|
||||||
sender().sendMessage(C.RED + "You must be in a studio world!");
|
sender().sendMessage(C.RED + "You must be in a studio world!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import com.volmit.iris.core.pregenerator.IrisPregenerator;
|
|||||||
import com.volmit.iris.core.pregenerator.PregenListener;
|
import com.volmit.iris.core.pregenerator.PregenListener;
|
||||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||||
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
||||||
import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
@@ -45,8 +44,6 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import static com.volmit.iris.core.tools.IrisPackBenchmarking.benchmarkInProgress;
|
|
||||||
|
|
||||||
public class PregeneratorJob implements PregenListener {
|
public class PregeneratorJob implements PregenListener {
|
||||||
private static final Color COLOR_EXISTS = parseColor("#4d7d5b");
|
private static final Color COLOR_EXISTS = parseColor("#4d7d5b");
|
||||||
private static final Color COLOR_BLACK = parseColor("#4d7d5b");
|
private static final Color COLOR_BLACK = parseColor("#4d7d5b");
|
||||||
@@ -81,12 +78,12 @@ public class PregeneratorJob implements PregenListener {
|
|||||||
this.task = task;
|
this.task = task;
|
||||||
this.pregenerator = new IrisPregenerator(task, method, this);
|
this.pregenerator = new IrisPregenerator(task, method, this);
|
||||||
max = new Position2(0, 0);
|
max = new Position2(0, 0);
|
||||||
min = new Position2(0, 0);
|
min = new Position2(Integer.MAX_VALUE, Integer.MAX_VALUE);
|
||||||
task.iterateRegions((xx, zz) -> {
|
task.iterateAllChunks((xx, zz) -> {
|
||||||
min.setX(Math.min(xx << 5, min.getX()));
|
min.setX(Math.min(xx, min.getX()));
|
||||||
min.setZ(Math.min(zz << 5, min.getZ()));
|
min.setZ(Math.min(zz, min.getZ()));
|
||||||
max.setX(Math.max((xx << 5) + 31, max.getX()));
|
max.setX(Math.max(xx, max.getX()));
|
||||||
max.setZ(Math.max((zz << 5) + 31, max.getZ()));
|
max.setZ(Math.max(zz, max.getZ()));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (IrisSettings.get().getGui().isUseServerLaunchedGuis() && task.isGui()) {
|
if (IrisSettings.get().getGui().isUseServerLaunchedGuis() && task.isGui()) {
|
||||||
@@ -162,7 +159,7 @@ public class PregeneratorJob implements PregenListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void drawRegion(int x, int z, Color color) {
|
public void drawRegion(int x, int z, Color color) {
|
||||||
J.a(() -> PregenTask.iterateRegion(x, z, (xx, zz) -> {
|
J.a(() -> task.iterateChunks(x, z, (xx, zz) -> {
|
||||||
draw(xx, zz, color);
|
draw(xx, zz, color);
|
||||||
J.sleep(3);
|
J.sleep(3);
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
* Copyright (c) 2024 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -56,6 +56,9 @@ import java.util.concurrent.ExecutorService;
|
|||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
//todo
|
||||||
|
// - Misalignment
|
||||||
|
// - Weird snapping?
|
||||||
public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener, MouseMotionListener, MouseInputListener {
|
public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener, MouseMotionListener, MouseInputListener {
|
||||||
private static final long serialVersionUID = 2094606939770332040L;
|
private static final long serialVersionUID = 2094606939770332040L;
|
||||||
private final KList<LivingEntity> lastEntities = new KList<>();
|
private final KList<LivingEntity> lastEntities = new KList<>();
|
||||||
@@ -412,8 +415,8 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
private double getWorldX(double screenX) {
|
private double getWorldX(double screenX) {
|
||||||
//return (mscale * screenX) + ((oxp / scale) * mscale);
|
return (mscale * screenX) + ((oxp / scale) * mscale);
|
||||||
return (mscale * screenX) + ((oxp / scale));
|
// return (mscale * screenX) + ((oxp / scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getWorldZ(double screenZ) {
|
private double getWorldZ(double screenZ) {
|
||||||
|
|||||||
@@ -55,10 +55,10 @@ public class IrisRenderer {
|
|||||||
IrisBiome b = renderer.getBiome((int) Math.round(x), renderer.getMaxHeight() - 1, (int) Math.round(z));
|
IrisBiome b = renderer.getBiome((int) Math.round(x), renderer.getMaxHeight() - 1, (int) Math.round(z));
|
||||||
IrisBiomeGeneratorLink g = b.getGenerators().get(0);
|
IrisBiomeGeneratorLink g = b.getGenerators().get(0);
|
||||||
Color c;
|
Color c;
|
||||||
if (g.getMax(renderer) <= 0) {
|
if (g.getMax() <= 0) {
|
||||||
// Max is below water level, so it is most likely an ocean biome
|
// Max is below water level, so it is most likely an ocean biome
|
||||||
c = Color.BLUE;
|
c = Color.BLUE;
|
||||||
} else if (g.getMin(renderer) < 0) {
|
} else if (g.getMin() < 0) {
|
||||||
// Min is below water level, but max is not, so it is most likely a shore biome
|
// Min is below water level, but max is not, so it is most likely a shore biome
|
||||||
c = Color.YELLOW;
|
c = Color.YELLOW;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.volmit.iris.core.link;
|
|||||||
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.data.IrisBlockData;
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@@ -49,7 +49,7 @@ public abstract class ExternalDataProvider {
|
|||||||
* @param blockId The id of the block to get
|
* @param blockId The id of the block to get
|
||||||
* @param state The state of the block to get
|
* @param state The state of the block to get
|
||||||
* @return Corresponding {@link BlockData} to the blockId
|
* @return Corresponding {@link BlockData} to the blockId
|
||||||
* may return {@link IrisBlockData} for blocks that need a world for placement
|
* may return {@link IrisCustomData} for blocks that need a world for placement
|
||||||
* @throws MissingResourceException when the blockId is invalid
|
* @throws MissingResourceException when the blockId is invalid
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -77,7 +77,7 @@ public abstract class ExternalDataProvider {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is used for placing blocks that need to use the plugins api
|
* This method is used for placing blocks that need to use the plugins api
|
||||||
* it will only be called when the {@link ExternalDataProvider#getBlockData(Identifier, KMap)} returned a {@link IrisBlockData}
|
* it will only be called when the {@link ExternalDataProvider#getBlockData(Identifier, KMap)} returned a {@link IrisCustomData}
|
||||||
*
|
*
|
||||||
* @param engine The engine of the world the block is being placed in
|
* @param engine The engine of the world the block is being placed in
|
||||||
* @param block The block where the block should be placed
|
* @param block The block where the block should be placed
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import com.volmit.iris.core.service.ExternalDataSVC;
|
|||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
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.IrisBlockData;
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
import com.volmit.iris.util.reflect.WrappedField;
|
import com.volmit.iris.util.reflect.WrappedField;
|
||||||
import com.volmit.iris.util.reflect.WrappedReturningMethod;
|
import com.volmit.iris.util.reflect.WrappedReturningMethod;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@@ -64,7 +64,7 @@ public class HMCLeavesDataProvider extends ExternalDataProvider {
|
|||||||
BlockData blockData = Bukkit.createBlockData(material);
|
BlockData blockData = Bukkit.createBlockData(material);
|
||||||
if (IrisSettings.get().getGenerator().preventLeafDecay && blockData instanceof Leaves leaves)
|
if (IrisSettings.get().getGenerator().preventLeafDecay && blockData instanceof Leaves leaves)
|
||||||
leaves.setPersistent(true);
|
leaves.setPersistent(true);
|
||||||
return new IrisBlockData(blockData, ExternalDataSVC.buildState(blockId, state));
|
return new IrisCustomData(blockData, ExternalDataSVC.buildState(blockId, state));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import com.volmit.iris.engine.framework.Engine;
|
|||||||
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.data.IrisBlockData;
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import io.lumine.mythic.bukkit.BukkitAdapter;
|
import io.lumine.mythic.bukkit.BukkitAdapter;
|
||||||
import io.lumine.mythic.bukkit.utils.serialize.Chroma;
|
import io.lumine.mythic.bukkit.utils.serialize.Chroma;
|
||||||
@@ -71,7 +71,7 @@ public class MythicCrucibleDataProvider extends ExternalDataProvider {
|
|||||||
CustomBlockItemContext blockItemContext = crucibleItem.getBlockData();
|
CustomBlockItemContext blockItemContext = crucibleItem.getBlockData();
|
||||||
FurnitureItemContext furnitureItemContext = crucibleItem.getFurnitureData();
|
FurnitureItemContext furnitureItemContext = crucibleItem.getFurnitureData();
|
||||||
if (furnitureItemContext != null) {
|
if (furnitureItemContext != null) {
|
||||||
return new IrisBlockData(B.getAir(), ExternalDataSVC.buildState(blockId, state));
|
return new IrisCustomData(B.getAir(), ExternalDataSVC.buildState(blockId, state));
|
||||||
} else if (blockItemContext != null) {
|
} else if (blockItemContext != null) {
|
||||||
return blockItemContext.getBlockData();
|
return blockItemContext.getBlockData();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import org.bukkit.plugin.Plugin;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class MythicMobsLink {
|
public class MythicMobsLink {
|
||||||
|
|
||||||
@@ -54,6 +55,6 @@ public class MythicMobsLink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Collection<String> getMythicMobTypes() {
|
public Collection<String> getMythicMobTypes() {
|
||||||
return isEnabled() ? MythicBukkit.inst().getMobManager().getMobNames() : null;
|
return isEnabled() ? MythicBukkit.inst().getMobManager().getMobNames() : List.of();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import com.volmit.iris.engine.data.cache.Cache;
|
|||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
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.data.IrisBlockData;
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@@ -49,9 +49,9 @@ public class NexoDataProvider extends ExternalDataProvider {
|
|||||||
BlockData data = NexoBlocks.blockData(blockId.key());
|
BlockData data = NexoBlocks.blockData(blockId.key());
|
||||||
if (data == null)
|
if (data == null)
|
||||||
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
return new IrisBlockData(data, blockState);
|
return new IrisCustomData(data, blockState);
|
||||||
} else if (NexoFurniture.isFurniture(blockId.key())) {
|
} else if (NexoFurniture.isFurniture(blockId.key())) {
|
||||||
return new IrisBlockData(B.getAir(), blockState);
|
return new IrisCustomData(B.getAir(), blockState);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
@@ -125,7 +125,7 @@ public class NexoDataProvider extends ExternalDataProvider {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Identifier[] getBlockTypes() {
|
public Identifier[] getBlockTypes() {
|
||||||
return Arrays.stream(NexoItems.itemNames())
|
return NexoItems.itemNames().stream()
|
||||||
.map(i -> new Identifier("nexo", i))
|
.map(i -> new Identifier("nexo", i))
|
||||||
.filter(i -> {
|
.filter(i -> {
|
||||||
try {
|
try {
|
||||||
@@ -140,7 +140,7 @@ public class NexoDataProvider extends ExternalDataProvider {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Identifier[] getItemTypes() {
|
public Identifier[] getItemTypes() {
|
||||||
return Arrays.stream(NexoItems.itemNames())
|
return NexoItems.itemNames().stream()
|
||||||
.map(i -> new Identifier("nexo", i))
|
.map(i -> new Identifier("nexo", i))
|
||||||
.filter(i -> {
|
.filter(i -> {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -23,19 +23,28 @@ import com.volmit.iris.core.IrisSettings;
|
|||||||
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class INMS {
|
public class INMS {
|
||||||
private static final Map<String, String> REVISION = Map.of(
|
private static final Map<String, String> REVISION = Map.of(
|
||||||
"1.20.5", "v1_20_R4",
|
"1.20.5", "v1_20_R4",
|
||||||
"1.20.6", "v1_20_R4",
|
"1.20.6", "v1_20_R4",
|
||||||
"1.21", "v1_21_R1",
|
"1.21", "v1_21_R1",
|
||||||
"1.21.1", "v1_21_R1",
|
"1.21.1", "v1_21_R1",
|
||||||
"1.21.2", "v1_21_R2",
|
"1.21.2", "v1_21_R2",
|
||||||
"1.21.3", "v1_21_R2"
|
"1.21.3", "v1_21_R2",
|
||||||
|
"1.21.4", "v1_21_R3"
|
||||||
);
|
);
|
||||||
|
private static final List<Version> PACKS = List.of(
|
||||||
|
new Version(21, 4, "31020"),
|
||||||
|
new Version(21, 2, "31000"),
|
||||||
|
new Version(20, 1, "3910")
|
||||||
|
);
|
||||||
|
|
||||||
//@done
|
//@done
|
||||||
private static final INMSBinding binding = bind();
|
private static final INMSBinding binding = bind();
|
||||||
|
public static final String OVERWORLD_TAG = getOverworldTag();
|
||||||
|
|
||||||
public static INMSBinding get() {
|
public static INMSBinding get() {
|
||||||
return binding;
|
return binding;
|
||||||
@@ -86,4 +95,26 @@ public class INMS {
|
|||||||
|
|
||||||
return new NMSBinding1X();
|
return new NMSBinding1X();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String getOverworldTag() {
|
||||||
|
var version = Bukkit.getServer().getBukkitVersion().split("-")[0].split("\\.", 3);
|
||||||
|
int major = 0;
|
||||||
|
int minor = 0;
|
||||||
|
|
||||||
|
if (version.length > 2) {
|
||||||
|
major = Integer.parseInt(version[1]);
|
||||||
|
minor = Integer.parseInt(version[2]);
|
||||||
|
} else if (version.length == 2) {
|
||||||
|
major = Integer.parseInt(version[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var p : PACKS) {
|
||||||
|
if (p.major > major || p.minor > minor)
|
||||||
|
continue;
|
||||||
|
return p.tag;
|
||||||
|
}
|
||||||
|
return "3910";
|
||||||
|
}
|
||||||
|
|
||||||
|
private record Version(int major, int minor, String tag) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,9 @@
|
|||||||
|
|
||||||
package com.volmit.iris.core.nms;
|
package com.volmit.iris.core.nms;
|
||||||
|
|
||||||
|
import com.volmit.iris.core.nms.container.AutoClosing;
|
||||||
import com.volmit.iris.core.nms.container.BiomeColor;
|
import com.volmit.iris.core.nms.container.BiomeColor;
|
||||||
|
import com.volmit.iris.core.nms.container.Pair;
|
||||||
import com.volmit.iris.core.nms.datapack.DataVersion;
|
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
@@ -30,15 +32,12 @@ import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess;
|
|||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.entity.Dolphin;
|
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.generator.structure.Structure;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
|
||||||
public interface INMSBinding {
|
public interface INMSBinding {
|
||||||
@@ -91,7 +90,12 @@ public interface INMSBinding {
|
|||||||
MCABiomeContainer newBiomeContainer(int min, int max);
|
MCABiomeContainer newBiomeContainer(int min, int max);
|
||||||
|
|
||||||
default World createWorld(WorldCreator c) {
|
default World createWorld(WorldCreator c) {
|
||||||
return c.createWorld();
|
if (missingDimensionTypes(true, true, true))
|
||||||
|
throw new IllegalStateException("Missing dimenstion types to create world");
|
||||||
|
|
||||||
|
try (var ignored = injectLevelStems()) {
|
||||||
|
return c.createWorld();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int countCustomBiomes();
|
int countCustomBiomes();
|
||||||
@@ -125,4 +129,10 @@ public interface INMSBinding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
KList<String> getStructureKeys();
|
KList<String> getStructureKeys();
|
||||||
|
|
||||||
|
AutoClosing injectLevelStems();
|
||||||
|
|
||||||
|
Pair<Integer, AutoClosing> injectUncached(boolean overworld, boolean nether, boolean end);
|
||||||
|
|
||||||
|
boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.volmit.iris.core.nms.container;
|
||||||
|
|
||||||
|
import com.volmit.iris.util.function.NastyRunnable;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class AutoClosing implements AutoCloseable {
|
||||||
|
private final AtomicBoolean closed = new AtomicBoolean();
|
||||||
|
private final NastyRunnable action;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
if (closed.getAndSet(true)) return;
|
||||||
|
try {
|
||||||
|
action.run();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,28 @@
|
|||||||
package com.volmit.iris.core.nms.datapack;
|
package com.volmit.iris.core.nms.datapack;
|
||||||
|
|
||||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
|
import com.volmit.iris.engine.object.IrisRange;
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
|
||||||
public interface IDataFixer {
|
public interface IDataFixer {
|
||||||
|
|
||||||
JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json);
|
default JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
JSONObject fixDimension(JSONObject json);
|
JSONObject rawDimension(Dimension dimension);
|
||||||
|
|
||||||
|
default JSONObject createDimension(Dimension dimension, IrisRange height, int logicalHeight) {
|
||||||
|
JSONObject obj = rawDimension(dimension);
|
||||||
|
obj.put("min_y", height.getMin());
|
||||||
|
obj.put("height", height.getMax() - height.getMin());
|
||||||
|
obj.put("logical_height", logicalHeight);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Dimension {
|
||||||
|
OVERRWORLD,
|
||||||
|
NETHER,
|
||||||
|
THE_END
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,81 @@
|
|||||||
package com.volmit.iris.core.nms.datapack.v1192;
|
package com.volmit.iris.core.nms.datapack.v1192;
|
||||||
|
|
||||||
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
||||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class DataFixerV1192 implements IDataFixer {
|
public class DataFixerV1192 implements IDataFixer {
|
||||||
|
|
||||||
@Override
|
private static final Map<Dimension, String> DIMENSIONS = Map.of(
|
||||||
public JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) {
|
Dimension.OVERRWORLD, """
|
||||||
return json;
|
{
|
||||||
}
|
"ambient_light": 0.0,
|
||||||
|
"bed_works": true,
|
||||||
|
"coordinate_scale": 1.0,
|
||||||
|
"effects": "minecraft:overworld",
|
||||||
|
"has_ceiling": false,
|
||||||
|
"has_raids": true,
|
||||||
|
"has_skylight": true,
|
||||||
|
"infiniburn": "#minecraft:infiniburn_overworld",
|
||||||
|
"monster_spawn_block_light_limit": 0,
|
||||||
|
"monster_spawn_light_level": {
|
||||||
|
"type": "minecraft:uniform",
|
||||||
|
"value": {
|
||||||
|
"max_inclusive": 7,
|
||||||
|
"min_inclusive": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"natural": true,
|
||||||
|
"piglin_safe": false,
|
||||||
|
"respawn_anchor_works": false,
|
||||||
|
"ultrawarm": false
|
||||||
|
}""",
|
||||||
|
Dimension.NETHER, """
|
||||||
|
{
|
||||||
|
"ambient_light": 0.1,
|
||||||
|
"bed_works": false,
|
||||||
|
"coordinate_scale": 8.0,
|
||||||
|
"effects": "minecraft:the_nether",
|
||||||
|
"fixed_time": 18000,
|
||||||
|
"has_ceiling": true,
|
||||||
|
"has_raids": false,
|
||||||
|
"has_skylight": false,
|
||||||
|
"infiniburn": "#minecraft:infiniburn_nether",
|
||||||
|
"monster_spawn_block_light_limit": 15,
|
||||||
|
"monster_spawn_light_level": 7,
|
||||||
|
"natural": false,
|
||||||
|
"piglin_safe": true,
|
||||||
|
"respawn_anchor_works": true,
|
||||||
|
"ultrawarm": true
|
||||||
|
}""",
|
||||||
|
Dimension.THE_END, """
|
||||||
|
{
|
||||||
|
"ambient_light": 0.0,
|
||||||
|
"bed_works": false,
|
||||||
|
"coordinate_scale": 1.0,
|
||||||
|
"effects": "minecraft:the_end",
|
||||||
|
"fixed_time": 6000,
|
||||||
|
"has_ceiling": false,
|
||||||
|
"has_raids": true,
|
||||||
|
"has_skylight": false,
|
||||||
|
"infiniburn": "#minecraft:infiniburn_end",
|
||||||
|
"monster_spawn_block_light_limit": 0,
|
||||||
|
"monster_spawn_light_level": {
|
||||||
|
"type": "minecraft:uniform",
|
||||||
|
"value": {
|
||||||
|
"max_inclusive": 7,
|
||||||
|
"min_inclusive": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"natural": false,
|
||||||
|
"piglin_safe": false,
|
||||||
|
"respawn_anchor_works": false,
|
||||||
|
"ultrawarm": false
|
||||||
|
}"""
|
||||||
|
);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JSONObject fixDimension(JSONObject json) {
|
public JSONObject rawDimension(Dimension dimension) {
|
||||||
return json;
|
return new JSONObject(DIMENSIONS.get(dimension));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.volmit.iris.core.nms.datapack.v1206;
|
package com.volmit.iris.core.nms.datapack.v1206;
|
||||||
|
|
||||||
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
import com.volmit.iris.core.nms.datapack.v1192.DataFixerV1192;
|
||||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
import com.volmit.iris.engine.object.IrisBiomeCustomSpawn;
|
import com.volmit.iris.engine.object.IrisBiomeCustomSpawn;
|
||||||
import com.volmit.iris.engine.object.IrisBiomeCustomSpawnType;
|
import com.volmit.iris.engine.object.IrisBiomeCustomSpawnType;
|
||||||
@@ -10,7 +10,7 @@ import com.volmit.iris.util.json.JSONObject;
|
|||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public class DataFixerV1206 implements IDataFixer {
|
public class DataFixerV1206 extends DataFixerV1192 {
|
||||||
@Override
|
@Override
|
||||||
public JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) {
|
public JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) {
|
||||||
int spawnRarity = biome.getSpawnRarity();
|
int spawnRarity = biome.getSpawnRarity();
|
||||||
@@ -45,7 +45,8 @@ public class DataFixerV1206 implements IDataFixer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JSONObject fixDimension(JSONObject json) {
|
public JSONObject rawDimension(Dimension dimension) {
|
||||||
|
JSONObject json = super.rawDimension(dimension);
|
||||||
if (!(json.get("monster_spawn_light_level") instanceof JSONObject lightLevel))
|
if (!(json.get("monster_spawn_light_level") instanceof JSONObject lightLevel))
|
||||||
return json;
|
return json;
|
||||||
var value = (JSONObject) lightLevel.remove("value");
|
var value = (JSONObject) lightLevel.remove("value");
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ package com.volmit.iris.core.nms.v1X;
|
|||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.nms.INMSBinding;
|
import com.volmit.iris.core.nms.INMSBinding;
|
||||||
|
import com.volmit.iris.core.nms.container.AutoClosing;
|
||||||
import com.volmit.iris.core.nms.container.BiomeColor;
|
import com.volmit.iris.core.nms.container.BiomeColor;
|
||||||
|
import com.volmit.iris.core.nms.container.Pair;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
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;
|
||||||
@@ -118,6 +120,21 @@ public class NMSBinding1X implements INMSBinding {
|
|||||||
return new KList<>(list);
|
return new KList<>(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AutoClosing injectLevelStems() {
|
||||||
|
return new AutoClosing(() -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pair<Integer, AutoClosing> injectUncached(boolean overworld, boolean nether, boolean end) {
|
||||||
|
return new Pair<>(0, new AutoClosing(() -> {}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag serializeEntity(Entity location) {
|
public CompoundTag serializeEntity(Entity location) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -165,8 +165,11 @@ public class ChunkUpdater {
|
|||||||
if (rX < dimensions.min.getX() || rX > dimensions.max.getX() || rZ < dimensions.min.getZ() || rZ > dimensions.max.getZ()) {
|
if (rX < dimensions.min.getX() || rX > dimensions.max.getX() || rZ < dimensions.min.getZ() || rZ > dimensions.max.getZ()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!new File(world.getWorldFolder(), "region" + File.separator + rX + "." + rZ + ".mca").exists()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PregenTask.iterateRegion(rX, rZ, (x, z) -> {
|
task.iterateChunks(rX, rZ, (x, z) -> {
|
||||||
while (paused.get() && !cancelled.get()) {
|
while (paused.get() && !cancelled.get()) {
|
||||||
J.sleep(50);
|
J.sleep(50);
|
||||||
}
|
}
|
||||||
@@ -348,8 +351,8 @@ public class ChunkUpdater {
|
|||||||
int width = maxZ - minZ + 1;
|
int width = maxZ - minZ + 1;
|
||||||
|
|
||||||
return new Dimensions(new Position2(minX, minZ), new Position2(maxX, maxZ), height * width, PregenTask.builder()
|
return new Dimensions(new Position2(minX, minZ), new Position2(maxX, maxZ), height * width, PregenTask.builder()
|
||||||
.width((int) Math.ceil(width / 2d))
|
.radiusZ((int) Math.ceil(width / 2d * 512))
|
||||||
.height((int) Math.ceil(height / 2d))
|
.radiusX((int) Math.ceil(height / 2d * 512))
|
||||||
.center(new Position2(oX, oZ))
|
.center(new Position2(oX, oZ))
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
package com.volmit.iris.core.pregenerator;
|
package com.volmit.iris.core.pregenerator;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.pack.IrisPack;
|
|
||||||
import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KSet;
|
import com.volmit.iris.util.collection.KSet;
|
||||||
@@ -83,7 +82,7 @@ public class IrisPregenerator {
|
|||||||
generatedLast = new AtomicInteger(0);
|
generatedLast = new AtomicInteger(0);
|
||||||
generatedLastMinute = new AtomicInteger(0);
|
generatedLastMinute = new AtomicInteger(0);
|
||||||
totalChunks = new AtomicInteger(0);
|
totalChunks = new AtomicInteger(0);
|
||||||
task.iterateRegions((_a, _b) -> totalChunks.addAndGet(1024));
|
task.iterateAllChunks((_a, _b) -> totalChunks.incrementAndGet());
|
||||||
startTime = new AtomicLong(M.ms());
|
startTime = new AtomicLong(M.ms());
|
||||||
ticker = new Looper() {
|
ticker = new Looper() {
|
||||||
@Override
|
@Override
|
||||||
@@ -194,7 +193,7 @@ public class IrisPregenerator {
|
|||||||
} else if (!regions) {
|
} else if (!regions) {
|
||||||
hit = true;
|
hit = true;
|
||||||
listener.onRegionGenerating(x, z);
|
listener.onRegionGenerating(x, z);
|
||||||
PregenTask.iterateRegion(x, z, (xx, zz) -> {
|
task.iterateChunks(x, z, (xx, zz) -> {
|
||||||
while (paused.get() && !shutdown.get()) {
|
while (paused.get() && !shutdown.get()) {
|
||||||
J.sleep(50);
|
J.sleep(50);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,17 +32,26 @@ import java.util.Comparator;
|
|||||||
@Data
|
@Data
|
||||||
public class PregenTask {
|
public class PregenTask {
|
||||||
private static final Position2 ZERO = new Position2(0, 0);
|
private static final Position2 ZERO = new Position2(0, 0);
|
||||||
private static final KList<Position2> ORDER_CENTER = computeChunkOrder();
|
|
||||||
private static final KMap<Position2, KList<Position2>> ORDERS = new KMap<>();
|
private static final KMap<Position2, KList<Position2>> ORDERS = new KMap<>();
|
||||||
|
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private boolean gui = false;
|
private final boolean gui = false;
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private Position2 center = new Position2(0, 0);
|
private final Position2 center = new Position2(0, 0);
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private int width = 1;
|
private final int radiusX = 1;
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private int height = 1;
|
private final int radiusZ = 1;
|
||||||
|
|
||||||
|
private final Bounds bounds = new Bounds();
|
||||||
|
|
||||||
|
protected PregenTask(boolean gui, Position2 center, int radiusX, int radiusZ) {
|
||||||
|
this.gui = gui;
|
||||||
|
this.center = new ProxiedPos(center);
|
||||||
|
this.radiusX = radiusX;
|
||||||
|
this.radiusZ = radiusZ;
|
||||||
|
bounds.update();
|
||||||
|
}
|
||||||
|
|
||||||
public static void iterateRegion(int xr, int zr, Spiraled s, Position2 pull) {
|
public static void iterateRegion(int xr, int zr, Spiraled s, Position2 pull) {
|
||||||
for (Position2 i : ORDERS.computeIfAbsent(pull, PregenTask::computeOrder)) {
|
for (Position2 i : ORDERS.computeIfAbsent(pull, PregenTask::computeOrder)) {
|
||||||
@@ -70,29 +79,72 @@ public class PregenTask {
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static KList<Position2> computeChunkOrder() {
|
public void iterateRegions(Spiraled s) {
|
||||||
Position2 center = new Position2(15, 15);
|
var bound = bounds.region();
|
||||||
KList<Position2> p = new KList<>();
|
new Spiraler(bound.sizeX, bound.sizeZ, ((x, z) -> {
|
||||||
new Spiraler(33, 33, (x, z) -> {
|
if (bound.check(x, z)) s.on(x, z);
|
||||||
int xx = x + 15;
|
})).setOffset(center.getX() >> 9, center.getZ() >> 9).drain();
|
||||||
int zz = z + 15;
|
|
||||||
if (xx < 0 || xx > 31 || zz < 0 || zz > 31) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.add(new Position2(xx, zz));
|
|
||||||
}).drain();
|
|
||||||
p.sort(Comparator.comparing((i) -> i.distance(center)));
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void iterateRegions(Spiraled s) {
|
public void iterateChunks(int rX, int rZ, Spiraled s) {
|
||||||
new Spiraler(getWidth() * 2, getHeight() * 2, s)
|
var bound = bounds.chunk();
|
||||||
.setOffset(center.getX(), center.getZ()).drain();
|
iterateRegion(rX, rZ, ((x, z) -> {
|
||||||
|
if (bound.check(x, z)) s.on(x, z);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void iterateAllChunks(Spiraled s) {
|
public void iterateAllChunks(Spiraled s) {
|
||||||
new Spiraler(getWidth() * 2, getHeight() * 2, (x, z) -> iterateRegion(x, z, s))
|
iterateRegions(((rX, rZ) -> iterateChunks(rX, rZ, s)));
|
||||||
.setOffset(center.getX(), center.getZ()).drain();
|
}
|
||||||
|
|
||||||
|
private class Bounds {
|
||||||
|
private Bound chunk = null;
|
||||||
|
private Bound region = null;
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
int maxX = center.getX() + radiusX;
|
||||||
|
int maxZ = center.getZ() + radiusZ;
|
||||||
|
int minX = center.getX() - radiusX;
|
||||||
|
int minZ = center.getZ() - radiusZ;
|
||||||
|
|
||||||
|
chunk = new Bound(minX >> 4, minZ >> 4, Math.ceilDiv(maxX, 16), Math.ceilDiv(maxZ, 16));
|
||||||
|
region = new Bound(minX >> 9, minZ >> 9, Math.ceilDiv(maxX, 512), Math.ceilDiv(maxZ, 512));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bound chunk() {
|
||||||
|
if (chunk == null) update();
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bound region() {
|
||||||
|
if (region == null) update();
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private record Bound(int minX, int maxX, int minZ, int maxZ, int sizeX, int sizeZ) {
|
||||||
|
private Bound(int minX, int minZ, int maxX, int maxZ) {
|
||||||
|
this(minX, maxX, minZ, maxZ, maxZ - minZ + 1, maxZ - minZ + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean check(int x, int z) {
|
||||||
|
return x >= minX && x <= maxX && z >= minZ && z <= maxZ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ProxiedPos extends Position2 {
|
||||||
|
public ProxiedPos(Position2 p) {
|
||||||
|
super(p.getX(), p.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setX(int x) {
|
||||||
|
throw new IllegalStateException("This Position2 may not be modified");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setZ(int z) {
|
||||||
|
throw new IllegalStateException("This Position2 may not be modified");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
package com.volmit.iris.core.pregenerator.methods;
|
package com.volmit.iris.core.pregenerator.methods;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.pregenerator.PregenListener;
|
import com.volmit.iris.core.pregenerator.PregenListener;
|
||||||
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
@@ -34,8 +35,10 @@ import org.bukkit.World;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class AsyncPregenMethod implements PregeneratorMethod {
|
public class AsyncPregenMethod implements PregeneratorMethod {
|
||||||
|
private static final AtomicInteger THREAD_COUNT = new AtomicInteger();
|
||||||
private final World world;
|
private final World world;
|
||||||
private final MultiBurst burst;
|
private final MultiBurst burst;
|
||||||
private final Semaphore semaphore;
|
private final Semaphore semaphore;
|
||||||
@@ -92,6 +95,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() {
|
||||||
unloadAndSaveAllChunks();
|
unloadAndSaveAllChunks();
|
||||||
|
increaseWorkerThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -104,6 +108,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
semaphore.acquireUninterruptibly(256);
|
semaphore.acquireUninterruptibly(256);
|
||||||
unloadAndSaveAllChunks();
|
unloadAndSaveAllChunks();
|
||||||
burst.close();
|
burst.close();
|
||||||
|
resetWorkerThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -140,4 +145,44 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void increaseWorkerThreads() {
|
||||||
|
THREAD_COUNT.updateAndGet(i -> {
|
||||||
|
if (i > 0) return 1;
|
||||||
|
try {
|
||||||
|
var field = Class.forName("ca.spottedleaf.moonrise.common.util.MoonriseCommon").getDeclaredField("WORKER_POOL");
|
||||||
|
var pool = field.get(null);
|
||||||
|
var threads = ((Thread[]) pool.getClass().getDeclaredMethod("getCoreThreads").invoke(pool)).length;
|
||||||
|
var adjusted = IrisSettings.get().getConcurrency().getWorldGenThreads();
|
||||||
|
if (threads >= adjusted) return 0;
|
||||||
|
|
||||||
|
pool.getClass().getDeclaredMethod("adjustThreadCount", int.class).invoke(pool, adjusted);
|
||||||
|
return threads;
|
||||||
|
} catch (ClassNotFoundException ignored) {
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.error("Failed to increase worker threads");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resetWorkerThreads() {
|
||||||
|
THREAD_COUNT.updateAndGet(i -> {
|
||||||
|
if (i == 0) return 0;
|
||||||
|
try {
|
||||||
|
var field = Class.forName("ca.spottedleaf.moonrise.common.util.MoonriseCommon").getDeclaredField("WORKER_POOL");
|
||||||
|
var pool = field.get(null);
|
||||||
|
var method = pool.getClass().getDeclaredMethod("adjustThreadCount", int.class);
|
||||||
|
method.invoke(pool, i);
|
||||||
|
return 0;
|
||||||
|
} catch (ClassNotFoundException ignored) {
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.error("Failed to reset worker threads");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.volmit.iris.core.safeguard;
|
package com.volmit.iris.core.safeguard;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.IrisSettings;
|
||||||
|
|
||||||
public class IrisSafeguard {
|
public class IrisSafeguard {
|
||||||
public static boolean unstablemode = false;
|
public static boolean unstablemode = false;
|
||||||
@@ -11,5 +12,13 @@ public class IrisSafeguard {
|
|||||||
Iris.info("Enabled Iris SafeGuard");
|
Iris.info("Enabled Iris SafeGuard");
|
||||||
ServerBootSFG.BootCheck();
|
ServerBootSFG.BootCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void earlySplash() {
|
||||||
|
if (ServerBootSFG.safeguardPassed || IrisSettings.get().getGeneral().DoomsdayAnnihilationSelfDestructMode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Iris.instance.splash();
|
||||||
|
UtilsSFG.splash();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.volmit.iris.core.safeguard;
|
|||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.nms.INMS;
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||||
|
import com.volmit.iris.engine.object.IrisContextInjector;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.PluginManager;
|
import org.bukkit.plugin.PluginManager;
|
||||||
@@ -29,6 +30,7 @@ public class ServerBootSFG {
|
|||||||
public static boolean isJRE = false;
|
public static boolean isJRE = false;
|
||||||
public static boolean hasPrivileges = true;
|
public static boolean hasPrivileges = true;
|
||||||
public static boolean unsuportedversion = false;
|
public static boolean unsuportedversion = false;
|
||||||
|
public static boolean missingDimensionTypes = false;
|
||||||
protected static boolean safeguardPassed;
|
protected static boolean safeguardPassed;
|
||||||
public static boolean passedserversoftware = true;
|
public static boolean passedserversoftware = true;
|
||||||
protected static int count;
|
protected static int count;
|
||||||
@@ -110,6 +112,12 @@ public class ServerBootSFG {
|
|||||||
severityMedium++;
|
severityMedium++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IrisContextInjector.isMissingDimensionTypes()) {
|
||||||
|
missingDimensionTypes = true;
|
||||||
|
joiner.add("Missing Dimension Types");
|
||||||
|
severityHigh++;
|
||||||
|
}
|
||||||
|
|
||||||
allIncompatibilities = joiner.toString();
|
allIncompatibilities = joiner.toString();
|
||||||
|
|
||||||
safeguardPassed = (severityHigh == 0 && severityMedium == 0 && severityLow == 0);
|
safeguardPassed = (severityHigh == 0 && severityMedium == 0 && severityLow == 0);
|
||||||
|
|||||||
@@ -37,7 +37,12 @@ public class UtilsSFG {
|
|||||||
}
|
}
|
||||||
if (ServerBootSFG.unsuportedversion) {
|
if (ServerBootSFG.unsuportedversion) {
|
||||||
Iris.safeguard(C.RED + "Server Version");
|
Iris.safeguard(C.RED + "Server Version");
|
||||||
Iris.safeguard(C.RED + "- Iris only supports 1.19.2 > 1.21.3");
|
Iris.safeguard(C.RED + "- Iris only supports 1.20.1 > 1.21.4");
|
||||||
|
}
|
||||||
|
if (ServerBootSFG.missingDimensionTypes) {
|
||||||
|
Iris.safeguard(C.RED + "Dimension Types");
|
||||||
|
Iris.safeguard(C.RED + "- Required Iris dimension types were not loaded.");
|
||||||
|
Iris.safeguard(C.RED + "- If this still happens after a restart please contact support.");
|
||||||
}
|
}
|
||||||
if (!ServerBootSFG.passedserversoftware) {
|
if (!ServerBootSFG.passedserversoftware) {
|
||||||
Iris.safeguard(C.YELLOW + "Unsupported Server Software");
|
Iris.safeguard(C.YELLOW + "Unsupported Server Software");
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.core.IrisSettings;
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.ServerConfigurator;
|
import com.volmit.iris.core.ServerConfigurator;
|
||||||
import com.volmit.iris.core.loader.IrisData;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.core.pack.IrisPack;
|
import com.volmit.iris.core.pack.IrisPack;
|
||||||
import com.volmit.iris.core.project.IrisProject;
|
import com.volmit.iris.core.project.IrisProject;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
@@ -64,7 +65,7 @@ public class StudioSVC implements IrisService {
|
|||||||
if (!f.exists()) {
|
if (!f.exists()) {
|
||||||
Iris.info("Downloading Default Pack " + pack);
|
Iris.info("Downloading Default Pack " + pack);
|
||||||
if (pack.equals("overworld")) {
|
if (pack.equals("overworld")) {
|
||||||
String url = "https://github.com/IrisDimensions/overworld/releases/download/" + Iris.OVERWORLD_TAG + "/overworld.zip";
|
String url = "https://github.com/IrisDimensions/overworld/releases/download/" + INMS.OVERWORLD_TAG + "/overworld.zip";
|
||||||
Iris.service(StudioSVC.class).downloadRelease(Iris.getSender(), url, false, false);
|
Iris.service(StudioSVC.class).downloadRelease(Iris.getSender(), url, false, false);
|
||||||
} else {
|
} else {
|
||||||
downloadSearch(Iris.getSender(), pack, false);
|
downloadSearch(Iris.getSender(), pack, false);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ 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.data.Cuboid;
|
import com.volmit.iris.util.data.Cuboid;
|
||||||
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
import com.volmit.iris.util.math.BlockPosition;
|
import com.volmit.iris.util.math.BlockPosition;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import com.volmit.iris.util.plugin.IrisService;
|
import com.volmit.iris.util.plugin.IrisService;
|
||||||
@@ -34,7 +35,6 @@ import com.volmit.iris.util.scheduling.J;
|
|||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.block.TileState;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.block.data.type.Sapling;
|
import org.bukkit.block.data.type.Sapling;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
@@ -142,7 +142,9 @@ public class TreeSVC implements IrisService {
|
|||||||
public void set(int x, int y, int z, BlockData d) {
|
public void set(int x, int y, int z, BlockData d) {
|
||||||
Block b = event.getWorld().getBlockAt(x, y, z);
|
Block b = event.getWorld().getBlockAt(x, y, z);
|
||||||
BlockState state = b.getState();
|
BlockState state = b.getState();
|
||||||
state.setBlockData(d);
|
if (d instanceof IrisCustomData data)
|
||||||
|
state.setBlockData(data.getBase());
|
||||||
|
else state.setBlockData(d);
|
||||||
blockStateList.add(b.getState());
|
blockStateList.add(b.getState());
|
||||||
dataCache.put(new Location(event.getWorld(), x, y, z), d);
|
dataCache.put(new Location(event.getWorld(), x, y, z), d);
|
||||||
}
|
}
|
||||||
@@ -213,12 +215,17 @@ public class TreeSVC implements IrisService {
|
|||||||
block = false;
|
block = false;
|
||||||
|
|
||||||
if (!iGrow.isCancelled()) {
|
if (!iGrow.isCancelled()) {
|
||||||
for (BlockState block : iGrow.getBlocks()) {
|
for (BlockState state : iGrow.getBlocks()) {
|
||||||
Location l = block.getLocation();
|
Location l = state.getLocation();
|
||||||
|
|
||||||
if (dataCache.containsKey(l)) {
|
BlockData d = dataCache.get(l);
|
||||||
l.getBlock().setBlockData(dataCache.get(l), false);
|
if (d == null) continue;
|
||||||
}
|
Block block = l.getBlock();
|
||||||
|
|
||||||
|
if (d instanceof IrisCustomData data) {
|
||||||
|
block.setBlockData(data.getBase(), false);
|
||||||
|
Iris.service(ExternalDataSVC.class).processUpdate(engine, block, data.getCustom());
|
||||||
|
} else block.setBlockData(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -30,15 +30,12 @@ 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.matter.Matter;
|
import com.volmit.iris.util.matter.Matter;
|
||||||
import com.volmit.iris.util.matter.WorldMatter;
|
import com.volmit.iris.util.matter.WorldMatter;
|
||||||
import com.volmit.iris.util.misc.E;
|
|
||||||
import com.volmit.iris.util.plugin.IrisService;
|
import com.volmit.iris.util.plugin.IrisService;
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
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.S;
|
|
||||||
import com.volmit.iris.util.scheduling.SR;
|
import com.volmit.iris.util.scheduling.SR;
|
||||||
import com.volmit.iris.util.scheduling.jobs.Job;
|
import com.volmit.iris.util.scheduling.jobs.Job;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
@@ -56,11 +53,11 @@ import java.awt.Color;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
import static com.volmit.iris.util.data.registry.Particles.CRIT_MAGIC;
|
||||||
|
import static com.volmit.iris.util.data.registry.Particles.REDSTONE;
|
||||||
|
|
||||||
public class WandSVC implements IrisService {
|
public class WandSVC implements IrisService {
|
||||||
private static final Particle CRIT_MAGIC = E.getOrDefault(Particle.class, "CRIT_MAGIC", "CRIT");
|
|
||||||
private static final Particle REDSTONE = E.getOrDefault(Particle.class, "REDSTONE", "DUST");
|
|
||||||
private static final int MS_PER_TICK = Integer.parseInt(System.getProperty("iris.ms_per_tick", "30"));
|
private static final int MS_PER_TICK = Integer.parseInt(System.getProperty("iris.ms_per_tick", "30"));
|
||||||
|
|
||||||
private static ItemStack dust;
|
private static ItemStack dust;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import com.google.common.util.concurrent.AtomicDouble;
|
|||||||
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.ServerConfigurator;
|
import com.volmit.iris.core.ServerConfigurator;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||||
import com.volmit.iris.core.service.StudioSVC;
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
import com.volmit.iris.engine.object.IrisDimension;
|
import com.volmit.iris.engine.object.IrisDimension;
|
||||||
@@ -83,7 +84,6 @@ public class IrisCreator {
|
|||||||
* Benchmark mode
|
* Benchmark mode
|
||||||
*/
|
*/
|
||||||
private boolean benchmark = false;
|
private boolean benchmark = false;
|
||||||
private boolean smartVanillaHeight = false;
|
|
||||||
|
|
||||||
public static boolean removeFromBukkitYml(String name) throws IOException {
|
public static boolean removeFromBukkitYml(String name) throws IOException {
|
||||||
YamlConfiguration yml = YamlConfiguration.loadConfiguration(BUKKIT_YML);
|
YamlConfiguration yml = YamlConfiguration.loadConfiguration(BUKKIT_YML);
|
||||||
@@ -137,7 +137,6 @@ public class IrisCreator {
|
|||||||
.name(name)
|
.name(name)
|
||||||
.seed(seed)
|
.seed(seed)
|
||||||
.studio(studio)
|
.studio(studio)
|
||||||
.smartVanillaHeight(smartVanillaHeight)
|
|
||||||
.create();
|
.create();
|
||||||
ServerConfigurator.installDataPacks(false);
|
ServerConfigurator.installDataPacks(false);
|
||||||
|
|
||||||
@@ -172,7 +171,7 @@ public class IrisCreator {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
J.sfut(() -> {
|
J.sfut(() -> {
|
||||||
world.set(wc.createWorld());
|
world.set(INMS.get().createWorld(wc));
|
||||||
}).get();
|
}).get();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ 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.exceptions.IrisException;
|
import com.volmit.iris.util.exceptions.IrisException;
|
||||||
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.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.Getter;
|
import lombok.Getter;
|
||||||
@@ -17,11 +18,6 @@ import org.bukkit.Bukkit;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.FileVisitResult;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.SimpleFileVisitor;
|
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -50,10 +46,7 @@ public class IrisPackBenchmarking {
|
|||||||
.start(() -> {
|
.start(() -> {
|
||||||
Iris.info("Setting up benchmark environment ");
|
Iris.info("Setting up benchmark environment ");
|
||||||
benchmarkInProgress = true;
|
benchmarkInProgress = true;
|
||||||
File file = new File("benchmark");
|
IO.delete(new File(Bukkit.getWorldContainer(), "benchmark"));
|
||||||
if (file.exists()) {
|
|
||||||
deleteDirectory(file.toPath());
|
|
||||||
}
|
|
||||||
createBenchmark();
|
createBenchmark();
|
||||||
while (!IrisToolbelt.isIrisWorld(Bukkit.getWorld("benchmark"))) {
|
while (!IrisToolbelt.isIrisWorld(Bukkit.getWorld("benchmark"))) {
|
||||||
J.sleep(1000);
|
J.sleep(1000);
|
||||||
@@ -72,7 +65,7 @@ public class IrisPackBenchmarking {
|
|||||||
|
|
||||||
public void finishedBenchmark(KList<Integer> cps) {
|
public void finishedBenchmark(KList<Integer> cps) {
|
||||||
try {
|
try {
|
||||||
String time = Form.duration(stopwatch.getMillis());
|
String time = Form.duration((long) stopwatch.getMilliseconds());
|
||||||
Engine engine = IrisToolbelt.access(Bukkit.getWorld("benchmark")).getEngine();
|
Engine engine = IrisToolbelt.access(Bukkit.getWorld("benchmark")).getEngine();
|
||||||
Iris.info("-----------------");
|
Iris.info("-----------------");
|
||||||
Iris.info("Results:");
|
Iris.info("Results:");
|
||||||
@@ -83,11 +76,7 @@ public class IrisPackBenchmarking {
|
|||||||
Iris.info(" - Lowest CPS: " + findLowest(cps));
|
Iris.info(" - Lowest CPS: " + findLowest(cps));
|
||||||
Iris.info("-----------------");
|
Iris.info("-----------------");
|
||||||
Iris.info("Creating a report..");
|
Iris.info("Creating a report..");
|
||||||
File profilers = new File("plugins" + File.separator + "Iris" + File.separator + "packbenchmarks");
|
File results = Iris.instance.getDataFile("packbenchmarks", dimension.getName() + " " + LocalDateTime.now(Clock.systemDefaultZone()).toString().replace(':', '-') + ".txt");
|
||||||
profilers.mkdir();
|
|
||||||
|
|
||||||
File results = new File(profilers, dimension.getName() + " " + LocalDateTime.now(Clock.systemDefaultZone()).toString().replace(':', '-') + ".txt");
|
|
||||||
results.getParentFile().mkdirs();
|
|
||||||
KMap<String, Double> metrics = engine.getMetrics().pull();
|
KMap<String, Double> metrics = engine.getMetrics().pull();
|
||||||
try (FileWriter writer = new FileWriter(results)) {
|
try (FileWriter writer = new FileWriter(results)) {
|
||||||
writer.write("-----------------\n");
|
writer.write("-----------------\n");
|
||||||
@@ -146,8 +135,8 @@ public class IrisPackBenchmarking {
|
|||||||
IrisToolbelt.pregenerate(PregenTask
|
IrisToolbelt.pregenerate(PregenTask
|
||||||
.builder()
|
.builder()
|
||||||
.gui(gui)
|
.gui(gui)
|
||||||
.width(radius)
|
.radiusX(radius)
|
||||||
.height(radius)
|
.radiusZ(radius)
|
||||||
.build(), Bukkit.getWorld("benchmark")
|
.build(), Bukkit.getWorld("benchmark")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -178,26 +167,4 @@ public class IrisPackBenchmarking {
|
|||||||
private int findHighest(KList<Integer> list) {
|
private int findHighest(KList<Integer> list) {
|
||||||
return Collections.max(list);
|
return Collections.max(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean deleteDirectory(Path dir) {
|
|
||||||
try {
|
|
||||||
Files.walkFileTree(dir, new SimpleFileVisitor<>() {
|
|
||||||
@Override
|
|
||||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
|
||||||
Files.delete(file);
|
|
||||||
return FileVisitResult.CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
|
||||||
Files.delete(dir);
|
|
||||||
return FileVisitResult.CONTINUE;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -21,10 +21,13 @@ package com.volmit.iris.core.tools;
|
|||||||
import com.volmit.iris.core.loader.IrisData;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
import com.volmit.iris.engine.object.*;
|
import com.volmit.iris.engine.object.*;
|
||||||
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
||||||
|
import com.volmit.iris.util.reflect.WrappedField;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.WorldCreator;
|
import org.bukkit.WorldCreator;
|
||||||
|
import org.bukkit.WorldType;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
@@ -32,7 +35,6 @@ public class IrisWorldCreator {
|
|||||||
private String name;
|
private String name;
|
||||||
private boolean studio = false;
|
private boolean studio = false;
|
||||||
private String dimensionName = null;
|
private String dimensionName = null;
|
||||||
private boolean smartVanillaHeight = false;
|
|
||||||
private long seed = 1337;
|
private long seed = 1337;
|
||||||
|
|
||||||
public IrisWorldCreator() {
|
public IrisWorldCreator() {
|
||||||
@@ -64,11 +66,6 @@ public class IrisWorldCreator {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IrisWorldCreator smartVanillaHeight(boolean smartVanillaHeight) {
|
|
||||||
this.smartVanillaHeight = smartVanillaHeight;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WorldCreator create() {
|
public WorldCreator create() {
|
||||||
IrisDimension dim = IrisData.loadAnyDimension(dimensionName);
|
IrisDimension dim = IrisData.loadAnyDimension(dimensionName);
|
||||||
|
|
||||||
@@ -82,7 +79,7 @@ public class IrisWorldCreator {
|
|||||||
.build();
|
.build();
|
||||||
ChunkGenerator g = new BukkitChunkGenerator(w, studio, studio
|
ChunkGenerator g = new BukkitChunkGenerator(w, studio, studio
|
||||||
? dim.getLoader().getDataFolder() :
|
? dim.getLoader().getDataFolder() :
|
||||||
new File(w.worldFolder(), "iris/pack"), dimensionName, smartVanillaHeight);
|
new File(w.worldFolder(), "iris/pack"), dimensionName);
|
||||||
|
|
||||||
|
|
||||||
return new WorldCreator(name)
|
return new WorldCreator(name)
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ package com.volmit.iris.core.wand;
|
|||||||
|
|
||||||
import com.volmit.iris.util.data.Cuboid;
|
import com.volmit.iris.util.data.Cuboid;
|
||||||
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.misc.E;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -29,8 +27,9 @@ import org.bukkit.util.Vector;
|
|||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
|
import static com.volmit.iris.util.data.registry.Particles.REDSTONE;
|
||||||
|
|
||||||
public class WandSelection {
|
public class WandSelection {
|
||||||
private static final Particle REDSTONE = E.getOrDefault(Particle.class, "REDSTONE", "DUST");
|
|
||||||
private final Cuboid c;
|
private final Cuboid c;
|
||||||
private final Player p;
|
private final Player p;
|
||||||
private static final double STEP = 0.10;
|
private static final double STEP = 0.10;
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ package com.volmit.iris.engine;
|
|||||||
import com.google.common.util.concurrent.AtomicDouble;
|
import com.google.common.util.concurrent.AtomicDouble;
|
||||||
import com.google.gson.Gson;
|
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.ServerConfigurator;
|
import com.volmit.iris.core.ServerConfigurator;
|
||||||
import com.volmit.iris.core.events.IrisEngineHotloadEvent;
|
import com.volmit.iris.core.events.IrisEngineHotloadEvent;
|
||||||
import com.volmit.iris.core.gui.PregeneratorJob;
|
import com.volmit.iris.core.gui.PregeneratorJob;
|
||||||
|
import com.volmit.iris.core.loader.ResourceLoader;
|
||||||
import com.volmit.iris.core.nms.container.BlockPos;
|
import com.volmit.iris.core.nms.container.BlockPos;
|
||||||
import com.volmit.iris.core.nms.container.Pair;
|
import com.volmit.iris.core.nms.container.Pair;
|
||||||
import com.volmit.iris.core.project.IrisProject;
|
import com.volmit.iris.core.project.IrisProject;
|
||||||
@@ -53,7 +53,6 @@ import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
@@ -63,11 +62,10 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(exclude = "context")
|
@EqualsAndHashCode(exclude = "context")
|
||||||
@@ -92,6 +90,7 @@ public class IrisEngine implements Engine {
|
|||||||
private final AtomicBoolean cleaning;
|
private final AtomicBoolean cleaning;
|
||||||
private final ChronoLatch cleanLatch;
|
private final ChronoLatch cleanLatch;
|
||||||
private final SeedManager seedManager;
|
private final SeedManager seedManager;
|
||||||
|
private CompletableFuture<Long> hash32;
|
||||||
private EngineMode mode;
|
private EngineMode mode;
|
||||||
private EngineEffects effects;
|
private EngineEffects effects;
|
||||||
private EngineExecutionEnvironment execution;
|
private EngineExecutionEnvironment execution;
|
||||||
@@ -174,8 +173,17 @@ public class IrisEngine implements Engine {
|
|||||||
complex = new IrisComplex(this);
|
complex = new IrisComplex(this);
|
||||||
execution = new IrisExecutionEnvironment(this);
|
execution = new IrisExecutionEnvironment(this);
|
||||||
effects = new IrisEngineEffects(this);
|
effects = new IrisEngineEffects(this);
|
||||||
|
hash32 = new CompletableFuture<>();
|
||||||
setupMode();
|
setupMode();
|
||||||
J.a(this::computeBiomeMaxes);
|
J.a(this::computeBiomeMaxes);
|
||||||
|
J.a(() -> {
|
||||||
|
File[] roots = getData().getLoaders()
|
||||||
|
.values()
|
||||||
|
.stream()
|
||||||
|
.map(ResourceLoader::getRoot)
|
||||||
|
.toArray(File[]::new);
|
||||||
|
hash32.complete(IO.hashRecursive(roots));
|
||||||
|
});
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.error("FAILED TO SETUP ENGINE!");
|
Iris.error("FAILED TO SETUP ENGINE!");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@@ -299,28 +300,6 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
energy += 1.2;
|
energy += 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
//@builder
|
|
||||||
IrisBiome biome = IrisSettings.get().getWorld().isAnbientEntitySpawningSystem()
|
|
||||||
? getEngine().getSurfaceBiome(c) : null;
|
|
||||||
IrisEntitySpawn v = IrisSettings.get().getWorld().isAnbientEntitySpawningSystem()
|
|
||||||
? spawnRandomly(Stream.concat(getData().getSpawnerLoader()
|
|
||||||
.loadAll(getDimension().getEntitySpawners())
|
|
||||||
.shuffleCopy(RNG.r).stream()
|
|
||||||
.filter(this::canSpawn)
|
|
||||||
.filter((i) -> i.isValid(biome))
|
|
||||||
.flatMap((i) -> stream(i, initial)),
|
|
||||||
Stream.concat(getData().getSpawnerLoader()
|
|
||||||
.loadAll(getEngine().getRegion(c.getX() << 4, c.getZ() << 4).getEntitySpawners())
|
|
||||||
.shuffleCopy(RNG.r).stream().filter(this::canSpawn)
|
|
||||||
.flatMap((i) -> stream(i, initial)),
|
|
||||||
getData().getSpawnerLoader()
|
|
||||||
.loadAll(getEngine().getSurfaceBiome(c.getX() << 4, c.getZ() << 4).getEntitySpawners())
|
|
||||||
.shuffleCopy(RNG.r).stream().filter(this::canSpawn)
|
|
||||||
.flatMap((i) -> stream(i, initial))))
|
|
||||||
.collect(Collectors.toList()))
|
|
||||||
.popRandom(RNG.r) : null;
|
|
||||||
//@done
|
|
||||||
|
|
||||||
if (IrisSettings.get().getWorld().isMarkerEntitySpawningSystem()) {
|
if (IrisSettings.get().getWorld().isMarkerEntitySpawningSystem()) {
|
||||||
getSpawnersFromMarkers(c).forEach((blockf, spawners) -> {
|
getSpawnersFromMarkers(c).forEach((blockf, spawners) -> {
|
||||||
if (spawners.isEmpty()) {
|
if (spawners.isEmpty()) {
|
||||||
@@ -335,94 +314,67 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v != null && v.getReferenceSpawner() != null) {
|
if (!IrisSettings.get().getWorld().isAnbientEntitySpawningSystem()) {
|
||||||
int maxEntCount = v.getReferenceSpawner().getMaxEntitiesPerChunk();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (Entity i : c.getEntities()) {
|
//@builder
|
||||||
if (i instanceof LivingEntity) {
|
Predicate<IrisSpawner> filter = i -> i.canSpawn(getEngine(), c.getX(), c.getZ());
|
||||||
if (-maxEntCount <= 0) {
|
ChunkCounter counter = new ChunkCounter(c.getEntities());
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
IrisBiome biome = getEngine().getSurfaceBiome(c);
|
||||||
spawn(c, v);
|
IrisEntitySpawn v = spawnRandomly(Stream.concat(getData().getSpawnerLoader()
|
||||||
} catch (Throwable e) {
|
.loadAll(getDimension().getEntitySpawners())
|
||||||
J.s(() -> spawn(c, v));
|
.shuffleCopy(RNG.r)
|
||||||
}
|
.stream()
|
||||||
|
.filter(filter)
|
||||||
|
.filter((i) -> i.isValid(biome)),
|
||||||
|
Stream.concat(getData()
|
||||||
|
.getSpawnerLoader()
|
||||||
|
.loadAll(getEngine().getRegion(c.getX() << 4, c.getZ() << 4).getEntitySpawners())
|
||||||
|
.shuffleCopy(RNG.r)
|
||||||
|
.stream()
|
||||||
|
.filter(filter),
|
||||||
|
getData().getSpawnerLoader()
|
||||||
|
.loadAll(getEngine().getSurfaceBiome(c.getX() << 4, c.getZ() << 4).getEntitySpawners())
|
||||||
|
.shuffleCopy(RNG.r)
|
||||||
|
.stream()
|
||||||
|
.filter(filter)))
|
||||||
|
.filter(counter)
|
||||||
|
.flatMap((i) -> stream(i, initial))
|
||||||
|
.collect(Collectors.toList()))
|
||||||
|
.getRandom();
|
||||||
|
//@done
|
||||||
|
if (v == null || v.getReferenceSpawner() == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
spawn(c, v);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
J.s(() -> spawn(c, v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void spawn(Chunk c, IrisEntitySpawn i) {
|
private void spawn(Chunk c, IrisEntitySpawn i) {
|
||||||
boolean allow = true;
|
IrisSpawner ref = i.getReferenceSpawner();
|
||||||
|
int s = i.spawn(getEngine(), c, RNG.r);
|
||||||
if (!i.getReferenceSpawner().getMaximumRatePerChunk().isInfinite()) {
|
actuallySpawned += s;
|
||||||
allow = false;
|
if (s > 0) {
|
||||||
IrisEngineChunkData cd = getEngine().getEngineData().getChunk(c.getX(), c.getZ());
|
ref.spawn(getEngine(), c.getX(), c.getZ());
|
||||||
IrisEngineSpawnerCooldown sc = null;
|
energy -= s * ((i.getEnergyMultiplier() * ref.getEnergyMultiplier() * 1));
|
||||||
for (IrisEngineSpawnerCooldown j : cd.getCooldowns()) {
|
|
||||||
if (j.getSpawner().equals(i.getReferenceSpawner().getLoadKey())) {
|
|
||||||
sc = j;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sc == null) {
|
|
||||||
sc = new IrisEngineSpawnerCooldown();
|
|
||||||
sc.setSpawner(i.getReferenceSpawner().getLoadKey());
|
|
||||||
cd.getCooldowns().add(sc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sc.canSpawn(i.getReferenceSpawner().getMaximumRatePerChunk())) {
|
|
||||||
sc.spawn(getEngine());
|
|
||||||
allow = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allow) {
|
|
||||||
int s = i.spawn(getEngine(), c, RNG.r);
|
|
||||||
actuallySpawned += s;
|
|
||||||
if (s > 0) {
|
|
||||||
getCooldown(i.getReferenceSpawner()).spawn(getEngine());
|
|
||||||
energy -= s * ((i.getEnergyMultiplier() * i.getReferenceSpawner().getEnergyMultiplier() * 1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void spawn(IrisPosition c, IrisEntitySpawn i) {
|
private void spawn(IrisPosition pos, IrisEntitySpawn i) {
|
||||||
boolean allow = true;
|
IrisSpawner ref = i.getReferenceSpawner();
|
||||||
|
if (!ref.canSpawn(getEngine(), pos.getX() >> 4, pos.getZ()))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!i.getReferenceSpawner().getMaximumRatePerChunk().isInfinite()) {
|
int s = i.spawn(getEngine(), pos, RNG.r);
|
||||||
allow = false;
|
actuallySpawned += s;
|
||||||
IrisEngineChunkData cd = getEngine().getEngineData().getChunk(c.getX() >> 4, c.getZ() >> 4);
|
if (s > 0) {
|
||||||
IrisEngineSpawnerCooldown sc = null;
|
ref.spawn(getEngine(), pos.getX() >> 4, pos.getZ() >> 4);
|
||||||
for (IrisEngineSpawnerCooldown j : cd.getCooldowns()) {
|
energy -= s * ((i.getEnergyMultiplier() * ref.getEnergyMultiplier() * 1));
|
||||||
if (j.getSpawner().equals(i.getReferenceSpawner().getLoadKey())) {
|
|
||||||
sc = j;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sc == null) {
|
|
||||||
sc = new IrisEngineSpawnerCooldown();
|
|
||||||
sc.setSpawner(i.getReferenceSpawner().getLoadKey());
|
|
||||||
cd.getCooldowns().add(sc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sc.canSpawn(i.getReferenceSpawner().getMaximumRatePerChunk())) {
|
|
||||||
sc.spawn(getEngine());
|
|
||||||
allow = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allow) {
|
|
||||||
int s = i.spawn(getEngine(), c, RNG.r);
|
|
||||||
actuallySpawned += s;
|
|
||||||
if (s > 0) {
|
|
||||||
getCooldown(i.getReferenceSpawner()).spawn(getEngine());
|
|
||||||
energy -= s * ((i.getEnergyMultiplier() * i.getReferenceSpawner().getEnergyMultiplier() * 1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,31 +402,6 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
return rarityTypes;
|
return rarityTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canSpawn(IrisSpawner i) {
|
|
||||||
return i.isValid(getEngine().getWorld().realWorld())
|
|
||||||
&& getCooldown(i).canSpawn(i.getMaximumRate());
|
|
||||||
}
|
|
||||||
|
|
||||||
private IrisEngineSpawnerCooldown getCooldown(IrisSpawner i) {
|
|
||||||
IrisEngineData ed = getEngine().getEngineData();
|
|
||||||
IrisEngineSpawnerCooldown cd = null;
|
|
||||||
|
|
||||||
for (IrisEngineSpawnerCooldown j : ed.getSpawnerCooldowns().copy()) {
|
|
||||||
if (j.getSpawner().equals(i.getLoadKey())) {
|
|
||||||
cd = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cd == null) {
|
|
||||||
cd = new IrisEngineSpawnerCooldown();
|
|
||||||
cd.setSpawner(i.getLoadKey());
|
|
||||||
cd.setLastSpawn(M.ms() - i.getMaximumRate().getInterval());
|
|
||||||
ed.getSpawnerCooldowns().add(cd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cd;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTick() {
|
public void onTick() {
|
||||||
|
|
||||||
@@ -708,4 +635,27 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
|
|
||||||
return (double) entityCount / (getEngine().getWorld().realWorld().getLoadedChunks().length + 1) * 1.28;
|
return (double) entityCount / (getEngine().getWorld().realWorld().getLoadedChunks().length + 1) * 1.28;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
private static class ChunkCounter implements Predicate<IrisSpawner> {
|
||||||
|
private final Entity[] entities;
|
||||||
|
private transient int index = 0;
|
||||||
|
private transient int count = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(IrisSpawner spawner) {
|
||||||
|
int max = spawner.getMaxEntitiesPerChunk();
|
||||||
|
if (max <= count)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (index < entities.length) {
|
||||||
|
if (entities[index++] instanceof LivingEntity) {
|
||||||
|
if (++count >= max)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ package com.volmit.iris.engine.data.chunk;
|
|||||||
import com.volmit.iris.core.nms.BiomeBaseInjector;
|
import com.volmit.iris.core.nms.BiomeBaseInjector;
|
||||||
import com.volmit.iris.core.nms.INMS;
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.util.data.IrisBiomeStorage;
|
import com.volmit.iris.util.data.IrisBiomeStorage;
|
||||||
import com.volmit.iris.util.data.IrisBlockData;
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@@ -121,7 +121,7 @@ public class LinkedTerrainChunk implements TerrainChunk {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void setBlock(int x, int y, int z, BlockData blockData) {
|
public synchronized void setBlock(int x, int y, int z, BlockData blockData) {
|
||||||
if (blockData instanceof IrisBlockData d)
|
if (blockData instanceof IrisCustomData d)
|
||||||
blockData = d.getBase();
|
blockData = d.getBase();
|
||||||
rawChunkData.setBlock(x, y, z, blockData);
|
rawChunkData.setBlock(x, y, z, blockData);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ package com.volmit.iris.engine.data.chunk;
|
|||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.nms.BiomeBaseInjector;
|
import com.volmit.iris.core.nms.BiomeBaseInjector;
|
||||||
import com.volmit.iris.util.data.IrisBlockData;
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
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;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
@@ -89,7 +89,7 @@ public class MCATerrainChunk implements TerrainChunk {
|
|||||||
if (blockData == null) {
|
if (blockData == null) {
|
||||||
Iris.error("NULL BD");
|
Iris.error("NULL BD");
|
||||||
}
|
}
|
||||||
if (blockData instanceof IrisBlockData data)
|
if (blockData instanceof IrisCustomData data)
|
||||||
blockData = data.getBase();
|
blockData = data.getBase();
|
||||||
|
|
||||||
mcaChunk.setBlockStateAt(xx, y, zz, NBTWorld.getCompound(blockData), false);
|
mcaChunk.setBlockStateAt(xx, y, zz, NBTWorld.getCompound(blockData), false);
|
||||||
|
|||||||
@@ -18,18 +18,16 @@
|
|||||||
|
|
||||||
package com.volmit.iris.engine.decorator;
|
package com.volmit.iris.engine.decorator;
|
||||||
|
|
||||||
import com.volmit.iris.engine.data.cache.Cache;
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
import com.volmit.iris.engine.object.IrisDecorationPart;
|
import com.volmit.iris.engine.object.IrisDecorationPart;
|
||||||
import com.volmit.iris.engine.object.IrisDecorator;
|
import com.volmit.iris.engine.object.IrisDecorator;
|
||||||
import com.volmit.iris.util.data.B;
|
|
||||||
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;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.block.data.MultipleFacing;
|
|
||||||
import org.bukkit.block.data.type.PointedDripstone;
|
import org.bukkit.block.data.type.PointedDripstone;
|
||||||
|
|
||||||
public class IrisCeilingDecorator extends IrisEngineDecorator {
|
public class IrisCeilingDecorator extends IrisEngineDecorator {
|
||||||
@@ -40,12 +38,14 @@ public class IrisCeilingDecorator extends IrisEngineDecorator {
|
|||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
@Override
|
@Override
|
||||||
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, IrisBiome biome, int height, int max) {
|
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, IrisBiome biome, int height, int max) {
|
||||||
IrisDecorator decorator = getDecorator(biome, realX, realZ);
|
RNG rng = getRNG(realX, realZ);
|
||||||
|
IrisDecorator decorator = getDecorator(rng, biome, realX, realZ);
|
||||||
|
|
||||||
if (decorator != null) {
|
if (decorator != null) {
|
||||||
if (!decorator.isStacking()) {
|
if (!decorator.isStacking()) {
|
||||||
data.set(x, height, z, fixFaces(decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()), realX, height, realZ));
|
data.set(x, height, z, fixFaces(decorator.getBlockData100(biome, rng, realX, height, realZ, getData()), data, x, z, realX, height, realZ));
|
||||||
} else {
|
} else {
|
||||||
int stack = decorator.getHeight(getRng().nextParallelRNG(Cache.key(realX, realZ)), realX, realZ, getData());
|
int stack = decorator.getHeight(rng, realX, realZ, getData());
|
||||||
if (decorator.isScaleStack()) {
|
if (decorator.isScaleStack()) {
|
||||||
stack = Math.min((int) Math.ceil((double) max * ((double) stack / 100)), decorator.getAbsoluteMaxStack());
|
stack = Math.min((int) Math.ceil((double) max * ((double) stack / 100)), decorator.getAbsoluteMaxStack());
|
||||||
} else {
|
} else {
|
||||||
@@ -53,7 +53,7 @@ public class IrisCeilingDecorator extends IrisEngineDecorator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stack == 1) {
|
if (stack == 1) {
|
||||||
data.set(x, height, z, decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData()));
|
data.set(x, height, z, decorator.getBlockDataForTop(biome, rng, realX, height, realZ, getData()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,8 +66,8 @@ public class IrisCeilingDecorator extends IrisEngineDecorator {
|
|||||||
double threshold = (((double) i) / (double) (stack - 1));
|
double threshold = (((double) i) / (double) (stack - 1));
|
||||||
|
|
||||||
BlockData bd = threshold >= decorator.getTopThreshold() ?
|
BlockData bd = threshold >= decorator.getTopThreshold() ?
|
||||||
decorator.getBlockDataForTop(biome, getRng(), realX, h, realZ, getData()) :
|
decorator.getBlockDataForTop(biome, rng, realX, h, realZ, getData()) :
|
||||||
decorator.getBlockData100(biome, getRng(), realX, h, realZ, getData());
|
decorator.getBlockData100(biome, rng, realX, h, realZ, getData());
|
||||||
|
|
||||||
if (bd instanceof PointedDripstone) {
|
if (bd instanceof PointedDripstone) {
|
||||||
PointedDripstone.Thickness th = PointedDripstone.Thickness.BASE;
|
PointedDripstone.Thickness th = PointedDripstone.Thickness.BASE;
|
||||||
@@ -97,24 +97,4 @@ public class IrisCeilingDecorator extends IrisEngineDecorator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private BlockData fixFaces(BlockData b, int x, int y, int z) {
|
|
||||||
if (B.isVineBlock(b)) {
|
|
||||||
MultipleFacing data = (MultipleFacing) b.clone();
|
|
||||||
boolean found = false;
|
|
||||||
for (BlockFace f : BlockFace.values()) {
|
|
||||||
if (!f.isCartesian())
|
|
||||||
continue;
|
|
||||||
Material m = getEngine().getMantle().get(x + f.getModX(), y + f.getModY(), z + f.getModZ()).getMaterial();
|
|
||||||
if (m.isSolid()) {
|
|
||||||
found = true;
|
|
||||||
data.setFace(f, m.isSolid());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
data.setFace(BlockFace.UP, true);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
package com.volmit.iris.engine.decorator;
|
package com.volmit.iris.engine.decorator;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.engine.data.cache.Cache;
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.framework.EngineAssignedComponent;
|
import com.volmit.iris.engine.framework.EngineAssignedComponent;
|
||||||
import com.volmit.iris.engine.framework.EngineDecorator;
|
import com.volmit.iris.engine.framework.EngineDecorator;
|
||||||
@@ -27,30 +26,42 @@ import com.volmit.iris.engine.object.IrisBiome;
|
|||||||
import com.volmit.iris.engine.object.IrisDecorationPart;
|
import com.volmit.iris.engine.object.IrisDecorationPart;
|
||||||
import com.volmit.iris.engine.object.IrisDecorator;
|
import com.volmit.iris.engine.object.IrisDecorator;
|
||||||
import com.volmit.iris.util.collection.KList;
|
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.documentation.BlockCoordinates;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.block.BlockSupport;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.block.data.MultipleFacing;
|
||||||
|
|
||||||
public abstract class IrisEngineDecorator extends EngineAssignedComponent implements EngineDecorator {
|
public abstract class IrisEngineDecorator extends EngineAssignedComponent implements EngineDecorator {
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final RNG rng;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final IrisDecorationPart part;
|
private final IrisDecorationPart part;
|
||||||
|
private final long seed;
|
||||||
|
private final long modX, modZ;
|
||||||
|
|
||||||
public IrisEngineDecorator(Engine engine, String name, IrisDecorationPart part) {
|
public IrisEngineDecorator(Engine engine, String name, IrisDecorationPart part) {
|
||||||
super(engine, name + " Decorator");
|
super(engine, name + " Decorator");
|
||||||
this.part = part;
|
this.part = part;
|
||||||
this.rng = new RNG(getSeed() + 29356788 - (part.ordinal() * 10439677L));
|
this.seed = getSeed() + 29356788 - (part.ordinal() * 10439677L);
|
||||||
|
this.modX = 29356788 ^ (part.ordinal() + 6);
|
||||||
|
this.modZ = 10439677 ^ (part.ordinal() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IrisDecorator getDecorator(IrisBiome biome, double realX, double realZ) {
|
@BlockCoordinates
|
||||||
KList<IrisDecorator> v = new KList<>();
|
protected RNG getRNG(int x, int z) {
|
||||||
RNG rng = new RNG(Cache.key((int) realX, (int) realZ));
|
return new RNG(x * modX + z * modZ + seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IrisDecorator getDecorator(RNG rng, IrisBiome biome, double realX, double realZ) {
|
||||||
|
KList<IrisDecorator> v = new KList<>();
|
||||||
|
|
||||||
|
RNG gRNG = new RNG(seed);
|
||||||
for (IrisDecorator i : biome.getDecorators()) {
|
for (IrisDecorator i : biome.getDecorators()) {
|
||||||
try {
|
try {
|
||||||
if (i.getPartOf().equals(part) && i.getBlockData(biome, this.rng, realX, realZ, getData()) != null) {
|
if (i.getPartOf().equals(part) && i.getBlockData(biome, gRNG, realX, realZ, getData()) != null) {
|
||||||
v.add(i);
|
v.add(i);
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@@ -65,4 +76,40 @@ public abstract class IrisEngineDecorator extends EngineAssignedComponent implem
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected BlockData fixFaces(BlockData b, Hunk<BlockData> hunk, int rX, int rZ, int x, int y, int z) {
|
||||||
|
if (B.isVineBlock(b)) {
|
||||||
|
MultipleFacing data = (MultipleFacing) b.clone();
|
||||||
|
data.getFaces().forEach(f -> data.setFace(f, false));
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (BlockFace f : BlockFace.values()) {
|
||||||
|
if (!f.isCartesian())
|
||||||
|
continue;
|
||||||
|
int yy = y + f.getModY();
|
||||||
|
|
||||||
|
BlockData r = getEngine().getMantle().get(x + f.getModX(), yy, z + f.getModZ());
|
||||||
|
if (r.isFaceSturdy(f.getOppositeFace(), BlockSupport.FULL)) {
|
||||||
|
found = true;
|
||||||
|
data.setFace(f, true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xx = rX + f.getModX();
|
||||||
|
int zz = rZ + f.getModZ();
|
||||||
|
if (xx < 0 || xx > 15 || zz < 0 || zz > 15 || yy < 0 || yy > hunk.getHeight())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
r = hunk.get(xx, yy, zz);
|
||||||
|
if (r.isFaceSturdy(f.getOppositeFace(), BlockSupport.FULL)) {
|
||||||
|
found = true;
|
||||||
|
data.setFace(f, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
data.setFace(BlockFace.DOWN, true);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,13 @@
|
|||||||
|
|
||||||
package com.volmit.iris.engine.decorator;
|
package com.volmit.iris.engine.decorator;
|
||||||
|
|
||||||
import com.volmit.iris.engine.data.cache.Cache;
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
import com.volmit.iris.engine.object.IrisDecorationPart;
|
import com.volmit.iris.engine.object.IrisDecorationPart;
|
||||||
import com.volmit.iris.engine.object.IrisDecorator;
|
import com.volmit.iris.engine.object.IrisDecorator;
|
||||||
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;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
public class IrisSeaFloorDecorator extends IrisEngineDecorator {
|
public class IrisSeaFloorDecorator extends IrisEngineDecorator {
|
||||||
@@ -35,7 +35,8 @@ public class IrisSeaFloorDecorator extends IrisEngineDecorator {
|
|||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
@Override
|
@Override
|
||||||
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, IrisBiome biome, int height, int max) {
|
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, IrisBiome biome, int height, int max) {
|
||||||
IrisDecorator decorator = getDecorator(biome, realX, realZ);
|
RNG rng = getRNG(realX, realZ);
|
||||||
|
IrisDecorator decorator = getDecorator(rng, biome, realX, realZ);
|
||||||
|
|
||||||
if (decorator != null) {
|
if (decorator != null) {
|
||||||
if (!decorator.isStacking()) {
|
if (!decorator.isStacking()) {
|
||||||
@@ -44,17 +45,17 @@ public class IrisSeaFloorDecorator extends IrisEngineDecorator {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (height >= 0 || height < getEngine().getHeight()) {
|
if (height >= 0 || height < getEngine().getHeight()) {
|
||||||
data.set(x, height, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));
|
data.set(x, height, z, decorator.getBlockData100(biome, rng, realX, height, realZ, getData()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int stack = decorator.getHeight(getRng().nextParallelRNG(Cache.key(realX, realZ)), realX, realZ, getData());
|
int stack = decorator.getHeight(rng, realX, realZ, getData());
|
||||||
if (decorator.isScaleStack()) {
|
if (decorator.isScaleStack()) {
|
||||||
int maxStack = max - height;
|
int maxStack = max - height;
|
||||||
stack = (int) Math.ceil((double) maxStack * ((double) stack / 100));
|
stack = (int) Math.ceil((double) maxStack * ((double) stack / 100));
|
||||||
} else stack = Math.min(stack, max - height);
|
} else stack = Math.min(stack, max - height);
|
||||||
|
|
||||||
if (stack == 1) {
|
if (stack == 1) {
|
||||||
data.set(x, height, z, decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData()));
|
data.set(x, height, z, decorator.getBlockDataForTop(biome, rng, realX, height, realZ, getData()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,8 +67,8 @@ public class IrisSeaFloorDecorator extends IrisEngineDecorator {
|
|||||||
|
|
||||||
double threshold = ((double) i) / (stack - 1);
|
double threshold = ((double) i) / (stack - 1);
|
||||||
data.set(x, h, z, threshold >= decorator.getTopThreshold() ?
|
data.set(x, h, z, threshold >= decorator.getTopThreshold() ?
|
||||||
decorator.getBlockDataForTop(biome, getRng(), realX, h, realZ, getData()) :
|
decorator.getBlockDataForTop(biome, rng, realX, h, realZ, getData()) :
|
||||||
decorator.getBlockData100(biome, getRng(), realX, h, realZ, getData()));
|
decorator.getBlockData100(biome, rng, realX, h, realZ, getData()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,13 @@
|
|||||||
|
|
||||||
package com.volmit.iris.engine.decorator;
|
package com.volmit.iris.engine.decorator;
|
||||||
|
|
||||||
import com.volmit.iris.engine.data.cache.Cache;
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
import com.volmit.iris.engine.object.IrisDecorationPart;
|
import com.volmit.iris.engine.object.IrisDecorationPart;
|
||||||
import com.volmit.iris.engine.object.IrisDecorator;
|
import com.volmit.iris.engine.object.IrisDecorator;
|
||||||
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;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
public class IrisSeaSurfaceDecorator extends IrisEngineDecorator {
|
public class IrisSeaSurfaceDecorator extends IrisEngineDecorator {
|
||||||
@@ -35,22 +35,23 @@ public class IrisSeaSurfaceDecorator extends IrisEngineDecorator {
|
|||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
@Override
|
@Override
|
||||||
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, IrisBiome biome, int height, int max) {
|
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, IrisBiome biome, int height, int max) {
|
||||||
IrisDecorator decorator = getDecorator(biome, realX, realZ);
|
RNG rng = getRNG(realX, realZ);
|
||||||
|
IrisDecorator decorator = getDecorator(rng, biome, realX, realZ);
|
||||||
|
|
||||||
if (decorator != null) {
|
if (decorator != null) {
|
||||||
if (!decorator.isStacking()) {
|
if (!decorator.isStacking()) {
|
||||||
if (height >= 0 || height < getEngine().getHeight()) {
|
if (height >= 0 || height < getEngine().getHeight()) {
|
||||||
data.set(x, height + 1, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));
|
data.set(x, height + 1, z, decorator.getBlockData100(biome, rng, realX, height, realZ, getData()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int stack = decorator.getHeight(getRng().nextParallelRNG(Cache.key(realX, realZ)), realX, realZ, getData());
|
int stack = decorator.getHeight(rng, realX, realZ, getData());
|
||||||
if (decorator.isScaleStack()) {
|
if (decorator.isScaleStack()) {
|
||||||
int maxStack = max - height;
|
int maxStack = max - height;
|
||||||
stack = (int) Math.ceil((double) maxStack * ((double) stack / 100));
|
stack = (int) Math.ceil((double) maxStack * ((double) stack / 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stack == 1) {
|
if (stack == 1) {
|
||||||
data.set(x, height, z, decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData()));
|
data.set(x, height, z, decorator.getBlockDataForTop(biome, rng, realX, height, realZ, getData()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,8 +63,8 @@ public class IrisSeaSurfaceDecorator extends IrisEngineDecorator {
|
|||||||
|
|
||||||
double threshold = ((double) i) / (stack - 1);
|
double threshold = ((double) i) / (stack - 1);
|
||||||
data.set(x, h + 1, z, threshold >= decorator.getTopThreshold() ?
|
data.set(x, h + 1, z, threshold >= decorator.getTopThreshold() ?
|
||||||
decorator.getBlockDataForTop(biome, getRng().nextParallelRNG(i), realX, h, realZ, getData()) :
|
decorator.getBlockDataForTop(biome, rng, realX, h, realZ, getData()) :
|
||||||
decorator.getBlockData100(biome, getRng().nextParallelRNG(i), realX, h, realZ, getData()));
|
decorator.getBlockData100(biome, rng, realX, h, realZ, getData()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,13 @@
|
|||||||
|
|
||||||
package com.volmit.iris.engine.decorator;
|
package com.volmit.iris.engine.decorator;
|
||||||
|
|
||||||
import com.volmit.iris.engine.data.cache.Cache;
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
import com.volmit.iris.engine.object.IrisDecorationPart;
|
import com.volmit.iris.engine.object.IrisDecorationPart;
|
||||||
import com.volmit.iris.engine.object.IrisDecorator;
|
import com.volmit.iris.engine.object.IrisDecorator;
|
||||||
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;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
public class IrisShoreLineDecorator extends IrisEngineDecorator {
|
public class IrisShoreLineDecorator extends IrisEngineDecorator {
|
||||||
@@ -42,7 +42,8 @@ public class IrisShoreLineDecorator extends IrisEngineDecorator {
|
|||||||
Math.round(getComplex().getHeightStream().get(realX, realZ1)) < getComplex().getFluidHeight() ||
|
Math.round(getComplex().getHeightStream().get(realX, realZ1)) < getComplex().getFluidHeight() ||
|
||||||
Math.round(getComplex().getHeightStream().get(realX, realZ_1)) < getComplex().getFluidHeight()
|
Math.round(getComplex().getHeightStream().get(realX, realZ_1)) < getComplex().getFluidHeight()
|
||||||
) {
|
) {
|
||||||
IrisDecorator decorator = getDecorator(biome, realX, realZ);
|
RNG rng = getRNG(realX, realZ);
|
||||||
|
IrisDecorator decorator = getDecorator(rng, biome, realX, realZ);
|
||||||
|
|
||||||
if (decorator != null) {
|
if (decorator != null) {
|
||||||
if (!decorator.isForcePlace() && !decorator.getSlopeCondition().isDefault()
|
if (!decorator.isForcePlace() && !decorator.getSlopeCondition().isDefault()
|
||||||
@@ -51,16 +52,16 @@ public class IrisShoreLineDecorator extends IrisEngineDecorator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!decorator.isStacking()) {
|
if (!decorator.isStacking()) {
|
||||||
data.set(x, height + 1, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));
|
data.set(x, height + 1, z, decorator.getBlockData100(biome, rng, realX, height, realZ, getData()));
|
||||||
} else {
|
} else {
|
||||||
int stack = decorator.getHeight(getRng().nextParallelRNG(Cache.key(realX, realZ)), realX, realZ, getData());
|
int stack = decorator.getHeight(rng, realX, realZ, getData());
|
||||||
if (decorator.isScaleStack()) {
|
if (decorator.isScaleStack()) {
|
||||||
int maxStack = max - height;
|
int maxStack = max - height;
|
||||||
stack = (int) Math.ceil((double) maxStack * ((double) stack / 100));
|
stack = (int) Math.ceil((double) maxStack * ((double) stack / 100));
|
||||||
} else stack = Math.min(max - height, stack);
|
} else stack = Math.min(max - height, stack);
|
||||||
|
|
||||||
if (stack == 1) {
|
if (stack == 1) {
|
||||||
data.set(x, height, z, decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData()));
|
data.set(x, height, z, decorator.getBlockDataForTop(biome, rng, realX, height, realZ, getData()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,8 +69,8 @@ public class IrisShoreLineDecorator extends IrisEngineDecorator {
|
|||||||
int h = height + i;
|
int h = height + i;
|
||||||
double threshold = ((double) i) / (stack - 1);
|
double threshold = ((double) i) / (stack - 1);
|
||||||
data.set(x, h + 1, z, threshold >= decorator.getTopThreshold() ?
|
data.set(x, h + 1, z, threshold >= decorator.getTopThreshold() ?
|
||||||
decorator.getBlockDataForTop(biome, getRng(), realX, h, realZ, getData()) :
|
decorator.getBlockDataForTop(biome, rng, realX, h, realZ, getData()) :
|
||||||
decorator.getBlockData100(biome, getRng(), realX, h, realZ, getData()));
|
decorator.getBlockData100(biome, rng, realX, h, realZ, getData()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
package com.volmit.iris.engine.decorator;
|
package com.volmit.iris.engine.decorator;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.engine.data.cache.Cache;
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.InferredType;
|
import com.volmit.iris.engine.object.InferredType;
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
@@ -28,11 +27,11 @@ import com.volmit.iris.engine.object.IrisDecorator;
|
|||||||
import com.volmit.iris.util.data.B;
|
import com.volmit.iris.util.data.B;
|
||||||
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;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.data.Bisected;
|
import org.bukkit.block.data.Bisected;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.block.data.MultipleFacing;
|
|
||||||
import org.bukkit.block.data.type.PointedDripstone;
|
import org.bukkit.block.data.type.PointedDripstone;
|
||||||
|
|
||||||
public class IrisSurfaceDecorator extends IrisEngineDecorator {
|
public class IrisSurfaceDecorator extends IrisEngineDecorator {
|
||||||
@@ -48,7 +47,8 @@ public class IrisSurfaceDecorator extends IrisEngineDecorator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BlockData bd, bdx;
|
BlockData bd, bdx;
|
||||||
IrisDecorator decorator = getDecorator(biome, realX, realZ);
|
RNG rng = getRNG(realX, realZ);
|
||||||
|
IrisDecorator decorator = getDecorator(rng, biome, realX, realZ);
|
||||||
bdx = data.get(x, height, z);
|
bdx = data.get(x, height, z);
|
||||||
boolean underwater = height < getDimension().getFluidHeight();
|
boolean underwater = height < getDimension().getFluidHeight();
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ public class IrisSurfaceDecorator extends IrisEngineDecorator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!decorator.isStacking()) {
|
if (!decorator.isStacking()) {
|
||||||
bd = decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData());
|
bd = decorator.getBlockData100(biome, rng, realX, height, realZ, getData());
|
||||||
|
|
||||||
if (!underwater) {
|
if (!underwater) {
|
||||||
if (!canGoOn(bd, bdx) && (!decorator.isForcePlace() && decorator.getForceBlock() == null)) {
|
if (!canGoOn(bd, bdx) && (!decorator.isForcePlace() && decorator.getForceBlock() == null)) {
|
||||||
@@ -68,12 +68,12 @@ public class IrisSurfaceDecorator extends IrisEngineDecorator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (decorator.getForceBlock() != null) {
|
if (decorator.getForceBlock() != null) {
|
||||||
data.set(x, height, z, fixFaces(decorator.getForceBlock().getBlockData(getData()), x, height, z));
|
data.set(x, height, z, fixFaces(decorator.getForceBlock().getBlockData(getData()), data, x, z, realX, height, realZ));
|
||||||
} else if (!decorator.isForcePlace()) {
|
} else if (!decorator.isForcePlace()) {
|
||||||
if (decorator.getWhitelist() != null && decorator.getWhitelist().stream().noneMatch(d -> d.getBlockData(getData()).equals(bdx))) {
|
if (decorator.getWhitelist() != null && decorator.getWhitelist().stream().noneMatch(d -> d.getBlockData(getData()).equals(bdx))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (decorator.getBlacklist() != null && decorator.getWhitelist().stream().anyMatch(d -> d.getBlockData(getData()).equals(bdx))) {
|
if (decorator.getBlacklist() != null && decorator.getBlacklist().stream().anyMatch(d -> d.getBlockData(getData()).equals(bdx))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,14 +91,14 @@ public class IrisSurfaceDecorator extends IrisEngineDecorator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (B.isAir(data.get(x, height + 1, z))) {
|
if (B.isAir(data.get(x, height + 1, z))) {
|
||||||
data.set(x, height + 1, z, fixFaces(bd, x, height + 1, z));
|
data.set(x, height + 1, z, fixFaces(bd, data, x, z, realX, height + 1, realZ));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (height < getDimension().getFluidHeight()) {
|
if (height < getDimension().getFluidHeight()) {
|
||||||
max = getDimension().getFluidHeight();
|
max = getDimension().getFluidHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
int stack = decorator.getHeight(getRng().nextParallelRNG(Cache.key(realX, realZ)), realX, realZ, getData());
|
int stack = decorator.getHeight(rng, realX, realZ, getData());
|
||||||
|
|
||||||
if (decorator.isScaleStack()) {
|
if (decorator.isScaleStack()) {
|
||||||
stack = Math.min((int) Math.ceil((double) max * ((double) stack / 100)), decorator.getAbsoluteMaxStack());
|
stack = Math.min((int) Math.ceil((double) max * ((double) stack / 100)), decorator.getAbsoluteMaxStack());
|
||||||
@@ -107,7 +107,7 @@ public class IrisSurfaceDecorator extends IrisEngineDecorator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stack == 1) {
|
if (stack == 1) {
|
||||||
data.set(x, height, z, decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData()));
|
data.set(x, height, z, decorator.getBlockDataForTop(biome, rng, realX, height, realZ, getData()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,8 +115,8 @@ public class IrisSurfaceDecorator extends IrisEngineDecorator {
|
|||||||
int h = height + i;
|
int h = height + i;
|
||||||
double threshold = ((double) i) / (stack - 1);
|
double threshold = ((double) i) / (stack - 1);
|
||||||
bd = threshold >= decorator.getTopThreshold() ?
|
bd = threshold >= decorator.getTopThreshold() ?
|
||||||
decorator.getBlockDataForTop(biome, getRng(), realX, h, realZ, getData()) :
|
decorator.getBlockDataForTop(biome, rng, realX, h, realZ, getData()) :
|
||||||
decorator.getBlockData100(biome, getRng(), realX, h, realZ, getData());
|
decorator.getBlockData100(biome, rng, realX, h, realZ, getData());
|
||||||
|
|
||||||
if (bd == null) {
|
if (bd == null) {
|
||||||
break;
|
break;
|
||||||
@@ -158,24 +158,4 @@ public class IrisSurfaceDecorator extends IrisEngineDecorator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private BlockData fixFaces(BlockData b, int x, int y, int z) {
|
|
||||||
if (B.isVineBlock(b)) {
|
|
||||||
MultipleFacing data = (MultipleFacing) b.clone();
|
|
||||||
boolean found = false;
|
|
||||||
for (BlockFace f : BlockFace.values()) {
|
|
||||||
if (!f.isCartesian())
|
|
||||||
continue;
|
|
||||||
Material m = getEngine().getMantle().get(x + f.getModX(), y + f.getModY(), z + f.getModZ()).getMaterial();
|
|
||||||
if (m.isSolid()) {
|
|
||||||
found = true;
|
|
||||||
data.setFace(f, m.isSolid());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
data.setFace(BlockFace.UP, true);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ import com.volmit.iris.util.context.ChunkContext;
|
|||||||
import com.volmit.iris.util.context.IrisContext;
|
import com.volmit.iris.util.context.IrisContext;
|
||||||
import com.volmit.iris.util.data.B;
|
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.IrisBlockData;
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
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.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
@@ -80,6 +80,7 @@ import java.awt.Color;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@@ -258,10 +259,8 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
|||||||
if (B.isUpdatable(data)) {
|
if (B.isUpdatable(data)) {
|
||||||
getMantle().updateBlock(x, y, z);
|
getMantle().updateBlock(x, y, z);
|
||||||
}
|
}
|
||||||
if (data instanceof IrisBlockData d) {
|
if (data instanceof IrisCustomData) {
|
||||||
getMantle().getMantle().set(x, y, z, d.getCustom());
|
getMantle().getMantle().flag(x >> 4, z >> 4, MantleFlag.CUSTOM, true);
|
||||||
} else {
|
|
||||||
getMantle().getMantle().remove(x, y, z, Identifier.class);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,6 +610,8 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
|||||||
|
|
||||||
int getGenerated();
|
int getGenerated();
|
||||||
|
|
||||||
|
CompletableFuture<Long> getHash32();
|
||||||
|
|
||||||
default <T> IrisPosition lookForStreamResult(T find, ProceduralStream<T> stream, Function2<T, T, Boolean> matcher, long timeout) {
|
default <T> IrisPosition lookForStreamResult(T find, ProceduralStream<T> stream, Function2<T, T, Boolean> matcher, long timeout) {
|
||||||
AtomicInteger checked = new AtomicInteger();
|
AtomicInteger checked = new AtomicInteger();
|
||||||
AtomicLong time = new AtomicLong(M.ms());
|
AtomicLong time = new AtomicLong(M.ms());
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import com.volmit.iris.engine.object.IrisLootTable;
|
|||||||
import com.volmit.iris.engine.object.TileData;
|
import com.volmit.iris.engine.object.TileData;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.data.B;
|
import com.volmit.iris.util.data.B;
|
||||||
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -78,7 +79,11 @@ public class WorldObjectPlacer implements IObjectPlacer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
block.setBlockData(d);
|
|
||||||
|
if (d instanceof IrisCustomData data) {
|
||||||
|
block.setBlockData(data.getBase());
|
||||||
|
Iris.warn("Tried to place custom block at " + x + ", " + y + ", " + z + " which is not supported!");
|
||||||
|
} else block.setBlockData(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import com.volmit.iris.engine.framework.Engine;
|
|||||||
import com.volmit.iris.engine.framework.placer.WorldObjectPlacer;
|
import com.volmit.iris.engine.framework.placer.WorldObjectPlacer;
|
||||||
import com.volmit.iris.engine.object.*;
|
import com.volmit.iris.engine.object.*;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.data.IrisBlockData;
|
|
||||||
import com.volmit.iris.util.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
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;
|
||||||
@@ -155,9 +154,6 @@ public class PlannedStructure {
|
|||||||
return v.place(xx, height, zz, placer, options, rng, (b, data) -> {
|
return v.place(xx, height, zz, placer, options, rng, (b, data) -> {
|
||||||
e.set(b.getX(), b.getY(), b.getZ(), v.getLoadKey() + "@" + id);
|
e.set(b.getX(), b.getY(), b.getZ(), v.getLoadKey() + "@" + id);
|
||||||
e.set(b.getX(), b.getY(), b.getZ(), container);
|
e.set(b.getX(), b.getY(), b.getZ(), container);
|
||||||
if (data instanceof IrisBlockData d) {
|
|
||||||
e.set(b.getX(), b.getY(), b.getZ(), d.getCustom());
|
|
||||||
}
|
|
||||||
}, null, getData().getEngine() != null ? getData() : eng.getData()) != -1;
|
}, null, getData().getEngine() != null ? getData() : eng.getData()) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import com.volmit.iris.util.collection.KList;
|
|||||||
import com.volmit.iris.util.context.ChunkContext;
|
import com.volmit.iris.util.context.ChunkContext;
|
||||||
import com.volmit.iris.util.context.IrisContext;
|
import com.volmit.iris.util.context.IrisContext;
|
||||||
import com.volmit.iris.util.data.B;
|
import com.volmit.iris.util.data.B;
|
||||||
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
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.hunk.Hunk;
|
import com.volmit.iris.util.hunk.Hunk;
|
||||||
@@ -104,7 +105,10 @@ public interface EngineMantle extends IObjectPlacer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void set(int x, int y, int z, BlockData d) {
|
default void set(int x, int y, int z, BlockData d) {
|
||||||
getMantle().set(x, y, z, d == null ? AIR : d);
|
if (d instanceof IrisCustomData data) {
|
||||||
|
getMantle().set(x, y, z, data.getBase());
|
||||||
|
getMantle().set(x, y, z, data.getCustom());
|
||||||
|
} else getMantle().set(x, y, z, d == null ? AIR : d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import com.volmit.iris.engine.object.IrisPosition;
|
|||||||
import com.volmit.iris.engine.object.TileData;
|
import com.volmit.iris.engine.object.TileData;
|
||||||
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.IrisCustomData;
|
||||||
import com.volmit.iris.util.function.Function3;
|
import com.volmit.iris.util.function.Function3;
|
||||||
import com.volmit.iris.util.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
import com.volmit.iris.util.mantle.MantleChunk;
|
import com.volmit.iris.util.mantle.MantleChunk;
|
||||||
@@ -166,7 +167,10 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void set(int x, int y, int z, BlockData d) {
|
public void set(int x, int y, int z, BlockData d) {
|
||||||
setData(x, y, z, d);
|
if (d instanceof IrisCustomData data) {
|
||||||
|
setData(x, y, z, data.getBase());
|
||||||
|
setData(x, y, z, data.getCustom());
|
||||||
|
} else setData(x, y, z, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -90,14 +90,30 @@ public class MantleJigsawComponent extends IrisMantleComponent {
|
|||||||
private boolean placeStructures(MantleWriter writer, long seed, int x, int z, KList<IrisJigsawStructurePlacement> structures,
|
private boolean placeStructures(MantleWriter writer, long seed, int x, int z, KList<IrisJigsawStructurePlacement> structures,
|
||||||
KSet<Position2> cachedRegions, KMap<String, KSet<Position2>> cache, KMap<Position2, Double> distanceCache) {
|
KSet<Position2> cachedRegions, KMap<String, KSet<Position2>> cache, KMap<Position2, Double> distanceCache) {
|
||||||
IrisJigsawStructurePlacement i = pick(structures, seed, x, z);
|
IrisJigsawStructurePlacement i = pick(structures, seed, x, z);
|
||||||
if (i == null || checkMinDistances(i.collectMinDistances(), x, z, cachedRegions, cache, distanceCache))
|
try {
|
||||||
return false;
|
if (i == null || checkMinDistances(i.collectMinDistances(), x, z, cachedRegions, cache, distanceCache))
|
||||||
|
return false;
|
||||||
|
if (!checkBiomes(i, x, z))
|
||||||
|
return false;
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
RNG rng = new RNG(seed);
|
RNG rng = new RNG(seed);
|
||||||
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());
|
||||||
return place(writer, position, structure, rng, false);
|
return place(writer, position, structure, rng, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean checkBiomes(IrisJigsawStructurePlacement placement, int x, int z) {
|
||||||
|
var biome = getEngineMantle().getEngine().getSurfaceBiome((x << 4) + 8, (z << 4) + 8);
|
||||||
|
if (biome == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var exclude = placement.getExclude();
|
||||||
|
return !(biome.isSea() && exclude.isExcludeOceanBiomes() ||
|
||||||
|
biome.isLand() && exclude.isExcludeLandBiomes() ||
|
||||||
|
biome.isShore() && exclude.isExcludeShoreBiomes());
|
||||||
|
}
|
||||||
|
|
||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
private boolean checkMinDistances(KMap<String, Integer> minDistances, int x, int z, KSet<Position2> cachedRegions, KMap<String, KSet<Position2>> cache, KMap<Position2, Double> distanceCache) {
|
private boolean checkMinDistances(KMap<String, Integer> minDistances, int x, int z, KSet<Position2> cachedRegions, KMap<String, KSet<Position2>> cache, KMap<Position2, Double> distanceCache) {
|
||||||
int range = 0;
|
int range = 0;
|
||||||
@@ -159,7 +175,7 @@ public class MantleJigsawComponent extends IrisMantleComponent {
|
|||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
private IrisJigsawStructurePlacement pick(List<IrisJigsawStructurePlacement> structures, long seed, int x, int z) {
|
private IrisJigsawStructurePlacement pick(List<IrisJigsawStructurePlacement> structures, long seed, int x, int z) {
|
||||||
return IRare.pick(structures.stream()
|
return IRare.pick(structures.stream()
|
||||||
.filter(p -> p.shouldPlace(getDimension().getJigsawStructureDivisor(), jigsaw(), x, z))
|
.filter(p -> p.shouldPlace(getData(), getDimension().getJigsawStructureDivisor(), jigsaw(), x, z))
|
||||||
.toList(), new RNG(seed).nextDouble());
|
.toList(), new RNG(seed).nextDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ 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.context.ChunkContext;
|
import com.volmit.iris.util.context.ChunkContext;
|
||||||
import com.volmit.iris.util.data.B;
|
import com.volmit.iris.util.data.B;
|
||||||
import com.volmit.iris.util.data.IrisBlockData;
|
|
||||||
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.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
@@ -116,9 +115,6 @@ public class MantleObjectComponent extends IrisMantleComponent {
|
|||||||
if (objectPlacement.isDolphinTarget() && objectPlacement.isUnderwater() && B.isStorageChest(data)) {
|
if (objectPlacement.isDolphinTarget() && objectPlacement.isUnderwater() && B.isStorageChest(data)) {
|
||||||
writer.setData(b.getX(), b.getY(), b.getZ(), MatterStructurePOI.BURIED_TREASURE);
|
writer.setData(b.getX(), b.getY(), b.getZ(), MatterStructurePOI.BURIED_TREASURE);
|
||||||
}
|
}
|
||||||
if (data instanceof IrisBlockData d) {
|
|
||||||
writer.setData(b.getX(), b.getY(), b.getZ(), d.getCustom());
|
|
||||||
}
|
|
||||||
}, null, getData());
|
}, null, getData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,10 +25,7 @@ import com.volmit.iris.engine.framework.Engine;
|
|||||||
import com.volmit.iris.engine.framework.EngineMode;
|
import com.volmit.iris.engine.framework.EngineMode;
|
||||||
import com.volmit.iris.engine.framework.EngineStage;
|
import com.volmit.iris.engine.framework.EngineStage;
|
||||||
import com.volmit.iris.engine.framework.IrisEngineMode;
|
import com.volmit.iris.engine.framework.IrisEngineMode;
|
||||||
import com.volmit.iris.engine.modifier.IrisCarveModifier;
|
import com.volmit.iris.engine.modifier.*;
|
||||||
import com.volmit.iris.engine.modifier.IrisDepositModifier;
|
|
||||||
import com.volmit.iris.engine.modifier.IrisPerfectionModifier;
|
|
||||||
import com.volmit.iris.engine.modifier.IrisPostModifier;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
public class ModeOverworld extends IrisEngineMode implements EngineMode {
|
public class ModeOverworld extends IrisEngineMode implements EngineMode {
|
||||||
@@ -41,6 +38,7 @@ public class ModeOverworld extends IrisEngineMode implements EngineMode {
|
|||||||
var post = new IrisPostModifier(getEngine());
|
var post = new IrisPostModifier(getEngine());
|
||||||
var deposit = new IrisDepositModifier(getEngine());
|
var deposit = new IrisDepositModifier(getEngine());
|
||||||
var perfection = new IrisPerfectionModifier(getEngine());
|
var perfection = new IrisPerfectionModifier(getEngine());
|
||||||
|
var custom = new IrisCustomModifier(getEngine());
|
||||||
EngineStage sBiome = (x, z, k, p, m, c) -> biome.actuate(x, z, p, m, c);
|
EngineStage sBiome = (x, z, k, p, m, c) -> biome.actuate(x, z, p, m, c);
|
||||||
EngineStage sGenMatter = (x, z, k, p, m, c) -> generateMatter(x >> 4, z >> 4, m, c);
|
EngineStage sGenMatter = (x, z, k, p, m, c) -> generateMatter(x >> 4, z >> 4, m, c);
|
||||||
EngineStage sTerrain = (x, z, k, p, m, c) -> terrain.actuate(x, z, k, m, c);
|
EngineStage sTerrain = (x, z, k, p, m, c) -> terrain.actuate(x, z, k, m, c);
|
||||||
@@ -50,6 +48,7 @@ public class ModeOverworld extends IrisEngineMode implements EngineMode {
|
|||||||
EngineStage sPost = (x, z, k, p, m, c) -> post.modify(x, z, k, m, c);
|
EngineStage sPost = (x, z, k, p, m, c) -> post.modify(x, z, k, m, c);
|
||||||
EngineStage sInsertMatter = (x, z, K, p, m, c) -> getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, K, m);
|
EngineStage sInsertMatter = (x, z, K, p, m, c) -> getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, K, m);
|
||||||
EngineStage sPerfection = (x, z, k, p, m, c) -> perfection.modify(x, z, k, m, c);
|
EngineStage sPerfection = (x, z, k, p, m, c) -> perfection.modify(x, z, k, m, c);
|
||||||
|
EngineStage sCustom = (x, z, k, p, m, c) -> custom.modify(x, z, k, m, c);
|
||||||
|
|
||||||
registerStage(burst(
|
registerStage(burst(
|
||||||
sGenMatter,
|
sGenMatter,
|
||||||
@@ -65,6 +64,6 @@ public class ModeOverworld extends IrisEngineMode implements EngineMode {
|
|||||||
sDecorant
|
sDecorant
|
||||||
));
|
));
|
||||||
registerStage(sPerfection);
|
registerStage(sPerfection);
|
||||||
|
registerStage(sCustom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public class IrisCarveModifier extends EngineAssignedModifier<BlockData> {
|
|||||||
public void onModify(int x, int z, Hunk<BlockData> output, boolean multicore, ChunkContext context) {
|
public void onModify(int x, int z, Hunk<BlockData> output, boolean multicore, ChunkContext context) {
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
Mantle mantle = getEngine().getMantle().getMantle();
|
Mantle mantle = getEngine().getMantle().getMantle();
|
||||||
MantleChunk mc = getEngine().getMantle().getMantle().getChunk(x, z);
|
MantleChunk mc = getEngine().getMantle().getMantle().getChunk(x, z).use();
|
||||||
KMap<Long, KList<Integer>> positions = new KMap<>();
|
KMap<Long, KList<Integer>> positions = new KMap<>();
|
||||||
KMap<IrisPosition, MatterCavern> walls = new KMap<>();
|
KMap<IrisPosition, MatterCavern> walls = new KMap<>();
|
||||||
Consumer4<Integer, Integer, Integer, MatterCavern> iterator = (xx, yy, zz, c) -> {
|
Consumer4<Integer, Integer, Integer, MatterCavern> iterator = (xx, yy, zz, c) -> {
|
||||||
@@ -166,6 +166,7 @@ public class IrisCarveModifier extends EngineAssignedModifier<BlockData> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
getEngine().getMetrics().getDeposit().put(p.getMilliseconds());
|
getEngine().getMetrics().getDeposit().put(p.getMilliseconds());
|
||||||
|
mc.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processZone(Hunk<BlockData> output, MantleChunk mc, Mantle mantle, CaveZone zone, int rx, int rz, int xx, int zz) {
|
private void processZone(Hunk<BlockData> output, MantleChunk mc, Mantle mantle, CaveZone zone, int rx, int rz, int xx, int zz) {
|
||||||
@@ -211,14 +212,6 @@ public class IrisCarveModifier extends EngineAssignedModifier<BlockData> {
|
|||||||
|
|
||||||
biome.setInferredType(InferredType.CAVE);
|
biome.setInferredType(InferredType.CAVE);
|
||||||
|
|
||||||
for (IrisDecorator i : biome.getDecorators()) {
|
|
||||||
if (i.getPartOf().equals(IrisDecorationPart.NONE) && B.isSolid(output.get(rx, zone.getFloor() - 1, rz))) {
|
|
||||||
decorant.getSurfaceDecorator().decorate(rx, rz, xx, xx, xx, zz, zz, zz, output, biome, zone.getFloor() - 1, zone.airThickness());
|
|
||||||
} else if (i.getPartOf().equals(IrisDecorationPart.CEILING) && B.isSolid(output.get(rx, zone.getCeiling() + 1, rz))) {
|
|
||||||
decorant.getCeilingDecorator().decorate(rx, rz, xx, xx, xx, zz, zz, zz, output, biome, zone.getCeiling(), zone.airThickness());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
KList<BlockData> blocks = biome.generateLayers(getDimension(), xx, zz, rng, 3, zone.floor, getData(), getComplex());
|
KList<BlockData> blocks = biome.generateLayers(getDimension(), xx, zz, rng, 3, zone.floor, getData(), getComplex());
|
||||||
|
|
||||||
for (int i = 0; i < zone.floor - 1; i++) {
|
for (int i = 0; i < zone.floor - 1; i++) {
|
||||||
@@ -260,6 +253,14 @@ public class IrisCarveModifier extends EngineAssignedModifier<BlockData> {
|
|||||||
output.set(rx, zone.ceiling + i + 1, rz, b);
|
output.set(rx, zone.ceiling + i + 1, rz, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (IrisDecorator i : biome.getDecorators()) {
|
||||||
|
if (i.getPartOf().equals(IrisDecorationPart.NONE) && B.isSolid(output.get(rx, zone.getFloor() - 1, rz))) {
|
||||||
|
decorant.getSurfaceDecorator().decorate(rx, rz, xx, xx, xx, zz, zz, zz, output, biome, zone.getFloor() - 1, zone.airThickness());
|
||||||
|
} else if (i.getPartOf().equals(IrisDecorationPart.CEILING) && B.isSolid(output.get(rx, zone.getCeiling() + 1, rz))) {
|
||||||
|
decorant.getCeilingDecorator().decorate(rx, rz, xx, xx, xx, zz, zz, zz, output, biome, zone.getCeiling(), zone.airThickness());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.volmit.iris.engine.modifier;
|
||||||
|
import com.volmit.iris.core.link.Identifier;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.engine.framework.EngineAssignedModifier;
|
||||||
|
import com.volmit.iris.util.context.ChunkContext;
|
||||||
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
|
import com.volmit.iris.util.hunk.Hunk;
|
||||||
|
import com.volmit.iris.util.mantle.MantleFlag;
|
||||||
|
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||||
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
public class IrisCustomModifier extends EngineAssignedModifier<BlockData> {
|
||||||
|
public IrisCustomModifier(Engine engine) {
|
||||||
|
super(engine, "Custom");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onModify(int x, int z, Hunk<BlockData> output, boolean multicore, ChunkContext context) {
|
||||||
|
var mc = getEngine().getMantle().getMantle().getChunk(x >> 4, z >> 4);
|
||||||
|
if (!mc.isFlagged(MantleFlag.CUSTOM_ACTIVE)) return;
|
||||||
|
mc.use();
|
||||||
|
|
||||||
|
BurstExecutor burst = MultiBurst.burst.burst(output.getHeight());
|
||||||
|
burst.setMulticore(multicore);
|
||||||
|
for (int y = 0; y < output.getHeight(); y++) {
|
||||||
|
int finalY = y;
|
||||||
|
burst.queue(() -> {
|
||||||
|
for (int rX = 0; rX < output.getWidth(); rX++) {
|
||||||
|
for (int rZ = 0; rZ < output.getDepth(); rZ++) {
|
||||||
|
BlockData b = output.get(rX, finalY, rZ);
|
||||||
|
if (!(b instanceof IrisCustomData d)) continue;
|
||||||
|
|
||||||
|
mc.getOrCreate(finalY >> 4)
|
||||||
|
.slice(Identifier.class)
|
||||||
|
.set(rX, finalY & 15, rZ, d.getCustom());
|
||||||
|
output.set(rX, finalY, rZ, d.getBase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
burst.complete();
|
||||||
|
mc.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -200,7 +200,7 @@ public class IrisBiome extends IrisRegistrant implements IRare {
|
|||||||
KMap<String, Integer> l = new KMap<>();
|
KMap<String, Integer> l = new KMap<>();
|
||||||
|
|
||||||
for (IrisBiomeGeneratorLink i : getGenerators()) {
|
for (IrisBiomeGeneratorLink i : getGenerators()) {
|
||||||
l.put(i.getGenerator(), i.getMax(engine));
|
l.put(i.getGenerator(), i.getMax());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ public class IrisBiome extends IrisRegistrant implements IRare {
|
|||||||
KMap<String, Integer> l = new KMap<>();
|
KMap<String, Integer> l = new KMap<>();
|
||||||
|
|
||||||
for (IrisBiomeGeneratorLink i : getGenerators()) {
|
for (IrisBiomeGeneratorLink i : getGenerators()) {
|
||||||
l.put(i.getGenerator(), i.getMin(engine));
|
l.put(i.getGenerator(), i.getMin());
|
||||||
}
|
}
|
||||||
|
|
||||||
return l;
|
return l;
|
||||||
@@ -457,7 +457,7 @@ public class IrisBiome extends IrisRegistrant implements IRare {
|
|||||||
int maxHeight = 0;
|
int maxHeight = 0;
|
||||||
|
|
||||||
for (IrisBiomeGeneratorLink i : getGenerators()) {
|
for (IrisBiomeGeneratorLink i : getGenerators()) {
|
||||||
maxHeight += i.getMax(engine);
|
maxHeight += i.getMax();
|
||||||
}
|
}
|
||||||
|
|
||||||
return maxHeight;
|
return maxHeight;
|
||||||
@@ -470,7 +470,7 @@ public class IrisBiome extends IrisRegistrant implements IRare {
|
|||||||
int maxHeight = 0;
|
int maxHeight = 0;
|
||||||
|
|
||||||
for (IrisBiomeGeneratorLink i : getGenerators()) {
|
for (IrisBiomeGeneratorLink i : getGenerators()) {
|
||||||
maxHeight += i.getMax(engine);
|
maxHeight += i.getMax();
|
||||||
}
|
}
|
||||||
|
|
||||||
int gg = 0;
|
int gg = 0;
|
||||||
|
|||||||
@@ -18,9 +18,7 @@
|
|||||||
|
|
||||||
package com.volmit.iris.engine.object;
|
package com.volmit.iris.engine.object;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
|
||||||
import com.volmit.iris.engine.object.annotations.*;
|
import com.volmit.iris.engine.object.annotations.*;
|
||||||
import com.volmit.iris.util.data.DataProvider;
|
import com.volmit.iris.util.data.DataProvider;
|
||||||
import com.volmit.iris.util.interpolation.IrisInterpolation;
|
import com.volmit.iris.util.interpolation.IrisInterpolation;
|
||||||
@@ -39,18 +37,16 @@ public class IrisBiomeGeneratorLink {
|
|||||||
@RegistryListResource(IrisGenerator.class)
|
@RegistryListResource(IrisGenerator.class)
|
||||||
@Desc("The generator id")
|
@Desc("The generator id")
|
||||||
private String generator = "default";
|
private String generator = "default";
|
||||||
@DependsOn({ "min", "max" })
|
@DependsOn({"min", "max"})
|
||||||
@Required
|
@Required
|
||||||
@MinNumber(-2032) // TODO: WARNING HEIGHT
|
@MinNumber(-2032) // TODO: WARNING HEIGHT
|
||||||
@MaxNumber(2032) // TODO: WARNING HEIGHT
|
@MaxNumber(2032) // TODO: WARNING HEIGHT
|
||||||
@Desc("The min block value (value + fluidHeight)")
|
@Desc("The min block value (value + fluidHeight)")
|
||||||
@Getter(AccessLevel.NONE)
|
|
||||||
private int min = 0;
|
private int min = 0;
|
||||||
@DependsOn({ "min", "max" })
|
@DependsOn({"min", "max"})
|
||||||
@Required
|
@Required
|
||||||
@MinNumber(-2032) // TODO: WARNING HEIGHT
|
@MinNumber(-2032) // TODO: WARNING HEIGHT
|
||||||
@MaxNumber(2032) // TODO: WARNING HEIGHT
|
@MaxNumber(2032) // TODO: WARNING HEIGHT
|
||||||
@Getter(AccessLevel.NONE)
|
|
||||||
@Desc("The max block value (value + fluidHeight)")
|
@Desc("The max block value (value + fluidHeight)")
|
||||||
private int max = 0;
|
private int max = 0;
|
||||||
|
|
||||||
@@ -66,70 +62,6 @@ public class IrisBiomeGeneratorLink {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private int[] getBiomeGeneratorsRaw(Engine engine) {
|
|
||||||
int max = engine.getDimension().getMinHeight();
|
|
||||||
int min = engine.getDimension().getMaxHeight();
|
|
||||||
for (IrisBiome biome : engine.getAllBiomes()) {
|
|
||||||
for (IrisBiomeGeneratorLink i : biome.getGenerators()) {
|
|
||||||
int biomeRawMax = i.getMaxRaw();
|
|
||||||
int biomeRawMin = i.getMinRaw();
|
|
||||||
if (max < biomeRawMax)
|
|
||||||
max = biomeRawMax;
|
|
||||||
if (min > biomeRawMin)
|
|
||||||
min = biomeRawMin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new int[] { min, max };
|
|
||||||
}
|
|
||||||
|
|
||||||
private int calculateHeight(Engine engine, int option) {
|
|
||||||
int dmx = engine.getDimension().getMaxHeight();
|
|
||||||
int dmn = engine.getDimension().getMinHeight();
|
|
||||||
int[] heights = getBiomeGeneratorsRaw(engine);
|
|
||||||
int gmx = heights[1];
|
|
||||||
int gmn = heights[0];
|
|
||||||
|
|
||||||
int mx = getMaxRaw();
|
|
||||||
int mn = getMinRaw();
|
|
||||||
if (engine.getDimension().isSmartVanillaHeight()) {
|
|
||||||
if (mx > 0)
|
|
||||||
mx = Math.min((int) (((float) mx / (float) gmx) * 300.0f), 300);
|
|
||||||
if (mx < 0)
|
|
||||||
mx = Math.min((int) (((float) mx / (float) gmn) * 300.0f), 56);
|
|
||||||
|
|
||||||
if (mn > 0)
|
|
||||||
mn = Math.min((int) (((float) mn / (float) gmx) * 300.0f), 300);
|
|
||||||
if (mn < 0)
|
|
||||||
mn = Math.min((int) (((float) mn / (float) gmn) * 300.0f), 56);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (option == 1) {
|
|
||||||
return mx;
|
|
||||||
}
|
|
||||||
if (option == 0) {
|
|
||||||
return mn;
|
|
||||||
}
|
|
||||||
Iris.error("Fatal Generator error!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMax(Engine engine) {
|
|
||||||
return calculateHeight(engine, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMin(Engine engine) {
|
|
||||||
return calculateHeight(engine, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getMaxRaw() {
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getMinRaw() {
|
|
||||||
return min;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getHeight(DataProvider xg, double x, double z, long seed) {
|
public double getHeight(DataProvider xg, double x, double z, long seed) {
|
||||||
double g = getCachedGenerator(xg).getHeight(x, z, seed);
|
double g = getCachedGenerator(xg).getHeight(x, z, seed);
|
||||||
g = g < 0 ? 0 : g;
|
g = g < 0 ? 0 : g;
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package com.volmit.iris.engine.object;
|
||||||
|
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
|
import com.volmit.iris.core.nms.container.AutoClosing;
|
||||||
|
import com.volmit.iris.util.misc.ServerProperties;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.world.WorldInitEvent;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.volmit.iris.Iris.instance;
|
||||||
|
|
||||||
|
public class IrisContextInjector implements Listener {
|
||||||
|
@Getter
|
||||||
|
private static boolean missingDimensionTypes = false;
|
||||||
|
private AutoClosing autoClosing = null;
|
||||||
|
private final int totalWorlds;
|
||||||
|
private int worldCounter = 0;
|
||||||
|
|
||||||
|
public IrisContextInjector() {
|
||||||
|
if (!Bukkit.getWorlds().isEmpty()) {
|
||||||
|
totalWorlds = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String levelName = ServerProperties.LEVEL_NAME;
|
||||||
|
List<String> irisWorlds = irisWorlds();
|
||||||
|
boolean overworld = irisWorlds.contains(levelName);
|
||||||
|
boolean nether = irisWorlds.contains(levelName + "_nether");
|
||||||
|
boolean end = irisWorlds.contains(levelName + "_end");
|
||||||
|
|
||||||
|
int i = 1;
|
||||||
|
if (Bukkit.getAllowNether()) i++;
|
||||||
|
if (Bukkit.getAllowEnd()) i++;
|
||||||
|
|
||||||
|
if (INMS.get().missingDimensionTypes(overworld, nether, end)) {
|
||||||
|
missingDimensionTypes = true;
|
||||||
|
totalWorlds = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overworld || nether || end) {
|
||||||
|
var pair = INMS.get().injectUncached(overworld, nether, end);
|
||||||
|
i += pair.getA() - 3;
|
||||||
|
autoClosing = pair.getB();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalWorlds = i;
|
||||||
|
instance.registerListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void on(WorldInitEvent event) {
|
||||||
|
if (++worldCounter < totalWorlds) return;
|
||||||
|
if (autoClosing != null) {
|
||||||
|
autoClosing.close();
|
||||||
|
autoClosing = null;
|
||||||
|
}
|
||||||
|
instance.unregisterListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> irisWorlds() {
|
||||||
|
var config = YamlConfiguration.loadConfiguration(ServerProperties.BUKKIT_YML);
|
||||||
|
ConfigurationSection section = config.getConfigurationSection("worlds");
|
||||||
|
if (section == null) return List.of();
|
||||||
|
|
||||||
|
return section.getKeys(false)
|
||||||
|
.stream()
|
||||||
|
.filter(k -> section.getString(k + ".generator", "").startsWith("Iris"))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,8 @@
|
|||||||
package com.volmit.iris.engine.object;
|
package com.volmit.iris.engine.object;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.IrisSettings;
|
||||||
|
import com.volmit.iris.core.ServerConfigurator.DimensionHeight;
|
||||||
import com.volmit.iris.core.loader.IrisData;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
import com.volmit.iris.core.loader.IrisRegistrant;
|
import com.volmit.iris.core.loader.IrisRegistrant;
|
||||||
import com.volmit.iris.core.nms.INMS;
|
import com.volmit.iris.core.nms.INMS;
|
||||||
@@ -26,6 +28,7 @@ import com.volmit.iris.core.nms.datapack.IDataFixer;
|
|||||||
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.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
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.io.IO;
|
import com.volmit.iris.util.io.IO;
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
@@ -54,73 +57,6 @@ import java.io.IOException;
|
|||||||
public class IrisDimension extends IrisRegistrant {
|
public class IrisDimension extends IrisRegistrant {
|
||||||
public static final BlockData STONE = Material.STONE.createBlockData();
|
public static final BlockData STONE = Material.STONE.createBlockData();
|
||||||
public static final BlockData WATER = Material.WATER.createBlockData();
|
public static final BlockData WATER = Material.WATER.createBlockData();
|
||||||
private static final String DP_OVERWORLD_DEFAULT = """
|
|
||||||
{
|
|
||||||
"ambient_light": 0.0,
|
|
||||||
"bed_works": true,
|
|
||||||
"coordinate_scale": 1.0,
|
|
||||||
"effects": "minecraft:overworld",
|
|
||||||
"has_ceiling": false,
|
|
||||||
"has_raids": true,
|
|
||||||
"has_skylight": true,
|
|
||||||
"infiniburn": "#minecraft:infiniburn_overworld",
|
|
||||||
"monster_spawn_block_light_limit": 0,
|
|
||||||
"monster_spawn_light_level": {
|
|
||||||
"type": "minecraft:uniform",
|
|
||||||
"value": {
|
|
||||||
"max_inclusive": 7,
|
|
||||||
"min_inclusive": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"natural": true,
|
|
||||||
"piglin_safe": false,
|
|
||||||
"respawn_anchor_works": false,
|
|
||||||
"ultrawarm": false
|
|
||||||
}""";
|
|
||||||
|
|
||||||
private static final String DP_NETHER_DEFAULT = """
|
|
||||||
{
|
|
||||||
"ambient_light": 0.1,
|
|
||||||
"bed_works": false,
|
|
||||||
"coordinate_scale": 8.0,
|
|
||||||
"effects": "minecraft:the_nether",
|
|
||||||
"fixed_time": 18000,
|
|
||||||
"has_ceiling": true,
|
|
||||||
"has_raids": false,
|
|
||||||
"has_skylight": false,
|
|
||||||
"infiniburn": "#minecraft:infiniburn_nether",
|
|
||||||
"monster_spawn_block_light_limit": 15,
|
|
||||||
"monster_spawn_light_level": 7,
|
|
||||||
"natural": false,
|
|
||||||
"piglin_safe": true,
|
|
||||||
"respawn_anchor_works": true,
|
|
||||||
"ultrawarm": true
|
|
||||||
}""";
|
|
||||||
|
|
||||||
private static final String DP_END_DEFAULT = """
|
|
||||||
{
|
|
||||||
"ambient_light": 0.0,
|
|
||||||
"bed_works": false,
|
|
||||||
"coordinate_scale": 1.0,
|
|
||||||
"effects": "minecraft:the_end",
|
|
||||||
"fixed_time": 6000,
|
|
||||||
"has_ceiling": false,
|
|
||||||
"has_raids": true,
|
|
||||||
"has_skylight": false,
|
|
||||||
"infiniburn": "#minecraft:infiniburn_end",
|
|
||||||
"monster_spawn_block_light_limit": 0,
|
|
||||||
"monster_spawn_light_level": {
|
|
||||||
"type": "minecraft:uniform",
|
|
||||||
"value": {
|
|
||||||
"max_inclusive": 7,
|
|
||||||
"min_inclusive": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"natural": false,
|
|
||||||
"piglin_safe": false,
|
|
||||||
"respawn_anchor_works": false,
|
|
||||||
"ultrawarm": false
|
|
||||||
}""";
|
|
||||||
private final transient AtomicCache<Position2> parallaxSize = new AtomicCache<>();
|
private final transient AtomicCache<Position2> parallaxSize = new AtomicCache<>();
|
||||||
private final transient AtomicCache<CNG> rockLayerGenerator = new AtomicCache<>();
|
private final transient AtomicCache<CNG> rockLayerGenerator = new AtomicCache<>();
|
||||||
private final transient AtomicCache<CNG> fluidLayerGenerator = new AtomicCache<>();
|
private final transient AtomicCache<CNG> fluidLayerGenerator = new AtomicCache<>();
|
||||||
@@ -234,8 +170,6 @@ public class IrisDimension extends IrisRegistrant {
|
|||||||
private IrisRange dimensionHeightEnd = new IrisRange(-64, 320);
|
private IrisRange dimensionHeightEnd = new IrisRange(-64, 320);
|
||||||
@Desc("Define the min and max Y bounds of this dimension. Please keep in mind that Iris internally generates from 0 to (max - min). \n\nFor example at -64 to 320, Iris is internally generating to 0 to 384, then on outputting chunks, it shifts it down by the min height (64 blocks). The default is -64 to 320. \n\nThe fluid height is placed at (fluid height + min height). So a fluid height of 63 would actually show up in the world at 1.")
|
@Desc("Define the min and max Y bounds of this dimension. Please keep in mind that Iris internally generates from 0 to (max - min). \n\nFor example at -64 to 320, Iris is internally generating to 0 to 384, then on outputting chunks, it shifts it down by the min height (64 blocks). The default is -64 to 320. \n\nThe fluid height is placed at (fluid height + min height). So a fluid height of 63 would actually show up in the world at 1.")
|
||||||
private IrisRange dimensionHeightNether = new IrisRange(-64, 320);
|
private IrisRange dimensionHeightNether = new IrisRange(-64, 320);
|
||||||
@Desc("Enable smart vanilla height")
|
|
||||||
private boolean smartVanillaHeight = false;
|
|
||||||
@RegistryListResource(IrisBiome.class)
|
@RegistryListResource(IrisBiome.class)
|
||||||
@Desc("Keep this either undefined or empty. Setting any biome name into this will force iris to only generate the specified biome. Great for testing.")
|
@Desc("Keep this either undefined or empty. Setting any biome name into this will force iris to only generate the specified biome. Great for testing.")
|
||||||
private String focus = "";
|
private String focus = "";
|
||||||
@@ -445,61 +379,35 @@ public class IrisDimension extends IrisRegistrant {
|
|||||||
return landBiomeStyle;
|
return landBiomeStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean installDataPack(IDataFixer fixer, DataProvider data, File datapacks, double ultimateMaxHeight, double ultimateMinHeight) {
|
public void installBiomes(IDataFixer fixer, DataProvider data, KList<File> folders, KSet<String> biomes) {
|
||||||
boolean write = false;
|
getAllBiomes(data)
|
||||||
boolean changed = false;
|
.stream()
|
||||||
|
.filter(IrisBiome::isCustom)
|
||||||
IO.delete(new File(datapacks, "iris/data/" + getLoadKey().toLowerCase()));
|
.map(IrisBiome::getCustomDerivitives)
|
||||||
|
.flatMap(KList::stream)
|
||||||
for (IrisBiome i : getAllBiomes(data)) {
|
.parallel()
|
||||||
if (i.isCustom()) {
|
.forEach(j -> {
|
||||||
write = true;
|
String json = j.generateJson(fixer);
|
||||||
|
synchronized (biomes) {
|
||||||
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
if (!biomes.add(j.getId())) {
|
||||||
File output = new File(datapacks, "iris/data/" + getLoadKey().toLowerCase() + "/worldgen/biome/" + j.getId() + ".json");
|
Iris.verbose("Duplicate Data Pack Biome: " + getLoadKey() + "/" + j.getId());
|
||||||
|
return;
|
||||||
if (!output.exists()) {
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Iris.verbose(" Installing Data Pack Biome: " + output.getPath());
|
|
||||||
output.getParentFile().mkdirs();
|
|
||||||
try {
|
|
||||||
IO.writeAll(output, j.generateJson(fixer));
|
|
||||||
} catch (IOException e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dimensionHeight.equals(new IrisRange(-64, 320)) && this.name.equalsIgnoreCase("overworld")) {
|
|
||||||
Iris.verbose(" Installing Data Pack Dimension Types: \"minecraft:overworld\", \"minecraft:the_nether\", \"minecraft:the_end\"");
|
|
||||||
dimensionHeight.setMax(ultimateMaxHeight);
|
|
||||||
dimensionHeight.setMin(ultimateMinHeight);
|
|
||||||
changed = writeDimensionType(fixer, changed, datapacks);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (write) {
|
|
||||||
File mcm = new File(datapacks, "iris/pack.mcmeta");
|
|
||||||
try {
|
|
||||||
IO.writeAll(mcm, """
|
|
||||||
{
|
|
||||||
"pack": {
|
|
||||||
"description": "Iris Data Pack. This pack contains all installed Iris Packs' resources.",
|
|
||||||
"pack_format": {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
""".replace("{}", INMS.get().getDataVersion().getPackFormat() + ""));
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
Iris.verbose(" Installing Data Pack MCMeta: " + mcm.getPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed;
|
for (File datapacks : folders) {
|
||||||
|
File output = new File(datapacks, "iris/data/" + getLoadKey().toLowerCase() + "/worldgen/biome/" + j.getId() + ".json");
|
||||||
|
|
||||||
|
Iris.verbose(" Installing Data Pack Biome: " + output.getPath());
|
||||||
|
output.getParentFile().mkdirs();
|
||||||
|
try {
|
||||||
|
IO.writeAll(output, json);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -517,66 +425,55 @@ public class IrisDimension extends IrisRegistrant {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean writeDimensionType(IDataFixer fixer, boolean changed, File datapacks) {
|
public static void writeShared(KList<File> folders, DimensionHeight height) {
|
||||||
File dimTypeOverworld = new File(datapacks, "iris/data/minecraft/dimension_type/overworld.json");
|
Iris.verbose(" Installing Data Pack Dimension Types: \"iris:overworld\", \"iris:the_nether\", \"iris:the_end\"");
|
||||||
if (!dimTypeOverworld.exists())
|
for (File datapacks : folders) {
|
||||||
changed = true;
|
write(datapacks, "overworld", height.overworldType());
|
||||||
dimTypeOverworld.getParentFile().mkdirs();
|
write(datapacks, "the_nether", height.netherType());
|
||||||
|
write(datapacks, "the_end", height.endType());
|
||||||
|
}
|
||||||
|
|
||||||
|
String raw = """
|
||||||
|
{
|
||||||
|
"pack": {
|
||||||
|
"description": "Iris Data Pack. This pack contains all installed Iris Packs' resources.",
|
||||||
|
"pack_format": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""".replace("{}", INMS.get().getDataVersion().getPackFormat() + "");
|
||||||
|
|
||||||
|
for (File datapacks : folders) {
|
||||||
|
File mcm = new File(datapacks, "iris/pack.mcmeta");
|
||||||
|
try {
|
||||||
|
IO.writeAll(mcm, raw);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
Iris.verbose(" Installing Data Pack MCMeta: " + mcm.getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void write(File datapacks, String type, String json) {
|
||||||
|
File dimType = new File(datapacks, "iris/data/iris/dimension_type/" + type + ".json");
|
||||||
|
File dimTypeVanilla = new File(datapacks, "iris/data/minecraft/dimension_type/" + type + ".json");
|
||||||
|
|
||||||
|
dimType.getParentFile().mkdirs();
|
||||||
try {
|
try {
|
||||||
IO.writeAll(dimTypeOverworld, generateDatapackJsonOverworld(fixer));
|
IO.writeAll(dimType, json);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IrisSettings.get().getGeneral().adjustVanillaHeight || dimTypeVanilla.exists()) {
|
||||||
File dimTypeNether = new File(datapacks, "iris/data/minecraft/dimension_type/the_nether.json");
|
dimTypeVanilla.getParentFile().mkdirs();
|
||||||
if (!dimTypeNether.exists())
|
try {
|
||||||
changed = true;
|
IO.writeAll(dimTypeVanilla, json);
|
||||||
dimTypeNether.getParentFile().mkdirs();
|
} catch (IOException e) {
|
||||||
try {
|
Iris.reportError(e);
|
||||||
IO.writeAll(dimTypeNether, generateDatapackJsonNether(fixer));
|
e.printStackTrace();
|
||||||
} catch (IOException e) {
|
}
|
||||||
Iris.reportError(e);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
File dimTypeEnd = new File(datapacks, "iris/data/minecraft/dimension_type/the_end.json");
|
|
||||||
if (!dimTypeEnd.exists())
|
|
||||||
changed = true;
|
|
||||||
dimTypeEnd.getParentFile().mkdirs();
|
|
||||||
try {
|
|
||||||
IO.writeAll(dimTypeEnd, generateDatapackJsonEnd(fixer));
|
|
||||||
} catch (IOException e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String generateDatapackJsonOverworld(IDataFixer fixer) {
|
|
||||||
JSONObject obj = new JSONObject(DP_OVERWORLD_DEFAULT);
|
|
||||||
obj.put("min_y", dimensionHeight.getMin());
|
|
||||||
obj.put("height", dimensionHeight.getMax() - dimensionHeight.getMin());
|
|
||||||
obj.put("logical_height", logicalHeight);
|
|
||||||
return fixer.fixDimension(obj).toString(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String generateDatapackJsonNether(IDataFixer fixer) {
|
|
||||||
JSONObject obj = new JSONObject(DP_NETHER_DEFAULT);
|
|
||||||
obj.put("min_y", dimensionHeightNether.getMin());
|
|
||||||
obj.put("height", dimensionHeightNether.getMax() - dimensionHeightNether.getMin());
|
|
||||||
obj.put("logical_height", logicalHeightNether);
|
|
||||||
return fixer.fixDimension(obj).toString(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String generateDatapackJsonEnd(IDataFixer fixer) {
|
|
||||||
JSONObject obj = new JSONObject(DP_END_DEFAULT);
|
|
||||||
obj.put("min_y", dimensionHeightEnd.getMin());
|
|
||||||
obj.put("height", dimensionHeightEnd.getMax() - dimensionHeightEnd.getMin());
|
|
||||||
obj.put("logical_height", logicalHeightEnd);
|
|
||||||
return fixer.fixDimension(obj).toString(4);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2022 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;
|
|
||||||
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
|
||||||
import com.volmit.iris.util.collection.KList;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class IrisEngineChunkData {
|
|
||||||
private long chunk;
|
|
||||||
private KList<IrisEngineSpawnerCooldown> cooldowns = new KList<>();
|
|
||||||
|
|
||||||
public void cleanup(Engine engine) {
|
|
||||||
for (IrisEngineSpawnerCooldown i : getCooldowns().copy()) {
|
|
||||||
IrisSpawner sp = engine.getData().getSpawnerLoader().load(i.getSpawner());
|
|
||||||
|
|
||||||
if (sp == null || i.canSpawn(sp.getMaximumRate())) {
|
|
||||||
getCooldowns().remove(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return cooldowns.isEmpty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,51 +20,31 @@ package com.volmit.iris.engine.object;
|
|||||||
|
|
||||||
import com.volmit.iris.engine.data.cache.Cache;
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class IrisEngineData {
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class IrisEngineData extends IrisSpawnerCooldowns {
|
||||||
private IrisEngineStatistics statistics = new IrisEngineStatistics();
|
private IrisEngineStatistics statistics = new IrisEngineStatistics();
|
||||||
private KList<IrisEngineSpawnerCooldown> spawnerCooldowns = new KList<>();
|
private KMap<Long, IrisSpawnerCooldowns> chunks = new KMap<>();
|
||||||
private KList<IrisEngineChunkData> chunks = new KList<>();
|
|
||||||
private Long seed = null;
|
private Long seed = null;
|
||||||
|
|
||||||
public void removeChunk(int x, int z) {
|
public void removeChunk(int x, int z) {
|
||||||
long k = Cache.key(x, z);
|
chunks.remove(Cache.key(x, z));
|
||||||
chunks.removeWhere((i) -> i.getChunk() == k);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IrisEngineChunkData getChunk(int x, int z) {
|
public IrisSpawnerCooldowns getChunk(int x, int z) {
|
||||||
long k = Cache.key(x, z);
|
return chunks.computeIfAbsent(Cache.key(x, z), k -> new IrisSpawnerCooldowns());
|
||||||
|
|
||||||
for (IrisEngineChunkData i : chunks) {
|
|
||||||
if (i.getChunk() == k) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IrisEngineChunkData c = new IrisEngineChunkData();
|
|
||||||
c.setChunk(k);
|
|
||||||
chunks.add(c);
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanup(Engine engine) {
|
public void cleanup(Engine engine) {
|
||||||
for (IrisEngineSpawnerCooldown i : getSpawnerCooldowns().copy()) {
|
super.cleanup(engine);
|
||||||
IrisSpawner sp = engine.getData().getSpawnerLoader().load(i.getSpawner());
|
|
||||||
|
|
||||||
if (sp == null || i.canSpawn(sp.getMaximumRate())) {
|
chunks.values().removeIf(chunk -> {
|
||||||
getSpawnerCooldowns().remove(i);
|
chunk.cleanup(engine);
|
||||||
}
|
return chunk.isEmpty();
|
||||||
}
|
});
|
||||||
|
|
||||||
for (IrisEngineChunkData i : chunks.copy()) {
|
|
||||||
i.cleanup(engine);
|
|
||||||
|
|
||||||
if (i.isEmpty()) {
|
|
||||||
getChunks().remove(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import com.volmit.iris.util.format.C;
|
|||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
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.misc.E;
|
|
||||||
import com.volmit.iris.util.plugin.Chunks;
|
import com.volmit.iris.util.plugin.Chunks;
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
@@ -57,6 +56,8 @@ import java.util.concurrent.ExecutionException;
|
|||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import static com.volmit.iris.util.data.registry.Particles.ITEM;
|
||||||
|
|
||||||
@SuppressWarnings("ALL")
|
@SuppressWarnings("ALL")
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@@ -66,7 +67,6 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
public class IrisEntity extends IrisRegistrant {
|
public class IrisEntity extends IrisRegistrant {
|
||||||
private static final Particle ITEM = E.getOrDefault(Particle.class, "ITEM_CRACK", "ITEM");
|
|
||||||
@Required
|
@Required
|
||||||
@Desc("The type of entity to spawn. To spawn a mythic mob, set this type to unknown and define mythic type.")
|
@Desc("The type of entity to spawn. To spawn a mythic mob, set this type to unknown and define mythic type.")
|
||||||
private EntityType type = EntityType.UNKNOWN;
|
private EntityType type = EntityType.UNKNOWN;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import com.dfsek.paralithic.eval.parser.Scope;
|
|||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.loader.IrisRegistrant;
|
import com.volmit.iris.core.loader.IrisRegistrant;
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
|
import com.volmit.iris.engine.object.IrisExpressionFunction.FunctionContext;
|
||||||
import com.volmit.iris.engine.object.annotations.ArrayType;
|
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;
|
||||||
@@ -46,12 +47,14 @@ import lombok.experimental.Accessors;
|
|||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
public class IrisExpression extends IrisRegistrant {
|
public class IrisExpression extends IrisRegistrant {
|
||||||
private static final Parser parser = new Parser();
|
|
||||||
|
|
||||||
@ArrayType(type = IrisExpressionLoad.class, min = 1)
|
@ArrayType(type = IrisExpressionLoad.class, min = 1)
|
||||||
@Desc("Variables to use in this expression")
|
@Desc("Variables to use in this expression")
|
||||||
private KList<IrisExpressionLoad> variables = new KList<>();
|
private KList<IrisExpressionLoad> variables = new KList<>();
|
||||||
|
|
||||||
|
@ArrayType(type = IrisExpressionFunction.class, min = 1)
|
||||||
|
@Desc("Functions to use in this expression")
|
||||||
|
private KList<IrisExpressionFunction> functions = new KList<>();
|
||||||
|
|
||||||
@Required
|
@Required
|
||||||
@Desc("The expression. Inherited variables are x, y and z. Avoid using those variable names.")
|
@Desc("The expression. Inherited variables are x, y and z. Avoid using those variable names.")
|
||||||
private String expression;
|
private String expression;
|
||||||
@@ -62,6 +65,7 @@ public class IrisExpression extends IrisRegistrant {
|
|||||||
private Expression expression() {
|
private Expression expression() {
|
||||||
return expressionCache.aquire(() -> {
|
return expressionCache.aquire(() -> {
|
||||||
Scope scope = new Scope(); // Create variable scope. This scope can hold both constants and invocation variables.
|
Scope scope = new Scope(); // Create variable scope. This scope can hold both constants and invocation variables.
|
||||||
|
Parser parser = new Parser();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (IrisExpressionLoad i : variables) {
|
for (IrisExpressionLoad i : variables) {
|
||||||
@@ -76,6 +80,12 @@ public class IrisExpression extends IrisRegistrant {
|
|||||||
Iris.error("Script Variable load error in " + getLoadFile().getPath());
|
Iris.error("Script Variable load error in " + getLoadFile().getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (IrisExpressionFunction f : functions) {
|
||||||
|
if (!f.isValid()) continue;
|
||||||
|
f.setData(getLoader());
|
||||||
|
parser.registerFunction(f.getName(), f);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return parser.parse(getExpression(), scope);
|
return parser.parse(getExpression(), scope);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@@ -103,7 +113,7 @@ public class IrisExpression extends IrisRegistrant {
|
|||||||
g[m++] = z;
|
g[m++] = z;
|
||||||
g[m] = -1;
|
g[m] = -1;
|
||||||
|
|
||||||
return expression().evaluate(g);
|
return expression().evaluate(new FunctionContext(rng), g);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double evaluate(RNG rng, double x, double y, double z) {
|
public double evaluate(RNG rng, double x, double y, double z) {
|
||||||
@@ -117,7 +127,7 @@ public class IrisExpression extends IrisRegistrant {
|
|||||||
g[m++] = y;
|
g[m++] = y;
|
||||||
g[m] = z;
|
g[m] = z;
|
||||||
|
|
||||||
return expression().evaluate(g);
|
return expression().evaluate(new FunctionContext(rng), g);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package com.volmit.iris.engine.object;
|
||||||
|
|
||||||
|
import com.dfsek.paralithic.functions.dynamic.Context;
|
||||||
|
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
||||||
|
import com.dfsek.paralithic.node.Statefulness;
|
||||||
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
|
import com.volmit.iris.engine.object.annotations.Desc;
|
||||||
|
import com.volmit.iris.engine.object.annotations.MinNumber;
|
||||||
|
import com.volmit.iris.engine.object.annotations.Required;
|
||||||
|
import com.volmit.iris.engine.object.annotations.Snippet;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
|
import lombok.*;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
@Snippet("expression-function")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Desc("Represents a function to use in your expression. Do not set the name to x, y, or z, also don't duplicate names.")
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class IrisExpressionFunction implements DynamicFunction {
|
||||||
|
@Required
|
||||||
|
@Desc("The function to assign this value to. Do not set the name to x, y, or z")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Desc("If defined, this variable will use a generator style as it's value")
|
||||||
|
private IrisGeneratorStyle styleValue = null;
|
||||||
|
|
||||||
|
@Desc("If defined, iris will use an internal stream from the engine as it's value")
|
||||||
|
private IrisEngineStreamType engineStreamValue = null;
|
||||||
|
|
||||||
|
@MinNumber(2)
|
||||||
|
@Desc("Number of arguments for the function")
|
||||||
|
private int args = 2;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.NONE)
|
||||||
|
@Setter(AccessLevel.NONE)
|
||||||
|
private transient final KMap<FunctionContext, Provider> cache = new KMap<>();
|
||||||
|
private transient IrisData data;
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
return styleValue != null || engineStreamValue != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getArgNumber() {
|
||||||
|
if (engineStreamValue != null) return 2;
|
||||||
|
return Math.max(args, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Statefulness statefulness() {
|
||||||
|
return Statefulness.STATEFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double eval(double... doubles) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double eval(@Nullable Context raw, double... args) {
|
||||||
|
return cache.computeIfAbsent((FunctionContext) raw, context -> {
|
||||||
|
assert context != null;
|
||||||
|
if (engineStreamValue != null) {
|
||||||
|
var stream = engineStreamValue.get(data.getEngine());
|
||||||
|
return d -> stream.get(d[0], d[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (styleValue != null) {
|
||||||
|
return styleValue.createNoCache(context.rng, data)::noise;
|
||||||
|
}
|
||||||
|
|
||||||
|
return d -> Double.NaN;
|
||||||
|
}).eval(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public record FunctionContext(@NonNull RNG rng) implements Context {
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
FunctionContext that = (FunctionContext) o;
|
||||||
|
return rng.getSeed() == that.rng.getSeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Long.hashCode(rng.getSeed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
private interface Provider {
|
||||||
|
double eval(double... args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,12 +23,11 @@ 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.Required;
|
import com.volmit.iris.engine.object.annotations.Required;
|
||||||
import com.volmit.iris.engine.object.annotations.Snippet;
|
import com.volmit.iris.engine.object.annotations.Snippet;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
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.stream.ProceduralStream;
|
import com.volmit.iris.util.stream.ProceduralStream;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.*;
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
@Snippet("expression-load")
|
@Snippet("expression-load")
|
||||||
@@ -57,6 +56,9 @@ public class IrisExpressionLoad {
|
|||||||
|
|
||||||
private transient AtomicCache<ProceduralStream<Double>> streamCache = new AtomicCache<>();
|
private transient AtomicCache<ProceduralStream<Double>> streamCache = new AtomicCache<>();
|
||||||
private transient AtomicCache<Double> valueCache = new AtomicCache<>();
|
private transient AtomicCache<Double> valueCache = new AtomicCache<>();
|
||||||
|
@Getter(AccessLevel.NONE)
|
||||||
|
@Setter(AccessLevel.NONE)
|
||||||
|
private transient final KMap<Long, CNG> styleCache = new KMap<>();
|
||||||
|
|
||||||
public double getValue(RNG rng, IrisData data, double x, double z) {
|
public double getValue(RNG rng, IrisData data, double x, double z) {
|
||||||
if (engineValue != null) {
|
if (engineValue != null) {
|
||||||
@@ -68,7 +70,8 @@ public class IrisExpressionLoad {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (styleValue != null) {
|
if (styleValue != null) {
|
||||||
return styleValue.create(rng, data).noise(x, z);
|
return styleCache.computeIfAbsent(rng.getSeed(), k -> styleValue.createNoCache(new RNG(k), data))
|
||||||
|
.noise(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
return staticValue;
|
return staticValue;
|
||||||
@@ -84,7 +87,8 @@ public class IrisExpressionLoad {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (styleValue != null) {
|
if (styleValue != null) {
|
||||||
return styleValue.create(rng, data).noise(x, y, z);
|
return styleCache.computeIfAbsent(rng.getSeed(), k -> styleValue.createNoCache(new RNG(k), data))
|
||||||
|
.noise(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
return staticValue;
|
return staticValue;
|
||||||
|
|||||||
@@ -123,8 +123,6 @@ public class IrisImage extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void writeDebug(IrisImageChannel channel) {
|
public void writeDebug(IrisImageChannel channel) {
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
File at = new File(getLoadFile().getParentFile(), "debug-see-" + getLoadFile().getName());
|
File at = new File(getLoadFile().getParentFile(), "debug-see-" + getLoadFile().getName());
|
||||||
BufferedImage b = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
|
BufferedImage b = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
|
||||||
|
|||||||
@@ -139,6 +139,14 @@ public class IrisJigsawStructure extends IrisRegistrant {
|
|||||||
loadPiece(i, pools, pieces);
|
loadPiece(i, pools, pieces);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pieces.isEmpty()) {
|
||||||
|
int max = 0;
|
||||||
|
for (String i : getPieces()) {
|
||||||
|
max = Math.max(max, getLoader().getJigsawPieceLoader().load(i).getMax2dDimension());
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
int avg = 0;
|
int avg = 0;
|
||||||
|
|
||||||
for (String i : pieces) {
|
for (String i : pieces) {
|
||||||
|
|||||||
@@ -19,13 +19,8 @@
|
|||||||
package com.volmit.iris.engine.object;
|
package com.volmit.iris.engine.object;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.engine.object.annotations.ArrayType;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
import com.volmit.iris.engine.object.annotations.Desc;
|
import com.volmit.iris.engine.object.annotations.*;
|
||||||
import com.volmit.iris.engine.object.annotations.MaxNumber;
|
|
||||||
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.annotations.Snippet;
|
|
||||||
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.documentation.ChunkCoordinates;
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
@@ -54,6 +49,7 @@ public class IrisJigsawStructurePlacement implements IRare {
|
|||||||
private int rarity = 100;
|
private int rarity = 100;
|
||||||
|
|
||||||
@Required
|
@Required
|
||||||
|
@DependsOn({"spacing", "separation"})
|
||||||
@Desc("The salt to use when generating the structure (to differentiate structures)")
|
@Desc("The salt to use when generating the structure (to differentiate structures)")
|
||||||
@MinNumber(Long.MIN_VALUE)
|
@MinNumber(Long.MIN_VALUE)
|
||||||
@MaxNumber(Long.MAX_VALUE)
|
@MaxNumber(Long.MAX_VALUE)
|
||||||
@@ -61,16 +57,29 @@ public class IrisJigsawStructurePlacement implements IRare {
|
|||||||
|
|
||||||
@Required
|
@Required
|
||||||
@MinNumber(0)
|
@MinNumber(0)
|
||||||
|
@DependsOn({"salt", "separation"})
|
||||||
@Desc("Average distance in chunks between two neighboring generation attempts")
|
@Desc("Average distance in chunks between two neighboring generation attempts")
|
||||||
private int spacing = -1;
|
private int spacing = -1;
|
||||||
|
|
||||||
@Required
|
@Required
|
||||||
@MinNumber(0)
|
@MinNumber(0)
|
||||||
|
@DependsOn({"salt", "spacing"})
|
||||||
@Desc("Minimum distance in chunks between two neighboring generation attempts\nThe maximum distance of two neighboring generation attempts is 2*spacing - separation")
|
@Desc("Minimum distance in chunks between two neighboring generation attempts\nThe maximum distance of two neighboring generation attempts is 2*spacing - separation")
|
||||||
private int separation = -1;
|
private int separation = -1;
|
||||||
|
|
||||||
@Desc("The method used to spread the structure")
|
@Desc("The method used to spread the structure")
|
||||||
private SpreadType spreadType = SpreadType.TRIANGULAR;
|
private SpreadType spreadType = SpreadType.LINEAR;
|
||||||
|
|
||||||
|
@DependsOn({"spreadType"})
|
||||||
|
@Desc("The noise style to use when spreadType is set to 'NOISE'\nThis ignores the spacing and separation parameters")
|
||||||
|
private IrisGeneratorStyle style = new IrisGeneratorStyle();
|
||||||
|
|
||||||
|
@DependsOn({"spreadType", "style"})
|
||||||
|
@Desc("Threshold for noise style")
|
||||||
|
private double threshold = 0.5;
|
||||||
|
|
||||||
|
@Desc("Exclude the structure from certain places")
|
||||||
|
private IrisPlacementExclusion exclude = new IrisPlacementExclusion();
|
||||||
|
|
||||||
@ArrayType(type = IrisJigsawMinDistance.class)
|
@ArrayType(type = IrisJigsawMinDistance.class)
|
||||||
@Desc("List of minimum distances to check for")
|
@Desc("List of minimum distances to check for")
|
||||||
@@ -89,20 +98,29 @@ public class IrisJigsawStructurePlacement implements IRare {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void calculateMissing(double divisor, long seed) {
|
private void calculateMissing(double divisor, long seed) {
|
||||||
seed = seed + hashCode();
|
if (salt != 0 && separation > 0 && spacing > 0)
|
||||||
|
return;
|
||||||
|
seed *= (long) structure.hashCode() * rarity;
|
||||||
if (salt == 0) {
|
if (salt == 0) {
|
||||||
salt = new RNG(seed).nextLong(Integer.MIN_VALUE, Integer.MAX_VALUE);
|
salt = new RNG(seed).l(Integer.MIN_VALUE, Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (separation == -1 || spacing == -1) {
|
if (separation == -1 || spacing == -1) {
|
||||||
separation = (int) Math.round(rarity / divisor);
|
separation = (int) Math.round(rarity / divisor);
|
||||||
spacing = new RNG(seed).nextInt(separation, separation * 2);
|
spacing = new RNG(seed).i(separation, separation * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
public boolean shouldPlace(double divisor, long seed, int x, int z) {
|
public boolean shouldPlace(IrisData data, double divisor, long seed, int x, int z) {
|
||||||
calculateMissing(divisor, seed);
|
calculateMissing(divisor, seed);
|
||||||
|
if (spreadType != SpreadType.NOISE)
|
||||||
|
return shouldPlaceSpread(seed, x, z);
|
||||||
|
|
||||||
|
return style.create(new RNG(seed + salt), data).noise(x, z) > threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldPlaceSpread(long seed, int x, int z) {
|
||||||
if (separation > spacing) {
|
if (separation > spacing) {
|
||||||
separation = spacing;
|
separation = spacing;
|
||||||
Iris.warn("JigsawStructurePlacement: separation must be less than or equal to spacing");
|
Iris.warn("JigsawStructurePlacement: separation must be less than or equal to spacing");
|
||||||
@@ -123,7 +141,9 @@ public class IrisJigsawStructurePlacement implements IRare {
|
|||||||
@Desc("Linear spread")
|
@Desc("Linear spread")
|
||||||
LINEAR(RNG::i),
|
LINEAR(RNG::i),
|
||||||
@Desc("Triangular spread")
|
@Desc("Triangular spread")
|
||||||
TRIANGULAR((rng, bound) -> (rng.i(bound) + rng.i(bound)) / 2);
|
TRIANGULAR((rng, bound) -> (rng.i(bound) + rng.i(bound)) / 2),
|
||||||
|
@Desc("Noise based spread\nThis ignores the spacing and separation parameters")
|
||||||
|
NOISE((rng, bound) -> 0);
|
||||||
private final SpreadMethod method;
|
private final SpreadMethod method;
|
||||||
|
|
||||||
SpreadType(SpreadMethod method) {
|
SpreadType(SpreadMethod method) {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ 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.context.IrisContext;
|
import com.volmit.iris.util.context.IrisContext;
|
||||||
import com.volmit.iris.util.data.B;
|
import com.volmit.iris.util.data.B;
|
||||||
import com.volmit.iris.util.data.IrisBlockData;
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
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.json.JSONObject;
|
||||||
@@ -53,8 +53,6 @@ import org.bukkit.Location;
|
|||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.BlockState;
|
|
||||||
import org.bukkit.block.TileState;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.block.data.MultipleFacing;
|
import org.bukkit.block.data.MultipleFacing;
|
||||||
import org.bukkit.block.data.Waterlogged;
|
import org.bukkit.block.data.Waterlogged;
|
||||||
@@ -943,7 +941,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
if (j.isExact() ? k.matches(data) : k.getMaterial().equals(data.getMaterial())) {
|
if (j.isExact() ? k.matches(data) : k.getMaterial().equals(data.getMaterial())) {
|
||||||
BlockData newData = j.getReplace(rng, i.getX() + x, i.getY() + y, i.getZ() + z, rdata).clone();
|
BlockData newData = j.getReplace(rng, i.getX() + x, i.getY() + y, i.getZ() + z, rdata).clone();
|
||||||
|
|
||||||
if (newData.getMaterial() == data.getMaterial() && !(newData instanceof IrisBlockData || data instanceof IrisBlockData))
|
if (newData.getMaterial() == data.getMaterial() && !(newData instanceof IrisCustomData || data instanceof IrisCustomData))
|
||||||
data = data.merge(newData);
|
data = data.merge(newData);
|
||||||
else
|
else
|
||||||
data = newData;
|
data = newData;
|
||||||
@@ -1012,8 +1010,9 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean wouldReplace = B.isSolid(placer.get(xx, yy, zz)) && B.isVineBlock(data);
|
boolean wouldReplace = B.isSolid(placer.get(xx, yy, zz)) && B.isVineBlock(data);
|
||||||
|
boolean place = !data.getMaterial().equals(Material.AIR) && !data.getMaterial().equals(Material.CAVE_AIR) && !wouldReplace;
|
||||||
|
|
||||||
if (!data.getMaterial().equals(Material.AIR) && !data.getMaterial().equals(Material.CAVE_AIR) && !wouldReplace) {
|
if (data instanceof IrisCustomData || place) {
|
||||||
placer.set(xx, yy, zz, data);
|
placer.set(xx, yy, zz, data);
|
||||||
if (tile != null) {
|
if (tile != null) {
|
||||||
placer.setTile(xx, yy, zz, tile);
|
placer.setTile(xx, yy, zz, tile);
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.volmit.iris.engine.object;
|
||||||
|
|
||||||
|
import com.volmit.iris.engine.object.annotations.ArrayType;
|
||||||
|
import com.volmit.iris.engine.object.annotations.Desc;
|
||||||
|
import com.volmit.iris.engine.object.annotations.RegistryListResource;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Desc("Represents an image map")
|
||||||
|
@Data
|
||||||
|
public class IrisPlacementExclusion {
|
||||||
|
|
||||||
|
@Desc("Excludes the structure from all ocean biomes defined in region")
|
||||||
|
private boolean excludeOceanBiomes;
|
||||||
|
|
||||||
|
@Desc("Excludes the structure from all shore biomes defined in region")
|
||||||
|
private boolean excludeShoreBiomes;
|
||||||
|
|
||||||
|
@Desc("Excludes the structure from all land biomes defined in region")
|
||||||
|
private boolean excludeLandBiomes;
|
||||||
|
|
||||||
|
@RegistryListResource(IrisBiome.class)
|
||||||
|
@Desc("tbd")
|
||||||
|
@ArrayType(min = 1, type = String.class)
|
||||||
|
private KList<String> excludeBiomes = new KList<>();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -50,4 +50,10 @@ public class IrisRange {
|
|||||||
public boolean contains(int v) {
|
public boolean contains(int v) {
|
||||||
return v >= min && v <= max;
|
return v >= min && v <= max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IrisRange merge(IrisRange other) {
|
||||||
|
min = Math.min(min, other.min);
|
||||||
|
max = Math.max(max, other.max);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class IrisRate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public long getInterval() {
|
public long getInterval() {
|
||||||
long t = per.getMilliseconds() / (amount == 0 ? 1 : amount);
|
long t = per.toMilliseconds() / (amount == 0 ? 1 : amount);
|
||||||
return Math.abs(t <= 0 ? 1 : t);
|
return Math.abs(t <= 0 ? 1 : t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
package com.volmit.iris.engine.object;
|
package com.volmit.iris.engine.object;
|
||||||
|
|
||||||
import com.volmit.iris.core.loader.IrisRegistrant;
|
import com.volmit.iris.core.loader.IrisRegistrant;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.annotations.ArrayType;
|
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.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
@@ -95,6 +96,37 @@ public class IrisSpawner extends IrisRegistrant {
|
|||||||
return timeBlock.isWithin(world) && weather.is(world);
|
return timeBlock.isWithin(world) && weather.is(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean canSpawn(Engine engine) {
|
||||||
|
if (!isValid(engine.getWorld().realWorld()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var rate = getMaximumRate();
|
||||||
|
return rate.isInfinite() || engine.getEngineData().getCooldown(this).canSpawn(rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canSpawn(Engine engine, int x, int z) {
|
||||||
|
if (!canSpawn(engine))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var rate = getMaximumRatePerChunk();
|
||||||
|
return rate.isInfinite() || engine.getEngineData().getChunk(x, z).getCooldown(this).canSpawn(rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void spawn(Engine engine) {
|
||||||
|
if (getMaximumRate().isInfinite())
|
||||||
|
return;
|
||||||
|
|
||||||
|
engine.getEngineData().getCooldown(this).spawn(engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void spawn(Engine engine, int x, int z) {
|
||||||
|
spawn(engine);
|
||||||
|
if (getMaximumRatePerChunk().isInfinite())
|
||||||
|
return;
|
||||||
|
|
||||||
|
engine.getEngineData().getChunk(x, z).getCooldown(this).spawn(engine);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFolderName() {
|
public String getFolderName() {
|
||||||
return "spawners";
|
return "spawners";
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.volmit.iris.engine.object;
|
||||||
|
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
@EqualsAndHashCode
|
||||||
|
public class IrisSpawnerCooldowns {
|
||||||
|
private final KMap<String, IrisEngineSpawnerCooldown> cooldowns = new KMap<>();
|
||||||
|
|
||||||
|
public IrisEngineSpawnerCooldown getCooldown(@NonNull IrisSpawner spawner) {
|
||||||
|
return getCooldown(spawner.getLoadKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IrisEngineSpawnerCooldown getCooldown(@NonNull String loadKey) {
|
||||||
|
return cooldowns.computeIfAbsent(loadKey, k -> {
|
||||||
|
IrisEngineSpawnerCooldown cd = new IrisEngineSpawnerCooldown();
|
||||||
|
cd.setSpawner(loadKey);
|
||||||
|
return cd;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanup(Engine engine) {
|
||||||
|
cooldowns.values().removeIf(cd -> {
|
||||||
|
IrisSpawner sp = engine.getData().getSpawnerLoader().load(cd.getSpawner());
|
||||||
|
return sp == null || cd.canSpawn(sp.getMaximumRate());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return cooldowns.isEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,7 +35,6 @@ import java.io.IOException;
|
|||||||
|
|
||||||
@SuppressWarnings("ALL")
|
@SuppressWarnings("ALL")
|
||||||
@Getter
|
@Getter
|
||||||
@ToString
|
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||||
@@ -137,4 +136,9 @@ public class TileData implements Cloneable {
|
|||||||
clone.properties = properties.copy(); //TODO make a deep copy
|
clone.properties = properties.copy(); //TODO make a deep copy
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return material.getKey() + gson.toJson(properties);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,8 +58,6 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@@ -86,7 +84,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
|||||||
private final boolean studio;
|
private final boolean studio;
|
||||||
private final AtomicInteger a = new AtomicInteger(0);
|
private final AtomicInteger a = new AtomicInteger(0);
|
||||||
private final CompletableFuture<Integer> spawnChunks = new CompletableFuture<>();
|
private final CompletableFuture<Integer> spawnChunks = new CompletableFuture<>();
|
||||||
private final boolean smartVanillaHeight;
|
|
||||||
private Engine engine;
|
private Engine engine;
|
||||||
private Looper hotloader;
|
private Looper hotloader;
|
||||||
private StudioMode lastMode;
|
private StudioMode lastMode;
|
||||||
@@ -96,7 +93,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
|||||||
|
|
||||||
private boolean initialized = false;
|
private boolean initialized = false;
|
||||||
|
|
||||||
public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey, boolean smartVanillaHeight) {
|
public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey) {
|
||||||
setup = new AtomicBoolean(false);
|
setup = new AtomicBoolean(false);
|
||||||
studioGenerator = null;
|
studioGenerator = null;
|
||||||
dummyBiomeProvider = new DummyBiomeProvider();
|
dummyBiomeProvider = new DummyBiomeProvider();
|
||||||
@@ -108,7 +105,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
|||||||
this.dataLocation = dataLocation;
|
this.dataLocation = dataLocation;
|
||||||
this.dimensionKey = dimensionKey;
|
this.dimensionKey = dimensionKey;
|
||||||
this.folder = new ReactiveFolder(dataLocation, (_a, _b, _c) -> hotload());
|
this.folder = new ReactiveFolder(dataLocation, (_a, _b, _c) -> hotload());
|
||||||
this.smartVanillaHeight = smartVanillaHeight;
|
|
||||||
Bukkit.getServer().getPluginManager().registerEvents(this, Iris.instance);
|
Bukkit.getServer().getPluginManager().registerEvents(this, Iris.instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,14 +182,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
|||||||
throw new RuntimeException("Missing Dimension: " + dimensionKey);
|
throw new RuntimeException("Missing Dimension: " + dimensionKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (smartVanillaHeight) {
|
|
||||||
dimension.setSmartVanillaHeight(true);
|
|
||||||
try (FileWriter writer = new FileWriter(data.getDimensionLoader().fileFor(dimension))) {
|
|
||||||
writer.write(data.getGson().toJson(dimension));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lastMode = StudioMode.NORMAL;
|
lastMode = StudioMode.NORMAL;
|
||||||
engine = new IrisEngine(new EngineTarget(world, dimension, data), studio);
|
engine = new IrisEngine(new EngineTarget(world, dimension, data), studio);
|
||||||
|
|||||||
@@ -22,10 +22,9 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.core.IrisSettings;
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.link.Identifier;
|
import com.volmit.iris.core.link.Identifier;
|
||||||
import com.volmit.iris.core.service.ExternalDataSVC;
|
import com.volmit.iris.core.service.ExternalDataSVC;
|
||||||
import com.volmit.iris.engine.object.IrisCompat;
|
|
||||||
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.misc.E;
|
import com.volmit.iris.util.data.registry.Materials;
|
||||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||||
import it.unimi.dsi.fastutil.ints.*;
|
import it.unimi.dsi.fastutil.ints.*;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@@ -47,7 +46,7 @@ public class B {
|
|||||||
private static final KMap<String, BlockData> custom = new KMap<>();
|
private static final KMap<String, BlockData> custom = new KMap<>();
|
||||||
|
|
||||||
private static final Material AIR_MATERIAL = Material.AIR;
|
private static final Material AIR_MATERIAL = Material.AIR;
|
||||||
private static final Material SHORT_GRASS = E.getOrDefault(Material.class, "GRASS", "SHORT_GRASS");
|
private static final Material SHORT_GRASS = Materials.GRASS;
|
||||||
private static final BlockData AIR = AIR_MATERIAL.createBlockData();
|
private static final BlockData AIR = AIR_MATERIAL.createBlockData();
|
||||||
private static final IntSet foliageCache = buildFoliageCache();
|
private static final IntSet foliageCache = buildFoliageCache();
|
||||||
private static final IntSet deepslateCache = buildDeepslateCache();
|
private static final IntSet deepslateCache = buildDeepslateCache();
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class IrisBlockData implements BlockData {
|
public class IrisCustomData implements BlockData {
|
||||||
private final @NonNull BlockData base;
|
private final @NonNull BlockData base;
|
||||||
private final @NotNull Identifier custom;
|
private final @NotNull Identifier custom;
|
||||||
|
|
||||||
@@ -40,12 +40,12 @@ public class IrisBlockData implements BlockData {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public BlockData merge(@NotNull BlockData blockData) {
|
public BlockData merge(@NotNull BlockData blockData) {
|
||||||
return new IrisBlockData(base.merge(blockData), custom);
|
return new IrisCustomData(base.merge(blockData), custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(@Nullable BlockData blockData) {
|
public boolean matches(@Nullable BlockData blockData) {
|
||||||
if (blockData instanceof IrisBlockData b)
|
if (blockData instanceof IrisCustomData b)
|
||||||
return custom.equals(b.custom) && base.matches(b.base);
|
return custom.equals(b.custom) && base.matches(b.base);
|
||||||
return base.matches(blockData);
|
return base.matches(blockData);
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ public class IrisBlockData implements BlockData {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public BlockData clone() {
|
public BlockData clone() {
|
||||||
return new IrisBlockData(base.clone(), custom);
|
return new IrisCustomData(base.clone(), custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.volmit.iris.util.data.registry;
|
||||||
|
|
||||||
|
import org.bukkit.attribute.Attribute;
|
||||||
|
|
||||||
|
public class Attributes {
|
||||||
|
public static final Attribute MAX_HEALTH = RegistryUtil.find(Attribute.class, "generic_max_health", "max_health");
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.volmit.iris.util.data.registry;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
|
||||||
|
import static com.volmit.iris.util.data.registry.RegistryUtil.find;
|
||||||
|
|
||||||
|
public class Materials {
|
||||||
|
public static final Material GRASS = find(Material.class, "grass", "short_grass");
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.volmit.iris.util.data.registry;
|
||||||
|
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
|
||||||
|
import static com.volmit.iris.util.data.registry.RegistryUtil.find;
|
||||||
|
|
||||||
|
public class Particles {
|
||||||
|
public static final Particle CRIT_MAGIC = find(Particle.class, "crit_magic", "crit");
|
||||||
|
public static final Particle REDSTONE = find(Particle.class, "redstone", "dust");
|
||||||
|
public static final Particle ITEM = find(Particle.class, "item_crack", "item");
|
||||||
|
}
|
||||||
@@ -0,0 +1,209 @@
|
|||||||
|
package com.volmit.iris.util.data.registry;
|
||||||
|
|
||||||
|
import com.volmit.iris.core.nms.container.Pair;
|
||||||
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Keyed;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.Registry;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public class RegistryUtil {
|
||||||
|
private static final AtomicCache<RegistryLookup> registryLookup = new AtomicCache<>();
|
||||||
|
private static final Map<Class<?>, Map<NamespacedKey, Keyed>> KEYED_REGISTRY = new HashMap<>();
|
||||||
|
private static final Map<Class<?>, Map<NamespacedKey, Object>> ENUM_REGISTRY = new HashMap<>();
|
||||||
|
private static final Map<Class<?>, Registry<Keyed>> REGISTRY = new HashMap<>();
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static <T> T find(@NonNull Class<T> typeClass, @NonNull String... keys) {
|
||||||
|
return find(typeClass, defaultLookup(), keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static <T> T find(@NonNull Class<T> typeClass, @Nullable Lookup<T> lookup, @NonNull String... keys) {
|
||||||
|
return find(typeClass, lookup, Arrays.stream(keys).map(NamespacedKey::minecraft).toArray(NamespacedKey[]::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T find(@NonNull Class<T> typeClass, @NonNull NamespacedKey... keys) {
|
||||||
|
return find(typeClass, defaultLookup(), keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static <T> T find(@NonNull Class<T> typeClass, @Nullable Lookup<T> lookup, @NonNull NamespacedKey... keys) {
|
||||||
|
if (keys.length == 0) throw new IllegalArgumentException("Need at least one key");
|
||||||
|
Registry<Keyed> registry = null;
|
||||||
|
if (Keyed.class.isAssignableFrom(typeClass)) {
|
||||||
|
registry = getRegistry(typeClass.asSubclass(Keyed.class));
|
||||||
|
}
|
||||||
|
if (registry == null) {
|
||||||
|
registry = REGISTRY.computeIfAbsent(typeClass, t -> Arrays.stream(Registry.class.getDeclaredFields())
|
||||||
|
.filter(field -> Modifier.isStatic(field.getModifiers()) && Modifier.isPublic(field.getModifiers()))
|
||||||
|
.filter(field -> Registry.class.isAssignableFrom(field.getType()))
|
||||||
|
.filter(field -> ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0].equals(t))
|
||||||
|
.map(field -> {
|
||||||
|
try {
|
||||||
|
return (Registry<Keyed>) field.get(null);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (registry != null) {
|
||||||
|
for (NamespacedKey key : keys) {
|
||||||
|
Keyed value = registry.get(key);
|
||||||
|
if (value != null)
|
||||||
|
return (T) value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lookup != null)
|
||||||
|
return lookup.find(typeClass, keys);
|
||||||
|
throw new IllegalArgumentException("No element found for keys: " + Arrays.toString(keys));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static <T> T findByField(@NonNull Class<T> typeClass, @NonNull NamespacedKey... keys) {
|
||||||
|
var values = KEYED_REGISTRY.computeIfAbsent(typeClass, RegistryUtil::getKeyedValues);
|
||||||
|
for (NamespacedKey key : keys) {
|
||||||
|
var value = values.get(key);
|
||||||
|
if (value != null)
|
||||||
|
return (T) value;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("No element found for keys: " + Arrays.toString(keys));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static <T> T findByEnum(@NonNull Class<T> typeClass, @NonNull NamespacedKey... keys) {
|
||||||
|
var values = ENUM_REGISTRY.computeIfAbsent(typeClass, RegistryUtil::getEnumValues);
|
||||||
|
for (NamespacedKey key : keys) {
|
||||||
|
var value = values.get(key);
|
||||||
|
if (value != null)
|
||||||
|
return (T) value;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("No element found for keys: " + Arrays.toString(keys));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static <T> Lookup<T> defaultLookup() {
|
||||||
|
return Lookup.combine(RegistryUtil::findByField, RegistryUtil::findByEnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<NamespacedKey, Keyed> getKeyedValues(@NonNull Class<?> typeClass) {
|
||||||
|
return Arrays.stream(typeClass.getDeclaredFields())
|
||||||
|
.filter(field -> Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers()))
|
||||||
|
.filter(field -> Keyed.class.isAssignableFrom(field.getType()))
|
||||||
|
.map(field -> {
|
||||||
|
try {
|
||||||
|
return (Keyed) field.get(null);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toMap(Keyed::getKey, Function.identity()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<NamespacedKey, Object> getEnumValues(@NonNull Class<?> typeClass) {
|
||||||
|
return Arrays.stream(typeClass.getDeclaredFields())
|
||||||
|
.filter(field -> Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers()))
|
||||||
|
.filter(field -> typeClass.isAssignableFrom(field.getType()))
|
||||||
|
.map(field -> {
|
||||||
|
try {
|
||||||
|
return new Pair<>(NamespacedKey.minecraft(field.getName().toLowerCase()), field.get(null));
|
||||||
|
} catch (Throwable e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toMap(Pair::getA, Pair::getB));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Lookup<T> {
|
||||||
|
@NonNull
|
||||||
|
T find(@NonNull Class<T> typeClass, @NonNull NamespacedKey... keys);
|
||||||
|
|
||||||
|
static <T> Lookup<T> combine(@NonNull Lookup<T>... lookups) {
|
||||||
|
if (lookups.length == 0) throw new IllegalArgumentException("Need at least one lookup");
|
||||||
|
return (typeClass, keys) -> {
|
||||||
|
for (Lookup<T> lookup : lookups) {
|
||||||
|
try {
|
||||||
|
return lookup.find(typeClass, keys);
|
||||||
|
} catch (IllegalArgumentException ignored) {}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("No element found for keys: " + Arrays.toString(keys));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static <T extends Keyed> Registry<T> getRegistry(@NotNull Class<T> type) {
|
||||||
|
RegistryLookup lookup = registryLookup.aquire(() -> {
|
||||||
|
RegistryLookup bukkit;
|
||||||
|
try {
|
||||||
|
bukkit = Bukkit::getRegistry;
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
bukkit = null;
|
||||||
|
}
|
||||||
|
return new DefaultRegistryLookup(bukkit);
|
||||||
|
});
|
||||||
|
return lookup.find(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface RegistryLookup {
|
||||||
|
@Nullable
|
||||||
|
<T extends Keyed> Registry<T> find(@NonNull Class<T> type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DefaultRegistryLookup implements RegistryLookup {
|
||||||
|
private final RegistryLookup bukkit;
|
||||||
|
private final Map<Type, Object> registries;
|
||||||
|
|
||||||
|
private DefaultRegistryLookup(RegistryLookup bukkit) {
|
||||||
|
this.bukkit = bukkit;
|
||||||
|
registries = Arrays.stream(Registry.class.getDeclaredFields())
|
||||||
|
.filter(field -> Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers()))
|
||||||
|
.filter(field -> Registry.class.isAssignableFrom(field.getType()))
|
||||||
|
.map(field -> {
|
||||||
|
var type = ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
|
||||||
|
try {
|
||||||
|
return new Pair<>(type, field.get(null));
|
||||||
|
} catch (Throwable e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toMap(Pair::getA, Pair::getB, (a, b) -> a));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public <T extends Keyed> Registry<T> find(@NonNull Class<T> type) {
|
||||||
|
if (bukkit == null) return (Registry<T>) registries.get(type);
|
||||||
|
try {
|
||||||
|
return bukkit.find(type);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
return (Registry<T>) registries.get(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
|
* Copyright (c) 2022 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.decree.handlers;
|
||||||
|
|
||||||
|
import com.volmit.iris.engine.object.IrisImageChannel;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.decree.DecreeParameterHandler;
|
||||||
|
import com.volmit.iris.util.decree.exceptions.DecreeParsingException;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class ImageChannelHandler implements DecreeParameterHandler<IrisImageChannel> {
|
||||||
|
@Override
|
||||||
|
public KList<IrisImageChannel> getPossibilities() {
|
||||||
|
return new KList<>(Arrays.stream(IrisImageChannel.values()).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(IrisImageChannel channel) {
|
||||||
|
return channel.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IrisImageChannel parse(String in, boolean force) throws DecreeParsingException {
|
||||||
|
return IrisImageChannel.valueOf(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supports(Class<?> type) {
|
||||||
|
return type.equals(IrisImageChannel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRandomDefault() {
|
||||||
|
return IrisImageChannel.BRIGHTNESS.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
|
* Copyright (c) 2024 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.decree.specialhandlers;
|
||||||
|
|
||||||
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
|
import com.volmit.iris.util.decree.exceptions.DecreeParsingException;
|
||||||
|
import com.volmit.iris.util.decree.handlers.BiomeHandler;
|
||||||
|
|
||||||
|
public class NullableBiomeHandler extends BiomeHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IrisBiome parse(String in, boolean force) throws DecreeParsingException {
|
||||||
|
return getPossibilities(in).stream().filter((i) -> toString(i).equalsIgnoreCase(in)).findFirst().orElse(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
|
* Copyright (c) 2024 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.decree.specialhandlers;
|
||||||
|
|
||||||
|
import com.volmit.iris.engine.object.IrisRegion;
|
||||||
|
import com.volmit.iris.util.decree.exceptions.DecreeParsingException;
|
||||||
|
import com.volmit.iris.util.decree.handlers.RegionHandler;
|
||||||
|
|
||||||
|
public class NullableRegionHandler extends RegionHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IrisRegion parse(String in, boolean force) throws DecreeParsingException {
|
||||||
|
return getPossibilities(in).stream().filter((i) -> toString(i).equalsIgnoreCase(in)).findFirst().orElse(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
package com.volmit.iris.util.hunk.view;
|
package com.volmit.iris.util.hunk.view;
|
||||||
|
|
||||||
import com.volmit.iris.util.data.B;
|
import com.volmit.iris.util.data.B;
|
||||||
import com.volmit.iris.util.data.IrisBlockData;
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
import com.volmit.iris.util.hunk.Hunk;
|
import com.volmit.iris.util.hunk.Hunk;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.generator.ChunkGenerator.ChunkData;
|
import org.bukkit.generator.ChunkGenerator.ChunkData;
|
||||||
@@ -73,7 +73,7 @@ public class ChunkDataHunkView implements Hunk<BlockData> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (t instanceof IrisBlockData d)
|
if (t instanceof IrisCustomData d)
|
||||||
t = d.getBase();
|
t = d.getBase();
|
||||||
chunk.setBlock(x, y + chunk.getMinHeight(), z, t);
|
chunk.setBlock(x, y + chunk.getMinHeight(), z, t);
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
|
|||||||
@@ -111,10 +111,12 @@ public class IO {
|
|||||||
return "¯\\_(ツ)_/¯";
|
return "¯\\_(ツ)_/¯";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String hashRecursive(File base) {
|
public static long hashRecursive(File... bases) {
|
||||||
LinkedList<File> files = new LinkedList<>();
|
LinkedList<File> files = new LinkedList<>();
|
||||||
Set<File> processed = new HashSet<>();
|
Set<File> processed = new HashSet<>();
|
||||||
files.add(base);
|
Arrays.parallelSort(bases, Comparator.comparing(File::getName));
|
||||||
|
files.addAll(Arrays.asList(bases));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
CRC32 crc = new CRC32();
|
CRC32 crc = new CRC32();
|
||||||
while (!files.isEmpty()) {
|
while (!files.isEmpty()) {
|
||||||
@@ -141,13 +143,13 @@ public class IO {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Long.toHexString(crc.getValue());
|
return crc.getValue();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String hash(File b) {
|
public static String hash(File b) {
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ 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 lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Synchronized;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
@@ -117,17 +116,16 @@ public class MantleChunk {
|
|||||||
ref.decrementAndGet();
|
ref.decrementAndGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
public void flag(MantleFlag flag, boolean f) {
|
public void flag(MantleFlag flag, boolean f) {
|
||||||
flags.set(flag.ordinal(), f ? 1 : 0);
|
flags.set(flag.ordinal(), f ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
public void raiseFlag(MantleFlag flag, Runnable r) {
|
public void raiseFlag(MantleFlag flag, Runnable r) {
|
||||||
if (!isFlagged(flag)) {
|
synchronized (this) {
|
||||||
flag(flag, true);
|
if (!isFlagged(flag)) flag(flag, true);
|
||||||
r.run();
|
else return;
|
||||||
}
|
}
|
||||||
|
r.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isFlagged(MantleFlag flag) {
|
public boolean isFlagged(MantleFlag flag) {
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ public enum MantleFlag {
|
|||||||
ETCHED,
|
ETCHED,
|
||||||
TILE,
|
TILE,
|
||||||
CUSTOM,
|
CUSTOM,
|
||||||
DISCOVERED;
|
DISCOVERED,
|
||||||
|
CUSTOM_ACTIVE;
|
||||||
|
|
||||||
static StateList getStateList() {
|
static StateList getStateList() {
|
||||||
return new StateList(MantleFlag.values());
|
return new StateList(MantleFlag.values());
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class Spiraler {
|
|||||||
|
|
||||||
public void next() {
|
public void next() {
|
||||||
if ((-sizeX / 2 <= x) && (x <= sizeX / 2) && (-sizeZ / 2 <= z) && (z <= sizeZ / 2)) {
|
if ((-sizeX / 2 <= x) && (x <= sizeX / 2) && (-sizeZ / 2 <= z) && (z <= sizeZ / 2)) {
|
||||||
spiraled.on(x + ox, z + ox);
|
spiraled.on(x + ox, z + oz);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z))) {
|
if ((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z))) {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
package com.volmit.iris.util.matter.slices;
|
package com.volmit.iris.util.matter.slices;
|
||||||
|
|
||||||
import com.volmit.iris.util.data.IrisBlockData;
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
import com.volmit.iris.util.data.palette.Palette;
|
import com.volmit.iris.util.data.palette.Palette;
|
||||||
import com.volmit.iris.util.matter.Sliced;
|
import com.volmit.iris.util.matter.Sliced;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@@ -41,7 +41,7 @@ public class BlockMatter extends RawMatter<BlockData> {
|
|||||||
public BlockMatter(int width, int height, int depth) {
|
public BlockMatter(int width, int height, int depth) {
|
||||||
super(width, height, depth, BlockData.class);
|
super(width, height, depth, BlockData.class);
|
||||||
registerWriter(World.class, ((w, d, x, y, z) -> {
|
registerWriter(World.class, ((w, d, x, y, z) -> {
|
||||||
if (d instanceof IrisBlockData c)
|
if (d instanceof IrisCustomData c)
|
||||||
w.getBlockAt(x, y, z).setBlockData(c.getBase());
|
w.getBlockAt(x, y, z).setBlockData(c.getBase());
|
||||||
else w.getBlockAt(x, y, z).setBlockData(d);
|
else w.getBlockAt(x, y, z).setBlockData(d);
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
package com.volmit.iris.util.misc;
|
|
||||||
|
|
||||||
public class E {
|
|
||||||
|
|
||||||
public static <T extends Enum<T>> T getOrDefault(Class<T> enumClass, String name, String fallback) {
|
|
||||||
try {
|
|
||||||
return Enum.valueOf(enumClass, name);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
return Enum.valueOf(enumClass, fallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.volmit.iris.util.misc;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class ServerProperties {
|
||||||
|
public static final Properties DATA = new Properties();
|
||||||
|
public static final File SERVER_PROPERTIES;
|
||||||
|
public static final File BUKKIT_YML;
|
||||||
|
|
||||||
|
public static final String LEVEL_NAME;
|
||||||
|
|
||||||
|
static {
|
||||||
|
String[] args = ProcessHandle.current()
|
||||||
|
.info()
|
||||||
|
.arguments()
|
||||||
|
.orElse(new String[0]);
|
||||||
|
|
||||||
|
String propertiesPath = "server.properties";
|
||||||
|
String bukkitYml = "bukkit.yml";
|
||||||
|
String levelName = null;
|
||||||
|
|
||||||
|
for (int i = 0; i < args.length - 1; i++) {
|
||||||
|
switch (args[i]) {
|
||||||
|
case "-c", "--config" -> propertiesPath = args[i + 1];
|
||||||
|
case "-b", "--bukkit-settings" -> bukkitYml = args[i + 1];
|
||||||
|
case "-w", "--level-name", "--world" -> levelName = args[i + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SERVER_PROPERTIES = new File(propertiesPath);
|
||||||
|
BUKKIT_YML = new File(bukkitYml);
|
||||||
|
try (FileInputStream in = new FileInputStream(SERVER_PROPERTIES)){
|
||||||
|
DATA.load(in);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (levelName != null) LEVEL_NAME = levelName;
|
||||||
|
else LEVEL_NAME = DATA.getProperty("level-name", "world");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
package com.volmit.iris.core.nms.v1_19_R1;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
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.object.IrisBiome;
|
|
||||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
|
||||||
import com.volmit.iris.util.collection.KMap;
|
|
||||||
import com.volmit.iris.util.math.RNG;
|
|
||||||
import net.minecraft.core.Holder;
|
|
||||||
import net.minecraft.core.Registry;
|
|
||||||
import net.minecraft.core.RegistryAccess;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.level.biome.Biome;
|
|
||||||
import net.minecraft.world.level.biome.BiomeSource;
|
|
||||||
import net.minecraft.world.level.biome.Climate;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.CraftServer;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.block.CraftBlock;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class CustomBiomeSource extends BiomeSource {
|
|
||||||
private final long seed;
|
|
||||||
private final Engine engine;
|
|
||||||
private final Registry<Biome> biomeCustomRegistry;
|
|
||||||
private final Registry<Biome> biomeRegistry;
|
|
||||||
private final AtomicCache<RegistryAccess> registryAccess = new AtomicCache<>();
|
|
||||||
private final RNG rng;
|
|
||||||
private final KMap<String, Holder<Biome>> customBiomes;
|
|
||||||
|
|
||||||
public CustomBiomeSource(long seed, Engine engine, World world) {
|
|
||||||
super(getAllBiomes(
|
|
||||||
((RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer()))
|
|
||||||
.registry(Registry.BIOME_REGISTRY).orElse(null),
|
|
||||||
((CraftWorld) world).getHandle().registryAccess().registry(Registry.BIOME_REGISTRY).orElse(null),
|
|
||||||
engine));
|
|
||||||
this.engine = engine;
|
|
||||||
this.seed = seed;
|
|
||||||
this.biomeCustomRegistry = registry().registry(Registry.BIOME_REGISTRY).orElse(null);
|
|
||||||
this.biomeRegistry = ((CraftWorld) world).getHandle().registryAccess().registry(Registry.BIOME_REGISTRY).orElse(null);
|
|
||||||
this.rng = new RNG(engine.getSeedManager().getBiome());
|
|
||||||
this.customBiomes = fillCustomBiomes(biomeCustomRegistry, engine);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Holder<Biome>> getAllBiomes(Registry<Biome> customRegistry, Registry<Biome> registry, Engine engine) {
|
|
||||||
List<Holder<Biome>> b = new ArrayList<>();
|
|
||||||
|
|
||||||
for (IrisBiome i : engine.getAllBiomes()) {
|
|
||||||
if (i.isCustom()) {
|
|
||||||
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
|
||||||
b.add(customRegistry.getHolder(customRegistry.getResourceKey(customRegistry
|
|
||||||
.get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
b.add(CraftBlock.biomeToBiomeBase(registry, i.getVanillaDerivative()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object getFor(Class<?> type, Object source) {
|
|
||||||
Object o = fieldFor(type, source);
|
|
||||||
|
|
||||||
if (o != null) {
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
return invokeFor(type, source);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object fieldFor(Class<?> returns, Object in) {
|
|
||||||
return fieldForClass(returns, in.getClass(), in);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object invokeFor(Class<?> returns, Object in) {
|
|
||||||
for (Method i : in.getClass().getMethods()) {
|
|
||||||
if (i.getReturnType().equals(returns)) {
|
|
||||||
i.setAccessible(true);
|
|
||||||
try {
|
|
||||||
Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()");
|
|
||||||
return i.invoke(in);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private static <T> T fieldForClass(Class<T> returnType, Class<?> sourceType, Object in) {
|
|
||||||
for (Field i : sourceType.getDeclaredFields()) {
|
|
||||||
if (i.getType().equals(returnType)) {
|
|
||||||
i.setAccessible(true);
|
|
||||||
try {
|
|
||||||
Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName());
|
|
||||||
return (T) i.get(in);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private KMap<String, Holder<Biome>> fillCustomBiomes(Registry<Biome> customRegistry, Engine engine) {
|
|
||||||
KMap<String, Holder<Biome>> m = new KMap<>();
|
|
||||||
|
|
||||||
for (IrisBiome i : engine.getAllBiomes()) {
|
|
||||||
if (i.isCustom()) {
|
|
||||||
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
|
|
||||||
m.put(j.getId(), customRegistry.getHolder(customRegistry.getResourceKey(customRegistry
|
|
||||||
.get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
private RegistryAccess registry() {
|
|
||||||
return registryAccess.aquire(() -> (RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Codec<? extends BiomeSource> codec() {
|
|
||||||
throw new UnsupportedOperationException("Not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Holder<Biome> getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) {
|
|
||||||
int m = (y - engine.getMinHeight()) << 2;
|
|
||||||
IrisBiome ib = engine.getComplex().getTrueBiomeStream().get(x << 2, z << 2);
|
|
||||||
if (ib.isCustom()) {
|
|
||||||
return customBiomes.get(ib.getCustomBiome(rng, x << 2, m, z << 2).getId());
|
|
||||||
} else {
|
|
||||||
org.bukkit.block.Biome v = ib.getSkyBiome(rng, x << 2, m, z << 2);
|
|
||||||
return CraftBlock.biomeToBiomeBase(biomeRegistry, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user