diff --git a/build.gradle b/build.gradle index 5a553b278..15dfc3e19 100644 --- a/build.gradle +++ b/build.gradle @@ -12,19 +12,9 @@ jar { } } -allprojects { +allprojects +{ apply plugin: 'java' - apply plugin: 'io.freefair.lombok' - - configurations { - testImplementation.extendsFrom annotationProcessor - } - - java { - toolchain { - languageVersion = JavaLanguageVersion.of(17) - } - } repositories { maven { url "https://dl.cloudsmith.io/public/arcane/archive/maven/" } @@ -42,26 +32,6 @@ allprojects { testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' } - - if (JavaVersion.current() != JavaVersion.VERSION_1_8 && - sourceSets.main.allJava.files.any { it.name == "module-info.java" }) { - tasks.withType(JavaCompile) { - options.compilerArgs += ['-Xplugin:Manifold', '--module-path', it.classpath.asPath] - } - } else { - tasks.withType(JavaCompile) { - options.compilerArgs += ['-Xplugin:Manifold'] - } - } -} - -subprojects { - apply plugin: 'java' - apply plugin: 'io.freefair.lombok' - - dependencies { - implementation rootProject - } } dependencies { diff --git a/bukkit/build.gradle b/bukkit/build.gradle index 82ac5569e..a3f54488d 100644 --- a/bukkit/build.gradle +++ b/bukkit/build.gradle @@ -1,11 +1,285 @@ plugins { id 'java' + id "io.freefair.lombok" version "6.3.0" + id "com.github.johnrengelman.shadow" version "7.1.2" + id "de.undercouch.download" version "5.0.1" } group rootProject.group version rootProject.version +def nmsVersion = "1.19" +def apiVersion = '1.19' +def spigotJarVersion = '1.19-R0.1-SNAPSHOT' +def name = getRootProject().getName() // Defined in settings.gradle +def main = 'com.volmit.iris.platform.bukkit.IrisBukkit' + +// ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED +// ======================== WINDOWS ============================= +registerCustomOutputTask('Cyberpwn', 'C://Users/cyberpwn/Documents/development/server/plugins') +registerCustomOutputTask('Psycho', 'D://Dan/MinecraftDevelopment/server/plugins') +registerCustomOutputTask('ArcaneArts', 'C://Users/arcane/Documents/development/server/plugins') +registerCustomOutputTask('Coco', 'D://Documents/MC/plugins') +registerCustomOutputTask('Strange', 'D://Servers/1.17 Test Server/plugins') +registerCustomOutputTask('Vatuu', 'D://Minecraft/Servers/1.19/plugins') +// ========================== UNIX ============================== +registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/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. + */ +file(jar.archiveFile.get().getAsFile().getParentFile().getParentFile().getParentFile().getAbsolutePath() + '/build/resources/main/plugin.yml').delete() + +/** + * Expand properties into plugin yml + */ +processResources { + filesMatching('**/plugin.yml') { + expand( + 'name': name.toString(), + 'version': version.toString(), + 'main': main.toString(), + 'apiversion': apiVersion.toString() + ) + } +} + +/** + * We need parameter meta for the decree command system + */ +compileJava { + options.compilerArgs << '-parameters' +} + +/** + * Configure Iris for shading + */ +shadowJar { + //minimize() + append("plugin.yml") + relocate 'com.volmit.fukkit', 'com.volmit.iris.util.fukkit' + relocate 'art.arcane.amulet', 'com.volmit.iris.util.amulet' + relocate 'art.arcane.source', 'com.volmit.iris.util.source' + dependencies { + include(dependency('art.arcane.source:Source')) + include(dependency('art.arcane:Amulet')) + include(dependency('com.volmit:Fukkit')) + include(dependency('systems.manifold:')) + include(dependency(":engine")) + } +} + +/** + * Faster dependency caches + */ +configurations.all { + resolutionStrategy.cacheChangingModulesFor 60, 'minutes' + resolutionStrategy.cacheDynamicVersionsFor 60, 'minutes' +} + +configurations { + testImplementation.extendsFrom annotationProcessor +} + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(17) + } +} + +repositories { + maven { url "https://dl.cloudsmith.io/public/arcane/archive/maven/" } + mavenCentral() +} + dependencies { implementation 'org.spigotmc:spigot-api:1.19-R0.1-SNAPSHOT' implementation 'com.volmit:Fukkit:22.6.13' + implementation project(":engine") } + +if (JavaVersion.current() != JavaVersion.VERSION_1_8 && + sourceSets.main.allJava.files.any { it.name == "module-info.java" }) { + tasks.withType(JavaCompile) { + options.compilerArgs += ['-Xplugin:Manifold', '--module-path', it.classpath.asPath] + } +} else { + tasks.withType(JavaCompile) { + options.compilerArgs += ['-Xplugin:Manifold'] + } +} + +if (JavaVersion.current().toString() != "17") { + System.err.println() + System.err.println("=========================================================================================================") + System.err.println("You must run gradle on Java 17. You are using " + JavaVersion.current()) + System.err.println() + System.err.println("=== For IDEs ===") + 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() + 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("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("=========================================================================================================") + System.err.println() + System.exit(69); +} + + +System.out.println(buildDir); +def buildToolsJar = new File(buildDir, "buildtools/BuildTools.jar"); +def specialSourceJar = new File(buildDir, "specialsource/SpecialSource.jar"); +def buildToolsFolder = new File(buildDir, "buildtools"); +def specialSourceFolder = new File(buildDir, "specialsource"); +def buildToolsHint = new File(buildDir, "buildtools/craftbukkit-" + nmsVersion + ".jar"); +def outputShadeJar = new File(buildDir, "libs/bukkit-" + version + "-all.jar"); +def ssiJar = new File(buildDir, "specialsource/bukkit-" + version + "-all.jar"); +def ssobfJar = new File(buildDir, "specialsource/Iris-" + version + "-rmo.jar"); +def ssJar = new File(buildDir, "specialsource/Iris-" + version + "-rma.jar"); +def homePath = System.properties['user.home'] +def m2 = new File(homePath + "/.m2/repository") +def m2s = m2.getAbsolutePath(); + +// ======================== Building Mapped Jars ============================= +task downloadBuildtools(type: Download) { + group "remapping" + src 'https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar' + dest buildToolsJar + onlyIf { + !buildToolsJar.exists() + } +} + +task downloadSpecialSource(type: Download) { + group "remapping" + src 'https://repo.maven.apache.org/maven2/net/md-5/SpecialSource/1.10.0/SpecialSource-1.10.0-shaded.jar' + dest specialSourceJar + onlyIf { + !specialSourceJar.exists() + } +} + +task executeBuildTools(dependsOn: downloadBuildtools, type: JavaExec) +{ + group "remapping" + classpath = files(buildToolsJar) + workingDir = buildToolsFolder + args = [ + "--rev", + nmsVersion, + "--compile", + "craftbukkit", + "--remap" + ] + onlyIf { + !buildToolsHint.exists() + } +} + +task copyBuildToSpecialSource(type: Copy) +{ + group "remapping" + from outputShadeJar + into specialSourceFolder + dependsOn(downloadSpecialSource, shadowJar) +} + +task specialSourceRemapObfuscate(type: JavaExec) +{ + group "remapping" + dependsOn(copyBuildToSpecialSource, downloadSpecialSource, shadowJar) + workingDir = specialSourceFolder + classpath = files(specialSourceJar, + new File(m2s + "/org/spigotmc/spigot/" + spigotJarVersion + "/spigot-" + spigotJarVersion + "-remapped-mojang.jar")) + mainClass = "net.md_5.specialsource.SpecialSource" + args = [ + "--live", + "-i", + ssiJar.getName(), + "-o", + ssobfJar.getName(), + "-m", + m2s + "/org/spigotmc/minecraft-server/" + spigotJarVersion + "/minecraft-server-" + spigotJarVersion + "-maps-mojang.txt", + "--reverse", + ] +} + +task specialSourceRemap(type: JavaExec) +{ + group "remapping" + dependsOn(specialSourceRemapObfuscate) + workingDir = specialSourceFolder + classpath = files(specialSourceJar, + new File(m2s + "/org/spigotmc/spigot/" + spigotJarVersion + "/spigot-" + spigotJarVersion + "-remapped-obf.jar")) + mainClass = "net.md_5.specialsource.SpecialSource" + args = [ + "--live", + "-i", + ssobfJar.getName(), + "-o", + ssJar.getName(), + "-m", + m2s + "/org/spigotmc/minecraft-server/" + spigotJarVersion + "/minecraft-server-" + spigotJarVersion + "-maps-spigot.csrg" + ] +} + +tasks.compileJava.dependsOn(executeBuildTools) + +compileJava { + options.encoding = "UTF-8" +} + +task setup() +{ + group("iris") + dependsOn(clean, executeBuildTools) +} + +task iris(type: Copy) +{ + group "iris" + from ssJar + into buildDir + rename { String fileName -> + fileName.replace('Iris-' + version + '-rma.jar', "Iris-" + version + ".jar") + } + dependsOn(specialSourceRemap) +} + +def registerCustomOutputTask(name, path) { + if (!System.properties['os.name'].toLowerCase().contains('windows')) { + return; + } + + tasks.register('build' + name, Copy) { + group('development') + outputs.upToDateWhen { false } + dependsOn(iris) + from(new File(buildDir, "Iris-" + version + ".jar")) + into(file(path)) + rename { String fileName -> + fileName.replace("Iris-" + version + ".jar", "Iris.jar") + } + } +} + +def registerCustomOutputTaskUnix(name, path) { + if (System.properties['os.name'].toLowerCase().contains('windows')) { + return; + } + + tasks.register('build' + name, Copy) { + group('development') + outputs.upToDateWhen { false } + dependsOn(iris) + from(new File(buildDir, "Iris-" + version + ".jar")) + into(file(path)) + rename { String fileName -> + fileName.replace("Iris-" + version + ".jar", "Iris.jar") + } + } +} \ No newline at end of file diff --git a/bukkit/src/main/java/com/volmit/iris/platform/bukkit/IrisBukkit.java b/bukkit/src/main/java/com/volmit/iris/platform/bukkit/IrisBukkit.java index 6e4223716..b6a9e0bf4 100644 --- a/bukkit/src/main/java/com/volmit/iris/platform/bukkit/IrisBukkit.java +++ b/bukkit/src/main/java/com/volmit/iris/platform/bukkit/IrisBukkit.java @@ -1,27 +1,39 @@ package com.volmit.iris.platform.bukkit; +import com.volmit.iris.engine.EngineConfiguration; import com.volmit.iris.platform.IrisPlatform; import com.volmit.iris.platform.PlatformBiome; import com.volmit.iris.platform.PlatformBlock; +import com.volmit.iris.platform.PlatformNamespaceKey; import com.volmit.iris.platform.PlatformWorld; +import com.volmit.iris.platform.bukkit.wrapper.BukkitKey; import lombok.Data; import lombok.EqualsAndHashCode; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.WorldCreator; import org.bukkit.block.Biome; +import org.bukkit.generator.ChunkGenerator; import org.bukkit.plugin.java.JavaPlugin; import java.util.Arrays; +import java.util.UUID; import java.util.stream.Stream; -@Data -@EqualsAndHashCode(callSuper = false) public class IrisBukkit extends JavaPlugin implements IrisPlatform { private static IrisBukkit instance; public void onEnable() { instance = this; + + getServer().getScheduler().scheduleSyncDelayedTask(this, () -> { + World world = Bukkit.createWorld(new WorldCreator("iristests/" + UUID.randomUUID()).generator(new IrisBukkitChunkGenerator(this, EngineConfiguration.builder() + .threads(4) + .mutable(true) + .timings(true) + .build()))); + }, 10); } public void onDisable() { @@ -41,7 +53,9 @@ public class IrisBukkit extends JavaPlugin implements IrisPlatform { public Stream getBlocks() { //This is because it's a method extension //noinspection Convert2MethodRef - return Arrays.stream(Material.values()).parallel().filter(Material::isBlock).map(Material::createBlockData).map(i -> i.bukkitBlock()); + return Arrays.stream(Material.values()).parallel().filter((i) -> !i.isLegacy()) + .filter(Material::isBlock) + .map(Material::createBlockData).map(i -> i.bukkitBlock()); } @Override @@ -67,4 +81,23 @@ public class IrisBukkit extends JavaPlugin implements IrisPlatform { return w.bukkitWorld(); } + + @Override + public PlatformBlock parseBlock(String raw) { + return Bukkit.createBlockData(raw).bukkitBlock(); + } + + @Override + public PlatformNamespaceKey key(String namespace, String key) { + return BukkitKey.of(namespace, key); + } + + @Override + public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) { + return new IrisBukkitChunkGenerator(this, EngineConfiguration.builder() + .threads(4) + .mutable(true) + .timings(true) + .build()); + } } diff --git a/bukkit/src/main/java/com/volmit/iris/platform/bukkit/IrisBukkitChunkGenerator.java b/bukkit/src/main/java/com/volmit/iris/platform/bukkit/IrisBukkitChunkGenerator.java new file mode 100644 index 000000000..29f973af1 --- /dev/null +++ b/bukkit/src/main/java/com/volmit/iris/platform/bukkit/IrisBukkitChunkGenerator.java @@ -0,0 +1,90 @@ +package com.volmit.iris.platform.bukkit; + +import art.arcane.amulet.collections.hunk.Hunk; +import art.arcane.amulet.metric.Average; +import art.arcane.amulet.metric.PrecisionStopwatch; +import com.volmit.iris.engine.EngineConfiguration; +import com.volmit.iris.engine.IrisEngine; +import com.volmit.iris.engine.feature.IrisFeatureSizedTarget; +import com.volmit.iris.engine.feature.IrisFeatureTarget; +import com.volmit.iris.engine.feature.standard.FeatureTerrain; +import com.volmit.iris.platform.IrisPlatform; +import com.volmit.iris.platform.PlatformBlock; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.generator.ChunkGenerator; +import com.volmit.iris.platform.bukkit.util.ChunkDataHunkView; +import org.bukkit.generator.WorldInfo; + +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.locks.ReentrantLock; + +public class IrisBukkitChunkGenerator extends ChunkGenerator { + private final IrisPlatform platform; + private final EngineConfiguration configuration; + private final AtomicReference engine; + private final ReentrantLock engineLock; + private final AtomicInteger perSecond; + private final PrecisionStopwatch p = PrecisionStopwatch.start(); + private final Average a = new Average(128); + + public IrisBukkitChunkGenerator(IrisPlatform platform, EngineConfiguration configuration) + { + this.perSecond = new AtomicInteger(0); + this.platform = platform; + this.configuration = configuration; + engine = new AtomicReference<>(); + engineLock = new ReentrantLock(); + } + + @Override + public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome) { + PrecisionStopwatch pp = PrecisionStopwatch.start(); + initEngine(world); + ChunkData data = Bukkit.createChunkData(world); + Hunk chunk = new ChunkDataHunkView(data); + IrisFeatureSizedTarget targetSize = IrisFeatureSizedTarget.builder() + .width(chunk.getWidth()) + .height(chunk.getHeight()) + .depth(chunk.getDepth()) + .offsetX(x << 4) + .offsetZ(z << 4) + .offsetY(0) + .build(); + FeatureTerrain.TerrainFeatureState state = engine.get().getTerrainFeature().prepare(engine.get(), targetSize); + engine.get().getTerrainFeature().generate(engine.get(), state, new IrisFeatureTarget<>(chunk, targetSize)); + perSecond.incrementAndGet(); + a.put(pp.getMilliseconds()); + + if(p.getMilliseconds() > 1000) + { + p.reset(); + p.begin(); + System.out.println("PERSECOND: " + perSecond.getAndSet(0) + " AMS: " + ((int)Math.round(a.getAverage())) + "ms"); + } + + return data; + } + + private void initEngine(World world) { + if(engine.get() == null) + { + engineLock.lock(); + + if(engine.get() == null) + { + engine.set(new IrisEngine(platform, world.bukkitWorld(), configuration)); + } + + engineLock.unlock(); + } + } + + @Override + public boolean canSpawn(World world, int x, int z) { + return false; + } +} diff --git a/bukkit/src/main/java/com/volmit/iris/platform/bukkit/util/ChunkDataHunkView.java b/bukkit/src/main/java/com/volmit/iris/platform/bukkit/util/ChunkDataHunkView.java new file mode 100644 index 000000000..525c45f66 --- /dev/null +++ b/bukkit/src/main/java/com/volmit/iris/platform/bukkit/util/ChunkDataHunkView.java @@ -0,0 +1,53 @@ +package com.volmit.iris.platform.bukkit.util; + +import art.arcane.amulet.collections.hunk.Hunk; +import com.volmit.iris.platform.PlatformBlock; +import com.volmit.iris.platform.bukkit.wrapper.BukkitBlock; +import org.bukkit.generator.ChunkGenerator; + +@SuppressWarnings("ClassCanBeRecord") +public class ChunkDataHunkView implements Hunk { + private final ChunkGenerator.ChunkData chunk; + + public ChunkDataHunkView(ChunkGenerator.ChunkData chunk) { + this.chunk = chunk; + } + + @Override + public int getWidth() { + return 16; + } + + @Override + public int getDepth() { + return 16; + } + + @Override + public int getHeight() { + return chunk.getMaxHeight() - chunk.getMinHeight(); + } + + @Override + public void set(int x1, int y1, int z1, int x2, int y2, int z2, PlatformBlock t) { + if(t == null) { + return; + } + + chunk.setRegion(x1, y1 + chunk.getMinHeight(), z1, x2, y2 + chunk.getMinHeight(), z2, ((BukkitBlock)t).getDelegate()); + } + + @Override + public void setRaw(int x, int y, int z, PlatformBlock t) { + if(t == null) { + return; + } + + chunk.setBlock(x, y + chunk.getMinHeight(), z, ((BukkitBlock)t).getDelegate()); + } + + @Override + public PlatformBlock getRaw(int x, int y, int z) { + return chunk.getBlockData(x, y + chunk.getMinHeight(), z).bukkitBlock(); + } +} \ No newline at end of file diff --git a/bukkit/src/main/resources/plugin.yml b/bukkit/src/main/resources/plugin.yml new file mode 100644 index 000000000..ca10fb760 --- /dev/null +++ b/bukkit/src/main/resources/plugin.yml @@ -0,0 +1,3 @@ +name: Iris +main: com.volmit.iris.platform.bukkit.IrisBukkit +version: 1.0.0 \ No newline at end of file diff --git a/engine/build.gradle b/engine/build.gradle new file mode 100644 index 000000000..506295f2c --- /dev/null +++ b/engine/build.gradle @@ -0,0 +1,34 @@ +plugins { + id 'java' + id "io.freefair.lombok" version "6.3.0" +} + +group rootProject.group +version rootProject.version + +jar { + manifest { + attributes('Contains-Sources': 'java,class') + } +} + +configurations { + testImplementation.extendsFrom annotationProcessor +} + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(17) + } +} + +if (JavaVersion.current() != JavaVersion.VERSION_1_8 && + sourceSets.main.allJava.files.any { it.name == "module-info.java" }) { + tasks.withType(JavaCompile) { + options.compilerArgs += ['-Xplugin:Manifold', '--module-path', it.classpath.asPath] + } +} else { + tasks.withType(JavaCompile) { + options.compilerArgs += ['-Xplugin:Manifold'] + } +} diff --git a/engine/src/main/java/com/volmit/iris/engine/EngineBlockCache.java b/engine/src/main/java/com/volmit/iris/engine/EngineBlockCache.java new file mode 100644 index 000000000..b00519e13 --- /dev/null +++ b/engine/src/main/java/com/volmit/iris/engine/EngineBlockCache.java @@ -0,0 +1,23 @@ +package com.volmit.iris.engine; + +import com.volmit.iris.platform.PlatformBlock; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class EngineBlockCache +{ + private final IrisEngine engine; + private final Map cache; + + public EngineBlockCache(IrisEngine engine) + { + this.engine = engine; + this.cache = new ConcurrentHashMap<>(); + } + + public PlatformBlock get(String t) + { + return cache.computeIfAbsent(t, (key) -> engine.getPlatform().parseBlock(key)); + } +} diff --git a/src/main/java/com/volmit/iris/engine/EngineConfiguration.java b/engine/src/main/java/com/volmit/iris/engine/EngineConfiguration.java similarity index 89% rename from src/main/java/com/volmit/iris/engine/EngineConfiguration.java rename to engine/src/main/java/com/volmit/iris/engine/EngineConfiguration.java index 60a499d61..17808ed7e 100644 --- a/src/main/java/com/volmit/iris/engine/EngineConfiguration.java +++ b/engine/src/main/java/com/volmit/iris/engine/EngineConfiguration.java @@ -1,5 +1,6 @@ package com.volmit.iris.engine; +import com.volmit.iris.platform.PlatformWorld; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/src/main/java/com/volmit/iris/engine/EngineRegistry.java b/engine/src/main/java/com/volmit/iris/engine/EngineRegistry.java similarity index 100% rename from src/main/java/com/volmit/iris/engine/EngineRegistry.java rename to engine/src/main/java/com/volmit/iris/engine/EngineRegistry.java diff --git a/engine/src/main/java/com/volmit/iris/engine/IrisEngine.java b/engine/src/main/java/com/volmit/iris/engine/IrisEngine.java new file mode 100644 index 000000000..c6b5ccace --- /dev/null +++ b/engine/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -0,0 +1,44 @@ +package com.volmit.iris.engine; + +import com.volmit.iris.engine.feature.IrisFeature; +import com.volmit.iris.engine.feature.standard.FeatureTerrain; +import com.volmit.iris.platform.IrisPlatform; +import com.volmit.iris.platform.PlatformBlock; +import com.volmit.iris.platform.PlatformNamespaceKey; +import com.volmit.iris.platform.PlatformRegistry; +import com.volmit.iris.platform.PlatformWorld; +import lombok.Data; + +@Data +public class IrisEngine { + private final IrisPlatform platform; + private final EngineRegistry registry; + private final EngineConfiguration configuration; + private final PlatformWorld world; + private final EngineBlockCache blockCache; + + private final FeatureTerrain terrainFeature; + + public IrisEngine(IrisPlatform platform, PlatformWorld world, EngineConfiguration configuration) { + this.configuration = configuration; + this.platform = platform; + this.world = world; + this.blockCache = new EngineBlockCache(this); + this.registry = EngineRegistry.builder() + .blockRegistry(new PlatformRegistry<>(platform.getBlocks())) + .biomeRegistry(new PlatformRegistry<>(platform.getBiomes())) + .build(); + + terrainFeature = new FeatureTerrain(this); + } + + public PlatformBlock block(String block) + { + return blockCache.get(block); + } + + public PlatformNamespaceKey key(String nsk) + { + return getPlatform().key(nsk); + } +} diff --git a/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeature.java b/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeature.java new file mode 100644 index 000000000..aaf1854dc --- /dev/null +++ b/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeature.java @@ -0,0 +1,19 @@ +package com.volmit.iris.engine.feature; + +import com.volmit.iris.engine.IrisEngine; +import com.volmit.iris.platform.PlatformNamespaced; +import lombok.Data; + +@Data +public abstract class IrisFeature { + private final String name; + + public IrisFeature(String name, IrisEngine engine) + { + this.name = name; + } + + public abstract S prepare(IrisEngine engine, IrisFeatureSizedTarget target); + + public abstract void generate(IrisEngine engine, S state, IrisFeatureTarget target); +} diff --git a/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureSizedTarget.java b/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureSizedTarget.java new file mode 100644 index 000000000..88956640b --- /dev/null +++ b/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureSizedTarget.java @@ -0,0 +1,74 @@ +package com.volmit.iris.engine.feature; + +import art.arcane.amulet.collections.hunk.Hunk; +import art.arcane.amulet.geometry.Vec; +import art.arcane.amulet.range.IntegerRange; +import com.volmit.iris.platform.PlatformNamespaced; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Data +public class IrisFeatureSizedTarget { + @Builder.Default + private final int width = 16; + @Builder.Default + private final int height = 0; + @Builder.Default + private final int depth = 16; + @Builder.Default + private final int offsetX = 0; + @Builder.Default + private final int offsetY = 0; + @Builder.Default + private final int offsetZ = 0; + + public int getAbsoluteMaxX() + { + return getOffsetX() + getWidth() - 1; + } + + public int getAbsoluteMaxY() + { + return getOffsetY() + getHeight() - 1; + } + + public int getAbsoluteMaxZ() + { + return getOffsetZ() + getDepth() - 1; + } + + public IntegerRange x() + { + return new IntegerRange(getOffsetX(), getAbsoluteMaxX()); + } + + public IntegerRange y() + { + return new IntegerRange(getOffsetY(), getAbsoluteMaxY()); + } + + public IntegerRange z() + { + return new IntegerRange(getOffsetZ(), getAbsoluteMaxZ()); + } + + public IntegerRange localX() + { + return new IntegerRange(0, getWidth() - 1); + } + + public IntegerRange localY() + { + return new IntegerRange(0, getHeight() - 1); + } + + public IntegerRange localZ() + { + return new IntegerRange(0, getDepth() - 1); + } +} diff --git a/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureState.java b/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureState.java new file mode 100644 index 000000000..71258b89e --- /dev/null +++ b/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureState.java @@ -0,0 +1,5 @@ +package com.volmit.iris.engine.feature; + +public interface IrisFeatureState { + +} diff --git a/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureTarget.java b/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureTarget.java new file mode 100644 index 000000000..ff6564fd9 --- /dev/null +++ b/engine/src/main/java/com/volmit/iris/engine/feature/IrisFeatureTarget.java @@ -0,0 +1,25 @@ +package com.volmit.iris.engine.feature; + +import art.arcane.amulet.collections.hunk.Hunk; +import com.volmit.iris.platform.PlatformNamespaced; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class IrisFeatureTarget extends IrisFeatureSizedTarget { + private final Hunk hunk; + + public IrisFeatureTarget(Hunk hunk, int offsetX, int offsetY, int offsetZ) + { + super(hunk.getWidth(), hunk.getHeight(), hunk.getDepth(), offsetX, offsetY, offsetZ); + this.hunk = hunk; + } + + public IrisFeatureTarget(Hunk hunk, IrisFeatureSizedTarget target) + { + this(hunk, target.getOffsetX(), target.getOffsetY(), target.getOffsetZ()); + } +} diff --git a/engine/src/main/java/com/volmit/iris/engine/feature/standard/FeatureTerrain.java b/engine/src/main/java/com/volmit/iris/engine/feature/standard/FeatureTerrain.java new file mode 100644 index 000000000..2d10617a0 --- /dev/null +++ b/engine/src/main/java/com/volmit/iris/engine/feature/standard/FeatureTerrain.java @@ -0,0 +1,68 @@ +package com.volmit.iris.engine.feature.standard; + +import art.arcane.amulet.range.IntegerRange; +import art.arcane.source.api.noise.Generator; +import art.arcane.source.api.noise.provider.SimplexProvider; +import com.volmit.iris.engine.IrisEngine; +import com.volmit.iris.engine.feature.IrisFeature; +import com.volmit.iris.engine.feature.IrisFeatureSizedTarget; +import com.volmit.iris.engine.feature.IrisFeatureState; +import com.volmit.iris.engine.feature.IrisFeatureTarget; +import com.volmit.iris.platform.PlatformBlock; +import com.volmit.iris.util.ShortNoiseCache; +import lombok.AllArgsConstructor; +import lombok.Data; + +public class FeatureTerrain extends IrisFeature +{ + private final PlatformBlock stone; + private final Generator generator; + + public FeatureTerrain(IrisEngine engine) + { + super("terrain", engine); + stone = engine.block("stone"); + this.generator = new Generator(new SimplexProvider(engine.getWorld().getSeed())) + .maxOutput(64) + .minOutput(0) + .scale(0.01); + } + + @Override + public TerrainFeatureState prepare(IrisEngine engine, IrisFeatureSizedTarget target) { + final ShortNoiseCache noise = new ShortNoiseCache(target.getWidth(), target.getDepth()); + int cx,cz; + + for(int x : target.x()) + { + cx = x - target.getOffsetX(); + + for(int z : target.z()) + { + cz = z - target.getOffsetZ(); + noise.set(cx, cz, (short) generator.noise(x, z)); + } + } + + return new TerrainFeatureState(noise); + } + + @Override + public void generate(IrisEngine engine, TerrainFeatureState state, IrisFeatureTarget target) { + for(int x : target.localX()) { + for(int z : target.localZ()) { + int h = state.getNoise().get(x, z); + for(int y : new IntegerRange(target.y().getLeftEndpoint(), Math.min(target.y().getRightEndpoint(), h))) + { + target.getHunk().set(x, y, z, stone); + } + } + } + } + + @Data + @AllArgsConstructor + public static class TerrainFeatureState implements IrisFeatureState { + private final ShortNoiseCache noise; + } +} diff --git a/src/main/java/com/volmit/iris/platform/IrisPlatform.java b/engine/src/main/java/com/volmit/iris/platform/IrisPlatform.java similarity index 59% rename from src/main/java/com/volmit/iris/platform/IrisPlatform.java rename to engine/src/main/java/com/volmit/iris/platform/IrisPlatform.java index b2223c0d0..dd87bf472 100644 --- a/src/main/java/com/volmit/iris/platform/IrisPlatform.java +++ b/engine/src/main/java/com/volmit/iris/platform/IrisPlatform.java @@ -12,4 +12,13 @@ public interface IrisPlatform { boolean isWorldLoaded(String name); PlatformWorld getWorld(String name); + + PlatformBlock parseBlock(String raw); + + PlatformNamespaceKey key(String namespace, String key); + + default PlatformNamespaceKey key(String nsk) + { + return key("minecraft", nsk); + } } diff --git a/src/main/java/com/volmit/iris/platform/PlatformBiome.java b/engine/src/main/java/com/volmit/iris/platform/PlatformBiome.java similarity index 100% rename from src/main/java/com/volmit/iris/platform/PlatformBiome.java rename to engine/src/main/java/com/volmit/iris/platform/PlatformBiome.java diff --git a/src/main/java/com/volmit/iris/platform/PlatformBlock.java b/engine/src/main/java/com/volmit/iris/platform/PlatformBlock.java similarity index 100% rename from src/main/java/com/volmit/iris/platform/PlatformBlock.java rename to engine/src/main/java/com/volmit/iris/platform/PlatformBlock.java diff --git a/src/main/java/com/volmit/iris/platform/PlatformChunk.java b/engine/src/main/java/com/volmit/iris/platform/PlatformChunk.java similarity index 100% rename from src/main/java/com/volmit/iris/platform/PlatformChunk.java rename to engine/src/main/java/com/volmit/iris/platform/PlatformChunk.java diff --git a/src/main/java/com/volmit/iris/platform/PlatformNamespaceKey.java b/engine/src/main/java/com/volmit/iris/platform/PlatformNamespaceKey.java similarity index 100% rename from src/main/java/com/volmit/iris/platform/PlatformNamespaceKey.java rename to engine/src/main/java/com/volmit/iris/platform/PlatformNamespaceKey.java diff --git a/src/main/java/com/volmit/iris/platform/PlatformNamespaced.java b/engine/src/main/java/com/volmit/iris/platform/PlatformNamespaced.java similarity index 100% rename from src/main/java/com/volmit/iris/platform/PlatformNamespaced.java rename to engine/src/main/java/com/volmit/iris/platform/PlatformNamespaced.java diff --git a/src/main/java/com/volmit/iris/platform/PlatformPlayer.java b/engine/src/main/java/com/volmit/iris/platform/PlatformPlayer.java similarity index 100% rename from src/main/java/com/volmit/iris/platform/PlatformPlayer.java rename to engine/src/main/java/com/volmit/iris/platform/PlatformPlayer.java diff --git a/src/main/java/com/volmit/iris/platform/PlatformRegistry.java b/engine/src/main/java/com/volmit/iris/platform/PlatformRegistry.java similarity index 100% rename from src/main/java/com/volmit/iris/platform/PlatformRegistry.java rename to engine/src/main/java/com/volmit/iris/platform/PlatformRegistry.java diff --git a/src/main/java/com/volmit/iris/platform/PlatformWorld.java b/engine/src/main/java/com/volmit/iris/platform/PlatformWorld.java similarity index 100% rename from src/main/java/com/volmit/iris/platform/PlatformWorld.java rename to engine/src/main/java/com/volmit/iris/platform/PlatformWorld.java diff --git a/engine/src/main/java/com/volmit/iris/util/FloatNoiseCache.java b/engine/src/main/java/com/volmit/iris/util/FloatNoiseCache.java new file mode 100644 index 000000000..2a74aeb2a --- /dev/null +++ b/engine/src/main/java/com/volmit/iris/util/FloatNoiseCache.java @@ -0,0 +1,22 @@ +package com.volmit.iris.util; + +public class FloatNoiseCache { + private final int width; + private final int height; + private final float[] cache; + + public FloatNoiseCache(int width, int height) + { + this.width = width; + this.height = height; + cache = new float[width * height]; + } + + public void set(int x, int y, float v) { + this.cache[y % this.height * this.width + x % this.width] = v; + } + + public float get(int x, int y) { + return this.cache[y % this.height * this.width + x % this.width]; + } +} diff --git a/engine/src/main/java/com/volmit/iris/util/ShortNoiseCache.java b/engine/src/main/java/com/volmit/iris/util/ShortNoiseCache.java new file mode 100644 index 000000000..d06e99b84 --- /dev/null +++ b/engine/src/main/java/com/volmit/iris/util/ShortNoiseCache.java @@ -0,0 +1,22 @@ +package com.volmit.iris.util; + +public class ShortNoiseCache { + private final int width; + private final int height; + private final short[] cache; + + public ShortNoiseCache(int width, int height) + { + this.width = width; + this.height = height; + cache = new short[width * height]; + } + + public void set(int x, int y, short v) { + this.cache[y % this.height * this.width + x % this.width] = v; + } + + public short get(int x, int y) { + return this.cache[y % this.height * this.width + x % this.width]; + } +} diff --git a/src/main/java/com/volmit/iris/util/WorldHeight.java b/engine/src/main/java/com/volmit/iris/util/WorldHeight.java similarity index 100% rename from src/main/java/com/volmit/iris/util/WorldHeight.java rename to engine/src/main/java/com/volmit/iris/util/WorldHeight.java diff --git a/settings.gradle b/settings.gradle index 2a265a2be..f561300f6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,14 @@ +pluginManagement { + repositories { + mavenLocal() + mavenCentral() + gradlePluginPortal() + maven { url "https://dl.cloudsmith.io/public/arcane/archive/maven/" } + } +} + rootProject.name = 'Iris' include 'bukkit' +include 'engine' +include 'engine' diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java deleted file mode 100644 index 1852d3d17..000000000 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.volmit.iris.engine; - -import com.volmit.iris.platform.IrisPlatform; -import com.volmit.iris.platform.PlatformRegistry; -import lombok.Data; - -@Data -public class IrisEngine { - private IrisPlatform platform; - private EngineRegistry registry; - private EngineConfiguration configuration; - - public IrisEngine(IrisPlatform platform, EngineConfiguration configuration) { - this.configuration = configuration; - this.platform = platform; - this.registry = EngineRegistry.builder() - .blockRegistry(new PlatformRegistry<>(platform.getBlocks())) - .biomeRegistry(new PlatformRegistry<>(platform.getBiomes())) - .build(); - } -}