plugins { id "java" // Plugin to handle dependencies id "com.github.johnrengelman.shadow" version '7.1.2' apply false // Plugin to create merged jars id "io.github.pacifistmc.forgix" version "1.2.6" // Manifold preprocessor id "systems.manifold.manifold-gradle-plugin" version "0.0.2-alpha" // Provides mc libraries to core // id "org.spongepowered.gradle.vanilla" version '0.2.1-SNAPSHOT' apply false } /** * Creates the list of preprocessors to use. * * @param mcVers array of all MC versions * @param mcIndex array index of the currently active MC version */ def writeBuildGradlePredefine(List mcVers, int mcIndex) { ArrayList redefineList = new ArrayList() for (int i = 0; i < mcVers.size(); i++) { String mcStr = mcVers[i].replace(".", "_") if (mcIndex < i) { redefineList.add("PRE_MC_" + mcStr) } if (mcIndex == i) { redefineList.add("MC_" + mcStr) } if (mcIndex >= i) { redefineList.add("POST_MC_" + mcStr) } } // Build the list of preprocessors to use StringBuilder sb = new StringBuilder() sb.append("# DON'T TOUCH THIS FILE, This is handled by the build script\n") // Check if this is a development build if (mod_version.toLowerCase().contains("dev")) { // WARNING: only use this for logging, we don't want to have confusion // when a method doesn't work correctly in the release build. sb.append("DEV_BUILD") sb.append("=\n") } // Build the MC version preprocessors for (String redefinedVersion : redefineList) { sb.append(redefinedVersion) sb.append("=\n") } new File(projectDir, "build.properties").text = sb.toString() } // Transfers the values set in settings.gradle to the rest of the project project.gradle.ext.getProperties().each { prop -> rootProject.ext.set(prop.key, prop.value) // println "Added prop [key:" + prop.key + ", value:" + prop.value + "]" } // Sets up manifold stuff writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex) // Sets up the version string (the name we use for our jar) rootProject.versionStr = rootProject.mod_version + "-" + rootProject.minecraft_version // + "-" + new Date().format("yyyy_MM_dd_HH_mm") // Forgix settings (used for merging jars) forgix { group = "com.seibel.lod" mergedJarName = "DistantHorizons-${rootProject.versionStr}.jar" forge { jarLocation = "build/libs/DistantHorizons-forge-${rootProject.versionStr}.jar" } fabric { jarLocation = "build/libs/DistantHorizons-fabric-${rootProject.versionStr}.jar" } removeDuplicate "com.seibel.lod.api" removeDuplicate "com.seibel.lod.core" } subprojects { p -> // Does the same as "p == project(":common") || p == project(":fabric") || p == project(":quilt") || p == project(":forge")" // Useful later on so we dont have duplicated code def isMinecraftSubProject = p != project(":core") && p != project(":api") // Apply plugins apply plugin: "java" if (isMinecraftSubProject) apply plugin: "systems.manifold.manifold-gradle-plugin" apply plugin: "com.github.johnrengelman.shadow" // apply plugin: "org.spongepowered.gradle.vanilla" // Provides minecraft libraries if (p == project(":core")) { apply plugin: "application" } // Set the manifold version (may not be required tough) manifold { manifoldVersion = rootProject.manifold_version } // set up custom configurations (configurations are a way to handle dependencies) configurations { // extends the shadowJar configuration shadowMe // have implemented dependencies automatically embedded in the final jar implementation.extendsFrom(shadowMe) if (isMinecraftSubProject) { // Shadow common common shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. compileClasspath.extendsFrom common runtimeClasspath.extendsFrom common developmentForge.extendsFrom common } } // Let the application plugin know where the main class is // (This will point to a non-existent class in all sub-projects except "Core") if (p == project(":core")) { application { mainClass.set('com.seibel.lod.core.jar.JarMain') } } dependencies { //=====================// // shared dependencies // //=====================// // Manifold if (isMinecraftSubProject) annotationProcessor("systems.manifold:manifold-preprocessor:${rootProject.manifold_version}") // Log4j implementation("org.apache.logging.log4j:log4j-api:${rootProject.log4j_version}") implementation("org.apache.logging.log4j:log4j-core:${rootProject.log4j_version}") // JOML implementation("org.joml:joml:${rootProject.joml_version}") // JUnit tests implementation("org.junit.jupiter:junit-jupiter:5.8.2") implementation("org.junit.jupiter:junit-jupiter-engine:5.8.2") implementation("junit:junit:4.13") // Compression shadowMe("org.tukaani:xz:1.9") // NightConfig (includes Toml & Json) shadowMe("com.electronwill.night-config:toml:${rootProject.nightconfig_version}") shadowMe("com.electronwill.night-config:json:${rootProject.nightconfig_version}") // Theming shadowMe("com.formdev:flatlaf:${rootProject.flatlaf_version}") // SVG shadowMe("com.formdev:flatlaf-extras:${rootProject.flatlaf_version}") shadowMe("com.formdev:svgSalamander:${rootProject.svgSalamander_version}") //==========================// // conditional dependencies // //==========================// // Add core if (isMinecraftSubProject) { shadowMe(project(":core")) { // Remove Junit test libraries exclude group: "org.junit.jupiter", module: "junit-jupiter" exclude group: "org.junit.jupiter", module: "junit-jupiter-engine" exclude group: "junit", module: "junit" // Removed dependencies transitive false } } // Add the api if (p != project(":api")) { shadowMe(project(":api")) { // Remove Junit test libraries exclude group: "org.junit.jupiter", module: "junit-jupiter" exclude group: "org.junit.jupiter", module: "junit-jupiter-engine" exclude group: "junit", module: "junit" // Removed dependencies transitive false } } // Add common if (isMinecraftSubProject && p != project(":common")) { // Common // implementation project(":common") common(project(path: ":common")) { transitive false } shadowCommon(project(path: ":common")) { transitive false } } } shadowJar { configurations = [project.configurations.shadowMe] if (isMinecraftSubProject && p != project(":common")) { configurations.push(project.configurations.shadowCommon) // Shadow the common subproject relocate "com.seibel.lod.common", "loaderCommon.${p.name}.com.seibel.lod.common" // Move the loader files to a different location } // Compression relocate 'org.tukaani', 'distanthorizons.libraries.tukaani' // NightConfig (includes Toml & Json) relocate 'com.electronwill.nightconfig', 'distanthorizons.libraries.electronwill.nightconfig' // Theming relocate 'com.formdev.flatlaf', 'distanthorizons.libraries.formdev.flatlaf' // SVG relocate 'com.kitfox.svg', 'distanthorizons.libraries.kitfox.svg' mergeServiceFiles() } // Using jar.finalizedBy(shadowJar) causes issues so we do this scuffed bypass jar.dependsOn(shadowJar) // Adds the standalone jar's entrypoint jar { from "LICENSE.txt" manifest { attributes 'Implementation-Title': rootProject.mod_name, 'Implementation-Version': rootProject.mod_version, 'Main-Class': 'com.seibel.lod.core.jar.JarMain' // When changing the main of the jar change this line } } // this can be un-commented if we ever wanted to make DH modular (AKA use a module-info.java file) again /* // Tells gradle where to look for other modules // Why isn't the classpath added to the modules path by default? if (p == project(":core")) { compileJava { inputs.property('moduleName', 'dhApi') doFirst { options.compilerArgs = [ '--module-path', classpath.asPath ] classpath = files() } } } */ // Run mergeJars when running build // TODO: Fix later // if (isMinecraftSubProject) { // build.finalizedBy(mergeJars) // assemble.finalizedBy(mergeJars) // } } allprojects { p -> // Does the same as "p == project(":common") || p == project(":fabric") || p == project(":quilt") || p == project(":forge")" // Useful later on so we dont have duplicated code def isMinecraftSubProject = p != project(":core") && p != project(":api") apply plugin: "java" apply plugin: "maven-publish" archivesBaseName = rootProject.mod_name version = project.name + "-" + rootProject.versionStr group = rootProject.maven_group repositories { // The central repo mavenCentral() // Used for Google's Collect library // TODO: Attempt to remove this library maven { url "https://repo.enonic.com/public/" } // For parchment mappings maven { url "https://maven.parchmentmc.org" } // For Architectury API maven { url "https://maven.architectury.dev" } // For Git repositories maven { url "https://jitpack.io" } // For Manifold Preprocessor maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } // Required for importing Modrinth mods maven { name = "Modrinth" url = "https://api.modrinth.com/maven" content { includeGroup "maven.modrinth" } } // Required for importing CursedForge mods maven { url "https://www.cursemaven.com" content { includeGroup "curse.maven" } } // Required for ModMenu maven { url "https://maven.terraformersmc.com/" } // Required for Mixins & VanillaGradle maven { url "https://repo.spongepowered.org/maven/" } // Required for Canvas (mod) maven { url "https://maven.vram.io/" } // These 2 are for importing mods that arnt on CursedForge, Modrinth, GitHub, GitLab or anywhere opensource flatDir { dirs "${rootDir}/mods/fabric" content { includeGroup "fabric-mod" } } flatDir { dirs "${rootDir}/mods/forge" content { includeGroup "forge-mod" } } } // Adds some dependencies that are in vanilla but not in core if (p == project(":core")) { OperatingSystem os = org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.currentOperatingSystem; // Set the OS lwjgl is using to the current os project.ext.lwjglNatives = "natives-" + os.toFamilyName() dependencies { // Imports most of lwjgl's libraries (well, only the ones that we need) implementation platform("org.lwjgl:lwjgl-bom:${rootProject.lwjgl_version}") implementation "org.lwjgl:lwjgl" implementation "org.lwjgl:lwjgl-assimp" implementation "org.lwjgl:lwjgl-glfw" implementation "org.lwjgl:lwjgl-openal" implementation "org.lwjgl:lwjgl-opengl" implementation "org.lwjgl:lwjgl-stb" implementation "org.lwjgl:lwjgl-tinyfd" runtimeOnly "org.lwjgl:lwjgl::$lwjglNatives" runtimeOnly "org.lwjgl:lwjgl-assimp::$lwjglNatives" runtimeOnly "org.lwjgl:lwjgl-glfw::$lwjglNatives" runtimeOnly "org.lwjgl:lwjgl-openal::$lwjglNatives" runtimeOnly "org.lwjgl:lwjgl-opengl::$lwjglNatives" runtimeOnly "org.lwjgl:lwjgl-stb::$lwjglNatives" runtimeOnly "org.lwjgl:lwjgl-tinyfd::$lwjglNatives" implementation "org.joml:joml:${rootProject.joml_version}" // Some other dependencies // TODO: Attempt to remove some of these dependencies from the core implementation("org.jetbrains:annotations:16.0.2") implementation("com.google.code.findbugs:jsr305:3.0.2") implementation("com.google.common:google-collect:0.5") implementation("com.google.guava:guava:31.1-jre") implementation("it.unimi.dsi:fastutil:8.5.11") } } // Put stuff from gradle.properties into the mod info processResources { def resourceTargets = ["fabric.mod.json", "quilt.mod.json", "META-INF/mods.toml"] // Location of where to inject the properties def intoTargets = ["$buildDir/resources/main/"] // Location of the built resources folder // Fix forge version numbering system as it is weird // For whatever reason forge uses [1.18, 1.18.1, 1.18.2) instead of the standard ["1.18", "1.18.1", "1.18.2"] which make more sense def compatible_forgemc_versions = "${compatible_minecraft_versions}".replaceAll("\"", "").replaceAll("]", ",)") // println compatible_forgemc_versions def replaceProperties = [ version : mod_version, mod_name : mod_readable_name, authors : mod_authors, description : mod_description, homepage : mod_homepage, source : mod_source, issues : mod_issues, discord : mod_discord, minecraft_version : minecraft_version, compatible_minecraft_versions: compatible_minecraft_versions, compatible_forgemc_versions : compatible_forgemc_versions, java_version : java_version ] // The left side is what gets replaced in the mod info and the right side is where to get it from in the gradle.properties inputs.properties replaceProperties replaceProperties.put "project", project filesMatching(resourceTargets) { expand replaceProperties } intoTargets.each { target -> if (file(target).exists()) { copy { from(sourceSets.main.resources) { include resourceTargets expand replaceProperties } into target } } } } task copyAccessWidener(type: Copy) { from project(":common").file("src/main/resources/${accessWidenerVersion}.lod.accesswidener") into(file(p.file("build/resources/main"))) rename "${accessWidenerVersion}.lod.accesswidener", "lod.accesswidener" } task copyCoreResources(type: Copy) { from fileTree(project(":core").file("src/main/resources")) into p.file("build/resources/main") } tasks.withType(JavaCompile) { if (isMinecraftSubProject) { options.release = rootProject.java_version as Integer options.compilerArgs += ['-Xplugin:Manifold'] } else { options.release = 8; // Core & Api should use Java 8 no matter what //options.release = rootProject.java_version as Integer // But if you want to test some stuff, then this can be enabled } options.encoding = "UTF-8" } java { withSourcesJar() } } // Delete the merged folder when running clean task cleanMergedJars() { def mergedFolder = file("Merged") if (mergedFolder.exists()) { delete(mergedFolder) } } // add cleanMergedJars to the end of the "clean" task tasks["clean"].finalizedBy(cleanMergedJars)