other updates!

This commit is contained in:
Brian Neumann-Fopiano 2023-05-16 23:38:37 -04:00
parent e3d2dfa99e
commit 12a6d022cf
19 changed files with 5626 additions and 5621 deletions

View File

@ -1,332 +1,332 @@
/* /*
* Iris is a World Generator for Minecraft Bukkit Servers * Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software) * Copyright (c) 2021 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
plugins { plugins {
id 'java' id 'java'
id 'java-library' id 'java-library'
id "io.freefair.lombok" version "6.3.0" id "io.freefair.lombok" version "6.3.0"
id "com.github.johnrengelman.shadow" version "7.1.2" id "com.github.johnrengelman.shadow" version "7.1.2"
id "de.undercouch.download" version "5.0.1" id "de.undercouch.download" version "5.0.1"
} }
version '2.6.1-1.19.4' version '2.6.2-1.19.4'
def nmsVersion = "1.19.4" //[NMS] def nmsVersion = "1.19.4" //[NMS]
def apiVersion = '1.19' def apiVersion = '1.19'
def specialSourceVersion = '1.11.0' //[NMS] def specialSourceVersion = '1.11.0' //[NMS]
def spigotJarVersion = '1.19.4-R0.1-SNAPSHOT' //[NMS] def spigotJarVersion = '1.19.4-R0.1-SNAPSHOT' //[NMS]
def name = getRootProject().getName() // Defined in settings.gradle def name = getRootProject().getName() // Defined in settings.gradle
def main = 'com.volmit.iris.Iris' def main = 'com.volmit.iris.Iris'
// 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 =============================
registerCustomOutputTask('Cyberpwn', 'C://Users/cyberpwn/Documents/development/server/plugins') registerCustomOutputTask('Cyberpwn', 'C://Users/cyberpwn/Documents/development/server/plugins')
registerCustomOutputTask('Psycho', 'C://Dan/MinecraftDevelopment/Server/plugins') registerCustomOutputTask('Psycho', 'C://Dan/MinecraftDevelopment/Server/plugins')
registerCustomOutputTask('ArcaneArts', 'C://Users/arcane/Documents/development/server/plugins') registerCustomOutputTask('ArcaneArts', 'C://Users/arcane/Documents/development/server/plugins')
registerCustomOutputTask('Coco', 'D://mcsm/plugins') registerCustomOutputTask('Coco', 'D://mcsm/plugins')
registerCustomOutputTask('Strange', 'D://Servers/1.17 Test Server/plugins') 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')
// ========================== UNIX ============================== // ========================== UNIX ==============================
registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins') registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins')
registerCustomOutputTaskUnix('PsychoLT', '/Users/brianfopiano/Desktop/REMOTES/RemoteMinecraft/plugins') registerCustomOutputTaskUnix('PsychoLT', '/Users/brianfopiano/Desktop/REMOTES/RemoteMinecraft/plugins')
// ============================================================== // ==============================================================
/** /**
* Gradle is weird sometimes, we need to delete the plugin yml from the build folder to actually filter properly. * Gradle is weird sometimes, we need to delete the plugin yml from the build folder to actually filter properly.
*/ */
file(jar.archiveFile.get().getAsFile().getParentFile().getParentFile().getParentFile().getAbsolutePath() + '/build/resources/main/plugin.yml').delete() file(jar.archiveFile.get().getAsFile().getParentFile().getParentFile().getParentFile().getAbsolutePath() + '/build/resources/main/plugin.yml').delete()
/** /**
* Expand properties into plugin yml * Expand properties into plugin yml
*/ */
processResources { processResources {
filesMatching('**/plugin.yml') { filesMatching('**/plugin.yml') {
expand( expand(
'name': name.toString(), 'name': name.toString(),
'version': version.toString(), 'version': version.toString(),
'main': main.toString(), 'main': main.toString(),
'apiversion': apiVersion.toString() 'apiversion': apiVersion.toString()
) )
} }
} }
/** /**
* Unified repo * Unified repo
*/ */
repositories { repositories {
mavenLocal { mavenLocal {
content { content {
includeGroup("org.bukkit") includeGroup("org.bukkit")
includeGroup("org.spigotmc") includeGroup("org.spigotmc")
} }
} }
mavenCentral() mavenCentral()
maven { url "https://arcanearts.jfrog.io/artifactory/archives" } maven { url "https://arcanearts.jfrog.io/artifactory/archives" }
maven { url "https://mvn.lumine.io/repository/maven-public/" } maven { url "https://mvn.lumine.io/repository/maven-public/" }
maven { url "https://jitpack.io"} maven { url "https://jitpack.io"}
maven { url "https://s01.oss.sonatype.org/content/repositories/snapshots" } maven { url "https://s01.oss.sonatype.org/content/repositories/snapshots" }
maven { url "https://mvn.lumine.io/repository/maven/" } maven { url "https://mvn.lumine.io/repository/maven/" }
maven { url "https://repo.triumphteam.dev/snapshots" } maven { url "https://repo.triumphteam.dev/snapshots" }
maven { url "https://repo.mineinabyss.com/releases" } maven { url "https://repo.mineinabyss.com/releases" }
} }
/** /**
* We need parameter meta for the decree command system * We need parameter meta for the decree command system
*/ */
compileJava { compileJava {
options.compilerArgs << '-parameters' options.compilerArgs << '-parameters'
} }
/** /**
* Configure Iris for shading * Configure Iris for shading
*/ */
shadowJar { shadowJar {
//minimize() //minimize()
append("plugin.yml") append("plugin.yml")
relocate 'com.dfsek.paralithic', 'com.volmit.iris.util.paralithic' relocate 'com.dfsek.paralithic', 'com.volmit.iris.util.paralithic'
relocate 'io.papermc.lib', 'com.volmit.iris.util.paper' relocate 'io.papermc.lib', 'com.volmit.iris.util.paper'
relocate 'net.kyori', 'com.volmit.iris.util.kyori' relocate 'net.kyori', 'com.volmit.iris.util.kyori'
dependencies { dependencies {
include(dependency('io.papermc:paperlib')) include(dependency('io.papermc:paperlib'))
include(dependency('com.dfsek:Paralithic')) include(dependency('com.dfsek:Paralithic'))
include(dependency('net.kyori:')) include(dependency('net.kyori:'))
} }
} }
configurations.all { configurations.all {
resolutionStrategy.cacheChangingModulesFor 60, 'minutes' resolutionStrategy.cacheChangingModulesFor 60, 'minutes'
resolutionStrategy.cacheDynamicVersionsFor 60, 'minutes' resolutionStrategy.cacheDynamicVersionsFor 60, 'minutes'
} }
/** /**
* Dependencies. * Dependencies.
* *
* Provided or classpath dependencies are not shaded and are available on the runtime classpath * Provided or classpath dependencies are not shaded and are available on the runtime classpath
* *
* Shaded dependencies are not available at runtime, nor are they available on mvn central so they * Shaded dependencies are not available at runtime, nor are they available on mvn central so they
* need to be shaded into the jar (increasing binary size) * need to be shaded into the jar (increasing binary size)
* *
* Dynamically loaded dependencies are defined in the plugin.yml (updating these must be updated in the * Dynamically loaded dependencies are defined in the plugin.yml (updating these must be updated in the
* plugin.yml also, otherwise they wont be available). These do not increase binary size). Only declare * plugin.yml also, otherwise they wont be available). These do not increase binary size). Only declare
* these dependencies if they are available on mvn central. * these dependencies if they are available on mvn central.
*/ */
dependencies { dependencies {
// Provided or Classpath // Provided or Classpath
compileOnly 'org.projectlombok:lombok:1.18.24' compileOnly 'org.projectlombok:lombok:1.18.24'
annotationProcessor 'org.projectlombok:lombok:1.18.24' annotationProcessor 'org.projectlombok:lombok:1.18.24'
implementation 'org.spigotmc:spigot-api:1.19.4-R0.1-SNAPSHOT' implementation 'org.spigotmc:spigot-api:1.19.4-R0.1-SNAPSHOT'
implementation 'org.bukkit:craftbukkit:1.19.4-R0.1-SNAPSHOT:remapped-mojang' //[NMS] implementation 'org.bukkit:craftbukkit:1.19.4-R0.1-SNAPSHOT:remapped-mojang' //[NMS]
// Third Party Integrations // Third Party Integrations
implementation 'com.github.oraxen:oraxen:1.152.5' implementation 'com.github.oraxen:oraxen:1.152.5'
implementation 'com.github.LoneDev6:api-itemsadder:3.2.5' implementation 'com.github.LoneDev6:api-itemsadder:3.4.1-r4'
implementation 'me.clip:placeholderapi:2.11.3' implementation 'me.clip:placeholderapi:2.11.3'
//implementation files('libs/CustomItems.jar') //implementation files('libs/CustomItems.jar')
// Shaded // Shaded
implementation 'com.dfsek:Paralithic:0.4.0' implementation 'com.dfsek:Paralithic:0.4.0'
implementation 'io.papermc:paperlib:1.0.5' implementation 'io.papermc:paperlib:1.0.5'
implementation "net.kyori:adventure-text-minimessage:4.13.1" implementation "net.kyori:adventure-text-minimessage:4.13.1"
implementation 'net.kyori:adventure-platform-bukkit:4.3.0' implementation 'net.kyori:adventure-platform-bukkit:4.3.0'
implementation 'net.kyori:adventure-api:4.13.1' implementation 'net.kyori:adventure-api:4.13.1'
implementation 'io.lumine:Mythic-Dist:5.2.1' implementation 'io.lumine:Mythic-Dist:5.2.1'
// Dynamically Loaded // Dynamically Loaded
implementation 'io.timeandspace:smoothie-map:2.0.2' implementation 'io.timeandspace:smoothie-map:2.0.2'
implementation 'it.unimi.dsi:fastutil:8.5.8' implementation 'it.unimi.dsi:fastutil:8.5.8'
implementation 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2' implementation 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2'
implementation 'org.zeroturnaround:zt-zip:1.14' implementation 'org.zeroturnaround:zt-zip:1.14'
implementation 'com.google.code.gson:gson:2.9.0' implementation 'com.google.code.gson:gson:2.9.0'
implementation 'org.ow2.asm:asm:9.2' implementation 'org.ow2.asm:asm:9.2'
implementation 'com.google.guava:guava:31.1-jre' implementation 'com.google.guava:guava:31.1-jre'
implementation 'bsf:bsf:2.4.0' implementation 'bsf:bsf:2.4.0'
implementation 'rhino:js:1.7R2' implementation 'rhino:js:1.7R2'
implementation 'com.github.ben-manes.caffeine:caffeine:3.0.6' implementation 'com.github.ben-manes.caffeine:caffeine:3.0.6'
implementation 'org.apache.commons:commons-lang3:3.12.0' implementation 'org.apache.commons:commons-lang3:3.12.0'
} }
if (JavaVersion.current().toString() != "17") { if (JavaVersion.current().toString() != "17") {
System.err.println() System.err.println()
System.err.println("=========================================================================================================") System.err.println("=========================================================================================================")
System.err.println("You must run gradle on Java 17. You are using " + JavaVersion.current()) System.err.println("You must run gradle on Java 17. You are using " + JavaVersion.current())
System.err.println() System.err.println()
System.err.println("=== For IDEs ===") System.err.println("=== For IDEs ===")
System.err.println("1. Configure the project for Java 17") System.err.println("1. Configure the project for Java 17")
System.err.println("2. Configure the bundled gradle to use Java 17 in settings") System.err.println("2. Configure the bundled gradle to use Java 17 in settings")
System.err.println() System.err.println()
System.err.println("=== For Command Line (gradlew) ===") System.err.println("=== For Command Line (gradlew) ===")
System.err.println("1. Install JDK 17 from https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html") System.err.println("1. Install JDK 17 from https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html")
System.err.println("2. Set JAVA_HOME environment variable to the new jdk installation folder such as C:\\Program Files\\Java\\jdk-17.0.1") System.err.println("2. Set JAVA_HOME environment variable to the new jdk installation folder such as C:\\Program Files\\Java\\jdk-17.0.1")
System.err.println("3. Open a new command prompt window to get the new environment variables if need be.") System.err.println("3. Open a new command prompt window to get the new environment variables if need be.")
System.err.println("=========================================================================================================") System.err.println("=========================================================================================================")
System.err.println() System.err.println()
System.exit(69); System.exit(69);
} }
def buildToolsJar = new File(buildDir, "buildtools/BuildTools.jar"); def buildToolsJar = new File(buildDir, "buildtools/BuildTools.jar");
def specialSourceJar = new File(buildDir, "specialsource/SpecialSource.jar"); def specialSourceJar = new File(buildDir, "specialsource/SpecialSource.jar");
def buildToolsFolder = new File(buildDir, "buildtools"); def buildToolsFolder = new File(buildDir, "buildtools");
def specialSourceFolder = new File(buildDir, "specialsource"); def specialSourceFolder = new File(buildDir, "specialsource");
def buildToolsHint = new File(buildDir, "buildtools/craftbukkit-" + nmsVersion + ".jar"); def buildToolsHint = new File(buildDir, "buildtools/craftbukkit-" + nmsVersion + ".jar");
def outputShadeJar = new File(buildDir, "libs/Iris-" + version + "-all.jar"); def outputShadeJar = new File(buildDir, "libs/Iris-" + version + "-all.jar");
def ssiJar = new File(buildDir, "specialsource/Iris-" + version + "-all.jar"); def ssiJar = new File(buildDir, "specialsource/Iris-" + version + "-all.jar");
def ssobfJar = new File(buildDir, "specialsource/Iris-" + version + "-rmo.jar"); def ssobfJar = new File(buildDir, "specialsource/Iris-" + version + "-rmo.jar");
def ssJar = new File(buildDir, "specialsource/Iris-" + version + "-rma.jar"); def ssJar = new File(buildDir, "specialsource/Iris-" + version + "-rma.jar");
def homePath = System.properties['user.home'] def homePath = System.properties['user.home']
def m2 = new File(homePath + "/.m2/repository") def m2 = new File(homePath + "/.m2/repository")
def m2s = m2.getAbsolutePath(); def m2s = m2.getAbsolutePath();
// ======================== Building Mapped Jars ============================= // ======================== Building Mapped Jars =============================
task downloadBuildtools(type: Download) { task downloadBuildtools(type: Download) {
group "remapping" group "remapping"
src 'https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar' src 'https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar'
dest buildToolsJar dest buildToolsJar
onlyIf { onlyIf {
!buildToolsJar.exists() !buildToolsJar.exists()
} }
} }
task downloadSpecialSource(type: Download) { task downloadSpecialSource(type: Download) {
group "remapping" group "remapping"
src 'https://repo.maven.apache.org/maven2/net/md-5/SpecialSource/' + specialSourceVersion + '/SpecialSource-'+specialSourceVersion+'-shaded.jar' src 'https://repo.maven.apache.org/maven2/net/md-5/SpecialSource/' + specialSourceVersion + '/SpecialSource-'+specialSourceVersion+'-shaded.jar'
dest specialSourceJar dest specialSourceJar
onlyIf { onlyIf {
!specialSourceJar.exists() !specialSourceJar.exists()
} }
} }
task executeBuildTools(dependsOn: downloadBuildtools, type: JavaExec) task executeBuildTools(dependsOn: downloadBuildtools, type: JavaExec)
{ {
group "remapping" group "remapping"
classpath = files(buildToolsJar) classpath = files(buildToolsJar)
workingDir = buildToolsFolder workingDir = buildToolsFolder
args = [ args = [
"--rev", "--rev",
nmsVersion, nmsVersion,
"--compile", "--compile",
"craftbukkit", "craftbukkit",
"--remap" "--remap"
] ]
onlyIf { onlyIf {
!buildToolsHint.exists() !buildToolsHint.exists()
} }
} }
task copyBuildToSpecialSource(type: Copy) task copyBuildToSpecialSource(type: Copy)
{ {
group "remapping" group "remapping"
from outputShadeJar from outputShadeJar
into specialSourceFolder into specialSourceFolder
dependsOn(downloadSpecialSource, shadowJar) dependsOn(downloadSpecialSource, shadowJar)
} }
task specialSourceRemapObfuscate(type: JavaExec) task specialSourceRemapObfuscate(type: JavaExec)
{ {
group "remapping" group "remapping"
dependsOn(copyBuildToSpecialSource, downloadSpecialSource, shadowJar) dependsOn(copyBuildToSpecialSource, downloadSpecialSource, shadowJar)
workingDir = specialSourceFolder workingDir = specialSourceFolder
classpath = files(specialSourceJar, classpath = files(specialSourceJar,
new File(m2s + "/org/spigotmc/spigot/" + spigotJarVersion + "/spigot-" + spigotJarVersion + "-remapped-mojang.jar")) new File(m2s + "/org/spigotmc/spigot/" + spigotJarVersion + "/spigot-" + spigotJarVersion + "-remapped-mojang.jar"))
mainClass = "net.md_5.specialsource.SpecialSource" mainClass = "net.md_5.specialsource.SpecialSource"
args = [ args = [
"--live", "--live",
"-i", "-i",
ssiJar.getName(), ssiJar.getName(),
"-o", "-o",
ssobfJar.getName(), ssobfJar.getName(),
"-m", "-m",
m2s + "/org/spigotmc/minecraft-server/" + spigotJarVersion + "/minecraft-server-" + spigotJarVersion + "-maps-mojang.txt", m2s + "/org/spigotmc/minecraft-server/" + spigotJarVersion + "/minecraft-server-" + spigotJarVersion + "-maps-mojang.txt",
"--reverse", "--reverse",
] ]
} }
task specialSourceRemap(type: JavaExec) task specialSourceRemap(type: JavaExec)
{ {
group "remapping" group "remapping"
dependsOn(specialSourceRemapObfuscate) dependsOn(specialSourceRemapObfuscate)
workingDir = specialSourceFolder workingDir = specialSourceFolder
classpath = files(specialSourceJar, classpath = files(specialSourceJar,
new File(m2s + "/org/spigotmc/spigot/" + spigotJarVersion + "/spigot-" + spigotJarVersion + "-remapped-obf.jar")) new File(m2s + "/org/spigotmc/spigot/" + spigotJarVersion + "/spigot-" + spigotJarVersion + "-remapped-obf.jar"))
mainClass = "net.md_5.specialsource.SpecialSource" mainClass = "net.md_5.specialsource.SpecialSource"
args = [ args = [
"--live", "--live",
"-i", "-i",
ssobfJar.getName(), ssobfJar.getName(),
"-o", "-o",
ssJar.getName(), ssJar.getName(),
"-m", "-m",
m2s + "/org/spigotmc/minecraft-server/" + spigotJarVersion + "/minecraft-server-" + spigotJarVersion + "-maps-spigot.csrg" m2s + "/org/spigotmc/minecraft-server/" + spigotJarVersion + "/minecraft-server-" + spigotJarVersion + "-maps-spigot.csrg"
] ]
} }
tasks.compileJava.dependsOn(executeBuildTools) tasks.compileJava.dependsOn(executeBuildTools)
compileJava { compileJava {
options.encoding = "UTF-8" options.encoding = "UTF-8"
} }
task setup() task setup()
{ {
group("iris") group("iris")
dependsOn(clean, executeBuildTools) dependsOn(clean, executeBuildTools)
} }
task iris(type: Copy) task iris(type: Copy)
{ {
group "iris" group "iris"
from ssJar from ssJar
into buildDir into buildDir
rename { String fileName -> rename { String fileName ->
fileName.replace('Iris-' + version + '-rma.jar', "Iris-" + version + ".jar") fileName.replace('Iris-' + version + '-rma.jar', "Iris-" + version + ".jar")
} }
dependsOn(specialSourceRemap) dependsOn(specialSourceRemap)
} }
def registerCustomOutputTask(name, path) { def registerCustomOutputTask(name, path) {
if (!System.properties['os.name'].toLowerCase().contains('windows')) { if (!System.properties['os.name'].toLowerCase().contains('windows')) {
return; return;
} }
tasks.register('build' + name, Copy) { tasks.register('build' + name, Copy) {
group('development') group('development')
outputs.upToDateWhen { false } outputs.upToDateWhen { false }
dependsOn(iris) dependsOn(iris)
from(new File(buildDir, "Iris-" + version + ".jar")) from(new File(buildDir, "Iris-" + version + ".jar"))
into(file(path)) into(file(path))
rename { String fileName -> rename { String fileName ->
fileName.replace("Iris-" + version + ".jar", "Iris.jar") fileName.replace("Iris-" + version + ".jar", "Iris.jar")
} }
} }
} }
def registerCustomOutputTaskUnix(name, path) { def registerCustomOutputTaskUnix(name, path) {
if (System.properties['os.name'].toLowerCase().contains('windows')) { if (System.properties['os.name'].toLowerCase().contains('windows')) {
return; return;
} }
tasks.register('build' + name, Copy) { tasks.register('build' + name, Copy) {
group('development') group('development')
outputs.upToDateWhen { false } outputs.upToDateWhen { false }
dependsOn(iris) dependsOn(iris)
from(new File(buildDir, "Iris-" + version + ".jar")) from(new File(buildDir, "Iris-" + version + ".jar"))
into(file(path)) into(file(path))
rename { String fileName -> rename { String fileName ->
fileName.replace("Iris-" + version + ".jar", "Iris.jar") fileName.replace("Iris-" + version + ".jar", "Iris.jar")
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,345 +1,342 @@
/* /*
* 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) 2022 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.volmit.iris.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.IrisSettings;
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.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.engine.object.IrisDimension;
import com.volmit.iris.engine.object.IrisEntity; import com.volmit.iris.engine.platform.PlatformChunkGenerator;
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.decree.DecreeContext;
import com.volmit.iris.util.decree.DecreeContext; 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.format.C;
import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.format.Form; import com.volmit.iris.util.parallel.BurstExecutor;
import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.parallel.MultiBurst; import com.volmit.iris.util.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.jobs.QueueJob;
import com.volmit.iris.util.scheduling.jobs.QueueJob; import org.bukkit.Bukkit;
import org.bukkit.Bukkit; import org.bukkit.Chunk;
import org.bukkit.Chunk; import org.bukkit.World;
import org.bukkit.Location;
import org.bukkit.World; import java.io.File;
import org.bukkit.util.Vector; import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.io.File; import java.util.concurrent.Future;
import java.io.IOException;
import java.util.concurrent.ExecutionException; @Decree(name = "iris", aliases = {"ir", "irs"}, description = "Basic Command")
import java.util.concurrent.Future; public class CommandIris implements DecreeExecutor {
private CommandStudio studio;
@Decree(name = "iris", aliases = {"ir", "irs"}, description = "Basic Command") private CommandPregen pregen;
public class CommandIris implements DecreeExecutor { private CommandSettings settings;
private CommandStudio studio; private CommandObject object;
private CommandPregen pregen; private CommandJigsaw jigsaw;
private CommandSettings settings; private CommandWhat what;
private CommandObject object; private CommandEdit edit;
private CommandJigsaw jigsaw; private CommandFind find;
private CommandWhat what;
private CommandEdit edit; @Decree(description = "Create a new world", aliases = {"+", "c"})
private CommandFind find; public void create(
@Param(aliases = "world-name", description = "The name of the world to create")
@Decree(description = "Create a new world", aliases = {"+", "c"}) String name,
public void create( @Param(aliases = "dimension", description = "The dimension type to create the world with", defaultValue = "default")
@Param(aliases = "world-name", description = "The name of the world to create") IrisDimension type,
String name, @Param(description = "The seed to generate the world with", defaultValue = "1337")
@Param(aliases = "dimension", description = "The dimension type to create the world with", defaultValue = "default") long seed
IrisDimension type, ) {
@Param(description = "The seed to generate the world with", defaultValue = "1337") if (name.equals("iris")) {
long seed sender().sendMessage(C.RED + "You cannot use the world name \"iris\" for creating worlds as Iris uses this directory for studio worlds.");
) { sender().sendMessage(C.RED + "May we suggest the name \"IrisWorld\" instead?");
if (name.equals("iris")) { return;
sender().sendMessage(C.RED + "You cannot use the world name \"iris\" for creating worlds as Iris uses this directory for studio worlds."); }
sender().sendMessage(C.RED + "May we suggest the name \"IrisWorld\" instead?");
return; if (new File(Bukkit.getWorldContainer(), name).exists()) {
} sender().sendMessage(C.RED + "That folder already exists!");
return;
if (new File(Bukkit.getWorldContainer(), name).exists()) { }
sender().sendMessage(C.RED + "That folder already exists!");
return; try {
} IrisToolbelt.createWorld()
.dimension(type.getLoadKey())
try { .name(name)
IrisToolbelt.createWorld() .seed(seed)
.dimension(type.getLoadKey()) .sender(sender())
.name(name) .studio(false)
.seed(seed) .create();
.sender(sender()) } catch (Throwable e) {
.studio(false) sender().sendMessage(C.RED + "Exception raised during creation. See the console for more details.");
.create(); Iris.error("Exception raised during world creation: " + e.getMessage());
} catch (Throwable e) { Iris.reportError(e);
sender().sendMessage(C.RED + "Exception raised during creation. See the console for more details."); return;
Iris.error("Exception raised during world creation: " + e.getMessage()); }
Iris.reportError(e);
return; sender().sendMessage(C.GREEN + "Successfully created your world!");
} }
sender().sendMessage(C.GREEN + "Successfully created your world!"); @Decree(description = "Remove an Iris world", aliases = {"del", "rm"}, sync = true)
} public void remove(
@Param(description = "The world to remove")
@Decree(description = "Remove an Iris world", aliases = {"del", "rm"}, sync = true) World world,
public void remove( @Param(description = "Whether to also remove the folder (if set to false, just does not load the world)", defaultValue = "true")
@Param(description = "The world to remove") boolean delete
World world, ) {
@Param(description = "Whether to also remove the folder (if set to false, just does not load the world)", defaultValue = "true") if (!IrisToolbelt.isIrisWorld(world)) {
boolean delete sender().sendMessage(C.RED + "This is not an Iris world. Iris worlds: " + String.join(", ", Bukkit.getServer().getWorlds().stream().filter(IrisToolbelt::isIrisWorld).map(World::getName).toList()));
) { return;
if (!IrisToolbelt.isIrisWorld(world)) { }
sender().sendMessage(C.RED + "This is not an Iris world. Iris worlds: " + String.join(", ", Bukkit.getServer().getWorlds().stream().filter(IrisToolbelt::isIrisWorld).map(World::getName).toList())); sender().sendMessage(C.GREEN + "Removing world: " + world.getName());
return; try {
} if (IrisToolbelt.removeWorld(world)) {
sender().sendMessage(C.GREEN + "Removing world: " + world.getName()); sender().sendMessage(C.GREEN + "Successfully removed " + world.getName() + " from bukkit.yml");
try { } else {
if (IrisToolbelt.removeWorld(world)) { sender().sendMessage(C.YELLOW + "Looks like the world was already removed from bukkit.yml");
sender().sendMessage(C.GREEN + "Successfully removed " + world.getName() + " from bukkit.yml"); }
} else { } catch (IOException e) {
sender().sendMessage(C.YELLOW + "Looks like the world was already removed from bukkit.yml"); sender().sendMessage(C.RED + "Failed to save bukkit.yml because of " + e.getMessage());
} e.printStackTrace();
} catch (IOException e) { }
sender().sendMessage(C.RED + "Failed to save bukkit.yml because of " + e.getMessage()); IrisToolbelt.evacuate(world, "Deleting world");
e.printStackTrace(); Bukkit.unloadWorld(world, false);
} if (delete && world.getWorldFolder().delete()) {
IrisToolbelt.evacuate(world, "Deleting world"); sender().sendMessage(C.GREEN + "Successfully removed world folder");
Bukkit.unloadWorld(world, false); } else {
if (delete && world.getWorldFolder().delete()) { sender().sendMessage(C.RED + "Failed to remove world folder");
sender().sendMessage(C.GREEN + "Successfully removed world folder"); }
} else { }
sender().sendMessage(C.RED + "Failed to remove world folder");
} @Decree(description = "Print version information")
} public void version() {
sender().sendMessage(C.GREEN + "Iris v" + Iris.instance.getDescription().getVersion() + " by Volmit Software");
@Decree(description = "Print version information") }
public void version() {
sender().sendMessage(C.GREEN + "Iris v" + Iris.instance.getDescription().getVersion() + " by Volmit Software"); @Decree(description = "Print world height information", origin = DecreeOrigin.PLAYER)
} public void height() {
sender().sendMessage(C.GREEN + "" + sender().player().getWorld().getMinHeight() + " to " + sender().player().getWorld().getMaxHeight());
@Decree(description = "Print world height information", origin = DecreeOrigin.PLAYER) sender().sendMessage(C.GREEN + "Total Height: " + (sender().player().getWorld().getMaxHeight() - sender().player().getWorld().getMinHeight()));
public void height() { }
sender().sendMessage(C.GREEN + "" + sender().player().getWorld().getMinHeight() + " to " + sender().player().getWorld().getMaxHeight());
sender().sendMessage(C.GREEN + "Total Height: " + (sender().player().getWorld().getMaxHeight() - sender().player().getWorld().getMinHeight())); @Decree(description = "QOL command to open a overworld studio world.", sync = true)
} public void so() {
sender().sendMessage(C.GREEN + "Opening studio for the \"Overworld\" pack (seed: 1337)");
@Decree(description = "QOL command to open a overworld studio world.", sync = true) Iris.service(StudioSVC.class).open(sender(), 1337, "overworld");
public void so() { }
sender().sendMessage(C.GREEN + "Opening studio for the \"Overworld\" pack (seed: 1337)");
Iris.service(StudioSVC.class).open(sender(), 1337, "overworld"); @Decree(description = "Set aura spins")
} public void aura(
@Param(description = "The h color value", defaultValue = "-20")
@Decree(description = "Set aura spins") int h,
public void aura( @Param(description = "The s color value", defaultValue = "7")
@Param(description = "The h color value", defaultValue = "-20") int s,
int h, @Param(description = "The b color value", defaultValue = "8")
@Param(description = "The s color value", defaultValue = "7") int b
int s, ) {
@Param(description = "The b color value", defaultValue = "8") IrisSettings.get().getGeneral().setSpinh(h);
int b IrisSettings.get().getGeneral().setSpins(s);
) { IrisSettings.get().getGeneral().setSpinb(b);
IrisSettings.get().getGeneral().setSpinh(h); IrisSettings.get().forceSave();
IrisSettings.get().getGeneral().setSpins(s); sender().sendMessage("<rainbow>Aura Spins updated to " + h + " " + s + " " + b);
IrisSettings.get().getGeneral().setSpinb(b); }
IrisSettings.get().forceSave();
sender().sendMessage("<rainbow>Aura Spins updated to " + h + " " + s + " " + b); @Decree(description = "Bitwise calculations")
} public void bitwise(
@Param(description = "The first value to run calculations on")
@Decree(description = "Bitwise calculations") int value1,
public void bitwise( @Param(description = "The operator: | & ^ ≺≺ ≻≻ ")
@Param(description = "The first value to run calculations on") String operator,
int value1, @Param(description = "The second value to run calculations on")
@Param(description = "The operator: | & ^ ≺≺ ≻≻ ") int value2
String operator, ) {
@Param(description = "The second value to run calculations on") Integer v = null;
int value2 switch (operator) {
) { case "|" -> v = value1 | value2;
Integer v = null; case "&" -> v = value1 & value2;
switch (operator) { case "^" -> v = value1 ^ value2;
case "|" -> v = value1 | value2; case "%" -> v = value1 % value2;
case "&" -> v = value1 & value2; case ">>" -> v = value1 >> value2;
case "^" -> v = value1 ^ value2; case "<<" -> v = value1 << value2;
case "%" -> v = value1 % value2; }
case ">>" -> v = value1 >> value2; if (v == null) {
case "<<" -> v = value1 << value2; sender().sendMessage(C.RED + "The operator you entered: (" + operator + ") is invalid!");
} return;
if (v == null) { }
sender().sendMessage(C.RED + "The operator you entered: (" + operator + ") is invalid!"); sender().sendMessage(C.GREEN + "" + value1 + " " + C.GREEN + operator.replaceAll("<", "").replaceAll(">", "").replaceAll("%", "") + " " + C.GREEN + value2 + C.GREEN + " returns " + C.GREEN + v);
return; }
}
sender().sendMessage(C.GREEN + "" + value1 + " " + C.GREEN + operator.replaceAll("<", "").replaceAll(">", "").replaceAll("%", "") + " " + C.GREEN + value2 + C.GREEN + " returns " + C.GREEN + v); @Decree(description = "Toggle debug")
} public void debug(
@Param(name = "on", description = "Whether or not debug should be on", defaultValue = "other")
@Decree(description = "Toggle debug") Boolean on
public void debug( ) {
@Param(name = "on", description = "Whether or not debug should be on", defaultValue = "other") boolean to = on == null ? !IrisSettings.get().getGeneral().isDebug() : on;
Boolean on IrisSettings.get().getGeneral().setDebug(to);
) { IrisSettings.get().forceSave();
boolean to = on == null ? !IrisSettings.get().getGeneral().isDebug() : on; sender().sendMessage(C.GREEN + "Set debug to: " + to);
IrisSettings.get().getGeneral().setDebug(to); }
IrisSettings.get().forceSave();
sender().sendMessage(C.GREEN + "Set debug to: " + to); @Decree(description = "Download a project.", aliases = "dl")
} public void download(
@Param(name = "pack", description = "The pack to download", defaultValue = "overworld", aliases = "project")
@Decree(description = "Download a project.", aliases = "dl") String pack,
public void download( @Param(name = "branch", description = "The branch to download from", defaultValue = "main")
@Param(name = "pack", description = "The pack to download", defaultValue = "overworld", aliases = "project") String branch,
String pack, @Param(name = "trim", description = "Whether or not to download a trimmed version (do not enable when editing)", defaultValue = "false")
@Param(name = "branch", description = "The branch to download from", defaultValue = "main") boolean trim,
String branch, @Param(name = "overwrite", description = "Whether or not to overwrite the pack with the downloaded one", aliases = "force", defaultValue = "false")
@Param(name = "trim", description = "Whether or not to download a trimmed version (do not enable when editing)", defaultValue = "false") boolean overwrite
boolean trim, ) {
@Param(name = "overwrite", description = "Whether or not to overwrite the pack with the downloaded one", aliases = "force", defaultValue = "false") sender().sendMessage(C.GREEN + "Downloading pack: " + pack + "/" + branch + (trim ? " trimmed" : "") + (overwrite ? " overwriting" : ""));
boolean overwrite if (pack.equals("overworld")) {
) { String url = "https://github.com/IrisDimensions/overworld/releases/download/" + Iris.OVERWORLD_TAG + "/overworld.zip";
sender().sendMessage(C.GREEN + "Downloading pack: " + pack + "/" + branch + (trim ? " trimmed" : "") + (overwrite ? " overwriting" : "")); Iris.service(StudioSVC.class).downloadRelease(sender(), url, trim, overwrite);
if (pack.equals("overworld")) { } else {
String url = "https://github.com/IrisDimensions/overworld/releases/download/" + Iris.OVERWORLD_TAG + "/overworld.zip"; Iris.service(StudioSVC.class).downloadSearch(sender(), "IrisDimensions/" + pack + "/" + branch, trim, overwrite);
Iris.service(StudioSVC.class).downloadRelease(sender(), url, trim, overwrite); }
} else { }
Iris.service(StudioSVC.class).downloadSearch(sender(), "IrisDimensions/" + pack + "/" + branch, trim, overwrite);
} @Decree(description = "Get metrics for your world", aliases = "measure", origin = DecreeOrigin.PLAYER)
} public void metrics() {
if (!IrisToolbelt.isIrisWorld(world())) {
@Decree(description = "Get metrics for your world", aliases = "measure", origin = DecreeOrigin.PLAYER) sender().sendMessage(C.RED + "You must be in an Iris world");
public void metrics() { return;
if (!IrisToolbelt.isIrisWorld(world())) { }
sender().sendMessage(C.RED + "You must be in an Iris world"); sender().sendMessage(C.GREEN + "Sending metrics...");
return; engine().printMetrics(sender());
} }
sender().sendMessage(C.GREEN + "Sending metrics...");
engine().printMetrics(sender()); @Decree(description = "Reload configuration file (this is also done automatically)")
} public void reload() {
IrisSettings.invalidate();
@Decree(description = "Reload configuration file (this is also done automatically)") IrisSettings.get();
public void reload() { sender().sendMessage(C.GREEN + "Hotloaded settings");
IrisSettings.invalidate(); }
IrisSettings.get();
sender().sendMessage(C.GREEN + "Hotloaded settings"); @Decree(name = "regen", description = "Regenerate nearby chunks.", aliases = "rg", sync = true, origin = DecreeOrigin.PLAYER)
} public void regen(
@Param(name = "radius", description = "The radius of nearby cunks", defaultValue = "5")
@Decree(name = "regen", description = "Regenerate nearby chunks.", aliases = "rg", sync = true, origin = DecreeOrigin.PLAYER) int radius
public void regen( ) {
@Param(name = "radius", description = "The radius of nearby cunks", defaultValue = "5") if (IrisToolbelt.isIrisWorld(player().getWorld())) {
int radius VolmitSender sender = sender();
) { J.a(() -> {
if (IrisToolbelt.isIrisWorld(player().getWorld())) { DecreeContext.touch(sender);
VolmitSender sender = sender(); PlatformChunkGenerator plat = IrisToolbelt.access(player().getWorld());
J.a(() -> { Engine engine = plat.getEngine();
DecreeContext.touch(sender); try {
PlatformChunkGenerator plat = IrisToolbelt.access(player().getWorld()); Chunk cx = player().getLocation().getChunk();
Engine engine = plat.getEngine(); KList<Runnable> js = new KList<>();
try { BurstExecutor b = MultiBurst.burst.burst();
Chunk cx = player().getLocation().getChunk(); b.setMulticore(false);
KList<Runnable> js = new KList<>(); int rad = engine.getMantle().getRealRadius();
BurstExecutor b = MultiBurst.burst.burst(); for (int i = -(radius + rad); i <= radius + rad; i++) {
b.setMulticore(false); for (int j = -(radius + rad); j <= radius + rad; j++) {
int rad = engine.getMantle().getRealRadius(); engine.getMantle().getMantle().deleteChunk(i + cx.getX(), j + cx.getZ());
for (int i = -(radius + rad); i <= radius + rad; i++) { }
for (int j = -(radius + rad); j <= radius + rad; j++) { }
engine.getMantle().getMantle().deleteChunk(i + cx.getX(), j + cx.getZ());
} for (int i = -radius; i <= radius; i++) {
} for (int j = -radius; j <= radius; j++) {
int finalJ = j;
for (int i = -radius; i <= radius; i++) { int finalI = i;
for (int j = -radius; j <= radius; j++) { b.queue(() -> plat.injectChunkReplacement(player().getWorld(), finalI + cx.getX(), finalJ + cx.getZ(), (f) -> {
int finalJ = j; synchronized (js) {
int finalI = i; js.add(f);
b.queue(() -> plat.injectChunkReplacement(player().getWorld(), finalI + cx.getX(), finalJ + cx.getZ(), (f) -> { }
synchronized (js) { }));
js.add(f); }
} }
}));
} b.complete();
} sender().sendMessage(C.GREEN + "Regenerating " + Form.f(js.size()) + " Sections");
QueueJob<Runnable> r = new QueueJob<>() {
b.complete(); final KList<Future<?>> futures = new KList<>();
sender().sendMessage(C.GREEN + "Regenerating " + Form.f(js.size()) + " Sections");
QueueJob<Runnable> r = new QueueJob<>() { @Override
final KList<Future<?>> futures = new KList<>(); public void execute(Runnable runnable) {
futures.add(J.sfut(runnable));
@Override
public void execute(Runnable runnable) { if (futures.size() > 64) {
futures.add(J.sfut(runnable)); while (futures.isNotEmpty()) {
try {
if (futures.size() > 64) { futures.remove(0).get();
while (futures.isNotEmpty()) { } catch (InterruptedException | ExecutionException e) {
try { e.printStackTrace();
futures.remove(0).get(); }
} catch (InterruptedException | ExecutionException e) { }
e.printStackTrace(); }
} }
}
} @Override
} public String getName() {
return "Regenerating";
@Override }
public String getName() { };
return "Regenerating"; r.queue(js);
} r.execute(sender());
}; } catch (Throwable e) {
r.queue(js); sender().sendMessage("Unable to parse view-distance");
r.execute(sender()); }
} catch (Throwable e) { });
sender().sendMessage("Unable to parse view-distance"); } else {
} sender().sendMessage(C.RED + "You must be in an Iris World to use regen!");
}); }
} else { }
sender().sendMessage(C.RED + "You must be in an Iris World to use regen!");
} @Decree(description = "Update the pack of a world (UNSAFE!)", name = "^world", aliases = "update-world")
} public void updateWorld(
@Param(description = "The world to update", contextual = true)
@Decree(description = "Update the pack of a world (UNSAFE!)", name = "^world", aliases = "update-world") World world,
public void updateWorld( @Param(description = "The pack to install into the world", contextual = true, aliases = "dimension")
@Param(description = "The world to update", contextual = true) IrisDimension pack,
World world, @Param(description = "Make sure to make a backup & read the warnings first!", defaultValue = "false", aliases = "c")
@Param(description = "The pack to install into the world", contextual = true, aliases = "dimension") boolean confirm,
IrisDimension pack, @Param(description = "Should Iris download the pack again for you", defaultValue = "false", name = "fresh-download", aliases = {"fresh", "new"})
@Param(description = "Make sure to make a backup & read the warnings first!", defaultValue = "false", aliases = "c") boolean freshDownload
boolean confirm, ) {
@Param(description = "Should Iris download the pack again for you", defaultValue = "false", name = "fresh-download", aliases = {"fresh", "new"}) if (!confirm) {
boolean freshDownload sender().sendMessage(new String[]{
) { C.RED + "You should always make a backup before using this",
if (!confirm) { C.YELLOW + "Issues caused by this can be, but are not limited to:",
sender().sendMessage(new String[]{ C.YELLOW + " - Broken chunks (cut-offs) between old and new chunks (before & after the update)",
C.RED + "You should always make a backup before using this", C.YELLOW + " - Regenerated chunks that do not fit in with the old chunks",
C.YELLOW + "Issues caused by this can be, but are not limited to:", C.YELLOW + " - Structures not spawning again when regenerating",
C.YELLOW + " - Broken chunks (cut-offs) between old and new chunks (before & after the update)", C.YELLOW + " - Caves not lining up",
C.YELLOW + " - Regenerated chunks that do not fit in with the old chunks", C.YELLOW + " - Terrain layers not lining up",
C.YELLOW + " - Structures not spawning again when regenerating", C.RED + "Now that you are aware of the risks, and have made a back-up:",
C.YELLOW + " - Caves not lining up", C.RED + "/iris ^world " + world.getName() + " " + pack.getLoadKey() + " confirm=true"
C.YELLOW + " - Terrain layers not lining up", });
C.RED + "Now that you are aware of the risks, and have made a back-up:", return;
C.RED + "/iris ^world " + world.getName() + " " + pack.getLoadKey() + " confirm=true" }
});
return; File folder = world.getWorldFolder();
} folder.mkdirs();
File folder = world.getWorldFolder(); if (freshDownload) {
folder.mkdirs(); Iris.service(StudioSVC.class).downloadSearch(sender(), pack.getLoadKey(), false, true);
}
if (freshDownload) {
Iris.service(StudioSVC.class).downloadSearch(sender(), pack.getLoadKey(), false, true); Iris.service(StudioSVC.class).installIntoWorld(sender(), pack.getLoadKey(), folder);
} }
}
Iris.service(StudioSVC.class).installIntoWorld(sender(), pack.getLoadKey(), folder);
}
}

View File

@ -1,86 +1,85 @@
/* /*
* 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) 2022 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.volmit.iris.core.gui.components; package com.volmit.iris.core.gui.components;
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.IrisBiomeGeneratorLink; import com.volmit.iris.engine.object.IrisBiomeGeneratorLink;
import com.volmit.iris.util.interpolation.IrisInterpolation; import com.volmit.iris.util.interpolation.IrisInterpolation;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.function.BiFunction; import java.util.function.BiFunction;
public class IrisRenderer { public class IrisRenderer {
private final Engine renderer; private final Engine renderer;
public IrisRenderer(Engine renderer) { public IrisRenderer(Engine renderer) {
this.renderer = renderer; this.renderer = renderer;
} }
public BufferedImage render(double sx, double sz, double size, int resolution, RenderType currentType) { public BufferedImage render(double sx, double sz, double size, int resolution, RenderType currentType) {
BufferedImage image = new BufferedImage(resolution, resolution, BufferedImage.TYPE_INT_RGB); BufferedImage image = new BufferedImage(resolution, resolution, BufferedImage.TYPE_INT_RGB);
BiFunction<Double, Double, Integer> colorFunction = (d, dx) -> Color.black.getRGB(); BiFunction<Double, Double, Integer> colorFunction = (d, dx) -> Color.black.getRGB();
switch (currentType) { switch (currentType) {
case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD -> case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD ->
colorFunction = (x, z) -> renderer.getComplex().getTrueBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); colorFunction = (x, z) -> renderer.getComplex().getTrueBiomeStream().get(x, z).getColor(renderer, currentType).getRGB();
case BIOME_LAND -> case BIOME_LAND ->
colorFunction = (x, z) -> renderer.getComplex().getLandBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); colorFunction = (x, z) -> renderer.getComplex().getLandBiomeStream().get(x, z).getColor(renderer, currentType).getRGB();
case BIOME_SEA -> case BIOME_SEA ->
colorFunction = (x, z) -> renderer.getComplex().getSeaBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); colorFunction = (x, z) -> renderer.getComplex().getSeaBiomeStream().get(x, z).getColor(renderer, currentType).getRGB();
case REGION -> case REGION ->
colorFunction = (x, z) -> renderer.getComplex().getRegionStream().get(x, z).getColor(renderer.getComplex(), currentType).getRGB(); colorFunction = (x, z) -> renderer.getComplex().getRegionStream().get(x, z).getColor(renderer.getComplex(), currentType).getRGB();
case CAVE_LAND -> case CAVE_LAND ->
colorFunction = (x, z) -> renderer.getComplex().getCaveBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); colorFunction = (x, z) -> renderer.getComplex().getCaveBiomeStream().get(x, z).getColor(renderer, currentType).getRGB();
case HEIGHT -> case HEIGHT ->
colorFunction = (x, z) -> Color.getHSBColor(renderer.getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB(); colorFunction = (x, z) -> Color.getHSBColor(renderer.getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB();
case CONTINENT -> case CONTINENT -> colorFunction = (x, z) -> {
colorFunction = (x, z) -> { 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() <= 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() < 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 { // Both min and max are above water level, so it is most likely a land biome
// Both min and max are above water level, so it is most likely a land biome c = Color.GREEN;
c = Color.GREEN; }
} return c.getRGB();
return c.getRGB(); };
}; }
}
double x, z;
double x, z; int i, j;
int i, j; for (i = 0; i < resolution; i++) {
for (i = 0; i < resolution; i++) { x = IrisInterpolation.lerp(sx, sx + size, (double) i / (double) (resolution));
x = IrisInterpolation.lerp(sx, sx + size, (double) i / (double) (resolution));
for (j = 0; j < resolution; j++) {
for (j = 0; j < resolution; j++) { z = IrisInterpolation.lerp(sz, sz + size, (double) j / (double) (resolution));
z = IrisInterpolation.lerp(sz, sz + size, (double) j / (double) (resolution)); image.setRGB(i, j, colorFunction.apply(x, z));
image.setRGB(i, j, colorFunction.apply(x, z)); }
} }
}
return image;
return image; }
} }
}

View File

@ -1,33 +1,33 @@
package com.volmit.iris.core.link; package com.volmit.iris.core.link;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
public record Identifier(String namespace, String key) { public record Identifier(String namespace, String key) {
private static final String DEFAULT_NAMESPACE = "minecraft"; private static final String DEFAULT_NAMESPACE = "minecraft";
public static Identifier fromString(String id) { public static Identifier fromString(String id) {
String[] strings = id.split(":", 2); String[] strings = id.split(":", 2);
if(strings.length == 1) { if (strings.length == 1) {
return new Identifier(DEFAULT_NAMESPACE, strings[0]); return new Identifier(DEFAULT_NAMESPACE, strings[0]);
} else { } else {
return new Identifier(strings[0], strings[1]); return new Identifier(strings[0], strings[1]);
} }
} }
@Override @Override
public String toString() { public String toString() {
return namespace + ":" + key; return namespace + ":" + key;
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(obj instanceof Identifier i) { if (obj instanceof Identifier i) {
return i.namespace().equals(this.namespace) && i.key().equals(this.key); return i.namespace().equals(this.namespace) && i.key().equals(this.key);
} else if(obj instanceof NamespacedKey i) { } else if (obj instanceof NamespacedKey i) {
return i.getNamespace().equals(this.namespace) && i.getKey().equals(this.key); return i.getNamespace().equals(this.namespace) && i.getKey().equals(this.key);
} else { } else {
return false; return false;
} }
} }
} }

View File

@ -1,71 +1,70 @@
package com.volmit.iris.core.link; package com.volmit.iris.core.link;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import dev.lone.itemsadder.api.CustomBlock; import dev.lone.itemsadder.api.CustomBlock;
import dev.lone.itemsadder.api.CustomStack; import dev.lone.itemsadder.api.CustomStack;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.util.Arrays; import java.util.MissingResourceException;
import java.util.MissingResourceException;
public class ItemAdderDataProvider extends ExternalDataProvider {
public class ItemAdderDataProvider extends ExternalDataProvider {
private KList<String> itemNamespaces, blockNamespaces;
private KList<String> itemNamespaces, blockNamespaces;
public ItemAdderDataProvider() {
public ItemAdderDataProvider() { super("ItemsAdder");
super("ItemsAdder"); }
}
@Override
@Override public void init() {
public void init() { this.itemNamespaces = new KList<>();
this.itemNamespaces = new KList<>(); this.blockNamespaces = new KList<>();
this.blockNamespaces = new KList<>();
for (Identifier i : getItemTypes()) {
for (Identifier i : getItemTypes()) { itemNamespaces.addIfMissing(i.namespace());
itemNamespaces.addIfMissing(i.namespace()); }
} for (Identifier i : getBlockTypes()) {
for (Identifier i : getBlockTypes()) { blockNamespaces.addIfMissing(i.namespace());
blockNamespaces.addIfMissing(i.namespace()); Iris.info("Found ItemAdder Block: " + i);
Iris.info("Found ItemAdder Block: " + i); }
} }
}
@Override
@Override public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
public BlockData getBlockData(Identifier blockId) throws MissingResourceException { return CustomBlock.getBaseBlockData(blockId.toString());
return CustomBlock.getBaseBlockData(blockId.toString()); }
}
@Override
@Override public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException { CustomStack stack = CustomStack.getInstance(itemId.toString());
CustomStack stack = CustomStack.getInstance(itemId.toString()); if (stack == null) {
if (stack == null) { throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key()); }
} return stack.getItemStack();
return stack.getItemStack(); }
}
@Override
@Override public Identifier[] getBlockTypes() {
public Identifier[] getBlockTypes() { KList<Identifier> keys = new KList<>();
KList<Identifier> keys = new KList<>(); for (String s : CustomBlock.getNamespacedIdsInRegistry()) {
for (String s : CustomBlock.getNamespacedIdsInRegistry()) { keys.add(Identifier.fromString(s));
keys.add(Identifier.fromString(s)); }
} return keys.toArray(new Identifier[0]);
return keys.toArray(new Identifier[0]); }
}
@Override
@Override public Identifier[] getItemTypes() {
public Identifier[] getItemTypes() { KList<Identifier> keys = new KList<>();
KList<Identifier> keys = new KList<>(); for (String s : CustomStack.getNamespacedIdsInRegistry()) {
for (String s : CustomStack.getNamespacedIdsInRegistry()) { keys.add(Identifier.fromString(s));
keys.add(Identifier.fromString(s)); }
} return keys.toArray(new Identifier[0]);
return keys.toArray(new Identifier[0]); }
}
@Override
@Override public boolean isValidProvider(Identifier id, boolean isItem) {
public boolean isValidProvider(Identifier id, boolean isItem) { return isItem ? this.itemNamespaces.contains(id.namespace()) : this.blockNamespaces.contains(id.namespace());
return isItem ? this.itemNamespaces.contains(id.namespace()) : this.blockNamespaces.contains(id.namespace()); }
} }
}

View File

@ -1,132 +1,134 @@
/* /*
* 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) 2022 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.volmit.iris.core.link; package com.volmit.iris.core.link;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.reflect.WrappedField; import com.volmit.iris.util.reflect.WrappedField;
import io.th0rgal.oraxen.api.OraxenItems; import io.th0rgal.oraxen.api.OraxenItems;
import io.th0rgal.oraxen.items.ItemBuilder; import io.th0rgal.oraxen.items.ItemBuilder;
import io.th0rgal.oraxen.mechanics.MechanicFactory; import io.th0rgal.oraxen.mechanics.MechanicFactory;
import io.th0rgal.oraxen.mechanics.MechanicsManager; import io.th0rgal.oraxen.mechanics.MechanicsManager;
import io.th0rgal.oraxen.mechanics.provided.gameplay.block.BlockMechanic; import io.th0rgal.oraxen.mechanics.provided.gameplay.block.BlockMechanic;
import io.th0rgal.oraxen.mechanics.provided.gameplay.block.BlockMechanicFactory; import io.th0rgal.oraxen.mechanics.provided.gameplay.block.BlockMechanicFactory;
import io.th0rgal.oraxen.mechanics.provided.gameplay.noteblock.NoteBlockMechanicFactory; import io.th0rgal.oraxen.mechanics.provided.gameplay.noteblock.NoteBlockMechanicFactory;
import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicFactory; import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicFactory;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.MultipleFacing; import org.bukkit.block.data.MultipleFacing;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.util.Map; import java.util.Map;
import java.util.MissingResourceException; import java.util.MissingResourceException;
import java.util.Optional; import java.util.Optional;
public class OraxenDataProvider extends ExternalDataProvider { public class OraxenDataProvider extends ExternalDataProvider {
private static final String FIELD_FACTORIES_MAP = "FACTORIES_BY_MECHANIC_ID"; private static final String FIELD_FACTORIES_MAP = "FACTORIES_BY_MECHANIC_ID";
private WrappedField<MechanicsManager, Map<String, MechanicFactory>> factories; private WrappedField<MechanicsManager, Map<String, MechanicFactory>> factories;
public OraxenDataProvider() { public OraxenDataProvider() {
super("Oraxen"); super("Oraxen");
} }
@Override @Override
public void init() { public void init() {
Iris.info("Setting up Oraxen Link..."); Iris.info("Setting up Oraxen Link...");
this.factories = new WrappedField<>(MechanicsManager.class, FIELD_FACTORIES_MAP); this.factories = new WrappedField<>(MechanicsManager.class, FIELD_FACTORIES_MAP);
if(this.factories.hasFailed()) { if (this.factories.hasFailed()) {
Iris.error("Failed to set up Oraxen Link: Unable to fetch MechanicFactoriesMap!"); Iris.error("Failed to set up Oraxen Link: Unable to fetch MechanicFactoriesMap!");
} }
} }
@Override @Override
public BlockData getBlockData(Identifier blockId) throws MissingResourceException { public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
MechanicFactory factory = getFactory(blockId); MechanicFactory factory = getFactory(blockId);
if (factory instanceof NoteBlockMechanicFactory f) if (factory instanceof NoteBlockMechanicFactory f)
return f.createNoteBlockData(blockId.key()); return f.createNoteBlockData(blockId.key());
else if (factory instanceof BlockMechanicFactory f) { else if (factory instanceof BlockMechanicFactory f) {
MultipleFacing newBlockData = (MultipleFacing) Bukkit.createBlockData(Material.MUSHROOM_STEM); MultipleFacing newBlockData = (MultipleFacing) Bukkit.createBlockData(Material.MUSHROOM_STEM);
BlockMechanic.setBlockFacing(newBlockData, ((BlockMechanic) f.getMechanic(blockId.key())).getCustomVariation()); BlockMechanic.setBlockFacing(newBlockData, ((BlockMechanic) f.getMechanic(blockId.key())).getCustomVariation());
return newBlockData; return newBlockData;
} else if (factory instanceof StringBlockMechanicFactory f) { } else if (factory instanceof StringBlockMechanicFactory f) {
return f.createTripwireData(blockId.key()); return f.createTripwireData(blockId.key());
} else } else
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key()); throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
} }
@Override @Override
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException { public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
Optional<ItemBuilder> opt = OraxenItems.getOptionalItemById(itemId.key()); Optional<ItemBuilder> opt = OraxenItems.getOptionalItemById(itemId.key());
return opt.orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key())).build(); return opt.orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key())).build();
} }
@Override @Override
public Identifier[] getBlockTypes() { public Identifier[] getBlockTypes() {
KList<Identifier> names = new KList<>(); KList<Identifier> names = new KList<>();
for (String name : OraxenItems.getItemNames()) { for (String name : OraxenItems.getItemNames()) {
try { try {
Identifier key = new Identifier("oraxen", name); Identifier key = new Identifier("oraxen", name);
if (getBlockData(key) != null) if (getBlockData(key) != null)
names.add(key); names.add(key);
} catch (MissingResourceException ignored) { } } catch (MissingResourceException ignored) {
} }
}
return names.toArray(new Identifier[0]);
} return names.toArray(new Identifier[0]);
}
@Override
public Identifier[] getItemTypes() { @Override
KList<Identifier> names = new KList<>(); public Identifier[] getItemTypes() {
for (String name : OraxenItems.getItemNames()) { KList<Identifier> names = new KList<>();
try { for (String name : OraxenItems.getItemNames()) {
Identifier key = new Identifier("oraxen", name); try {
if (getItemStack(key) != null) Identifier key = new Identifier("oraxen", name);
names.add(key); if (getItemStack(key) != null)
} catch (MissingResourceException ignored) { } names.add(key);
} } catch (MissingResourceException ignored) {
}
return names.toArray(new Identifier[0]); }
}
return names.toArray(new Identifier[0]);
@Override }
public boolean isReady() {
if(super.isReady()) { @Override
if(factories == null) { public boolean isReady() {
this.factories = new WrappedField<>(MechanicsManager.class, FIELD_FACTORIES_MAP); if (super.isReady()) {
} if (factories == null) {
return super.isReady() && !factories.hasFailed(); this.factories = new WrappedField<>(MechanicsManager.class, FIELD_FACTORIES_MAP);
} }
return false; return super.isReady() && !factories.hasFailed();
} }
return false;
@Override }
public boolean isValidProvider(Identifier key, boolean isItem) {
return key.namespace().equalsIgnoreCase("oraxen"); @Override
} public boolean isValidProvider(Identifier key, boolean isItem) {
return key.namespace().equalsIgnoreCase("oraxen");
private MechanicFactory getFactory(Identifier key) throws MissingResourceException { }
return factories.get().values().stream()
.filter(i -> i.getItems().contains(key.key())) private MechanicFactory getFactory(Identifier key) throws MissingResourceException {
.findFirst() return factories.get().values().stream()
.orElseThrow(() -> new MissingResourceException("Failed to find BlockData!", key.namespace(), key.key())); .filter(i -> i.getItems().contains(key.key()))
} .findFirst()
} .orElseThrow(() -> new MissingResourceException("Failed to find BlockData!", key.namespace(), key.key()));
}
}

View File

@ -1,157 +1,157 @@
package com.volmit.iris.core.nms.v19_4; package com.volmit.iris.core.nms.v19_4;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.volmit.iris.Iris; 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.framework.Engine;
import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisBiome;
import com.volmit.iris.engine.object.IrisBiomeCustom; import com.volmit.iris.engine.object.IrisBiomeCustom;
import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess; import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.biome.Climate; import net.minecraft.world.level.biome.Climate;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.craftbukkit.v1_19_R3.CraftServer; import org.bukkit.craftbukkit.v1_19_R3.CraftServer;
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R3.block.CraftBlock; import org.bukkit.craftbukkit.v1_19_R3.block.CraftBlock;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Stream; import java.util.stream.Stream;
public class CustomBiomeSource extends BiomeSource { public class CustomBiomeSource extends BiomeSource {
private final long seed; private final long seed;
private final Engine engine; private final Engine engine;
private final Registry<Biome> biomeCustomRegistry; private final Registry<Biome> biomeCustomRegistry;
private final Registry<Biome> biomeRegistry; private final Registry<Biome> biomeRegistry;
private final AtomicCache<RegistryAccess> registryAccess = new AtomicCache<>(); private final AtomicCache<RegistryAccess> registryAccess = new AtomicCache<>();
private final RNG rng; private final RNG rng;
private final KMap<String, Holder<Biome>> customBiomes; private final KMap<String, Holder<Biome>> customBiomes;
public CustomBiomeSource(long seed, Engine engine, World world) { public CustomBiomeSource(long seed, Engine engine, World world) {
this.engine = engine; this.engine = engine;
this.seed = seed; this.seed = seed;
this.biomeCustomRegistry = registry().registry(Registries.BIOME).orElse(null); this.biomeCustomRegistry = registry().registry(Registries.BIOME).orElse(null);
this.biomeRegistry = ((RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())).registry(Registries.BIOME).orElse(null); this.biomeRegistry = ((RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())).registry(Registries.BIOME).orElse(null);
this.rng = new RNG(engine.getSeedManager().getBiome()); this.rng = new RNG(engine.getSeedManager().getBiome());
this.customBiomes = fillCustomBiomes(biomeCustomRegistry, engine); this.customBiomes = fillCustomBiomes(biomeCustomRegistry, engine);
} }
@Override private static List<Holder<Biome>> getAllBiomes(Registry<Biome> customRegistry, Registry<Biome> registry, Engine engine) {
protected Stream<Holder<Biome>> collectPossibleBiomes() { List<Holder<Biome>> b = new ArrayList<>();
return getAllBiomes(
((RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())) for (IrisBiome i : engine.getAllBiomes()) {
.registry(Registries.BIOME).orElse(null), if (i.isCustom()) {
((CraftWorld) engine.getWorld().realWorld()).getHandle().registryAccess().registry(Registries.BIOME).orElse(null), for (IrisBiomeCustom j : i.getCustomDerivitives()) {
engine).stream(); b.add(customRegistry.getHolder(customRegistry.getResourceKey(customRegistry
} .get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get());
}
private static List<Holder<Biome>> getAllBiomes(Registry<Biome> customRegistry, Registry<Biome> registry, Engine engine) { } else {
List<Holder<Biome>> b = new ArrayList<>(); b.add(CraftBlock.biomeToBiomeBase(registry, i.getVanillaDerivative()));
}
for (IrisBiome i : engine.getAllBiomes()) { }
if (i.isCustom()) {
for (IrisBiomeCustom j : i.getCustomDerivitives()) { return b;
b.add(customRegistry.getHolder(customRegistry.getResourceKey(customRegistry }
.get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get());
} private static Object getFor(Class<?> type, Object source) {
} else { Object o = fieldFor(type, source);
b.add(CraftBlock.biomeToBiomeBase(registry, i.getVanillaDerivative()));
} if (o != null) {
} return o;
}
return b;
} return invokeFor(type, source);
}
private static Object getFor(Class<?> type, Object source) {
Object o = fieldFor(type, source); private static Object fieldFor(Class<?> returns, Object in) {
return fieldForClass(returns, in.getClass(), in);
if (o != null) { }
return o;
} private static Object invokeFor(Class<?> returns, Object in) {
for (Method i : in.getClass().getMethods()) {
return invokeFor(type, source); if (i.getReturnType().equals(returns)) {
} i.setAccessible(true);
try {
private static Object fieldFor(Class<?> returns, Object in) { Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()");
return fieldForClass(returns, in.getClass(), in); return i.invoke(in);
} } catch (Throwable e) {
e.printStackTrace();
private static Object invokeFor(Class<?> returns, Object in) { }
for (Method i : in.getClass().getMethods()) { }
if (i.getReturnType().equals(returns)) { }
i.setAccessible(true);
try { return null;
Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); }
return i.invoke(in);
} catch (Throwable e) { @SuppressWarnings("unchecked")
e.printStackTrace(); 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 {
return null; Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName());
} return (T) i.get(in);
} catch (IllegalAccessException e) {
@SuppressWarnings("unchecked") e.printStackTrace();
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); return null;
try { }
Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName());
return (T) i.get(in); @Override
} catch (IllegalAccessException e) { protected Stream<Holder<Biome>> collectPossibleBiomes() {
e.printStackTrace(); return getAllBiomes(
} ((RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer()))
} .registry(Registries.BIOME).orElse(null),
} ((CraftWorld) engine.getWorld().realWorld()).getHandle().registryAccess().registry(Registries.BIOME).orElse(null),
return null; engine).stream();
} }
private KMap<String, Holder<Biome>> fillCustomBiomes(Registry<Biome> customRegistry, Engine engine) { private KMap<String, Holder<Biome>> fillCustomBiomes(Registry<Biome> customRegistry, Engine engine) {
KMap<String, Holder<Biome>> m = new KMap<>(); KMap<String, Holder<Biome>> m = new KMap<>();
for (IrisBiome i : engine.getAllBiomes()) { for (IrisBiome i : engine.getAllBiomes()) {
if (i.isCustom()) { if (i.isCustom()) {
for (IrisBiomeCustom j : i.getCustomDerivitives()) { for (IrisBiomeCustom j : i.getCustomDerivitives()) {
m.put(j.getId(), customRegistry.getHolder(customRegistry.getResourceKey(customRegistry m.put(j.getId(), customRegistry.getHolder(customRegistry.getResourceKey(customRegistry
.get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get()); .get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get());
} }
} }
} }
return m; return m;
} }
private RegistryAccess registry() { private RegistryAccess registry() {
return registryAccess.aquire(() -> (RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())); return registryAccess.aquire(() -> (RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer()));
} }
@Override @Override
protected Codec<? extends BiomeSource> codec() { protected Codec<? extends BiomeSource> codec() {
throw new UnsupportedOperationException("Not supported"); throw new UnsupportedOperationException("Not supported");
} }
@Override @Override
public Holder<Biome> getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) { public Holder<Biome> getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) {
int m = (y - engine.getMinHeight()) << 2; int m = (y - engine.getMinHeight()) << 2;
IrisBiome ib = engine.getComplex().getTrueBiomeStream().get(x << 2, z << 2); IrisBiome ib = engine.getComplex().getTrueBiomeStream().get(x << 2, z << 2);
if (ib.isCustom()) { if (ib.isCustom()) {
return customBiomes.get(ib.getCustomBiome(rng, x << 2, m, z << 2).getId()); return customBiomes.get(ib.getCustomBiome(rng, x << 2, m, z << 2).getId());
} else { } else {
org.bukkit.block.Biome v = ib.getSkyBiome(rng, x << 2, m, z << 2); org.bukkit.block.Biome v = ib.getSkyBiome(rng, x << 2, m, z << 2);
return CraftBlock.biomeToBiomeBase(biomeRegistry, v); return CraftBlock.biomeToBiomeBase(biomeRegistry, v);
} }
} }
} }

View File

@ -1,115 +1,118 @@
/* /*
* 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) 2022 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.volmit.iris.core.service; package com.volmit.iris.core.service;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.link.*; import com.volmit.iris.core.link.ExternalDataProvider;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.core.link.Identifier;
import com.volmit.iris.util.plugin.IrisService; import com.volmit.iris.core.link.ItemAdderDataProvider;
import io.th0rgal.oraxen.api.OraxenBlocks; import com.volmit.iris.core.link.OraxenDataProvider;
import lombok.Data; import com.volmit.iris.util.collection.KList;
import org.bukkit.Bukkit; import com.volmit.iris.util.plugin.IrisService;
import org.bukkit.block.data.BlockData; import lombok.Data;
import org.bukkit.event.EventHandler; import org.bukkit.Bukkit;
import org.bukkit.event.server.PluginEnableEvent; import org.bukkit.block.data.BlockData;
import org.bukkit.inventory.ItemStack; import org.bukkit.event.EventHandler;
import org.bukkit.event.server.PluginEnableEvent;
import java.util.MissingResourceException; import org.bukkit.inventory.ItemStack;
import java.util.Optional;
import java.util.MissingResourceException;
@Data import java.util.Optional;
public class ExternalDataSVC implements IrisService {
@Data
private KList<ExternalDataProvider> providers = new KList<>(), activeProviders = new KList<>(); public class ExternalDataSVC implements IrisService {
@Override private KList<ExternalDataProvider> providers = new KList<>(), activeProviders = new KList<>();
public void onEnable() {
Iris.info("Loading ExternalDataProvider..."); @Override
Bukkit.getPluginManager().registerEvents(this, Iris.instance); public void onEnable() {
Iris.info("Loading ExternalDataProvider...");
providers.add(new OraxenDataProvider()); Bukkit.getPluginManager().registerEvents(this, Iris.instance);
if (Bukkit.getPluginManager().getPlugin("Oraxen") != null){
Iris.info("Oraxen found, loading OraxenDataProvider..."); providers.add(new OraxenDataProvider());
} if (Bukkit.getPluginManager().getPlugin("Oraxen") != null) {
providers.add(new ItemAdderDataProvider()); Iris.info("Oraxen found, loading OraxenDataProvider...");
if (Bukkit.getPluginManager().getPlugin("ItemAdder") != null){ }
Iris.info("ItemAdder found, loading ItemAdderDataProvider..."); providers.add(new ItemAdderDataProvider());
} if (Bukkit.getPluginManager().getPlugin("ItemAdder") != null) {
Iris.info("ItemAdder found, loading ItemAdderDataProvider...");
for (ExternalDataProvider p : providers) { }
if (p.isReady()) {
activeProviders.add(p); for (ExternalDataProvider p : providers) {
p.init(); if (p.isReady()) {
Iris.info("Enabled ExternalDataProvider for %s.", p.getPluginId()); activeProviders.add(p);
} p.init();
} Iris.info("Enabled ExternalDataProvider for %s.", p.getPluginId());
} }
}
@Override }
public void onDisable() { }
@Override
@EventHandler public void onDisable() {
public void onPluginEnable(PluginEnableEvent e) { }
if(activeProviders.stream().noneMatch(p -> p.getPlugin().equals(e.getPlugin()))) {
providers.stream().filter(p -> p.isReady() && p.getPlugin().equals(e.getPlugin())).findFirst().ifPresent(edp -> { @EventHandler
activeProviders.add(edp); public void onPluginEnable(PluginEnableEvent e) {
edp.init(); if (activeProviders.stream().noneMatch(p -> p.getPlugin().equals(e.getPlugin()))) {
Iris.info("Enabled ExternalDataProvider for %s.", edp.getPluginId()); providers.stream().filter(p -> p.isReady() && p.getPlugin().equals(e.getPlugin())).findFirst().ifPresent(edp -> {
}); activeProviders.add(edp);
} edp.init();
} Iris.info("Enabled ExternalDataProvider for %s.", edp.getPluginId());
});
public Optional<BlockData> getBlockData(Identifier key) { }
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(key, false)).findFirst(); }
if (provider.isEmpty())
return Optional.empty(); public Optional<BlockData> getBlockData(Identifier key) {
try { Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(key, false)).findFirst();
return Optional.of(provider.get().getBlockData(key)); if (provider.isEmpty())
} catch (MissingResourceException e) { return Optional.empty();
Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]"); try {
return Optional.empty(); return Optional.of(provider.get().getBlockData(key));
} } catch (MissingResourceException e) {
} Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]");
return Optional.empty();
public Optional<ItemStack> getItemStack(Identifier key) { }
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(key, true)).findFirst(); }
if (provider.isEmpty()) {
Iris.warn("No matching Provider found for modded material \"%s\"!", key); public Optional<ItemStack> getItemStack(Identifier key) {
return Optional.empty(); Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(key, true)).findFirst();
} if (provider.isEmpty()) {
try { Iris.warn("No matching Provider found for modded material \"%s\"!", key);
return Optional.of(provider.get().getItemStack(key)); return Optional.empty();
} catch (MissingResourceException e) { }
Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]"); try {
return Optional.empty(); return Optional.of(provider.get().getItemStack(key));
} } catch (MissingResourceException e) {
} Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]");
return Optional.empty();
public Identifier[] getAllBlockIdentifiers() { }
KList<Identifier> names = new KList<>(); }
activeProviders.forEach(p -> names.add(p.getBlockTypes()));
return names.toArray(new Identifier[0]); public Identifier[] getAllBlockIdentifiers() {
} KList<Identifier> names = new KList<>();
activeProviders.forEach(p -> names.add(p.getBlockTypes()));
public Identifier[] getAllItemIdentifiers() { return names.toArray(new Identifier[0]);
KList<Identifier> names = new KList<>(); }
activeProviders.forEach(p -> names.add(p.getItemTypes()));
return names.toArray(new Identifier[0]); public Identifier[] getAllItemIdentifiers() {
} KList<Identifier> names = new KList<>();
} activeProviders.forEach(p -> names.add(p.getItemTypes()));
return names.toArray(new Identifier[0]);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,179 +1,179 @@
/* /*
* 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) 2022 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.volmit.iris.engine.framework; package com.volmit.iris.engine.framework;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.events.IrisEngineHotloadEvent; import com.volmit.iris.core.events.IrisEngineHotloadEvent;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.C;
import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.plugin.VolmitSender;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.entity.EnderSignal; import org.bukkit.entity.EnderSignal;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.Action; import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.WorldSaveEvent; import org.bukkit.event.world.WorldSaveEvent;
import org.bukkit.event.world.WorldUnloadEvent; import org.bukkit.event.world.WorldUnloadEvent;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
public abstract class EngineAssignedWorldManager extends EngineAssignedComponent implements EngineWorldManager, Listener { public abstract class EngineAssignedWorldManager extends EngineAssignedComponent implements EngineWorldManager, Listener {
private final int taskId; private final int taskId;
protected AtomicBoolean ignoreTP = new AtomicBoolean(false); protected AtomicBoolean ignoreTP = new AtomicBoolean(false);
public EngineAssignedWorldManager() { public EngineAssignedWorldManager() {
super(null, null); super(null, null);
taskId = -1; taskId = -1;
} }
public EngineAssignedWorldManager(Engine engine) { public EngineAssignedWorldManager(Engine engine) {
super(engine, "World"); super(engine, "World");
Iris.instance.registerListener(this); Iris.instance.registerListener(this);
taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::onTick, 0, 0); taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::onTick, 0, 0);
} }
@EventHandler @EventHandler
public void on(IrisEngineHotloadEvent e) { public void on(IrisEngineHotloadEvent e) {
for (Player i : e.getEngine().getWorld().getPlayers()) { for (Player i : e.getEngine().getWorld().getPlayers()) {
i.playSound(i.getLocation(), Sound.BLOCK_AMETHYST_BLOCK_BREAK, 1f, 1.8f); i.playSound(i.getLocation(), Sound.BLOCK_AMETHYST_BLOCK_BREAK, 1f, 1.8f);
VolmitSender s = new VolmitSender(i); VolmitSender s = new VolmitSender(i);
s.sendTitle(C.IRIS + "Engine " + C.AQUA + "<font:minecraft:uniform>Hotloaded", 70, 60, 410); s.sendTitle(C.IRIS + "Engine " + C.AQUA + "<font:minecraft:uniform>Hotloaded", 70, 60, 410);
} }
} }
// @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) // @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
// public void on(PlayerTeleportEvent e) { // public void on(PlayerTeleportEvent e) {
// if(ignoreTP.get()) { // if(ignoreTP.get()) {
// System.out.println("IgTP1"); // System.out.println("IgTP1");
// return; // return;
// } // }
// //
// if(!PaperLib.isPaper() || e.getTo() == null) { // if(!PaperLib.isPaper() || e.getTo() == null) {
// System.out.println("IgTP2"); // System.out.println("IgTP2");
// //
//// return; //// return;
// } // }
// //
//// try { //// try {
//// System.out.println("IgTP3"); //// System.out.println("IgTP3");
//// ////
//// if(e.getTo().getWorld().equals(getTarget().getWorld().realWorld())) { //// if(e.getTo().getWorld().equals(getTarget().getWorld().realWorld())) {
//// System.out.println("IgTP4"); //// System.out.println("IgTP4");
//// ////
//// getEngine().getWorldManager().teleportAsync(e); //// getEngine().getWorldManager().teleportAsync(e);
//// } //// }
//// } catch(Throwable ex) { //// } catch(Throwable ex) {
//// ////
//// } //// }
// } // }
@EventHandler @EventHandler
public void on(WorldSaveEvent e) { public void on(WorldSaveEvent e) {
if (e.getWorld().equals(getTarget().getWorld().realWorld())) { if (e.getWorld().equals(getTarget().getWorld().realWorld())) {
getEngine().save(); getEngine().save();
} }
} }
@EventHandler @EventHandler
public void onItemUse(PlayerInteractEvent e) { public void onItemUse(PlayerInteractEvent e) {
if (e.getItem() == null || e.getHand() != EquipmentSlot.HAND) { if (e.getItem() == null || e.getHand() != EquipmentSlot.HAND) {
return; return;
} }
if (e.getAction() == Action.LEFT_CLICK_BLOCK || e.getAction() == Action.LEFT_CLICK_AIR) { if (e.getAction() == Action.LEFT_CLICK_BLOCK || e.getAction() == Action.LEFT_CLICK_AIR) {
return; return;
} }
if (e.getPlayer().getWorld().equals(getTarget().getWorld().realWorld()) && e.getItem().getType() == Material.ENDER_EYE) { if (e.getPlayer().getWorld().equals(getTarget().getWorld().realWorld()) && e.getItem().getType() == Material.ENDER_EYE) {
if (e.getClickedBlock() != null && e.getClickedBlock().getType() == Material.END_PORTAL_FRAME) { if (e.getClickedBlock() != null && e.getClickedBlock().getType() == Material.END_PORTAL_FRAME) {
return; return;
} }
KList<Position2> positions = getEngine().getDimension().getStrongholds(getEngine().getSeedManager().getSpawn()); KList<Position2> positions = getEngine().getDimension().getStrongholds(getEngine().getSeedManager().getSpawn());
if (positions.isEmpty()) { if (positions.isEmpty()) {
return; return;
} }
Position2 playerPos = new Position2(e.getPlayer().getLocation().getBlockX(), e.getPlayer().getLocation().getBlockZ()); Position2 playerPos = new Position2(e.getPlayer().getLocation().getBlockX(), e.getPlayer().getLocation().getBlockZ());
Position2 pr = positions.get(0); Position2 pr = positions.get(0);
double d = pr.distance(playerPos); double d = pr.distance(playerPos);
for (Position2 pos : positions) { for (Position2 pos : positions) {
double distance = pos.distance(playerPos); double distance = pos.distance(playerPos);
if (distance < d) { if (distance < d) {
d = distance; d = distance;
pr = pos; pr = pos;
} }
} }
if (e.getPlayer().getGameMode() != GameMode.CREATIVE) { if (e.getPlayer().getGameMode() != GameMode.CREATIVE) {
if (e.getItem().getAmount() > 1) { if (e.getItem().getAmount() > 1) {
e.getPlayer().getInventory().getItemInMainHand().setAmount(e.getItem().getAmount() - 1); e.getPlayer().getInventory().getItemInMainHand().setAmount(e.getItem().getAmount() - 1);
} else { } else {
e.getPlayer().getInventory().setItemInMainHand(null); e.getPlayer().getInventory().setItemInMainHand(null);
} }
} }
EnderSignal eye = e.getPlayer().getWorld().spawn(e.getPlayer().getLocation().clone().add(0, 0.5F, 0), EnderSignal.class); EnderSignal eye = e.getPlayer().getWorld().spawn(e.getPlayer().getLocation().clone().add(0, 0.5F, 0), EnderSignal.class);
eye.setTargetLocation(new Location(e.getPlayer().getWorld(), pr.getX(), 40, pr.getZ())); eye.setTargetLocation(new Location(e.getPlayer().getWorld(), pr.getX(), 40, pr.getZ()));
eye.getWorld().playSound(eye, Sound.ENTITY_ENDER_EYE_LAUNCH, 1, 1); eye.getWorld().playSound(eye, Sound.ENTITY_ENDER_EYE_LAUNCH, 1, 1);
Iris.debug("ESignal: " + eye.getTargetLocation().getBlockX() + " " + eye.getTargetLocation().getBlockX()); Iris.debug("ESignal: " + eye.getTargetLocation().getBlockX() + " " + eye.getTargetLocation().getBlockX());
} }
} }
@EventHandler @EventHandler
public void on(WorldUnloadEvent e) { public void on(WorldUnloadEvent e) {
if (e.getWorld().equals(getTarget().getWorld().realWorld())) { if (e.getWorld().equals(getTarget().getWorld().realWorld())) {
getEngine().close(); getEngine().close();
} }
} }
@EventHandler @EventHandler
public void on(BlockBreakEvent e) { public void on(BlockBreakEvent e) {
if (e.getPlayer().getWorld().equals(getTarget().getWorld().realWorld())) { if (e.getPlayer().getWorld().equals(getTarget().getWorld().realWorld())) {
onBlockBreak(e); onBlockBreak(e);
} }
} }
@EventHandler @EventHandler
public void on(BlockPlaceEvent e) { public void on(BlockPlaceEvent e) {
if (e.getPlayer().getWorld().equals(getTarget().getWorld().realWorld())) { if (e.getPlayer().getWorld().equals(getTarget().getWorld().realWorld())) {
onBlockPlace(e); onBlockPlace(e);
} }
} }
@EventHandler @EventHandler
public void on(ChunkLoadEvent e) { public void on(ChunkLoadEvent e) {
if (e.getChunk().getWorld().equals(getTarget().getWorld().realWorld())) { if (e.getChunk().getWorld().equals(getTarget().getWorld().realWorld())) {
onChunkLoad(e.getChunk(), e.isNewChunk()); onChunkLoad(e.getChunk(), e.isNewChunk());
} }
} }
@Override @Override
public void close() { public void close() {
super.close(); super.close();
Iris.instance.unregisterListener(this); Iris.instance.unregisterListener(this);
Bukkit.getScheduler().cancelTask(taskId); Bukkit.getScheduler().cancelTask(taskId);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,252 +1,252 @@
/* /*
* 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) 2022 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.volmit.iris.engine.object; package com.volmit.iris.engine.object;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
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.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.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.format.C; import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form; import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.noise.CNG; import com.volmit.iris.util.noise.CNG;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.TagParser; import net.minecraft.nbt.TagParser;
import org.bukkit.DyeColor; import org.bukkit.DyeColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack;
import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta; import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.material.Colorable; import org.bukkit.material.Colorable;
import java.awt.*; import java.awt.*;
import java.util.Optional; import java.util.Optional;
@Snippet("loot") @Snippet("loot")
@Accessors(chain = true) @Accessors(chain = true)
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Desc("Represents a loot entry") @Desc("Represents a loot entry")
@Data @Data
public class IrisLoot { public class IrisLoot {
private final transient AtomicCache<CNG> chance = new AtomicCache<>(); private final transient AtomicCache<CNG> chance = new AtomicCache<>();
@Desc("The target inventory slot types to fill this loot with") @Desc("The target inventory slot types to fill this loot with")
private InventorySlotType slotTypes = InventorySlotType.STORAGE; private InventorySlotType slotTypes = InventorySlotType.STORAGE;
@MinNumber(1) @MinNumber(1)
@Desc("The sub rarity of this loot. Calculated after this loot table has been picked.") @Desc("The sub rarity of this loot. Calculated after this loot table has been picked.")
private int rarity = 1; private int rarity = 1;
@MinNumber(1) @MinNumber(1)
@Desc("Minimum amount of this loot") @Desc("Minimum amount of this loot")
private int minAmount = 1; private int minAmount = 1;
@MinNumber(1) @MinNumber(1)
@Desc("Maximum amount of this loot") @Desc("Maximum amount of this loot")
private int maxAmount = 1; private int maxAmount = 1;
@MinNumber(1) @MinNumber(1)
@Desc("The display name of this item") @Desc("The display name of this item")
private String displayName = null; private String displayName = null;
@MinNumber(0) @MinNumber(0)
@MaxNumber(1) @MaxNumber(1)
@Desc("Minimum durability percent") @Desc("Minimum durability percent")
private double minDurability = 0; private double minDurability = 0;
@MinNumber(0) @MinNumber(0)
@MaxNumber(1) @MaxNumber(1)
@Desc("Maximum durability percent") @Desc("Maximum durability percent")
private double maxDurability = 1; private double maxDurability = 1;
@Desc("Define a custom model identifier 1.14+ only") @Desc("Define a custom model identifier 1.14+ only")
private Integer customModel = null; private Integer customModel = null;
@Desc("Set this to true to prevent it from being broken") @Desc("Set this to true to prevent it from being broken")
private boolean unbreakable = false; private boolean unbreakable = false;
@ArrayType(min = 1, type = ItemFlag.class) @ArrayType(min = 1, type = ItemFlag.class)
@Desc("The item flags to add") @Desc("The item flags to add")
private KList<ItemFlag> itemFlags = new KList<>(); private KList<ItemFlag> itemFlags = new KList<>();
@Desc("Apply enchantments to this item") @Desc("Apply enchantments to this item")
@ArrayType(min = 1, type = IrisEnchantment.class) @ArrayType(min = 1, type = IrisEnchantment.class)
private KList<IrisEnchantment> enchantments = new KList<>(); private KList<IrisEnchantment> enchantments = new KList<>();
@Desc("Apply attribute modifiers to this item") @Desc("Apply attribute modifiers to this item")
@ArrayType(min = 1, type = IrisAttributeModifier.class) @ArrayType(min = 1, type = IrisAttributeModifier.class)
private KList<IrisAttributeModifier> attributes = new KList<>(); private KList<IrisAttributeModifier> attributes = new KList<>();
@ArrayType(min = 1, type = String.class) @ArrayType(min = 1, type = String.class)
@Desc("Add lore to this item") @Desc("Add lore to this item")
private KList<String> lore = new KList<>(); private KList<String> lore = new KList<>();
@RegistryListItemType @RegistryListItemType
@Required @Required
@Desc("This is the item or block type. Does not accept minecraft:*, only materials such as DIAMOND_SWORD or DIRT. The exception are modded materials, as they require a namespace.") @Desc("This is the item or block type. Does not accept minecraft:*, only materials such as DIAMOND_SWORD or DIRT. The exception are modded materials, as they require a namespace.")
private String type = ""; private String type = "";
@Desc("The dye color") @Desc("The dye color")
private DyeColor dyeColor = null; private DyeColor dyeColor = null;
@Desc("The leather armor color") @Desc("The leather armor color")
private String leatherColor = null; private String leatherColor = null;
@Desc("Defines a custom NBT Tag for the item.") @Desc("Defines a custom NBT Tag for the item.")
private KMap<String, Object> customNbt; private KMap<String, Object> customNbt;
public Material getType() { public Material getType() {
return B.getMaterial(type); return B.getMaterial(type);
} }
public ItemStack get(boolean debug, RNG rng) { public ItemStack get(boolean debug, RNG rng) {
try { try {
ItemStack is = getItemStack(rng); ItemStack is = getItemStack(rng);
if (is == null) if (is == null)
return new ItemStack(Material.AIR); return new ItemStack(Material.AIR);
is.setItemMeta(applyProperties(is, rng, debug, null)); is.setItemMeta(applyProperties(is, rng, debug, null));
return applyCustomNbt(is); return applyCustomNbt(is);
} catch (Throwable e) { } catch (Throwable e) {
Iris.reportError(e); Iris.reportError(e);
return new ItemStack(Material.AIR); return new ItemStack(Material.AIR);
} }
} }
public ItemStack get(boolean debug, boolean giveSomething, IrisLootTable table, RNG rng, int x, int y, int z) { public ItemStack get(boolean debug, boolean giveSomething, IrisLootTable table, RNG rng, int x, int y, int z) {
if (debug) { if (debug) {
chance.reset(); chance.reset();
} }
if (giveSomething || chance.aquire(() -> NoiseStyle.STATIC.create(rng)).fit(1, rarity * table.getRarity(), x, y, z) == 1) { if (giveSomething || chance.aquire(() -> NoiseStyle.STATIC.create(rng)).fit(1, rarity * table.getRarity(), x, y, z) == 1) {
try { try {
ItemStack is = getItemStack(rng); ItemStack is = getItemStack(rng);
if (is == null) if (is == null)
return null; return null;
is.setItemMeta(applyProperties(is, rng, debug, table)); is.setItemMeta(applyProperties(is, rng, debug, table));
return applyCustomNbt(is); return applyCustomNbt(is);
} catch (Throwable e) { } catch (Throwable e) {
//Iris.reportError(e); //Iris.reportError(e);
e.printStackTrace(); e.printStackTrace();
} }
} }
return null; return null;
} }
// TODO Better Third Party Item Acquisition // TODO Better Third Party Item Acquisition
private ItemStack getItemStack(RNG rng) { private ItemStack getItemStack(RNG rng) {
if (!type.startsWith("minecraft:") && type.contains(":")) { if (!type.startsWith("minecraft:") && type.contains(":")) {
Optional<ItemStack> opt = Iris.service(ExternalDataSVC.class).getItemStack(Identifier.fromString(type)); Optional<ItemStack> opt = Iris.service(ExternalDataSVC.class).getItemStack(Identifier.fromString(type));
if (opt.isEmpty()) { if (opt.isEmpty()) {
Iris.warn("Unknown Material: " + type); Iris.warn("Unknown Material: " + type);
return new ItemStack(Material.AIR); return new ItemStack(Material.AIR);
} }
ItemStack is = opt.get(); ItemStack is = opt.get();
is.setAmount(Math.max(1, rng.i(getMinAmount(), getMaxAmount()))); is.setAmount(Math.max(1, rng.i(getMinAmount(), getMaxAmount())));
return is; return is;
} }
return new ItemStack(getType(), Math.max(1, rng.i(getMinAmount(), getMaxAmount()))); return new ItemStack(getType(), Math.max(1, rng.i(getMinAmount(), getMaxAmount())));
} }
private ItemMeta applyProperties(ItemStack is, RNG rng, boolean debug, IrisLootTable table) { private ItemMeta applyProperties(ItemStack is, RNG rng, boolean debug, IrisLootTable table) {
ItemMeta m = is.getItemMeta(); ItemMeta m = is.getItemMeta();
if (m == null) { if (m == null) {
return null; return null;
} }
for (IrisEnchantment i : getEnchantments()) { for (IrisEnchantment i : getEnchantments()) {
i.apply(rng, m); i.apply(rng, m);
} }
for (IrisAttributeModifier i : getAttributes()) { for (IrisAttributeModifier i : getAttributes()) {
i.apply(rng, m); i.apply(rng, m);
} }
m.setUnbreakable(isUnbreakable()); m.setUnbreakable(isUnbreakable());
for (ItemFlag i : getItemFlags()) { for (ItemFlag i : getItemFlags()) {
m.addItemFlags(i); m.addItemFlags(i);
} }
if (getCustomModel() != null) { if (getCustomModel() != null) {
m.setCustomModelData(getCustomModel()); m.setCustomModelData(getCustomModel());
} }
if (is.getType().getMaxDurability() > 0 && m instanceof Damageable d) { if (is.getType().getMaxDurability() > 0 && m instanceof Damageable d) {
int max = is.getType().getMaxDurability(); int max = is.getType().getMaxDurability();
d.setDamage((int) Math.round(Math.max(0, Math.min(max, (1D - rng.d(getMinDurability(), getMaxDurability())) * max)))); d.setDamage((int) Math.round(Math.max(0, Math.min(max, (1D - rng.d(getMinDurability(), getMaxDurability())) * max))));
} }
if (getLeatherColor() != null && m instanceof LeatherArmorMeta leather) { if (getLeatherColor() != null && m instanceof LeatherArmorMeta leather) {
Color c = Color.decode(getLeatherColor()); Color c = Color.decode(getLeatherColor());
leather.setColor(org.bukkit.Color.fromRGB(c.getRed(), c.getGreen(), c.getBlue())); leather.setColor(org.bukkit.Color.fromRGB(c.getRed(), c.getGreen(), c.getBlue()));
} }
if (getDyeColor() != null && m instanceof Colorable colorable) { if (getDyeColor() != null && m instanceof Colorable colorable) {
colorable.setColor(getDyeColor()); colorable.setColor(getDyeColor());
} }
if(displayName != null) { if (displayName != null) {
m.setLocalizedName(C.translateAlternateColorCodes('&', displayName)); m.setLocalizedName(C.translateAlternateColorCodes('&', displayName));
m.setDisplayName(C.translateAlternateColorCodes('&', displayName)); m.setDisplayName(C.translateAlternateColorCodes('&', displayName));
} }
KList<String> lore = new KList<>(); KList<String> lore = new KList<>();
getLore().forEach((i) -> getLore().forEach((i) ->
{ {
String mf = C.translateAlternateColorCodes('&', i); String mf = C.translateAlternateColorCodes('&', i);
if (mf.length() > 24) { if (mf.length() > 24) {
for (String g : Form.wrapWords(mf, 24).split("\\Q\n\\E")) { for (String g : Form.wrapWords(mf, 24).split("\\Q\n\\E")) {
lore.add(g.trim()); lore.add(g.trim());
} }
} else { } else {
lore.add(mf); lore.add(mf);
} }
}); });
if (debug) { if (debug) {
if (table == null) { if (table == null) {
if (lore.isNotEmpty()) { if (lore.isNotEmpty()) {
lore.add(C.GRAY + "--------------------"); lore.add(C.GRAY + "--------------------");
} }
lore.add(C.GRAY + "1 in " + (getRarity()) + " Chance (" + Form.pc(1D / (getRarity()), 5) + ")"); lore.add(C.GRAY + "1 in " + (getRarity()) + " Chance (" + Form.pc(1D / (getRarity()), 5) + ")");
} else { } else {
if (lore.isNotEmpty()) { if (lore.isNotEmpty()) {
lore.add(C.GRAY + "--------------------"); lore.add(C.GRAY + "--------------------");
} }
lore.add(C.GRAY + "From: " + table.getName() + " (" + Form.pc(1D / table.getRarity(), 5) + ")"); lore.add(C.GRAY + "From: " + table.getName() + " (" + Form.pc(1D / table.getRarity(), 5) + ")");
lore.add(C.GRAY + "1 in " + (table.getRarity() * getRarity()) + " Chance (" + Form.pc(1D / (table.getRarity() * getRarity()), 5) + ")"); lore.add(C.GRAY + "1 in " + (table.getRarity() * getRarity()) + " Chance (" + Form.pc(1D / (table.getRarity() * getRarity()), 5) + ")");
} }
} }
m.setLore(lore); m.setLore(lore);
return m; return m;
} }
private ItemStack applyCustomNbt(ItemStack stack) throws CommandSyntaxException { private ItemStack applyCustomNbt(ItemStack stack) throws CommandSyntaxException {
if (customNbt == null || customNbt.isEmpty()) if (customNbt == null || customNbt.isEmpty())
return stack; return stack;
net.minecraft.world.item.ItemStack s = CraftItemStack.asNMSCopy(stack); net.minecraft.world.item.ItemStack s = CraftItemStack.asNMSCopy(stack);
CompoundTag tag = TagParser.parseTag(new JSONObject(customNbt).toString()); CompoundTag tag = TagParser.parseTag(new JSONObject(customNbt).toString());
tag.merge(s.getOrCreateTag()); tag.merge(s.getOrCreateTag());
s.setTag(tag); s.setTag(tag);
return CraftItemStack.asBukkitCopy(s); return CraftItemStack.asBukkitCopy(s);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,426 +1,426 @@
/* /*
* 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) 2022 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.volmit.iris.engine.platform; package com.volmit.iris.engine.platform;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.core.nms.v19_4.CustomBiomeSource; import com.volmit.iris.core.nms.v19_4.CustomBiomeSource;
import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.core.service.StudioSVC;
import com.volmit.iris.engine.IrisEngine; import com.volmit.iris.engine.IrisEngine;
import com.volmit.iris.engine.data.chunk.TerrainChunk; import com.volmit.iris.engine.data.chunk.TerrainChunk;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineTarget; import com.volmit.iris.engine.framework.EngineTarget;
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.object.StudioMode; import com.volmit.iris.engine.object.StudioMode;
import com.volmit.iris.engine.platform.studio.StudioGenerator; import com.volmit.iris.engine.platform.studio.StudioGenerator;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.data.IrisBiomeStorage; import com.volmit.iris.util.data.IrisBiomeStorage;
import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.hunk.view.BiomeGridHunkHolder; import com.volmit.iris.util.hunk.view.BiomeGridHunkHolder;
import com.volmit.iris.util.hunk.view.ChunkDataHunkHolder; import com.volmit.iris.util.hunk.view.ChunkDataHunkHolder;
import com.volmit.iris.util.io.ReactiveFolder; import com.volmit.iris.util.io.ReactiveFolder;
import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.Looper; import com.volmit.iris.util.scheduling.Looper;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Setter; import lombok.Setter;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldInitEvent; import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.generator.BiomeProvider; import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.ChunkGenerator; import org.bukkit.generator.ChunkGenerator;
import org.bukkit.generator.WorldInfo; import org.bukkit.generator.WorldInfo;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import sun.misc.Unsafe; import sun.misc.Unsafe;
import java.io.File; import java.io.File;
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;
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;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer; import java.util.function.Consumer;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Data @Data
public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChunkGenerator, Listener { public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChunkGenerator, Listener {
private static final int LOAD_LOCKS = Runtime.getRuntime().availableProcessors() * 4; private static final int LOAD_LOCKS = Runtime.getRuntime().availableProcessors() * 4;
private final Semaphore loadLock; private final Semaphore loadLock;
private final IrisWorld world; private final IrisWorld world;
private final File dataLocation; private final File dataLocation;
private final String dimensionKey; private final String dimensionKey;
private final ReactiveFolder folder; private final ReactiveFolder folder;
private final ReentrantLock lock = new ReentrantLock(); private final ReentrantLock lock = new ReentrantLock();
private final KList<BlockPopulator> populators; private final KList<BlockPopulator> populators;
private final ChronoLatch hotloadChecker; private final ChronoLatch hotloadChecker;
private final AtomicBoolean setup; private final AtomicBoolean setup;
private final boolean studio; private final boolean studio;
private final AtomicInteger a = new AtomicInteger(0); private final AtomicInteger a = new AtomicInteger(0);
private Engine engine; private Engine engine;
private Looper hotloader; private Looper hotloader;
private StudioMode lastMode; private StudioMode lastMode;
private DummyBiomeProvider dummyBiomeProvider; private DummyBiomeProvider dummyBiomeProvider;
@Setter @Setter
private StudioGenerator studioGenerator; private StudioGenerator studioGenerator;
private boolean initialized = false; private boolean initialized = false;
public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey) { 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();
populators = new KList<>(); populators = new KList<>();
loadLock = new Semaphore(LOAD_LOCKS); loadLock = new Semaphore(LOAD_LOCKS);
this.world = world; this.world = world;
this.hotloadChecker = new ChronoLatch(1000, false); this.hotloadChecker = new ChronoLatch(1000, false);
this.studio = studio; this.studio = studio;
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());
Bukkit.getServer().getPluginManager().registerEvents(this, Iris.instance); Bukkit.getServer().getPluginManager().registerEvents(this, Iris.instance);
} }
private static Field getField(Class clazz, String fieldName) private static Field getField(Class clazz, String fieldName)
throws NoSuchFieldException { throws NoSuchFieldException {
try { try {
return clazz.getDeclaredField(fieldName); return clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) { } catch (NoSuchFieldException e) {
Class superClass = clazz.getSuperclass(); Class superClass = clazz.getSuperclass();
if (superClass == null) { if (superClass == null) {
throw e; throw e;
} else { } else {
return getField(superClass, fieldName); return getField(superClass, fieldName);
} }
} }
} }
@EventHandler @EventHandler
public void onWorldInit(WorldInitEvent event) { public void onWorldInit(WorldInitEvent event) {
try { try {
if(!initialized) { if (!initialized) {
world.setRawWorldSeed(event.getWorld().getSeed()); world.setRawWorldSeed(event.getWorld().getSeed());
if (world.name().equals(event.getWorld().getName())) { if (world.name().equals(event.getWorld().getName())) {
ServerLevel serverLevel = ((CraftWorld) event.getWorld()).getHandle(); ServerLevel serverLevel = ((CraftWorld) event.getWorld()).getHandle();
Engine engine = getEngine(event.getWorld()); Engine engine = getEngine(event.getWorld());
Class<?> clazz = serverLevel.getChunkSource().chunkMap.generator.getClass(); Class<?> clazz = serverLevel.getChunkSource().chunkMap.generator.getClass();
Field biomeSource = getField(clazz, "b"); Field biomeSource = getField(clazz, "b");
biomeSource.setAccessible(true); biomeSource.setAccessible(true);
Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true); unsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) unsafeField.get(null); Unsafe unsafe = (Unsafe) unsafeField.get(null);
CustomBiomeSource customBiomeSource = new CustomBiomeSource(event.getWorld().getSeed(), engine, event.getWorld()); CustomBiomeSource customBiomeSource = new CustomBiomeSource(event.getWorld().getSeed(), engine, event.getWorld());
unsafe.putObject(biomeSource.get(serverLevel.getChunkSource().chunkMap.generator), unsafe.objectFieldOffset(biomeSource), customBiomeSource); unsafe.putObject(biomeSource.get(serverLevel.getChunkSource().chunkMap.generator), unsafe.objectFieldOffset(biomeSource), customBiomeSource);
biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource); biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource);
Iris.info("Injected Iris Biome Source into " + event.getWorld().getName()); Iris.info("Injected Iris Biome Source into " + event.getWorld().getName());
initialized = true; initialized = true;
} }
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
private void setupEngine() { private void setupEngine() {
IrisData data = IrisData.get(dataLocation); IrisData data = IrisData.get(dataLocation);
IrisDimension dimension = data.getDimensionLoader().load(dimensionKey); IrisDimension dimension = data.getDimensionLoader().load(dimensionKey);
if (dimension == null) { if (dimension == null) {
Iris.error("Oh No! There's no pack in " + data.getDataFolder().getPath() + " or... there's no dimension for the key " + dimensionKey); Iris.error("Oh No! There's no pack in " + data.getDataFolder().getPath() + " or... there's no dimension for the key " + dimensionKey);
IrisDimension test = IrisData.loadAnyDimension(dimensionKey); IrisDimension test = IrisData.loadAnyDimension(dimensionKey);
if (test != null) { if (test != null) {
Iris.warn("Looks like " + dimensionKey + " exists in " + test.getLoadFile().getPath() + " "); Iris.warn("Looks like " + dimensionKey + " exists in " + test.getLoadFile().getPath() + " ");
Iris.service(StudioSVC.class).installIntoWorld(Iris.getSender(), dimensionKey, dataLocation.getParentFile().getParentFile()); Iris.service(StudioSVC.class).installIntoWorld(Iris.getSender(), dimensionKey, dataLocation.getParentFile().getParentFile());
Iris.warn("Attempted to install into " + data.getDataFolder().getPath()); Iris.warn("Attempted to install into " + data.getDataFolder().getPath());
data.dump(); data.dump();
data.clearLists(); data.clearLists();
test = data.getDimensionLoader().load(dimensionKey); test = data.getDimensionLoader().load(dimensionKey);
if (test != null) { if (test != null) {
Iris.success("Woo! Patched the Engine!"); Iris.success("Woo! Patched the Engine!");
dimension = test; dimension = test;
} else { } else {
Iris.error("Failed to patch dimension!"); Iris.error("Failed to patch dimension!");
throw new RuntimeException("Missing Dimension: " + dimensionKey); throw new RuntimeException("Missing Dimension: " + dimensionKey);
} }
} else { } else {
Iris.error("Nope, you don't have an installation containing " + dimensionKey + " try downloading it?"); Iris.error("Nope, you don't have an installation containing " + dimensionKey + " try downloading it?");
throw new RuntimeException("Missing Dimension: " + dimensionKey); throw new RuntimeException("Missing Dimension: " + dimensionKey);
} }
} }
lastMode = StudioMode.NORMAL; lastMode = StudioMode.NORMAL;
engine = new IrisEngine(new EngineTarget(world, dimension, data), studio); engine = new IrisEngine(new EngineTarget(world, dimension, data), studio);
populators.clear(); populators.clear();
} }
@Override @Override
public void injectChunkReplacement(World world, int x, int z, Consumer<Runnable> jobs) { public void injectChunkReplacement(World world, int x, int z, Consumer<Runnable> jobs) {
try { try {
loadLock.acquire(); loadLock.acquire();
IrisBiomeStorage st = new IrisBiomeStorage(); IrisBiomeStorage st = new IrisBiomeStorage();
TerrainChunk tc = TerrainChunk.createUnsafe(world, st); TerrainChunk tc = TerrainChunk.createUnsafe(world, st);
Hunk<BlockData> blocks = Hunk.view(tc); Hunk<BlockData> blocks = Hunk.view(tc);
Hunk<Biome> biomes = Hunk.view(tc, tc.getMinHeight(), tc.getMaxHeight()); Hunk<Biome> biomes = Hunk.view(tc, tc.getMinHeight(), tc.getMaxHeight());
this.world.bind(world); this.world.bind(world);
getEngine().generate(x << 4, z << 4, blocks, biomes, true); getEngine().generate(x << 4, z << 4, blocks, biomes, true);
Iris.debug("Regenerated " + x + " " + z); Iris.debug("Regenerated " + x + " " + z);
int t = 0; int t = 0;
for (int i = getEngine().getHeight() >> 4; i >= 0; i--) { for (int i = getEngine().getHeight() >> 4; i >= 0; i--) {
if (!world.isChunkLoaded(x, z)) { if (!world.isChunkLoaded(x, z)) {
continue; continue;
} }
Chunk c = world.getChunkAt(x, z); Chunk c = world.getChunkAt(x, z);
for (Entity ee : c.getEntities()) { for (Entity ee : c.getEntities()) {
if (ee instanceof Player) { if (ee instanceof Player) {
continue; continue;
} }
J.s(ee::remove); J.s(ee::remove);
} }
J.s(() -> engine.getWorldManager().onChunkLoad(c, false)); J.s(() -> engine.getWorldManager().onChunkLoad(c, false));
int finalI = i; int finalI = i;
jobs.accept(() -> { jobs.accept(() -> {
for (int xx = 0; xx < 16; xx++) { for (int xx = 0; xx < 16; xx++) {
for (int yy = 0; yy < 16; yy++) { for (int yy = 0; yy < 16; yy++) {
for (int zz = 0; zz < 16; zz++) { for (int zz = 0; zz < 16; zz++) {
if (yy + (finalI << 4) >= engine.getHeight() || yy + (finalI << 4) < 0) { if (yy + (finalI << 4) >= engine.getHeight() || yy + (finalI << 4) < 0) {
continue; continue;
} }
c.getBlock(xx, yy + (finalI << 4) + world.getMinHeight(), zz) c.getBlock(xx, yy + (finalI << 4) + world.getMinHeight(), zz)
.setBlockData(tc.getBlockData(xx, yy + (finalI << 4) + world.getMinHeight(), zz), false); .setBlockData(tc.getBlockData(xx, yy + (finalI << 4) + world.getMinHeight(), zz), false);
} }
} }
} }
}); });
} }
loadLock.release(); loadLock.release();
} catch (Throwable e) { } catch (Throwable e) {
loadLock.release(); loadLock.release();
Iris.error("======================================"); Iris.error("======================================");
e.printStackTrace(); e.printStackTrace();
Iris.reportErrorChunk(x, z, e, "CHUNK"); Iris.reportErrorChunk(x, z, e, "CHUNK");
Iris.error("======================================"); Iris.error("======================================");
ChunkData d = Bukkit.createChunkData(world); ChunkData d = Bukkit.createChunkData(world);
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) { for (int j = 0; j < 16; j++) {
d.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA.createBlockData()); d.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA.createBlockData());
} }
} }
} }
} }
private Engine getEngine(WorldInfo world) { private Engine getEngine(WorldInfo world) {
if (setup.get()) { if (setup.get()) {
return getEngine(); return getEngine();
} }
lock.lock(); lock.lock();
if (setup.get()) { if (setup.get()) {
return getEngine(); return getEngine();
} }
setup.set(true); setup.set(true);
getWorld().setRawWorldSeed(world.getSeed()); getWorld().setRawWorldSeed(world.getSeed());
setupEngine(); setupEngine();
this.hotloader = studio ? new Looper() { this.hotloader = studio ? new Looper() {
@Override @Override
protected long loop() { protected long loop() {
if (hotloadChecker.flip()) { if (hotloadChecker.flip()) {
folder.check(); folder.check();
} }
return 250; return 250;
} }
} : null; } : null;
if (studio) { if (studio) {
hotloader.setPriority(Thread.MIN_PRIORITY); hotloader.setPriority(Thread.MIN_PRIORITY);
hotloader.start(); hotloader.start();
hotloader.setName(getTarget().getWorld().name() + " Hotloader"); hotloader.setName(getTarget().getWorld().name() + " Hotloader");
} }
lock.unlock(); lock.unlock();
return engine; return engine;
} }
@Override @Override
public void close() { public void close() {
withExclusiveControl(() -> { withExclusiveControl(() -> {
if (isStudio()) { if (isStudio()) {
hotloader.interrupt(); hotloader.interrupt();
} }
getEngine().close(); getEngine().close();
folder.clear(); folder.clear();
populators.clear(); populators.clear();
}); });
} }
@Override @Override
public boolean isStudio() { public boolean isStudio() {
return studio; return studio;
} }
@Override @Override
public void hotload() { public void hotload() {
if (!isStudio()) { if (!isStudio()) {
return; return;
} }
withExclusiveControl(() -> getEngine().hotload()); withExclusiveControl(() -> getEngine().hotload());
} }
public void withExclusiveControl(Runnable r) { public void withExclusiveControl(Runnable r) {
J.a(() -> { J.a(() -> {
try { try {
loadLock.acquire(LOAD_LOCKS); loadLock.acquire(LOAD_LOCKS);
r.run(); r.run();
loadLock.release(LOAD_LOCKS); loadLock.release(LOAD_LOCKS);
} catch (Throwable e) { } catch (Throwable e) {
Iris.reportError(e); Iris.reportError(e);
} }
}); });
} }
@Override @Override
public void touch(World world) { public void touch(World world) {
getEngine(world); getEngine(world);
} }
@Override @Override
public void generateNoise(@NotNull WorldInfo world, @NotNull Random random, int x, int z, @NotNull ChunkGenerator.ChunkData d) { public void generateNoise(@NotNull WorldInfo world, @NotNull Random random, int x, int z, @NotNull ChunkGenerator.ChunkData d) {
try { try {
getEngine(world); getEngine(world);
computeStudioGenerator(); computeStudioGenerator();
TerrainChunk tc = TerrainChunk.create(d, new IrisBiomeStorage()); TerrainChunk tc = TerrainChunk.create(d, new IrisBiomeStorage());
this.world.bind(world); this.world.bind(world);
if (studioGenerator != null) { if (studioGenerator != null) {
studioGenerator.generateChunk(getEngine(), tc, x, z); studioGenerator.generateChunk(getEngine(), tc, x, z);
} else { } else {
ChunkDataHunkHolder blocks = new ChunkDataHunkHolder(tc); ChunkDataHunkHolder blocks = new ChunkDataHunkHolder(tc);
BiomeGridHunkHolder biomes = new BiomeGridHunkHolder(tc, tc.getMinHeight(), tc.getMaxHeight()); BiomeGridHunkHolder biomes = new BiomeGridHunkHolder(tc, tc.getMinHeight(), tc.getMaxHeight());
getEngine().generate(x << 4, z << 4, blocks, biomes, false); getEngine().generate(x << 4, z << 4, blocks, biomes, false);
blocks.apply(); blocks.apply();
biomes.apply(); biomes.apply();
} }
Iris.debug("Generated " + x + " " + z); Iris.debug("Generated " + x + " " + z);
} catch (Throwable e) { } catch (Throwable e) {
Iris.error("======================================"); Iris.error("======================================");
e.printStackTrace(); e.printStackTrace();
Iris.reportErrorChunk(x, z, e, "CHUNK"); Iris.reportErrorChunk(x, z, e, "CHUNK");
Iris.error("======================================"); Iris.error("======================================");
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) { for (int j = 0; j < 16; j++) {
d.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA.createBlockData()); d.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA.createBlockData());
} }
} }
} }
} }
@Override @Override
public int getBaseHeight(@NotNull WorldInfo worldInfo, @NotNull Random random, int x, int z, @NotNull HeightMap heightMap) { public int getBaseHeight(@NotNull WorldInfo worldInfo, @NotNull Random random, int x, int z, @NotNull HeightMap heightMap) {
return 4; return 4;
} }
private void computeStudioGenerator() { private void computeStudioGenerator() {
if (!getEngine().getDimension().getStudioMode().equals(lastMode)) { if (!getEngine().getDimension().getStudioMode().equals(lastMode)) {
lastMode = getEngine().getDimension().getStudioMode(); lastMode = getEngine().getDimension().getStudioMode();
getEngine().getDimension().getStudioMode().inject(this); getEngine().getDimension().getStudioMode().inject(this);
} }
} }
@NotNull @NotNull
@Override @Override
public List<BlockPopulator> getDefaultPopulators(@NotNull World world) { public List<BlockPopulator> getDefaultPopulators(@NotNull World world) {
return populators; return populators;
} }
@Override @Override
public boolean isParallelCapable() { public boolean isParallelCapable() {
return true; return true;
} }
@Override @Override
public boolean shouldGenerateCaves() { public boolean shouldGenerateCaves() {
return false; return false;
} }
@Override @Override
public boolean shouldGenerateDecorations() { public boolean shouldGenerateDecorations() {
return false; return false;
} }
@Override @Override
public boolean shouldGenerateMobs() { public boolean shouldGenerateMobs() {
return false; return false;
} }
@Override @Override
public boolean shouldGenerateStructures() { public boolean shouldGenerateStructures() {
return false; return false;
} }
@Override @Override
public boolean shouldGenerateNoise() { public boolean shouldGenerateNoise() {
return false; return false;
} }
@Override @Override
public boolean shouldGenerateSurface() { public boolean shouldGenerateSurface() {
return false; return false;
} }
@Override @Override
public boolean shouldGenerateBedrock() { public boolean shouldGenerateBedrock() {
return false; return false;
} }
@Nullable @Nullable
@Override @Override
public BiomeProvider getDefaultBiomeProvider(@NotNull WorldInfo worldInfo) { public BiomeProvider getDefaultBiomeProvider(@NotNull WorldInfo worldInfo) {
return dummyBiomeProvider; return dummyBiomeProvider;
} }
} }

View File

@ -1,39 +1,37 @@
/* /*
* 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) 2022 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.volmit.iris.util.decree.context; package com.volmit.iris.util.decree.context;
import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.util.decree.DecreeContextHandler;
import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.decree.DecreeContextHandler; import org.bukkit.util.Vector;
import com.volmit.iris.util.plugin.VolmitSender;
import org.bukkit.util.Vector; public class VectorContextHandler implements DecreeContextHandler<Vector> {
public Class<Vector> getType() {
public class VectorContextHandler implements DecreeContextHandler<Vector> { return Vector.class;
public Class<Vector> getType() { }
return Vector.class;
} public Vector handle(VolmitSender sender) {
if (sender.isPlayer()) {
public Vector handle(VolmitSender sender) { return sender.player().getLocation().toVector();
if (sender.isPlayer()) { }
return sender.player().getLocation().toVector();
} return null;
}
return null; }
}
}

View File

@ -1,42 +1,42 @@
package com.volmit.iris.util.reflect; package com.volmit.iris.util.reflect;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import java.lang.reflect.Field; import java.lang.reflect.Field;
public class WrappedField<C, T> { public class WrappedField<C, T> {
private final Field field; private final Field field;
public WrappedField(Class<C> origin, String methodName) { public WrappedField(Class<C> origin, String methodName) {
Field f = null; Field f = null;
try { try {
f = origin.getDeclaredField(methodName); f = origin.getDeclaredField(methodName);
f.setAccessible(true); f.setAccessible(true);
} catch(NoSuchFieldException e) { } catch (NoSuchFieldException e) {
Iris.error("Failed to created WrappedField %s#%s: %s%s", origin.getSimpleName(), methodName, e.getClass().getSimpleName(), e.getMessage().equals("") ? "" : " | " + e.getMessage()); Iris.error("Failed to created WrappedField %s#%s: %s%s", origin.getSimpleName(), methodName, e.getClass().getSimpleName(), e.getMessage().equals("") ? "" : " | " + e.getMessage());
} }
this.field = f; this.field = f;
} }
public T get() { public T get() {
return get(null); return get(null);
} }
public T get(C instance) { public T get(C instance) {
if(field == null) { if (field == null) {
return null; return null;
} }
try { try {
return (T)field.get(instance); return (T) field.get(instance);
} catch(IllegalAccessException e) { } catch (IllegalAccessException e) {
Iris.error("Failed to get WrappedField %s#%s: %s%s", field.getDeclaringClass().getSimpleName(), field.getName(), e.getClass().getSimpleName(), e.getMessage().equals("") ? "" : " | " + e.getMessage()); Iris.error("Failed to get WrappedField %s#%s: %s%s", field.getDeclaringClass().getSimpleName(), field.getName(), e.getClass().getSimpleName(), e.getMessage().equals("") ? "" : " | " + e.getMessage());
return null; return null;
} }
} }
public boolean hasFailed() { public boolean hasFailed() {
return field == null; return field == null;
} }
} }

View File

@ -1,39 +1,39 @@
package com.volmit.iris.util.reflect; package com.volmit.iris.util.reflect;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
public final class WrappedReturningMethod<C, R> { public final class WrappedReturningMethod<C, R> {
private final Method method; private final Method method;
public WrappedReturningMethod(Class<C> origin, String methodName, Class<?>... paramTypes) { public WrappedReturningMethod(Class<C> origin, String methodName, Class<?>... paramTypes) {
Method m = null; Method m = null;
try { try {
m = origin.getDeclaredMethod(methodName, paramTypes); m = origin.getDeclaredMethod(methodName, paramTypes);
m.setAccessible(true); m.setAccessible(true);
} catch(NoSuchMethodException e) { } catch (NoSuchMethodException e) {
Iris.error("Failed to created WrappedMethod %s#%s: %s%s", origin.getSimpleName(), methodName, e.getClass().getSimpleName(), e.getMessage().equals("") ? "" : " | " + e.getMessage()); Iris.error("Failed to created WrappedMethod %s#%s: %s%s", origin.getSimpleName(), methodName, e.getClass().getSimpleName(), e.getMessage().equals("") ? "" : " | " + e.getMessage());
} }
this.method = m; this.method = m;
} }
public R invoke(Object... args) { public R invoke(Object... args) {
return invoke(null, args); return invoke(null, args);
} }
public R invoke(C instance, Object... args) { public R invoke(C instance, Object... args) {
if(method == null) { if (method == null) {
return null; return null;
} }
try { try {
return (R)method.invoke(instance, args); return (R) method.invoke(instance, args);
} catch(InvocationTargetException | IllegalAccessException e) { } catch (InvocationTargetException | IllegalAccessException e) {
Iris.error("Failed to invoke WrappedMethod %s#%s: %s%s", method.getDeclaringClass().getSimpleName(), method.getName(), e.getClass().getSimpleName(), e.getMessage().equals("") ? "" : " | " + e.getMessage()); Iris.error("Failed to invoke WrappedMethod %s#%s: %s%s", method.getDeclaringClass().getSimpleName(), method.getName(), e.getClass().getSimpleName(), e.getMessage().equals("") ? "" : " | " + e.getMessage());
return null; return null;
} }
} }
} }

View File

@ -1,289 +1,289 @@
package com.volmit.iris.util.uniques; package com.volmit.iris.util.uniques;
import com.volmit.iris.engine.object.NoiseStyle; import com.volmit.iris.engine.object.NoiseStyle;
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.format.Form; import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.function.NoiseProvider; import com.volmit.iris.util.function.NoiseProvider;
import com.volmit.iris.util.interpolation.InterpolationMethod; import com.volmit.iris.util.interpolation.InterpolationMethod;
import com.volmit.iris.util.interpolation.IrisInterpolation; import com.volmit.iris.util.interpolation.IrisInterpolation;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.noise.CNG; import com.volmit.iris.util.noise.CNG;
import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.BurstExecutor;
import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch; import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import com.volmit.iris.util.stream.ProceduralStream; import com.volmit.iris.util.stream.ProceduralStream;
import com.volmit.iris.util.uniques.features.*; import com.volmit.iris.util.uniques.features.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
public class UniqueRenderer { public class UniqueRenderer {
static final List<UFeature> backgrounds = List.of(new UFWarpedBackground()); static final List<UFeature> backgrounds = List.of(new UFWarpedBackground());
static final List<UFeature> interpolators = List.of(new UFInterpolator(), new UFNOOP()); static final List<UFeature> interpolators = List.of(new UFInterpolator(), new UFNOOP());
static final List<UFeature> features = List.of(new UFWarpedLines(), new UFWarpedDisc(), new UFWarpedDots(), new UFWarpedCircle()); static final List<UFeature> features = List.of(new UFWarpedLines(), new UFWarpedDisc(), new UFWarpedDots(), new UFWarpedCircle());
static UniqueRenderer renderer; static UniqueRenderer renderer;
private final String seed; private final String seed;
private final ProceduralStream<RNG> spatialSeed; private final ProceduralStream<RNG> spatialSeed;
private final int width; private final int width;
private final int height; private final int height;
private final KMap<String, String> writing = new KMap<>(); private final KMap<String, String> writing = new KMap<>();
private final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2); private final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
int cores = Runtime.getRuntime().availableProcessors(); private final KList<NoiseStyle> sortedStyles = new KList<NoiseStyle>();
private final KList<NoiseStyle> sortedStyles = new KList<NoiseStyle>(); private final KList<InterpolationMethod> sortedInterpolators = new KList<InterpolationMethod>();
private final KList<InterpolationMethod> sortedInterpolators = new KList<InterpolationMethod>(); int cores = Runtime.getRuntime().availableProcessors();
public UniqueRenderer(String seed, int width, int height) { public UniqueRenderer(String seed, int width, int height) {
renderer = this; renderer = this;
computeNoiseStyles(3000, 2); computeNoiseStyles(3000, 2);
computeInterpolationMethods(3000, 2); computeInterpolationMethods(3000, 2);
this.seed = seed; this.seed = seed;
this.width = width; this.width = width;
this.height = height; this.height = height;
spatialSeed = NoiseStyle.FRACTAL_WATER.stream(new RNG(seed)).convert((d) -> new RNG(Math.round(seed.hashCode() + (d * 934321234D)))); spatialSeed = NoiseStyle.FRACTAL_WATER.stream(new RNG(seed)).convert((d) -> new RNG(Math.round(seed.hashCode() + (d * 934321234D))));
new Thread(() -> { new Thread(() -> {
while (true) { while (true) {
J.sleep(5000); J.sleep(5000);
if (!writing.isEmpty()) { if (!writing.isEmpty()) {
System.out.println(Form.repeat("\n", 60)); System.out.println(Form.repeat("\n", 60));
System.out.println(Form.memSize(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(), 2) + " of " + Form.memSize(Runtime.getRuntime().totalMemory(), 2)); System.out.println(Form.memSize(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(), 2) + " of " + Form.memSize(Runtime.getRuntime().totalMemory(), 2));
KMap<String, String> c = writing.copy(); KMap<String, String> c = writing.copy();
for (String i : writing.k().sort()) { for (String i : writing.k().sort()) {
String prog = ""; String prog = "";
String f = writing.get(i); String f = writing.get(i);
if (f.contains("%")) { if (f.contains("%")) {
String v = f.split("\\Q%\\E")[0]; String v = f.split("\\Q%\\E")[0];
try { try {
prog = drawProgress(Double.valueOf(Integer.parseInt(v.substring(v.length() - 2))) / 100D, 30); prog = drawProgress(Double.valueOf(Integer.parseInt(v.substring(v.length() - 2))) / 100D, 30);
} catch (Throwable e) { } catch (Throwable e) {
try { try {
prog = drawProgress(Double.valueOf(Integer.parseInt(v.substring(v.length() - 1))) / 100D, 30); prog = drawProgress(Double.valueOf(Integer.parseInt(v.substring(v.length() - 1))) / 100D, 30);
} catch (Throwable ee) { } catch (Throwable ee) {
try { try {
prog = drawProgress(Double.valueOf(Integer.parseInt(v.substring(v.length() - 3))) / 100D, 30); prog = drawProgress(Double.valueOf(Integer.parseInt(v.substring(v.length() - 3))) / 100D, 30);
} catch (Throwable eee) { } catch (Throwable eee) {
} }
} }
} }
} }
System.out.println(prog + " " + i + " => " + f); System.out.println(prog + " " + i + " => " + f);
} }
} }
} }
}).start(); }).start();
} }
public UMeta renderFrameBuffer(long id, double t) { public UMeta renderFrameBuffer(long id, double t) {
UMeta meta = new UMeta(); UMeta meta = new UMeta();
meta.setId(id); meta.setId(id);
meta.setTime(t); meta.setTime(t);
RNG rng = spatialSeed.get(id, id + ((id * id) % (id / 3D))); RNG rng = spatialSeed.get(id, id + ((id * id) % (id / 3D)));
RNG rngbg = spatialSeed.get(id, -id + ((id * id) % (id / 4D))); RNG rngbg = spatialSeed.get(id, -id + ((id * id) % (id / 4D)));
BufferedImage buf = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); BufferedImage buf = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
BufferedImage bufFG = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); BufferedImage bufFG = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
UImage image = new UBufferedImage(buf); UImage image = new UBufferedImage(buf);
UImage imageFG = new UBufferedImage(bufFG); UImage imageFG = new UBufferedImage(bufFG);
ChronoLatch cl = new ChronoLatch(250); ChronoLatch cl = new ChronoLatch(250);
UFeature background = rng.pick(backgrounds); UFeature background = rng.pick(backgrounds);
UFeature interpolator = rng.pick(interpolators); UFeature interpolator = rng.pick(interpolators);
UFeature foreground = rng.pick(features); UFeature foreground = rng.pick(features);
UFeature foregroundInterpolator = rng.pick(interpolators); UFeature foregroundInterpolator = rng.pick(interpolators);
UFeatureMeta backgroundMeta = new UFeatureMeta(); UFeatureMeta backgroundMeta = new UFeatureMeta();
UFeatureMeta foregroundMeta = new UFeatureMeta(); UFeatureMeta foregroundMeta = new UFeatureMeta();
UFeatureMeta backgroundInterpolatorMeta = new UFeatureMeta(); UFeatureMeta backgroundInterpolatorMeta = new UFeatureMeta();
UFeatureMeta foregroundInterpolatorMeta = new UFeatureMeta(); UFeatureMeta foregroundInterpolatorMeta = new UFeatureMeta();
background.render(image, rngbg, t, (p) -> { background.render(image, rngbg, t, (p) -> {
if (cl.flip()) { if (cl.flip()) {
writing.put("#" + id + ":" + t, Form.pc(p / 4D) + " [" + background.getClass().getSimpleName() + " " + Form.pc(p) + "]"); writing.put("#" + id + ":" + t, Form.pc(p / 4D) + " [" + background.getClass().getSimpleName() + " " + Form.pc(p) + "]");
} }
}, backgroundMeta); }, backgroundMeta);
backgroundMeta.setFeature(background.getClass().getSimpleName()); backgroundMeta.setFeature(background.getClass().getSimpleName());
meta.registerFeature("background", backgroundMeta); meta.registerFeature("background", backgroundMeta);
interpolator.render(image, rng, t, (p) -> { interpolator.render(image, rng, t, (p) -> {
if (cl.flip()) { if (cl.flip()) {
writing.put("#" + id + ":" + t, Form.pc(0.25 + (p / 4d)) + " [" + interpolator.getClass().getSimpleName() + " " + Form.pc(p) + "]"); writing.put("#" + id + ":" + t, Form.pc(0.25 + (p / 4d)) + " [" + interpolator.getClass().getSimpleName() + " " + Form.pc(p) + "]");
} }
}, backgroundInterpolatorMeta); }, backgroundInterpolatorMeta);
backgroundInterpolatorMeta.setFeature(interpolator.getClass().getSimpleName()); backgroundInterpolatorMeta.setFeature(interpolator.getClass().getSimpleName());
meta.registerFeature("backgroundInterpolator", backgroundInterpolatorMeta); meta.registerFeature("backgroundInterpolator", backgroundInterpolatorMeta);
foreground.render(imageFG, rng, t, (p) -> { foreground.render(imageFG, rng, t, (p) -> {
if (cl.flip()) { if (cl.flip()) {
writing.put("#" + id + ":" + t, Form.pc(0.5 + (p / 4d)) + " [" + foreground.getClass().getSimpleName() + " " + Form.pc(p) + "]"); writing.put("#" + id + ":" + t, Form.pc(0.5 + (p / 4d)) + " [" + foreground.getClass().getSimpleName() + " " + Form.pc(p) + "]");
} }
}, foregroundMeta); }, foregroundMeta);
foregroundMeta.setFeature(foreground.getClass().getSimpleName()); foregroundMeta.setFeature(foreground.getClass().getSimpleName());
meta.registerFeature("foreground", foregroundMeta); meta.registerFeature("foreground", foregroundMeta);
overlay(imageFG, bufFG, image); overlay(imageFG, bufFG, image);
foregroundInterpolator.render(image, rng, t, (p) -> { foregroundInterpolator.render(image, rng, t, (p) -> {
if (cl.flip()) { if (cl.flip()) {
writing.put("#" + id + ":" + t, Form.pc(0.75 + (p / 4d)) + " [" + interpolator.getClass().getSimpleName() + " " + Form.pc(p) + "]"); writing.put("#" + id + ":" + t, Form.pc(0.75 + (p / 4d)) + " [" + interpolator.getClass().getSimpleName() + " " + Form.pc(p) + "]");
} }
}, foregroundInterpolatorMeta); }, foregroundInterpolatorMeta);
foregroundInterpolatorMeta.setFeature(foregroundInterpolator.getClass().getSimpleName()); foregroundInterpolatorMeta.setFeature(foregroundInterpolator.getClass().getSimpleName());
meta.registerFeature("foregroundInterpolator", foregroundInterpolatorMeta); meta.registerFeature("foregroundInterpolator", foregroundInterpolatorMeta);
overlay(imageFG, bufFG, image); overlay(imageFG, bufFG, image);
meta.setImage(buf); meta.setImage(buf);
writing.remove("#" + id + ":" + t); writing.remove("#" + id + ":" + t);
return meta; return meta;
} }
private void overlay(UImage layer, BufferedImage layerBuf, UImage onto) { private void overlay(UImage layer, BufferedImage layerBuf, UImage onto) {
for (int i = 0; i < onto.getWidth(); i++) { for (int i = 0; i < onto.getWidth(); i++) {
for (int j = 0; j < onto.getHeight(); j++) { for (int j = 0; j < onto.getHeight(); j++) {
if (layerBuf.getRGB(i, j) != 0) { if (layerBuf.getRGB(i, j) != 0) {
onto.set(i, j, layer.get(i, j)); onto.set(i, j, layer.get(i, j));
} }
} }
} }
} }
private String drawProgress(double progress, int len) { private String drawProgress(double progress, int len) {
int max = len; int max = len;
int in = (int) Math.round(progress * max); int in = (int) Math.round(progress * max);
max -= in; max -= in;
return "[" + Form.repeat("=", in) + Form.repeat(" ", max) + "]"; return "[" + Form.repeat("=", in) + Form.repeat(" ", max) + "]";
} }
private void computeNoiseStyles(double time, double scope) { private void computeNoiseStyles(double time, double scope) {
List<NoiseStyle> allowedStyles = new KList<>(NoiseStyle.values()); List<NoiseStyle> allowedStyles = new KList<>(NoiseStyle.values());
allowedStyles.remove(NoiseStyle.FLAT); allowedStyles.remove(NoiseStyle.FLAT);
KMap<NoiseStyle, Integer> speeds = new KMap<>(); KMap<NoiseStyle, Integer> speeds = new KMap<>();
double allocateMS = time; double allocateMS = time;
double maxTestDuration = allocateMS / allowedStyles.size(); double maxTestDuration = allocateMS / allowedStyles.size();
System.out.println("Running Noise Style Benchmark for " + Form.duration(allocateMS, 0) + "."); System.out.println("Running Noise Style Benchmark for " + Form.duration(allocateMS, 0) + ".");
System.out.println("Benchmarking " + allowedStyles.size() + " + Noise Styles for " + Form.duration(maxTestDuration, 1) + " each."); System.out.println("Benchmarking " + allowedStyles.size() + " + Noise Styles for " + Form.duration(maxTestDuration, 1) + " each.");
System.out.println(); System.out.println();
for (NoiseStyle i : allowedStyles) { for (NoiseStyle i : allowedStyles) {
int score = 0; int score = 0;
CNG cng = i.create(new RNG("renderspeedtest")); CNG cng = i.create(new RNG("renderspeedtest"));
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
double g = 0; double g = 0;
while (p.getMilliseconds() < maxTestDuration) { while (p.getMilliseconds() < maxTestDuration) {
cng.noise(g, -g * 2); cng.noise(g, -g * 2);
g += 0.1; g += 0.1;
g *= 1.25; g *= 1.25;
score++; score++;
} }
speeds.put(i, score); speeds.put(i, score);
} }
for (NoiseStyle i : speeds.sortKNumber()) { for (NoiseStyle i : speeds.sortKNumber()) {
System.out.println(Form.capitalizeWords(i.name().toLowerCase(Locale.ROOT).replaceAll("\\Q_\\E", " ")) + " => " + Form.f(speeds.get(i))); System.out.println(Form.capitalizeWords(i.name().toLowerCase(Locale.ROOT).replaceAll("\\Q_\\E", " ")) + " => " + Form.f(speeds.get(i)));
} }
System.out.println(); System.out.println();
int takeUpTo = (int) Math.max(1, scope * speeds.size()); int takeUpTo = (int) Math.max(1, scope * speeds.size());
System.out.println("Choosing the fastest " + Form.pc(scope) + " styles (" + takeUpTo + ")"); System.out.println("Choosing the fastest " + Form.pc(scope) + " styles (" + takeUpTo + ")");
for (NoiseStyle i : speeds.sortKNumber().reverse()) { for (NoiseStyle i : speeds.sortKNumber().reverse()) {
if (takeUpTo-- <= 0) { if (takeUpTo-- <= 0) {
break; break;
} }
sortedStyles.add(i); sortedStyles.add(i);
System.out.println("- " + Form.capitalizeWords(i.name().toLowerCase(Locale.ROOT).replaceAll("\\Q_\\E", " "))); System.out.println("- " + Form.capitalizeWords(i.name().toLowerCase(Locale.ROOT).replaceAll("\\Q_\\E", " ")));
} }
} }
private void computeInterpolationMethods(double time, double scope) { private void computeInterpolationMethods(double time, double scope) {
List<InterpolationMethod> allowedStyles = new KList<>(InterpolationMethod.values()); List<InterpolationMethod> allowedStyles = new KList<>(InterpolationMethod.values());
allowedStyles.remove(InterpolationMethod.NONE); allowedStyles.remove(InterpolationMethod.NONE);
KMap<InterpolationMethod, Integer> speeds = new KMap<>(); KMap<InterpolationMethod, Integer> speeds = new KMap<>();
double allocateMS = time; double allocateMS = time;
double maxTestDuration = allocateMS / allowedStyles.size(); double maxTestDuration = allocateMS / allowedStyles.size();
System.out.println("Running Interpolation Method Benchmark for " + Form.duration(allocateMS, 0) + "."); System.out.println("Running Interpolation Method Benchmark for " + Form.duration(allocateMS, 0) + ".");
System.out.println("Benchmarking " + allowedStyles.size() + " + Interpolation Methods for " + Form.duration(maxTestDuration, 1) + " each."); System.out.println("Benchmarking " + allowedStyles.size() + " + Interpolation Methods for " + Form.duration(maxTestDuration, 1) + " each.");
System.out.println(); System.out.println();
RNG r = new RNG("renderspeedtestinterpolation"); RNG r = new RNG("renderspeedtestinterpolation");
CNG cng = NoiseStyle.SIMPLEX.create(r); CNG cng = NoiseStyle.SIMPLEX.create(r);
NoiseProvider np = (x, z) -> cng.noise(x, z); NoiseProvider np = (x, z) -> cng.noise(x, z);
for (InterpolationMethod i : allowedStyles) { for (InterpolationMethod i : allowedStyles) {
int score = 0; int score = 0;
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
double g = 0; double g = 0;
while (p.getMilliseconds() < maxTestDuration) { while (p.getMilliseconds() < maxTestDuration) {
IrisInterpolation.getNoise(i, (int) g, (int) (-g * 2.225), r.d(4, 64), np); IrisInterpolation.getNoise(i, (int) g, (int) (-g * 2.225), r.d(4, 64), np);
cng.noise(g, -g * 2); cng.noise(g, -g * 2);
g += 1.1; g += 1.1;
g *= 1.25; g *= 1.25;
score++; score++;
} }
speeds.put(i, score); speeds.put(i, score);
} }
for (InterpolationMethod i : speeds.sortKNumber()) { for (InterpolationMethod i : speeds.sortKNumber()) {
System.out.println(Form.capitalizeWords(i.name().toLowerCase(Locale.ROOT).replaceAll("\\Q_\\E", " ")) + " => " + Form.f(speeds.get(i))); System.out.println(Form.capitalizeWords(i.name().toLowerCase(Locale.ROOT).replaceAll("\\Q_\\E", " ")) + " => " + Form.f(speeds.get(i)));
} }
System.out.println(); System.out.println();
int takeUpTo = (int) Math.max(1, scope * speeds.size()); int takeUpTo = (int) Math.max(1, scope * speeds.size());
System.out.println("Choosing the fastest " + Form.pc(scope) + " interpolators (" + takeUpTo + ")"); System.out.println("Choosing the fastest " + Form.pc(scope) + " interpolators (" + takeUpTo + ")");
for (InterpolationMethod i : speeds.sortKNumber().reverse()) { for (InterpolationMethod i : speeds.sortKNumber().reverse()) {
if (takeUpTo-- <= 0) { if (takeUpTo-- <= 0) {
break; break;
} }
sortedInterpolators.add(i); sortedInterpolators.add(i);
System.out.println("- " + Form.capitalizeWords(i.name().toLowerCase(Locale.ROOT).replaceAll("\\Q_\\E", " "))); System.out.println("- " + Form.capitalizeWords(i.name().toLowerCase(Locale.ROOT).replaceAll("\\Q_\\E", " ")));
} }
} }
public void writeCollectionFrames(File folder, int fromId, int toId) { public void writeCollectionFrames(File folder, int fromId, int toId) {
folder.mkdirs(); folder.mkdirs();
BurstExecutor burst = new BurstExecutor(executor, Math.min(toId - fromId, 1000)); BurstExecutor burst = new BurstExecutor(executor, Math.min(toId - fromId, 1000));
burst.setMulticore(true); burst.setMulticore(true);
AtomicInteger ai = new AtomicInteger(0); AtomicInteger ai = new AtomicInteger(0);
int max = toId - fromId; int max = toId - fromId;
for (int i = fromId; i <= toId; i++) { for (int i = fromId; i <= toId; i++) {
int ii = i; int ii = i;
burst.queue(() -> { burst.queue(() -> {
writing.put("!#[" + fromId + "-" + toId + "] Collection", ai.get() + " of " + max + " (" + Form.pc(ai.get() / (double) max, 0) + ")"); writing.put("!#[" + fromId + "-" + toId + "] Collection", ai.get() + " of " + max + " (" + Form.pc(ai.get() / (double) max, 0) + ")");
writeFrame(new File(folder, ii + ".png"), ii, 0); writeFrame(new File(folder, ii + ".png"), ii, 0);
ai.incrementAndGet(); ai.incrementAndGet();
writing.put("!#[" + fromId + "-" + toId + "] Collection", ai.get() + " of " + max + " (" + Form.pc(ai.get() / (double) max, 0) + ")"); writing.put("!#[" + fromId + "-" + toId + "] Collection", ai.get() + " of " + max + " (" + Form.pc(ai.get() / (double) max, 0) + ")");
}); });
} }
burst.complete(); burst.complete();
writing.remove("!#[" + fromId + "-" + toId + "] Collection"); writing.remove("!#[" + fromId + "-" + toId + "] Collection");
} }
public void writeFrame(File destination, long id, double t) { public void writeFrame(File destination, long id, double t) {
try { try {
renderFrameBuffer(id, t).export(destination); renderFrameBuffer(id, t).export(destination);
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public void report(String s) { public void report(String s) {
System.out.println(s); System.out.println(s);
} }
public KList<NoiseStyle> getStyles() { public KList<NoiseStyle> getStyles() {
return sortedStyles; return sortedStyles;
} }
public List<InterpolationMethod> getInterpolators() { public List<InterpolationMethod> getInterpolators() {
return sortedInterpolators; return sortedInterpolators;
} }
} }