diff --git a/build.gradle b/build.gradle
index a9c2c24..ee4213a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,412 +1,67 @@
-//version: 1699290261
-/*
- DO NOT CHANGE THIS FILE!
- Also, you may replace this file at any time if there is an update available.
- Please check https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/master/build.gradle for updates.
- */
-
-
-import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
-import com.gtnewhorizons.retrofuturagradle.ObfuscationAttribute
-import com.gtnewhorizons.retrofuturagradle.mcp.ReobfuscatedJar
-import com.gtnewhorizons.retrofuturagradle.minecraft.RunMinecraftTask
-import com.gtnewhorizons.retrofuturagradle.util.Distribution
-import com.matthewprenger.cursegradle.CurseArtifact
-import com.matthewprenger.cursegradle.CurseRelation
-import com.modrinth.minotaur.dependencies.ModDependency
-import com.modrinth.minotaur.dependencies.VersionDependency
-import org.gradle.internal.logging.text.StyledTextOutput.Style
-import org.gradle.internal.logging.text.StyledTextOutputFactory
-import org.gradle.internal.xml.XmlTransformer
-import org.jetbrains.gradle.ext.Application
-import org.jetbrains.gradle.ext.Gradle
-
-import javax.inject.Inject
-import java.nio.file.Files
-import java.nio.file.Paths
-import java.util.concurrent.TimeUnit
-
buildscript {
repositories {
mavenCentral()
-
- maven {
- name 'forge'
- url 'https://maven.minecraftforge.net'
- }
+ maven { url "https://maven.minecraftforge.net" }
maven {
- // GTNH RetroFuturaGradle and ASM Fork
- name "GTNH Maven"
- url "http://jenkins.usrv.eu:8081/nexus/content/groups/public/"
- allowInsecureProtocol = true
+ name = "GTNH Maven"
+ url = uri("https://nexus.gtnewhorizons.com/repository/public/")
}
maven {
- name 'sonatype'
- url 'https://oss.sonatype.org/content/repositories/snapshots/'
+ name = "LegacyModdingMC"
+ url = uri("https://maven.legacy-modding.dev/releases")
}
- maven {
- name 'Scala CI dependencies'
- url 'https://repo1.maven.org/maven2/'
- }
-
- mavenLocal()
}
}
+
plugins {
- id 'java-library'
- id "org.jetbrains.gradle.plugin.idea-ext" version "1.1.7"
- id 'eclipse'
- id 'scala'
- id 'maven-publish'
- id 'org.jetbrains.kotlin.jvm' version '1.8.0' apply false
- id 'org.jetbrains.kotlin.kapt' version '1.8.0' apply false
- id 'com.google.devtools.ksp' version '1.8.0-1.0.9' apply false
- id 'org.ajoberstar.grgit' version '4.1.1' // 4.1.1 is the last jvm8 supporting version, unused, available for addon.gradle
- id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
- id 'com.palantir.git-version' version '3.0.0' apply false
- id 'de.undercouch.download' version '5.4.0'
- id 'com.github.gmazzo.buildconfig' version '3.1.0' apply false // Unused, available for addon.gradle
- id 'com.diffplug.spotless' version '6.13.0' apply false // 6.13.0 is the last jvm8 supporting version
- id 'com.modrinth.minotaur' version '2.+' apply false
- id 'com.matthewprenger.cursegradle' version '1.4.0' apply false
+ id 'java'
id 'com.gtnewhorizons.retrofuturagradle' version '1.3.24'
}
-print("You might want to check out './gradlew :faq' if your build fails.\n")
-
-boolean settingsupdated = verifySettingsGradle()
-settingsupdated = verifyGitAttributes() || settingsupdated
-if (settingsupdated)
- throw new GradleException("Settings has been updated, please re-run task.")
-
-// In submodules, .git is a file pointing to the real git dir
-if (project.file('.git/HEAD').isFile() || project.file('.git').isFile()) {
- apply plugin: 'com.palantir.git-version'
-}
-
-def out = services.get(StyledTextOutputFactory).create('an-output')
-
-def projectJavaVersion = JavaLanguageVersion.of(8)
-
-boolean disableSpotless = project.hasProperty("disableSpotless") ? project.disableSpotless.toBoolean() : false
-boolean disableCheckstyle = project.hasProperty("disableCheckstyle") ? project.disableCheckstyle.toBoolean() : false
-
-final String CHECKSTYLE_CONFIG = """
-
-
-
-
-
-
-
-
-
-
-
-"""
-
-checkPropertyExists("modName")
-checkPropertyExists("modVersion")
-checkPropertyExists("modId")
-checkPropertyExists("modGroup")
-checkPropertyExists("autoUpdateBuildScript")
-checkPropertyExists("minecraftVersion")
-checkPropertyExists("forgeVersion")
-checkPropertyExists("replaceGradleTokenInFile")
-checkPropertyExists("gradleTokenVersion")
-checkPropertyExists("apiPackage")
-checkPropertyExists("accessTransformersFile")
-checkPropertyExists("usesMixins")
-checkPropertyExists("mixinPlugin")
-checkPropertyExists("mixinsPackage")
-checkPropertyExists("coreModClass")
-checkPropertyExists("containsMixinsAndOrCoreModOnly")
-checkPropertyExists("usesShadowedDependencies")
-checkPropertyExists("developmentEnvironmentUserName")
-
-propertyDefaultIfUnset("generateGradleTokenClass", "")
-propertyDefaultIfUnset("includeWellKnownRepositories", true)
-propertyDefaultIfUnset("noPublishedSources", false)
-propertyDefaultIfUnset("usesMixinDebug", project.usesMixins)
-propertyDefaultIfUnset("forceEnableMixins", false)
-propertyDefaultIfUnset("channel", "stable")
-propertyDefaultIfUnset("mappingsVersion", "12")
-propertyDefaultIfUnset("usesMavenPublishing", true)
-propertyDefaultIfUnset("mavenPublishUrl", "http://jenkins.usrv.eu:8081/nexus/content/repositories/releases")
-propertyDefaultIfUnset("modrinthProjectId", "")
-propertyDefaultIfUnset("modrinthRelations", "")
-propertyDefaultIfUnset("curseForgeProjectId", "")
-propertyDefaultIfUnset("curseForgeRelations", "")
-propertyDefaultIfUnset("minimizeShadowedDependencies", true)
-propertyDefaultIfUnset("relocateShadowedDependencies", true)
-// Deprecated properties (kept for backwards compat)
-propertyDefaultIfUnset("gradleTokenModId", "")
-propertyDefaultIfUnset("gradleTokenModName", "")
-propertyDefaultIfUnset("gradleTokenGroupName", "")
-
-propertyDefaultIfUnset("enableModernJavaSyntax", false) // On by default for new projects only
-propertyDefaultIfUnset("enableGenericInjection", false) // On by default for new projects only
-
-// this is meant to be set using the user wide property file. by default we do nothing.
-propertyDefaultIfUnset("ideaOverrideBuildType", "") // Can be nothing, "gradle" or "idea"
-
-project.extensions.add(com.diffplug.blowdryer.Blowdryer, "Blowdryer", com.diffplug.blowdryer.Blowdryer) // Make blowdryer available in "apply from:" scripts
-if (!disableSpotless) {
- apply plugin: 'com.diffplug.spotless'
- apply from: Blowdryer.file('spotless.gradle')
-}
-
-if (!disableCheckstyle) {
- apply plugin: 'checkstyle'
- tasks.named("checkstylePatchedMc") { enabled = false }
- tasks.named("checkstyleMcLauncher") { enabled = false }
- tasks.named("checkstyleIdeVirtualMain") { enabled = false }
- tasks.named("checkstyleInjectedTags") { enabled = false }
- checkstyle {
- config = resources.text.fromString(CHECKSTYLE_CONFIG)
- }
-}
-
-String javaSourceDir = "src/main/java/"
-String scalaSourceDir = "src/main/scala/"
-String kotlinSourceDir = "src/main/kotlin/"
-
-if (usesShadowedDependencies.toBoolean()) {
- apply plugin: "com.github.johnrengelman.shadow"
-}
+group = modGroup
+version = modVersion
+archivesBaseName = modName
java {
toolchain {
- if (enableModernJavaSyntax.toBoolean()) {
- languageVersion.set(JavaLanguageVersion.of(17))
- } else {
- languageVersion.set(projectJavaVersion)
- }
- vendor.set(JvmVendorSpec.AZUL)
+ languageVersion.set(JavaLanguageVersion.of(8))
}
- if (!noPublishedSources) {
- withSourcesJar()
- }
-}
-
-tasks.withType(JavaCompile).configureEach {
- options.encoding = "UTF-8"
-}
-
-tasks.withType(ScalaCompile).configureEach {
- options.encoding = "UTF-8"
-}
-
-pluginManager.withPlugin('org.jetbrains.kotlin.jvm') {
- // If Kotlin is enabled in the project
- kotlin {
- jvmToolchain(8)
- }
- // Kotlin hacks our source sets, so we hack Kotlin's tasks
- def disabledKotlinTaskList = [
- "kaptGenerateStubsMcLauncherKotlin",
- "kaptGenerateStubsPatchedMcKotlin",
- "kaptGenerateStubsInjectedTagsKotlin",
- "compileMcLauncherKotlin",
- "compilePatchedMcKotlin",
- "compileInjectedTagsKotlin",
- "kaptMcLauncherKotlin",
- "kaptPatchedMcKotlin",
- "kaptInjectedTagsKotlin",
- "kspMcLauncherKotlin",
- "kspPatchedMcKotlin",
- "kspInjectedTagsKotlin",
- ]
- tasks.configureEach { task ->
- if (task.name in disabledKotlinTaskList) {
- task.enabled = false
- }
- }
-}
-
-configurations {
- create("runtimeOnlyNonPublishable") {
- description = "Runtime only dependencies that are not published alongside the jar"
- canBeConsumed = false
- canBeResolved = false
- }
-
- create("devOnlyNonPublishable") {
- description = "Runtime and compiletime dependencies that are not published alongside the jar (compileOnly + runtimeOnlyNonPublishable)"
- canBeConsumed = false
- canBeResolved = false
- }
- compileOnly.extendsFrom(devOnlyNonPublishable)
- runtimeOnlyNonPublishable.extendsFrom(devOnlyNonPublishable)
}
if (enableModernJavaSyntax.toBoolean()) {
- repositories {
- mavenCentral {
- mavenContent {
- includeGroup("me.eigenraven.java8unsupported")
- }
- }
- }
-
dependencies {
annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.0'
- // workaround for https://github.com/bsideup/jabel/issues/174
- annotationProcessor 'net.java.dev.jna:jna-platform:5.13.0'
compileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.0') {
- transitive = false // We only care about the 1 annotation class
+ transitive = false
}
- // Allow using jdk.unsupported classes like sun.misc.Unsafe in the compiled code, working around JDK-8206937.
- patchedMinecraft('me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0')
}
tasks.withType(JavaCompile).configureEach {
- if (it.name in ["compileMcLauncherJava", "compilePatchedMcJava"]) {
- return
- }
- sourceCompatibility = 17 // for the IDE support
+ sourceCompatibility = 17
options.release.set(8)
javaCompiler.set(javaToolchains.compilerFor {
languageVersion.set(JavaLanguageVersion.of(17))
- vendor.set(JvmVendorSpec.AZUL)
})
}
}
-eclipse {
- classpath {
- downloadSources = true
- downloadJavadoc = true
- }
-}
-
-final String modGroupPath = modGroup.toString().replace('.' as char, '/' as char)
-final String apiPackagePath = apiPackage.toString().replace('.' as char, '/' as char)
-
-String targetPackageJava = javaSourceDir + modGroupPath
-String targetPackageScala = scalaSourceDir + modGroupPath
-String targetPackageKotlin = kotlinSourceDir + modGroupPath
-if (!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
- throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
-}
-
-if (apiPackage) {
- targetPackageJava = javaSourceDir + modGroupPath + "/" + apiPackagePath
- targetPackageScala = scalaSourceDir + modGroupPath + "/" + apiPackagePath
- targetPackageKotlin = kotlinSourceDir + modGroupPath + "/" + apiPackagePath
- if (!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
- throw new GradleException("Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
- }
-}
-
-if (accessTransformersFile) {
- for (atFile in accessTransformersFile.split(" ")) {
- String targetFile = "src/main/resources/META-INF/" + atFile.trim()
- if (!getFile(targetFile).exists()) {
- throw new GradleException("Could not resolve \"accessTransformersFile\"! Could not find " + targetFile)
- }
- tasks.deobfuscateMergedJarToSrg.accessTransformerFiles.from(targetFile)
- tasks.srgifyBinpatchedJar.accessTransformerFiles.from(targetFile)
- }
-} else {
- boolean atsFound = false
- for (File at : sourceSets.getByName("main").resources.files) {
- if (at.name.toLowerCase().endsWith("_at.cfg")) {
- atsFound = true
- tasks.deobfuscateMergedJarToSrg.accessTransformerFiles.from(at)
- tasks.srgifyBinpatchedJar.accessTransformerFiles.from(at)
- }
- }
- for (File at : sourceSets.getByName("api").resources.files) {
- if (at.name.toLowerCase().endsWith("_at.cfg")) {
- atsFound = true
- tasks.deobfuscateMergedJarToSrg.accessTransformerFiles.from(at)
- tasks.srgifyBinpatchedJar.accessTransformerFiles.from(at)
- }
- }
- if (atsFound) {
- logger.warn("Found and added access transformers in the resources folder, please configure gradle.properties to explicitly mention them by name")
- }
-}
-
-if (usesMixins.toBoolean()) {
- if (mixinsPackage.isEmpty()) {
- throw new GradleException("\"usesMixins\" requires \"mixinsPackage\" to be set!")
- }
- final String mixinPackagePath = mixinsPackage.toString().replaceAll("\\.", "/")
- final String mixinPluginPath = mixinPlugin.toString().replaceAll("\\.", "/")
-
- targetPackageJava = javaSourceDir + modGroupPath + "/" + mixinPackagePath
- targetPackageScala = scalaSourceDir + modGroupPath + "/" + mixinPackagePath
- targetPackageKotlin = kotlinSourceDir + modGroupPath + "/" + mixinPackagePath
- if (!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
- throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
- }
-
- if (!mixinPlugin.isEmpty()) {
- String targetFileJava = javaSourceDir + modGroupPath + "/" + mixinPluginPath + ".java"
- String targetFileScala = scalaSourceDir + modGroupPath + "/" + mixinPluginPath + ".scala"
- String targetFileScalaJava = scalaSourceDir + modGroupPath + "/" + mixinPluginPath + ".java"
- String targetFileKotlin = kotlinSourceDir + modGroupPath + "/" + mixinPluginPath + ".kt"
- if (!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) {
- throw new GradleException("Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin)
- }
- }
-}
-
-if (coreModClass) {
- final String coreModPath = coreModClass.toString().replaceAll("\\.", "/")
- String targetFileJava = javaSourceDir + modGroupPath + "/" + coreModPath + ".java"
- String targetFileScala = scalaSourceDir + modGroupPath + "/" + coreModPath + ".scala"
- String targetFileScalaJava = scalaSourceDir + modGroupPath + "/" + coreModPath + ".java"
- String targetFileKotlin = kotlinSourceDir + modGroupPath + "/" + coreModPath + ".kt"
- if (!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) {
- throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin)
- }
-}
-
-configurations.configureEach {
- resolutionStrategy.cacheChangingModulesFor(0, TimeUnit.SECONDS)
-
- // Make sure GregTech build won't time out
- System.setProperty("org.gradle.internal.http.connectionTimeout", 120000 as String)
- System.setProperty("org.gradle.internal.http.socketTimeout", 120000 as String)
-}
-
-// Fix Jenkins' Git: chmod a file should not be detected as a change and append a '.dirty' to the version
-try {
- 'git config core.fileMode false'.execute()
-}
-catch (Exception ignored) {
- out.style(Style.Failure).println("git isn't installed at all")
-}
-
-// Pulls version first from the VERSION env and then git tag
-String identifiedVersion = modVersion
-String versionOverride = modVersion
-version = identifiedVersion
-
-group = "com.github.GTNewHorizons"
-if (project.hasProperty("customArchiveBaseName") && customArchiveBaseName) {
- base {
- archivesName = customArchiveBaseName
+if (generateGradleTokenClass) {
+ tasks.named("injectTags").configure {
+ outputClassName.set(generateGradleTokenClass)
}
-} else {
- base {
- archivesName = modId
+ tasks.named("compileJava").configure {
+ dependsOn("injectTags")
}
}
+sourceCompatibility = 1.8
+targetCompatibility = 1.8
minecraft {
- if (replaceGradleTokenInFile) {
- for (f in replaceGradleTokenInFile.split(',')) {
- tagReplacementFiles.add f
- }
- }
+ mcVersion = minecraftVersion
+ username = developmentEnvironmentUserName
+
if (gradleTokenModId) {
injectedTags.put gradleTokenModId, modId
}
@@ -419,1167 +74,71 @@ minecraft {
if (gradleTokenGroupName) {
injectedTags.put gradleTokenGroupName, modGroup
}
- if (enableGenericInjection.toBoolean()) {
- injectMissingGenerics.set(true)
- }
-
- username = developmentEnvironmentUserName.toString()
-
- lwjgl3Version = "3.3.2"
-
- // Enable assertions in the current mod
- extraRunJvmArguments.add("-ea:${modGroup}")
if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) {
- if (usesMixinDebug.toBoolean()) {
- extraRunJvmArguments.addAll([
- "-Dmixin.debug.countInjections=true",
- "-Dmixin.debug.verbose=true",
- "-Dmixin.debug.export=true"
- ])
- }
+ extraRunJvmArguments.add("-Dmixin.env.disableRefMap=true")
}
- // Blowdryer is present in some old mod builds, do not propagate it further as a dependency
- // IC2 has no reobf jars in its Maven
- groupsToExcludeFromAutoReobfMapping.addAll(["com.diffplug", "com.diffplug.durian", "net.industrial-craft"])
-}
-
-if (generateGradleTokenClass) {
- tasks.injectTags.outputClassName.set(generateGradleTokenClass)
-}
-
-// Custom reobf auto-mappings
-configurations.configureEach {
- dependencies.configureEach { dep ->
- if (dep instanceof org.gradle.api.artifacts.ExternalModuleDependency) {
- if (dep.group == "net.industrial-craft" && dep.name == "industrialcraft-2") {
- // https://www.curseforge.com/minecraft/mc-mods/industrial-craft/files/2353971
- project.dependencies.reobfJarConfiguration("curse.maven:ic2-242638:2353971")
- }
- }
- }
- def obfuscationAttr = it.attributes.getAttribute(ObfuscationAttribute.OBFUSCATION_ATTRIBUTE)
- if (obfuscationAttr != null && obfuscationAttr.name == ObfuscationAttribute.SRG) {
- resolutionStrategy.eachDependency { DependencyResolveDetails details ->
- // Remap CoFH core cursemaven dev jar to the obfuscated version for runObfClient/Server
- if (details.requested.group == 'curse.maven' && details.requested.name.endsWith('-69162') && details.requested.version == '2388751') {
- details.useVersion '2388750'
- details.because 'Pick obfuscated jar'
- }
- }
- }
-}
-
-// Ensure tests have access to minecraft classes
-sourceSets {
- test {
- java {
- compileClasspath += sourceSets.patchedMc.output + sourceSets.mcLauncher.output
- runtimeClasspath += sourceSets.patchedMc.output + sourceSets.mcLauncher.output
- }
- }
-}
-
-if (file('addon.gradle.kts').exists()) {
- apply from: 'addon.gradle.kts'
-} else if (file('addon.gradle').exists()) {
- apply from: 'addon.gradle'
-}
-
-// File for local tweaks not commited to Git
-if (file('addon.local.gradle.kts').exists()) {
- apply from: 'addon.local.gradle.kts'
-} else if (file('addon.local.gradle').exists()) {
- apply from: 'addon.local.gradle'
-}
-
-// Allow unsafe repos but warn
-repositories.configureEach { repo ->
- if (repo instanceof org.gradle.api.artifacts.repositories.UrlArtifactRepository) {
- if (repo.getUrl() != null && repo.getUrl().getScheme() == "http" && !repo.allowInsecureProtocol) {
- logger.warn("Deprecated: Allowing insecure connections for repo '${repo.name}' - add 'allowInsecureProtocol = true'")
- repo.allowInsecureProtocol = true
- }
+ if (coreModClass) {
+ extraRunJvmArguments.add("-Dfml.coreMods.load=${modGroup}.${coreModClass}")
}
}
-if (file('repositories.gradle.kts').exists()) {
- apply from: 'repositories.gradle.kts'
-} else if (file('repositories.gradle').exists()) {
- apply from: 'repositories.gradle'
-} else {
- logger.error("Neither repositories.gradle.kts nor repositories.gradle was found, make sure you extracted the full ExampleMod template.")
- throw new RuntimeException("Missing repositories.gradle[.kts]")
-}
-configurations {
- runtimeClasspath.extendsFrom(runtimeOnlyNonPublishable)
- testRuntimeClasspath.extendsFrom(runtimeOnlyNonPublishable)
- for (config in [compileClasspath, runtimeClasspath, testCompileClasspath, testRuntimeClasspath]) {
- if (usesShadowedDependencies.toBoolean()) {
- config.extendsFrom(shadowImplementation)
- // TODO: remove Compile after all uses are refactored to Implementation
- config.extendsFrom(shadeCompile)
- config.extendsFrom(shadowCompile)
- }
- }
- // A "bag-of-dependencies"-style configuration for backwards compatibility, gets put in "api"
- create("compile") {
- description = "Deprecated: use api or implementation instead, gets put in api"
- canBeConsumed = false
- canBeResolved = false
- visible = false
- }
- create("testCompile") {
- description = "Deprecated: use testImplementation instead"
- canBeConsumed = false
- canBeResolved = false
- visible = false
- }
- api.extendsFrom(compile)
- testImplementation.extendsFrom(testCompile)
-}
+repositories {
+ flatDir { dirs 'libs' }
-afterEvaluate {
- if (!configurations.compile.allDependencies.empty || !configurations.testCompile.allDependencies.empty) {
- logger.warn("This project uses deprecated `compile` dependencies, please migrate to using `api` and `implementation`")
- logger.warn("For more details, see https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/master/dependencies.gradle")
- }
-}
+ mavenCentral()
-repositories {
maven {
- name 'Overmind forge repo mirror'
- url 'https://gregtech.overminddl1.com/'
+ url = uri("https://maven.minecraftforge.net")
}
+
maven {
name = "GTNH Maven"
- url = "http://jenkins.usrv.eu:8081/nexus/content/groups/public/"
- allowInsecureProtocol = true
+ url = uri("https://nexus.gtnewhorizons.com/repository/public/")
}
+
maven {
- name 'sonatype'
- url 'https://oss.sonatype.org/content/repositories/snapshots/'
- content {
- includeGroup "org.lwjgl"
- }
- }
- if (includeWellKnownRepositories.toBoolean()) {
- exclusiveContent {
- forRepository {
- maven {
- name "CurseMaven"
- url "https://cursemaven.com"
- }
- }
- filter {
- includeGroup "curse.maven"
- }
- }
- exclusiveContent {
- forRepository {
- maven {
- name = "Modrinth"
- url = "https://api.modrinth.com/maven"
- }
- }
- filter {
- includeGroup "maven.modrinth"
- }
- }
- maven {
- name = "ic2"
- url = getURL("https://maven.ic2.player.to/", "https://maven2.ic2.player.to/")
- content {
- includeGroup "net.industrial-craft"
- }
- metadataSources {
- mavenPom()
- artifact()
- }
- }
- maven {
- name "MMD Maven"
- url "https://maven.mcmoddev.com/"
- }
+ name = "LegacyModdingMC"
+ url = uri("https://maven.legacy-modding.dev/releases")
}
}
-def mixinProviderGroup = "io.github.legacymoddingmc"
-def mixinProviderModule = "unimixins"
-def mixinProviderVersion = "0.1.13"
-def mixinProviderSpecNoClassifer = "${mixinProviderGroup}:${mixinProviderModule}:${mixinProviderVersion}"
-def mixinProviderSpec = "${mixinProviderSpecNoClassifer}:dev"
-ext.mixinProviderSpec = mixinProviderSpec
-
-def mixingConfigRefMap = 'mixins.' + modId + '.refmap.json'
-
dependencies {
- if (usesMixins.toBoolean()) {
- annotationProcessor('org.ow2.asm:asm-debug-all:5.0.3')
- annotationProcessor('com.google.guava:guava:24.1.1-jre')
- annotationProcessor('com.google.code.gson:gson:2.8.6')
- annotationProcessor(mixinProviderSpec)
- if (usesMixinDebug.toBoolean()) {
- runtimeOnlyNonPublishable('org.jetbrains:intellij-fernflower:1.2.1.16')
- }
- }
- if (usesMixins.toBoolean()) {
- implementation(modUtils.enableMixins(mixinProviderSpec, mixingConfigRefMap))
- } else if (forceEnableMixins.toBoolean()) {
- runtimeOnlyNonPublishable(mixinProviderSpec)
- }
-}
+ implementation name: 'cindercore'
+ implementation name: 'lotr'
+ implementation name: 'optifine'
+ implementation name: 'variabletriggers'
-pluginManager.withPlugin('org.jetbrains.kotlin.kapt') {
if (usesMixins.toBoolean()) {
- dependencies {
- kapt(mixinProviderSpec)
- }
- }
-}
-
-// Replace old mixin mods with unimixins
-// https://docs.gradle.org/8.0.2/userguide/resolution_rules.html#sec:substitution_with_classifier
-configurations.all {
- resolutionStrategy.dependencySubstitution {
- substitute module('com.gtnewhorizon:gtnhmixins') using module(mixinProviderSpecNoClassifer) withClassifier("dev") because("Unimixins replaces other mixin mods")
- substitute module('com.github.GTNewHorizons:Mixingasm') using module(mixinProviderSpecNoClassifer) withClassifier("dev") because("Unimixins replaces other mixin mods")
- substitute module('com.github.GTNewHorizons:SpongePoweredMixin') using module(mixinProviderSpecNoClassifer) withClassifier("dev") because("Unimixins replaces other mixin mods")
- substitute module('com.github.GTNewHorizons:SpongeMixins') using module(mixinProviderSpecNoClassifer) withClassifier("dev") because("Unimixins replaces other mixin mods")
- substitute module('io.github.legacymoddingmc:unimixins') using module(mixinProviderSpecNoClassifer) withClassifier("dev") because("Our previous unimixins upload was missing the dev classifier")
+ annotationProcessor("io.github.legacymoddingmc:unimixins:0.1.13:dev")
+ implementation(modUtils.enableMixins("io.github.legacymoddingmc:unimixins:0.1.13:dev", "mixins.${modId}.refmap.json"))
}
}
-dependencies {
- constraints {
- def minGtnhLibVersion = "0.0.13"
- implementation("com.github.GTNewHorizons:GTNHLib:${minGtnhLibVersion}") {
- because("fixes duplicate mod errors in java 17 configurations using old gtnhlib")
- }
- runtimeOnly("com.github.GTNewHorizons:GTNHLib:${minGtnhLibVersion}") {
- because("fixes duplicate mod errors in java 17 configurations using old gtnhlib")
- }
- devOnlyNonPublishable("com.github.GTNewHorizons:GTNHLib:${minGtnhLibVersion}") {
- because("fixes duplicate mod errors in java 17 configurations using old gtnhlib")
- }
- runtimeOnlyNonPublishable("com.github.GTNewHorizons:GTNHLib:${minGtnhLibVersion}") {
- because("fixes duplicate mod errors in java 17 configurations using old gtnhlib")
- }
- }
-}
-
-if (file('dependencies.gradle.kts').exists()) {
- apply from: 'dependencies.gradle.kts'
-} else if (file('dependencies.gradle').exists()) {
- apply from: 'dependencies.gradle'
-} else {
- logger.error("Neither dependencies.gradle.kts nor dependencies.gradle was found, make sure you extracted the full ExampleMod template.")
- throw new RuntimeException("Missing dependencies.gradle[.kts]")
-}
-
-tasks.register('generateAssets') {
- group = "GTNH Buildscript"
- description = "Generates a mixin config file at /src/main/resources/mixins.modid.json if needed"
- onlyIf { usesMixins.toBoolean() }
- doLast {
- def mixinConfigFile = getFile("/src/main/resources/mixins." + modId + ".json")
- if (!mixinConfigFile.exists()) {
- def mixinPluginLine = ""
- if (!mixinPlugin.isEmpty()) {
- // We might not have a mixin plugin if we're using early/late mixins
- mixinPluginLine += """\n "plugin": "${modGroup}.${mixinPlugin}", """
- }
-
- mixinConfigFile.text = """{
- "required": true,
- "minVersion": "0.8.5-GTNH",
- "package": "${modGroup}.${mixinsPackage}",${mixinPluginLine}
- "refmap": "${mixingConfigRefMap}",
- "target": "@env(DEFAULT)",
- "compatibilityLevel": "JAVA_8",
- "mixins": [],
- "client": [],
- "server": []
-}
-"""
- }
- }
-}
-
-if (usesMixins.toBoolean()) {
- tasks.named("processResources").configure {
- dependsOn("generateAssets")
- }
-
- tasks.named("compileJava", JavaCompile).configure {
- options.compilerArgs += [
- // Elan: from what I understand they are just some linter configs so you get some warning on how to properly code
- "-XDenableSunApiLintControl",
- "-XDignore.symbol.file"
- ]
+jar {
+ manifest {
+ attributes(
+ "FMLCorePlugin": "${modGroup}.${coreModClass}",
+ "FMLCorePluginContainsFMLMod": "true",
+ "TweakClass": "org.spongepowered.asm.launch.MixinTweaker",
+ "MixinConfigs": "mixins.${modId}.json",
+ "ForceLoadAsMod": "true"
+ )
}
}
-tasks.named("processResources", ProcessResources).configure {
- // this will ensure that this task is redone when the versions change.
+tasks.processResources {
inputs.property "version", project.version
inputs.property "mcversion", project.minecraft.mcVersion
- exclude("spotless.gradle")
- // replace stuff in mcmod.info, nothing else. replaces ${key} with value in text
- filesMatching("mcmod.info") {
- expand "minecraftVersion": project.minecraft.mcVersion,
+ filesMatching("mcmod.info") {
+ expand(
+ "minecraftVersion": project.minecraft.mcVersion,
"modVersion": modVersion,
"modId": modId,
"modName": modName
+ )
}
-
- if (usesMixins.toBoolean()) {
- dependsOn("compileJava", "compileScala")
- }
-}
-
-ext.java17Toolchain = (JavaToolchainSpec spec) -> {
- spec.languageVersion.set(JavaLanguageVersion.of(17))
- spec.vendor.set(JvmVendorSpec.matching("jetbrains"))
-}
-
-ext.java17DependenciesCfg = configurations.create("java17Dependencies") {
- extendsFrom(configurations.getByName("runtimeClasspath")) // Ensure consistent transitive dependency resolution
- canBeConsumed = false
-}
-ext.java17PatchDependenciesCfg = configurations.create("java17PatchDependencies") {
- canBeConsumed = false
-}
-
-dependencies {
- def lwjgl3ifyVersion = '1.5.1'
- if (modId != 'lwjgl3ify') {
- java17Dependencies("com.github.GTNewHorizons:lwjgl3ify:${lwjgl3ifyVersion}")
- }
- if (modId != 'hodgepodge') {
- java17Dependencies('com.github.GTNewHorizons:Hodgepodge:2.3.17')
- }
-
- java17PatchDependencies("com.github.GTNewHorizons:lwjgl3ify:${lwjgl3ifyVersion}:forgePatches") {transitive = false}
-}
-
-ext.java17JvmArgs = [
- // Java 9+ support
- "--illegal-access=warn",
- "-Djava.security.manager=allow",
- "-Dfile.encoding=UTF-8",
- "--add-opens", "java.base/jdk.internal.loader=ALL-UNNAMED",
- "--add-opens", "java.base/java.net=ALL-UNNAMED",
- "--add-opens", "java.base/java.nio=ALL-UNNAMED",
- "--add-opens", "java.base/java.io=ALL-UNNAMED",
- "--add-opens", "java.base/java.lang=ALL-UNNAMED",
- "--add-opens", "java.base/java.lang.reflect=ALL-UNNAMED",
- "--add-opens", "java.base/java.text=ALL-UNNAMED",
- "--add-opens", "java.base/java.util=ALL-UNNAMED",
- "--add-opens", "java.base/jdk.internal.reflect=ALL-UNNAMED",
- "--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED",
- "--add-opens", "jdk.naming.dns/com.sun.jndi.dns=ALL-UNNAMED,java.naming",
- "--add-opens", "java.desktop/sun.awt.image=ALL-UNNAMED",
- "--add-modules", "jdk.dynalink",
- "--add-opens", "jdk.dynalink/jdk.dynalink.beans=ALL-UNNAMED",
- "--add-modules", "java.sql.rowset",
- "--add-opens", "java.sql.rowset/javax.sql.rowset.serial=ALL-UNNAMED"
-]
-
-ext.hotswapJvmArgs = [
- // DCEVM advanced hot reload
- "-XX:+AllowEnhancedClassRedefinition",
- "-XX:HotswapAgent=fatjar"
-]
-
-ext.setupHotswapAgentTask = tasks.register("setupHotswapAgent") {
- group = "GTNH Buildscript"
- description = "Installs a recent version of HotSwapAgent into the Java 17 JetBrains runtime directory"
- def hsaUrl = 'https://github.com/HotswapProjects/HotswapAgent/releases/download/1.4.2-SNAPSHOT/hotswap-agent-1.4.2-SNAPSHOT.jar'
- def targetFolderProvider = javaToolchains.launcherFor(java17Toolchain).map {it.metadata.installationPath.dir("lib/hotswap")}
- def targetFilename = "hotswap-agent.jar"
- onlyIf {
- !targetFolderProvider.get().file(targetFilename).asFile.exists()
- }
- doLast {
- def targetFolder = targetFolderProvider.get()
- targetFolder.asFile.mkdirs()
- download.run {
- src hsaUrl
- dest targetFolder.file(targetFilename).asFile
- overwrite false
- tempAndMove true
- }
- }
-}
-
-public abstract class RunHotswappableMinecraftTask extends RunMinecraftTask {
- // IntelliJ doesn't seem to allow commandline arguments so we also support an env variable
- private boolean enableHotswap = Boolean.valueOf(System.getenv("HOTSWAP"));
-
- @Input
- public boolean getEnableHotswap() { return enableHotswap }
- @Option(option = "hotswap", description = "Enables HotSwapAgent for enhanced class reloading under a debugger")
- public boolean setEnableHotswap(boolean enable) { enableHotswap = enable }
-
- @Inject
- public RunHotswappableMinecraftTask(Distribution side, String superTask, org.gradle.api.invocation.Gradle gradle) {
- super(side, gradle)
-
- this.lwjglVersion = 3
- this.javaLauncher = project.javaToolchains.launcherFor(project.java17Toolchain)
- this.extraJvmArgs.addAll(project.java17JvmArgs)
- this.extraJvmArgs.addAll(project.provider(() -> enableHotswap ? project.hotswapJvmArgs : []))
-
- this.classpath(project.java17PatchDependenciesCfg)
- if (side == Distribution.CLIENT) {
- this.classpath(project.minecraftTasks.lwjgl3Configuration)
- }
- // Use a raw provider instead of map to not create a dependency on the task
- this.classpath(project.provider(() -> project.tasks.named(superTask, RunMinecraftTask).get().classpath))
- this.classpath.filter { file ->
- !file.path.contains("2.9.4-nightly-20150209") // Remove lwjgl2
- }
- this.classpath(project.java17DependenciesCfg)
- }
-
- public void setup(Project project) {
- super.setup(project)
- if (project.usesMixins.toBoolean()) {
- this.extraJvmArgs.addAll(project.provider(() -> {
- def mixinCfg = project.configurations.detachedConfiguration(project.dependencies.create(project.mixinProviderSpec))
- mixinCfg.canBeConsumed = false
- mixinCfg.transitive = false
- enableHotswap ? ["-javaagent:" + mixinCfg.singleFile.absolutePath] : []
- }))
- }
- }
-}
-
-def runClient17Task = tasks.register("runClient17", RunHotswappableMinecraftTask, Distribution.CLIENT, "runClient")
-runClient17Task.configure {
- setup(project)
- group = "Modded Minecraft"
- description = "Runs the modded client using Java 17, lwjgl3ify and Hodgepodge"
- dependsOn(setupHotswapAgentTask, mcpTasks.launcherSources.classesTaskName, minecraftTasks.taskDownloadVanillaAssets, mcpTasks.taskPackagePatchedMc, 'jar')
- mainClass = "GradleStart"
- username = minecraft.username
- userUUID = minecraft.userUUID
-}
-
-def runServer17Task = tasks.register("runServer17", RunHotswappableMinecraftTask, Distribution.DEDICATED_SERVER, "runServer")
-runServer17Task.configure {
- setup(project)
- group = "Modded Minecraft"
- description = "Runs the modded server using Java 17, lwjgl3ify and Hodgepodge"
- dependsOn(setupHotswapAgentTask, mcpTasks.launcherSources.classesTaskName, minecraftTasks.taskDownloadVanillaAssets, mcpTasks.taskPackagePatchedMc, 'jar')
- mainClass = "GradleStartServer"
- extraArgs.add("nogui")
-}
-
-def getManifestAttributes() {
- def manifestAttributes = [:]
- if (!containsMixinsAndOrCoreModOnly.toBoolean() && (usesMixins.toBoolean() || coreModClass)) {
- manifestAttributes += ["FMLCorePluginContainsFMLMod": true]
- }
-
- if (accessTransformersFile) {
- manifestAttributes += ["FMLAT": accessTransformersFile.toString()]
- }
-
- if (coreModClass) {
- manifestAttributes += ["FMLCorePlugin": modGroup + "." + coreModClass]
- }
-
- if (usesMixins.toBoolean()) {
- manifestAttributes += [
- "TweakClass" : "org.spongepowered.asm.launch.MixinTweaker",
- "MixinConfigs" : "mixins." + modId + ".json",
- "ForceLoadAsMod": !containsMixinsAndOrCoreModOnly.toBoolean()
- ]
- }
- return manifestAttributes
-}
-
-tasks.named("jar", Jar).configure {
- manifest {
- attributes(getManifestAttributes())
- }
-}
-
-if (usesShadowedDependencies.toBoolean()) {
- tasks.named("shadowJar", ShadowJar).configure {
- manifest {
- attributes(getManifestAttributes())
- }
-
- if (minimizeShadowedDependencies.toBoolean()) {
- minimize() // This will only allow shading for actually used classes
- }
- configurations = [
- project.configurations.shadowImplementation,
- project.configurations.shadowCompile,
- project.configurations.shadeCompile
- ]
- archiveClassifier.set('dev')
- if (relocateShadowedDependencies.toBoolean()) {
- relocationPrefix = modGroup + ".shadow"
- enableRelocation = true
- }
- }
- configurations.runtimeElements.outgoing.artifacts.clear()
- configurations.apiElements.outgoing.artifacts.clear()
- configurations.runtimeElements.outgoing.artifact(tasks.named("shadowJar", ShadowJar))
- configurations.apiElements.outgoing.artifact(tasks.named("shadowJar", ShadowJar))
- tasks.named("jar", Jar) {
- enabled = false
- finalizedBy(tasks.shadowJar)
- }
- tasks.named("reobfJar", ReobfuscatedJar) {
- inputJar.set(tasks.named("shadowJar", ShadowJar).flatMap({it.archiveFile}))
- }
- AdhocComponentWithVariants javaComponent = (AdhocComponentWithVariants) project.components.findByName("java")
- javaComponent.withVariantsFromConfiguration(configurations.shadowRuntimeElements) {
- skip()
- }
- for (runTask in ["runClient", "runServer", "runClient17", "runServer17"]) {
- tasks.named(runTask).configure {
- dependsOn("shadowJar")
- }
- }
-}
-ext.publishableDevJar = usesShadowedDependencies.toBoolean() ? tasks.shadowJar : tasks.jar
-ext.publishableObfJar = tasks.reobfJar
-
-tasks.register('apiJar', Jar) {
- from(sourceSets.main.allSource) {
- include modGroupPath + "/" + apiPackagePath + '/**'
- }
-
- from(sourceSets.main.output) {
- include modGroupPath + "/" + apiPackagePath + '/**'
- }
-
- from(sourceSets.main.resources.srcDirs) {
- include("LICENSE")
- }
-
- getArchiveClassifier().set('api')
-}
-
-artifacts {
- if (!noPublishedSources) {
- archives tasks.named("sourcesJar")
- }
- if (apiPackage) {
- archives tasks.named("apiJar")
- }
-}
-
-idea {
- module {
- downloadJavadoc = true
- downloadSources = true
- inheritOutputDirs = true
- }
- project {
- settings {
- if (ideaOverrideBuildType != "") {
- delegateActions {
- if ("gradle".equalsIgnoreCase(ideaOverrideBuildType)) {
- delegateBuildRunToGradle = true
- testRunner = org.jetbrains.gradle.ext.ActionDelegationConfig.TestRunner.GRADLE
- } else if ("idea".equalsIgnoreCase(ideaOverrideBuildType)) {
- delegateBuildRunToGradle = false
- testRunner = org.jetbrains.gradle.ext.ActionDelegationConfig.TestRunner.PLATFORM
- } else {
- throw GradleScriptException('Accepted value for ideaOverrideBuildType is one of gradle or idea.')
- }
- }
- }
- runConfigurations {
- "0. Build and Test"(Gradle) {
- taskNames = ["build"]
- }
- "1. Run Client"(Gradle) {
- taskNames = ["runClient"]
- }
- "2. Run Server"(Gradle) {
- taskNames = ["runServer"]
- }
- "1a. Run Client (Java 17)"(Gradle) {
- taskNames = ["runClient17"]
- }
- "2a. Run Server (Java 17)"(Gradle) {
- taskNames = ["runServer17"]
- }
- "1b. Run Client (Java 17, Hotswap)"(Gradle) {
- taskNames = ["runClient17"]
- envs = ["HOTSWAP": "true"]
- }
- "2b. Run Server (Java 17, Hotswap)"(Gradle) {
- taskNames = ["runServer17"]
- envs = ["HOTSWAP": "true"]
- }
- "3. Run Obfuscated Client"(Gradle) {
- taskNames = ["runObfClient"]
- }
- "4. Run Obfuscated Server"(Gradle) {
- taskNames = ["runObfServer"]
- }
- if (!disableSpotless) {
- "5. Apply spotless"(Gradle) {
- taskNames = ["spotlessApply"]
- }
- }
- def coreModArgs = ""
- if (coreModClass) {
- coreModArgs = ' "-Dfml.coreMods.load=' + modGroup + '.' + coreModClass + '"'
- }
- "Run Client (IJ Native)"(Application) {
- mainClass = "GradleStart"
- moduleName = project.name + ".ideVirtualMain"
- afterEvaluate {
- workingDirectory = tasks.runClient.workingDir.absolutePath
- programParameters = tasks.runClient.calculateArgs(project).collect { '"' + it + '"' }.join(' ')
- jvmArgs = tasks.runClient.calculateJvmArgs(project).collect { '"' + it + '"' }.join(' ') +
- ' ' + tasks.runClient.systemProperties.collect { '"-D' + it.key + '=' + it.value.toString() + '"' }.join(' ') +
- coreModArgs
- }
- }
- "Run Server (IJ Native)"(Application) {
- mainClass = "GradleStartServer"
- moduleName = project.name + ".ideVirtualMain"
- afterEvaluate {
- workingDirectory = tasks.runServer.workingDir.absolutePath
- programParameters = tasks.runServer.calculateArgs(project).collect { '"' + it + '"' }.join(' ')
- jvmArgs = tasks.runServer.calculateJvmArgs(project).collect { '"' + it + '"' }.join(' ') +
- ' ' + tasks.runServer.systemProperties.collect { '"-D' + it.key + '=' + it.value.toString() + '"' }.join(' ') +
- coreModArgs
- }
- }
- }
- compiler.javac {
- afterEvaluate {
- javacAdditionalOptions = "-encoding utf8"
- moduleJavacAdditionalOptions = [
- (project.name + ".main"): tasks.compileJava.options.compilerArgs.collect { '"' + it + '"' }.join(' ')
- ]
- }
- }
- withIDEADir { File ideaDir ->
- if (!ideaDir.path.contains(".idea")) {
- // If an .ipr file exists, the project root directory is passed here instead of the .idea subdirectory
- ideaDir = new File(ideaDir, ".idea")
- }
- if (ideaDir.isDirectory()) {
- def miscFile = new File(ideaDir, "misc.xml")
- if (miscFile.isFile()) {
- boolean dirty = false
- def miscTransformer = new XmlTransformer()
- miscTransformer.addAction { root ->
- Node rootNode = root.asNode()
- def rootManager = rootNode
- .component.find { it.@name == 'ProjectRootManager' }
- if (!rootManager) {
- rootManager = rootNode.appendNode('component', ['name': 'ProjectRootManager', 'version': '2'])
- dirty = true
- }
- def output = rootManager.output
- if (!output) {
- output = rootManager.appendNode('output')
- dirty = true
- }
- if (!output.@url) {
- // Only modify the output url if it doesn't yet have one, or if the existing one is blank somehow.
- // This is a sensible default for most setups
- output.@url = 'file://$PROJECT_DIR$/build/ideaBuild'
- dirty = true
- }
- }
- def result = miscTransformer.transform(miscFile.text)
- if (dirty) {
- miscFile.write(result)
- }
- } else {
- miscFile.text = """
-
-
-
-
-
-"""
- }
- }
- }
- }
- }
-}
-
-tasks.named("processIdeaSettings").configure {
- dependsOn("injectTags")
-}
-
-tasks.named("ideVirtualMainClasses").configure {
- // Make IntelliJ "Build project" build the mod jars
- dependsOn("jar", "reobfJar")
- if (!disableSpotless) {
- dependsOn("spotlessCheck")
- }
-}
-
-// workaround variable hiding in pom processing
-def projectConfigs = project.configurations
-
-publishing {
- publications {
- create("maven", MavenPublication) {
- from components.java
-
- if (apiPackage) {
- artifact apiJar
- }
-
- groupId = System.getenv("ARTIFACT_GROUP_ID") ?: project.group
- artifactId = System.getenv("ARTIFACT_ID") ?: project.name
- // Using the identified version, not project.version as it has the prepended 1.7.10
- version = System.getenv("RELEASE_VERSION") ?: identifiedVersion
- }
- }
- repositories {
- if (usesMavenPublishing.toBoolean() && System.getenv("MAVEN_USER") != null) {
- maven {
- url = mavenPublishUrl
- allowInsecureProtocol = mavenPublishUrl.startsWith("http://") // Mostly for the GTNH maven
- credentials {
- username = System.getenv("MAVEN_USER") ?: "NONE"
- password = System.getenv("MAVEN_PASSWORD") ?: "NONE"
- }
- }
- }
- }
-}
-
-if (modrinthProjectId.size() != 0 && System.getenv("MODRINTH_TOKEN") != null) {
- apply plugin: 'com.modrinth.minotaur'
-
- File changelogFile = new File(System.getenv("CHANGELOG_FILE") ?: "CHANGELOG.md")
-
- modrinth {
- token = System.getenv("MODRINTH_TOKEN")
- projectId = modrinthProjectId
- versionNumber = identifiedVersion
- versionType = identifiedVersion.endsWith("-pre") ? "beta" : "release"
- changelog = changelogFile.exists() ? changelogFile.getText("UTF-8") : ""
- uploadFile = publishableObfJar
- additionalFiles = getSecondaryArtifacts()
- gameVersions = [minecraftVersion]
- loaders = ["forge"]
- debugMode = false
- }
-
- if (modrinthRelations.size() != 0) {
- String[] deps = modrinthRelations.split(";")
- deps.each { dep ->
- if (dep.size() == 0) {
- return
- }
- String[] parts = dep.split(":")
- String[] qual = parts[0].split("-")
- addModrinthDep(qual[0], qual[1], parts[1])
- }
- }
- if (usesMixins.toBoolean()) {
- addModrinthDep("required", "project", "unimixins")
- }
- tasks.modrinth.dependsOn(build)
- tasks.publish.dependsOn(tasks.modrinth)
-}
-
-if (curseForgeProjectId.size() != 0 && System.getenv("CURSEFORGE_TOKEN") != null) {
- apply plugin: 'com.matthewprenger.cursegradle'
-
- File changelogFile = new File(System.getenv("CHANGELOG_FILE") ?: "CHANGELOG.md")
-
- curseforge {
- apiKey = System.getenv("CURSEFORGE_TOKEN")
- project {
- id = curseForgeProjectId
- if (changelogFile.exists()) {
- changelogType = "markdown"
- changelog = changelogFile
- }
- releaseType = identifiedVersion.endsWith("-pre") ? "beta" : "release"
- addGameVersion minecraftVersion
- addGameVersion "Forge"
- mainArtifact publishableObfJar
- for (artifact in getSecondaryArtifacts()) addArtifact artifact
- }
-
- options {
- javaIntegration = false
- forgeGradleIntegration = false
- debug = false
- }
- }
-
- if (curseForgeRelations.size() != 0) {
- String[] deps = curseForgeRelations.split(";")
- deps.each { dep ->
- if (dep.size() == 0) {
- return
- }
- String[] parts = dep.split(":")
- addCurseForgeRelation(parts[0], parts[1])
- }
- }
- if (usesMixins.toBoolean()) {
- addCurseForgeRelation("requiredDependency", "unimixins")
- }
- tasks.curseforge.dependsOn(build)
- tasks.publish.dependsOn(tasks.curseforge)
-}
-
-def addModrinthDep(String scope, String type, String name) {
- com.modrinth.minotaur.dependencies.Dependency dep;
- if (!(scope in ["required", "optional", "incompatible", "embedded"])) {
- throw new Exception("Invalid modrinth dependency scope: " + scope)
- }
- switch (type) {
- case "project":
- dep = new ModDependency(name, scope)
- break
- case "version":
- dep = new VersionDependency(name, scope)
- break
- default:
- throw new Exception("Invalid modrinth dependency type: " + type)
- }
- project.modrinth.dependencies.add(dep)
-}
-
-def addCurseForgeRelation(String type, String name) {
- if (!(type in ["requiredDependency", "embeddedLibrary", "optionalDependency", "tool", "incompatible"])) {
- throw new Exception("Invalid CurseForge relation type: " + type)
- }
- CurseArtifact artifact = project.curseforge.curseProjects[0].mainArtifact
- CurseRelation rel = (artifact.curseRelations ?: (artifact.curseRelations = new CurseRelation()))
- rel."$type"(name)
-}
-
-// Updating
-
-def buildscriptGradleVersion = "8.2.1"
-
-tasks.named('wrapper', Wrapper).configure {
- gradleVersion = buildscriptGradleVersion
-}
-
-tasks.register('updateBuildScript') {
- group = 'GTNH Buildscript'
- description = 'Updates the build script to the latest version'
-
- if (gradle.gradleVersion != buildscriptGradleVersion && !Boolean.getBoolean('DISABLE_BUILDSCRIPT_GRADLE_UPDATE')) {
- dependsOn('wrapper')
- }
-
- doLast {
- if (performBuildScriptUpdate()) return
-
- print("Build script already up-to-date!")
- }
-}
-
-if (!project.getGradle().startParameter.isOffline() && !Boolean.getBoolean('DISABLE_BUILDSCRIPT_UPDATE_CHECK') && isNewBuildScriptVersionAvailable()) {
- if (autoUpdateBuildScript.toBoolean()) {
- performBuildScriptUpdate()
- } else {
- out.style(Style.SuccessHeader).println("Build script update available! Run 'gradle updateBuildScript'")
- if (gradle.gradleVersion != buildscriptGradleVersion) {
- out.style(Style.SuccessHeader).println("updateBuildScript can update gradle from ${gradle.gradleVersion} to ${buildscriptGradleVersion}\n")
- }
- }
-}
-
-// If you want to add more cases to this task, implement them as arguments if total amount to print gets too large
-tasks.register('faq') {
- group = 'GTNH Buildscript'
- description = 'Prints frequently asked questions about building a project'
-
- doLast {
- print("If your build fails to fetch dependencies, run './gradlew updateDependencies'. " +
- "Or you can manually check if the versions are still on the distributing sites - " +
- "the links can be found in repositories.gradle and build.gradle:repositories, " +
- "but not build.gradle:buildscript.repositories - those ones are for gradle plugin metadata.\n\n" +
- "If your build fails to recognize the syntax of new Java versions, enable Jabel in your " +
- "gradle.properties. See how it's done in GTNH ExampleMod/gradle.properties. " +
- "However, keep in mind that Jabel enables only syntax features, but not APIs that were introduced in " +
- "Java 9 or later.")
- }
-}
-
-static URL availableBuildScriptUrl() {
- new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/master/build.gradle")
-}
-
-static URL exampleSettingsGradleUrl() {
- new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/master/settings.gradle.example")
-}
-
-static URL exampleGitAttributesUrl() {
- new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/master/.gitattributes")
-}
-
-
-boolean verifyGitAttributes() {
- def gitattributesFile = getFile(".gitattributes")
- if (!gitattributesFile.exists()) {
- println("Downloading default .gitattributes")
- exampleGitAttributesUrl().withInputStream { i -> gitattributesFile.withOutputStream { it << i } }
- exec {
- workingDir '.'
- commandLine 'git', 'add', '--renormalize', '.'
- }
- return true
- }
- return false
-}
-
-boolean verifySettingsGradle() {
- def settingsFile = getFile("settings.gradle")
- if (!settingsFile.exists()) {
- println("Downloading default settings.gradle")
- exampleSettingsGradleUrl().withInputStream { i -> settingsFile.withOutputStream { it << i } }
- return true
- }
- return false
-}
-
-boolean performBuildScriptUpdate() {
- if (isNewBuildScriptVersionAvailable()) {
- def buildscriptFile = getFile("build.gradle")
- availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } }
- def out = services.get(StyledTextOutputFactory).create('buildscript-update-output')
- out.style(Style.Success).print("Build script updated. Please REIMPORT the project or RESTART your IDE!")
- boolean settingsupdated = verifySettingsGradle()
- settingsupdated = verifyGitAttributes() || settingsupdated
- if (settingsupdated)
- throw new GradleException("Settings has been updated, please re-run task.")
- return true
- }
- return false
-}
-
-boolean isNewBuildScriptVersionAvailable() {
- Map parameters = ["connectTimeout": 2000, "readTimeout": 2000]
-
- String currentBuildScript = getFile("build.gradle").getText()
- String currentBuildScriptHash = getVersionHash(currentBuildScript)
- String availableBuildScriptHash
- try {
- String availableBuildScript = availableBuildScriptUrl().newInputStream(parameters).getText()
- availableBuildScriptHash = getVersionHash(availableBuildScript)
- } catch (IOException e) {
- logger.warn("Could not check for buildscript update availability: {}", e.message)
- return false
- }
-
- boolean isUpToDate = currentBuildScriptHash.empty || availableBuildScriptHash.empty || currentBuildScriptHash == availableBuildScriptHash
- return !isUpToDate
-}
-
-static String getVersionHash(String buildScriptContent) {
- String versionLine = buildScriptContent.find("^//version: [a-z0-9]*")
- if (versionLine != null) {
- return versionLine.split(": ").last()
- }
- return ""
-}
-
-// Parameter Deobfuscation
-
-tasks.register('deobfParams') {
- group = 'GTNH Buildscript'
- description = 'Rename all obfuscated parameter names inherited from Minecraft classes'
- doLast { // TODO
-
- String mcpDir = "$project.gradle.gradleUserHomeDir/caches/minecraft/de/oceanlabs/mcp/mcp_$channel/$mappingsVersion"
- String mcpZIP = "$mcpDir/mcp_$channel-$mappingsVersion-${minecraftVersion}.zip"
- String paramsCSV = "$mcpDir/params.csv"
-
- download.run {
- src "https://maven.minecraftforge.net/de/oceanlabs/mcp/mcp_$channel/$mappingsVersion-$minecraftVersion/mcp_$channel-$mappingsVersion-${minecraftVersion}.zip"
- dest mcpZIP
- overwrite false
- }
-
- if (!file(paramsCSV).exists()) {
- println("Extracting MCP archive ...")
- copy {
- from(zipTree(mcpZIP))
- into(mcpDir)
- }
- }
-
- println("Parsing params.csv ...")
- Map params = new HashMap<>()
- Files.lines(Paths.get(paramsCSV)).forEach { line ->
- String[] cells = line.split(",")
- if (cells.length > 2 && cells[0].matches("p_i?\\d+_\\d+_")) {
- params.put(cells[0], cells[1])
- }
- }
-
- out.style(Style.Success).println("Modified ${replaceParams(file("$projectDir/src/main/java"), params)} files!")
- out.style(Style.Failure).println("Don't forget to verify that the code still works as before!\n It could be broken due to duplicate variables existing now\n or parameters taking priority over other variables.")
- }
-}
-
-static int replaceParams(File file, Map params) {
- int fileCount = 0
-
- if (file.isDirectory()) {
- for (File f : file.listFiles()) {
- fileCount += replaceParams(f, params)
- }
- return fileCount
- }
- println("Visiting ${file.getName()} ...")
- try {
- String content = new String(Files.readAllBytes(file.toPath()))
- int hash = content.hashCode()
- params.forEach { key, value ->
- content = content.replaceAll(key, value)
- }
- if (hash != content.hashCode()) {
- Files.write(file.toPath(), content.getBytes("UTF-8"))
- return 1
- }
- } catch (Exception e) {
- e.printStackTrace()
- }
- return 0
-}
-
-// Dependency Deobfuscation (Deprecated, use the new RFG API documented in dependencies.gradle)
-
-def deobf(String sourceURL) {
- try {
- URL url = new URL(sourceURL)
- String fileName = url.getFile()
-
- //get rid of directories:
- int lastSlash = fileName.lastIndexOf("/")
- if (lastSlash > 0) {
- fileName = fileName.substring(lastSlash + 1)
- }
- //get rid of extension:
- if (fileName.endsWith(".jar") || fileName.endsWith(".litemod")) {
- fileName = fileName.substring(0, fileName.lastIndexOf("."))
- }
-
- String hostName = url.getHost()
- if (hostName.startsWith("www.")) {
- hostName = hostName.substring(4)
- }
- List parts = Arrays.asList(hostName.split("\\."))
- Collections.reverse(parts)
- hostName = String.join(".", parts)
-
- return deobf(sourceURL, "$hostName/$fileName")
- } catch (Exception ignored) {
- return deobf(sourceURL, "deobf/${sourceURL.hashCode()}")
- }
-}
-
-def deobfMaven(String repoURL, String mavenDep) {
- if (!repoURL.endsWith("/")) {
- repoURL += "/"
- }
- String[] parts = mavenDep.split(":")
- parts[0] = parts[0].replace('.', '/')
- def jarURL = repoURL + parts[0] + "/" + parts[1] + "/" + parts[2] + "/" + parts[1] + "-" + parts[2] + ".jar"
- return deobf(jarURL)
-}
-
-def deobfCurse(String curseDep) {
- return dependencies.rfg.deobf("curse.maven:$curseDep")
-}
-
-// The method above is to be preferred. Use this method if the filename is not at the end of the URL.
-def deobf(String sourceURL, String rawFileName) {
- String bon2Version = "2.5.1"
- String fileName = URLDecoder.decode(rawFileName, "UTF-8")
- String cacheDir = "$project.gradle.gradleUserHomeDir/caches"
- String obfFile = "$cacheDir/modules-2/files-2.1/${fileName}.jar"
-
- download.run {
- src sourceURL
- dest obfFile
- quiet true
- overwrite false
- }
- return dependencies.rfg.deobf(files(obfFile))
-}
-// Helper methods
-
-def checkPropertyExists(String propertyName) {
- if (!project.hasProperty(propertyName)) {
- throw new GradleException("This project requires a property \"" + propertyName + "\"! Please add it your \"gradle.properties\". You can find all properties and their description here: https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/main/gradle.properties")
- }
-}
-
-def propertyDefaultIfUnset(String propertyName, defaultValue) {
- if (!project.hasProperty(propertyName) || project.property(propertyName) == "") {
- project.ext.setProperty(propertyName, defaultValue)
- }
-}
-
-def getFile(String relativePath) {
- return new File(projectDir, relativePath)
-}
-
-def getSecondaryArtifacts() {
- // Because noPublishedSources from the beginning of the script is somehow not visible here...
- boolean noPublishedSources = project.hasProperty("noPublishedSources") ? project.noPublishedSources.toBoolean() : false
- def secondaryArtifacts = [publishableDevJar]
- if (!noPublishedSources) secondaryArtifacts += [sourcesJar]
- if (apiPackage) secondaryArtifacts += [apiJar]
- return secondaryArtifacts
-}
-
-def getURL(String main, String fallback) {
- return pingURL(main, 10000) ? main : fallback
-}
-
-// credit: https://stackoverflow.com/a/3584332
-def pingURL(String url, int timeout) {
- url = url.replaceFirst("^https", "http") // Otherwise an exception may be thrown on invalid SSL certificates.
- try {
- HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection()
- connection.setConnectTimeout(timeout)
- connection.setReadTimeout(timeout)
- connection.setRequestMethod("HEAD")
- int responseCode = connection.getResponseCode()
- return 200 <= responseCode && responseCode <= 399
- } catch (IOException ignored) {
- return false
- }
-}
-
-// For easier scripting of things that require variables defined earlier in the buildscript
-if (file('addon.late.gradle.kts').exists()) {
- apply from: 'addon.late.gradle.kts'
-} else if (file('addon.late.gradle').exists()) {
- apply from: 'addon.late.gradle'
-}
-
-// File for local tweaks not commited to Git
-if (file('addon.late.local.gradle.kts').exists()) {
- apply from: 'addon.late.local.gradle.kts'
-} else if (file('addon.late.local.gradle').exists()) {
- apply from: 'addon.late.local.gradle'
}
diff --git a/dependencies.gradle b/dependencies.gradle
deleted file mode 100644
index 5651b6f..0000000
--- a/dependencies.gradle
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Add your dependencies here. Supported configurations:
- * - api("group:name:version:classifier"): if you use the types from this dependency in the public API of this mod
- * Available at runtime and compiletime for mods depending on this mod
- * - implementation("g:n:v:c"): if you need this for internal implementation details of the mod, but none of it is visible via the public API
- * Available at runtime but not compiletime for mods depending on this mod
- * - compileOnly("g:n:v:c"): if the mod you're building doesn't need this dependency during runtime at all, e.g. for optional mods
- * Not available at all for mods depending on this mod, only visible at compiletime for this mod
- * - compileOnlyApi("g:n:v:c"): like compileOnly, but also visible at compiletime for mods depending on this mod
- * Available at compiletime but not runtime for mods depending on this mod
- * - runtimeOnlyNonPublishable("g:n:v:c"): if you want to include a mod in this mod's runClient/runServer runs, but not publish it as a dependency
- * Not available at all for mods depending on this mod, only visible at runtime for this mod
- * - devOnlyNonPublishable("g:n:v:c"): a combination of runtimeOnlyNonPublishable and compileOnly for dependencies present at both compiletime and runtime,
- * but not published as Maven dependencies - useful for RFG-deobfuscated dependencies or local testing
- * - runtimeOnly("g:n:v:c"): if you don't need this at compile time, but want it to be present at runtime
- * Available at runtime for mods depending on this mod
- * - annotationProcessor("g:n:v:c"): mostly for java compiler plugins, if you know you need this, use it, otherwise don't worry
- * - testCONFIG("g:n:v:c") - replace CONFIG by one of the above (except api), same as above but for the test sources instead of main
- *
- * - shadowImplementation("g:n:v:c"): effectively the same as API, but the dependency is included in your jar under a renamed package name
- * Requires you to enable usesShadowedDependencies in gradle.properties
- *
- * - compile("g:n:v:c"): deprecated, replace with "api" (works like the old "compile") or "implementation" (can be more efficient)
- *
- * You can exclude transitive dependencies (dependencies of the chosen dependency) by appending { transitive = false } if needed,
- * but use this sparingly as it can break using your mod as another mod's dependency if you're not careful.
- *
- * To depend on obfuscated jars you can use `devOnlyNonPublishable(rfg.deobf("dep:spec:1.2.3"))` to fetch an obfuscated jar from maven,
- * or `devOnlyNonPublishable(rfg.deobf(project.files("libs/my-mod-jar.jar")))` to use a file.
- *
- * Gradle names for some of the configuration can be misleading, compileOnlyApi and runtimeOnly both get published as dependencies in Maven, but compileOnly does not.
- * The buildscript adds runtimeOnlyNonPublishable to also have a runtime dependency that's not published.
- *
- * For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph
- */
-dependencies {
- implementation files('libs/cindercore.jar')
- implementation files('libs/lotr.jar')
- implementation files('libs/optifine.jar')
- implementation files('libs/variabletriggers.jar')
-}
diff --git a/gradle.properties b/gradle.properties
index 8278628..7ca3422 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,153 +1,31 @@
modName = CinderLoE
modVersion = 1.4.0
-
-# This is a case-sensitive string to identify your mod. Convention is to use lower case.
modId = cinder_loe
-
modGroup = com.zivilon.cinder_loe
-# WHY is there no version field?
-# The build script relies on git to provide a version via tags. It is super easy and will enable you to always know the
-# code base or your binary. Check out this tutorial: https://blog.mattclemente.com/2017/10/13/versioning-with-git-tags/
-
-# Will update your build.gradle automatically whenever an update is available
-autoUpdateBuildScript = false
-
minecraftVersion = 1.7.10
-forgeVersion = 10.13.4.1614
-
-# Specify a MCP channel and mappings version for dependency deobfuscation and the deobfParams task.
-channel = stable
-mappingsVersion = 12
-
-# Define other MCP mappings for dependency deobfuscation
-remoteMappings = https://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/
-# Select a username for testing your mod with breakpoints. You may leave this empty for a random username each time you
-# restart Minecraft in development. Choose this dependent on your mod:
-# Do you need consistent player progressing (for example Thaumcraft)? -> Select a name
-# Do you need to test how your custom blocks interacts with a player that is not the owner? -> leave name empty
developmentEnvironmentUserName = Developer
-# Enables using modern java syntax (up to version 17) via Jabel, while still targeting JVM 8.
-# See https://github.com/bsideup/jabel for details on how this works.
enableModernJavaSyntax = true
-# Enables injecting missing generics into the decompiled source code for a better coding experience
-# Turns most publicly visible List, Map, etc. into proper List, Map types
-enableGenericInjection = false
-
# Generate a class with String fields for the mod id, name, version and group name named with the fields below
generateGradleTokenClass = com.zivilon.cinder_loe.Tags
gradleTokenModId = MODID
gradleTokenModName = MODNAME
gradleTokenVersion =
gradleTokenGroupName = GROUPNAME
-# [DEPRECATED]
-# Multiple source files can be defined here by providing a comma-seperated list: Class1.java,Class2.java,Class3.java
-# public static final String VERSION = "GRADLETOKEN_VERSION";
-# The string's content will be replaced with your mod's version when compiled. You should use this to specify your mod's
-# version in @Mod([...], version = VERSION, [...])
-# Leave these properties empty to skip individual token replacements
-replaceGradleTokenInFile =
-
-# In case your mod provides an API for other mods to implement you may declare its package here. Otherwise, you can
-# leave this property empty.
-# Example value: apiPackage = api + modGroup = com.myname.mymodid -> com.myname.mymodid.api
-apiPackage =
-
-# Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/META-INF/
-# There can be multiple files in a space-separated list.
-# Example value: mymodid_at.cfg nei_at.cfg
-accessTransformersFile =
# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled!
usesMixins = true
-# Adds some debug arguments like verbose output and export
-usesMixinDebug = false
-# Specify the location of your implementation of IMixinConfigPlugin. Leave it empty otherwise.
-mixinPlugin =
-# Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail!
-mixinsPackage = mixins
# Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin!
# This parameter is for legacy compatibility only
# Example value: coreModClass = asm.FMLPlugin + modGroup = com.myname.mymodid -> com.myname.mymodid.asm.FMLPlugin
coreModClass = coremod.CoreMod
-# If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class
-# that is annotated with @Mod) you want this to be true. When in doubt: leave it on false!
-containsMixinsAndOrCoreModOnly = false
# Enables Mixins even if this mod doesn't use them, useful if one of the dependencies uses mixins.
forceEnableMixins = false
-# If enabled, you may use 'shadowCompile' for dependencies. They will be integrated in your jar. It is your
-# responsibility check the licence and request permission for distribution, if required.
-usesShadowedDependencies = false
-# If disabled, won't remove unused classes from shaded dependencies. Some libraries use reflection to access
-# their own classes, making the minimization unreliable.
-minimizeShadowedDependencies = true
-# If disabled, won't rename the shadowed classes.
-relocateShadowedDependencies = true
-
-# Adds the GTNH maven, CurseMaven, IC2/Player maven, and some more well-known 1.7.10 repositories
-includeWellKnownRepositories = false
-
-# Change these to your Maven coordinates if you want to publish to a custom Maven repository instead of the default GTNH Maven.
-# Authenticate with the MAVEN_USERNAME and MAVEN_PASSWORD environment variables.
-# If you need a more complex setup disable maven publishing here and add a publishing repository to addon.gradle.
-usesMavenPublishing = false
-# mavenPublishUrl = http://jenkins.usrv.eu:8081/nexus/content/repositories/releases
-
-# Publishing to modrinth requires you to set the MODRINTH_TOKEN environment variable to your current modrinth API token.
-
-# The project's ID on Modrinth. Can be either the slug or the ID.
-# Leave this empty if you don't want to publish on Modrinth.
-modrinthProjectId =
-
-# The project's relations on Modrinth. You can use this to refer to other projects on Modrinth.
-# Syntax: scope1-type1:name1;scope2-type2:name2;...
-# Where scope can be one of [required, optional, incompatible, embedded],
-# type can be one of [project, version],
-# and the name is the Modrinth project or version slug/id of the other mod.
-# Example: required-project:fplib;optional-project:gasstation;incompatible-project:gregtech
-# Note: GTNH Mixins is automatically set as a required dependency if usesMixins = true
-modrinthRelations =
-
-
-# Publishing to CurseForge requires you to set the CURSEFORGE_TOKEN environment variable to one of your CurseForge API tokens.
-
-# The project's numeric ID on CurseForge. You can find this in the About Project box.
-# Leave this empty if you don't want to publish on CurseForge.
-curseForgeProjectId =
-
-# The project's relations on CurseForge. You can use this to refer to other projects on CurseForge.
-# Syntax: type1:name1;type2:name2;...
-# Where type can be one of [requiredDependency, embeddedLibrary, optionalDependency, tool, incompatible],
-# and the name is the CurseForge project slug of the other mod.
-# Example: requiredDependency:railcraft;embeddedLibrary:cofhlib;incompatible:buildcraft
-# Note: GTNH Mixins is automatically set as a required dependency if usesMixins = true
-curseForgeRelations =
-
-
# Optional parameter to customize the produced artifacts. Use this to preserver artifact naming when migrating older
# projects. New projects should not use this parameter.
customArchiveBaseName = CinderLoE
-
-# Optional parameter to prevent the source code from being published
-# noPublishedSources =
-
-# Uncomment this to disable spotless checks
-# This should only be uncommented to keep it easier to sync with upstream/other forks.
-# That is, if there is no other active fork/upstream, NEVER change this.
-disableSpotless = true
-
-# Uncomment this to disable checkstyle checks (currently wildcard import check).
- disableCheckstyle = true
-
-# Override the IDEA build type. Valid value is "" (leave blank, do not override), "idea" (force use native IDEA build), "gradle"
-# (force use delegated build).
-# This is meant to be set in $HOME/.gradle/gradle.properties.
-# e.g. add "systemProp.org.gradle.project.ideaOverrideBuildType=idea" will override the build type to be always native build.
-# WARNING: If you do use this option, it will overwrite whatever you have in your existing projects. This might not be what you want!
-# Usually there is no need to uncomment this here as other developers do not necessarily use the same build type as you.
-# ideaOverrideBuildType = idea
diff --git a/gradlew b/gradlew
old mode 100644
new mode 100755
diff --git a/src/main/java/com/zivilon/cinder_loe/CinderEventHandler.java b/src/main/java/com/zivilon/cinder_loe/CinderEventHandler.java
index 56e75ee..86b9fdc 100644
--- a/src/main/java/com/zivilon/cinder_loe/CinderEventHandler.java
+++ b/src/main/java/com/zivilon/cinder_loe/CinderEventHandler.java
@@ -2,12 +2,15 @@ package com.zivilon.cinder_loe;
import com.zivilon.cinder_loe.entity.corrupt.CorruptMan;
import com.zivilon.cinder_loe.items.BrokenHalo;
+import com.zivilon.cinder_loe.network.PacketWarbandLocations;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.IFuelHandler;
import cpw.mods.fml.common.eventhandler.EventPriority;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
+import cpw.mods.fml.common.gameevent.TickEvent;
import cpw.mods.fml.common.registry.GameRegistry;
import lotr.common.LOTRMod;
+import lotr.common.LOTRDimension;
import lotr.common.enchant.LOTREnchantment;
import lotr.common.enchant.LOTREnchantmentHelper;
import lotr.common.item.*;
@@ -32,6 +35,7 @@ import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
+import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.living.LivingAttackEvent;
import net.minecraftforge.event.entity.living.LivingHurtEvent;
@@ -47,6 +51,23 @@ public class CinderEventHandler implements IFuelHandler {
MinecraftForge.TERRAIN_GEN_BUS.register(this);
GameRegistry.registerFuelHandler(this);
}
+
+ @SubscribeEvent
+ public void onWorldTick(TickEvent.WorldTickEvent event) {
+ World world = event.world;
+ if (world.isRemote)
+ return;
+ if (event.phase == TickEvent.Phase.END) {
+ if (world == DimensionManager.getWorld(LOTRDimension.MIDDLE_EARTH.dimensionID)) {
+ if (!world.playerEntities.isEmpty()) {
+ if (world.getTotalWorldTime() % 20L == 0L) {
+ PacketWarbandLocations.send_warband_locations(world);
+ }
+ }
+ }
+ }
+ }
+
@SubscribeEvent
public void onArrowLoose(ArrowLooseEvent event) {
Entity attacker = event.entityLiving;
diff --git a/src/main/java/com/zivilon/cinder_loe/CinderLoE.java b/src/main/java/com/zivilon/cinder_loe/CinderLoE.java
index e1a2279..4079fa5 100644
--- a/src/main/java/com/zivilon/cinder_loe/CinderLoE.java
+++ b/src/main/java/com/zivilon/cinder_loe/CinderLoE.java
@@ -7,6 +7,7 @@ import com.zivilon.cinder_loe.client.render.*;
import com.zivilon.cinder_loe.client.render.corrupt.*;
import com.zivilon.cinder_loe.client.render.projectile.*;
import com.zivilon.cinder_loe.command.CommandCinderCharacter;
+import com.zivilon.cinder_loe.command.CommandWarband;
import com.zivilon.cinder_loe.entity.*;
import com.zivilon.cinder_loe.entity.corrupt.*;
import com.zivilon.cinder_loe.entity.npc.*;
@@ -23,6 +24,7 @@ import com.zivilon.cinder_loe.entity.npc.radagast.*;
import com.zivilon.cinder_loe.entity.projectile.*;
import com.zivilon.cinder_loe.entity.trader.*;
import com.zivilon.cinder_loe.items.*;
+import com.zivilon.cinder_loe.network.*;
import com.zivilon.cinder_loe.potion.LoEPotions;
import com.zivilon.cinder_loe.tileentity.*;
import com.zivilon.cinder_loe.util.Utilities;
@@ -321,6 +323,7 @@ public class CinderLoE {
registerBlocks();
registerItems();
ItemRegistration.registerItems();
+ PacketRegistration.register();
registerEntities();
modEventHandler = new CinderEventHandler();
LoEPotions.registerPotions();
@@ -359,6 +362,7 @@ public class CinderLoE {
public void serverStarting(FMLServerStartingEvent event) {
CharacterRoleAPI.loadRolesFromFile();
event.registerServerCommand(new CommandCinderCharacter());
+ event.registerServerCommand(new CommandWarband());
}
public void registerEntities() { // Last ID added: 60
diff --git a/src/main/java/com/zivilon/cinder_loe/CinderLoE_Config.java b/src/main/java/com/zivilon/cinder_loe/CinderLoE_Config.java
index dd81b1a..d8639bf 100644
--- a/src/main/java/com/zivilon/cinder_loe/CinderLoE_Config.java
+++ b/src/main/java/com/zivilon/cinder_loe/CinderLoE_Config.java
@@ -13,6 +13,7 @@ public class CinderLoE_Config {
public static float enchantment_color_green;
public static float enchantment_color_blue;
public static String corrupt_faction;
+ public static String skeleton_faction;
public static boolean objective_lindon;
public static boolean objective_arnor;
@@ -41,7 +42,8 @@ public class CinderLoE_Config {
enchantment_color_green = config.getFloat("EnchantmentColorGreen", Configuration.CATEGORY_GENERAL, 0.19f, 0.0f, 1.0f, "Configure green color for enchantments");
enchantment_color_blue = config.getFloat("EnchantmentColorBlue", Configuration.CATEGORY_GENERAL, 0.608f, 0.0f, 1.0f, "Configure blue color for enchantments");
- corrupt_faction = config.getString("CorruptFaction", Configuration.CATEGORY_GENERAL, "MORDOR", "Configure the alignment the Corrupt npcs follow");
+ corrupt_faction = config.getString("CorruptFaction", Configuration.CATEGORY_GENERAL, "UTUMNO", "Configure the alignment the Corrupt npcs follow");
+ skeleton_faction = config.getString("SkeletonFaction", Configuration.CATEGORY_GENERAL, "UTUMNO", "Configure the alignment the Skeleton npcs follow");
objective_lindon = config.getBoolean("Lindon", Configuration.CATEGORY_GENERAL, false, "set true if Lindon Objective Complete");
objective_arnor = config.getBoolean("Arnor", Configuration.CATEGORY_GENERAL, false,"set true if Arnor Objective Complete");
diff --git a/src/main/java/com/zivilon/cinder_loe/command/CommandWarband.java b/src/main/java/com/zivilon/cinder_loe/command/CommandWarband.java
new file mode 100644
index 0000000..2b4dc85
--- /dev/null
+++ b/src/main/java/com/zivilon/cinder_loe/command/CommandWarband.java
@@ -0,0 +1,151 @@
+package com.zivilon.cinder_loe.command;
+
+import com.zivilon.cinder_loe.world.event.Warband;
+import com.zivilon.cinder_loe.world.event.WarbandFaction;
+
+import net.minecraft.command.CommandBase;
+import net.minecraft.command.ICommandSender;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.util.ChatComponentText;
+
+import lotr.common.world.map.LOTRWaypoint;
+
+import com.zivilon.cinder_loe.character.CharacterRoleAPI;
+import com.zivilon.cinder_loe.util.Utilities;
+
+import java.util.UUID;
+
+public class CommandWarband extends CommandBase {
+ @Override
+ public String getCommandName() {
+ return "warband";
+ }
+
+ @Override
+ public String getCommandUsage(ICommandSender sender) {
+ return "/warband [faction_name] [waypoint] [x] [z]";
+ }
+
+ @Override
+ public int getRequiredPermissionLevel() {
+ return 4;
+ }
+
+ @Override
+ public void processCommand(ICommandSender sender, String[] args) {
+ if(!validate_args(args)) {
+ sender.addChatMessage(new ChatComponentText("Incorrect arguments. Usage: " + getCommandUsage(sender)));
+ return;
+ }
+
+ String action = args[0];
+ System.out.println("Checking arg " + action);
+ switch (action) {
+ case "reset":
+ reset_warband();
+ sender.addChatMessage(new ChatComponentText("Warband timer has been reset. A new warband may now spawn."));
+ return;
+ case "list":
+ list_warbands(sender);
+ return;
+ case "summon":
+ summon_warband(sender, args);
+ return;
+ }
+ }
+
+ public void summon_warband(ICommandSender sender, String[] args) {
+ WarbandFaction faction = WarbandFaction.get_warband_by_name(args[1]);
+ LOTRWaypoint waypoint = null;
+ String waypoint_name = null;
+ int x = 0;
+ int z = 0;
+
+ if (args.length == 2) {
+ if (!(sender instanceof EntityPlayer)) {
+ System.out.println("Console must specify location to summon warband. Options:");
+ System.out.println("/warband ");
+ System.out.println("/warband ");
+ return;
+ }
+ EntityPlayer player = (EntityPlayer)sender;
+ x = (int)player.posX;
+ z = (int)player.posZ;
+ Warband.initialize_warband(faction, x, z);
+ }
+
+ if (args.length == 3) {
+ waypoint_name = args[2];
+ waypoint = LOTRWaypoint.waypointForName(waypoint_name);
+ if (waypoint == null) {
+ sender.addChatMessage(new ChatComponentText("Invalid waypoint \"" + waypoint_name + "\""));
+ }
+ Warband.initialize_warband(faction, waypoint);
+ return;
+ }
+
+ if (args.length == 4) {
+ try {
+ x = Integer.parseInt(args[2]);
+ z = Integer.parseInt(args[3]);
+ } catch (Exception e) {
+ sender.addChatMessage(new ChatComponentText("Invalid coordinates provided"));
+ return;
+ }
+ Warband.initialize_warband(faction, x, z);
+ return;
+ }
+
+ if (args.length > 4) {
+ try {
+ x = Integer.parseInt(args[3]);
+ z = Integer.parseInt(args[4]);
+ } catch (Exception e) {
+ sender.addChatMessage(new ChatComponentText("Invalid coordinates provided"));
+ return;
+ }
+ waypoint_name = args[2];
+ waypoint = LOTRWaypoint.waypointForName(waypoint_name);
+ if (waypoint == null) {
+ sender.addChatMessage(new ChatComponentText("Invalid waypoint \"" + waypoint_name + "\""));
+ return;
+ }
+ Warband.initialize_warband(faction, waypoint, x, z);
+ return;
+ }
+ }
+
+ public static boolean validate_args(String[] args) {
+ System.out.println("Validating...");
+ if (args.length < 1) return false;
+ String action = "";
+ System.out.println("Checking arg \"" + args[0] + "\"");
+ if (args[0].equals("summon") || args[0].equals("reset") || args[0].equals("list")) {
+ action = args[0];
+ } else {
+ System.out.println("Failed test 1");
+ return false;
+ }
+ if (action.equals("summon")) {
+ if (args.length < 2) {
+ System.out.println("Failed test 2");
+ return false;
+ }
+ WarbandFaction faction = WarbandFaction.get_warband_by_name(args[1]);
+ if (faction == null) return false;
+ }
+ return true;
+ }
+
+ public static void reset_warband() {
+ // Set last warband to have happened 10 hours ago, thus allowing new warband
+ Warband.last_warband_timestamp = System.currentTimeMillis() / 1000L - (60*60*10);
+ }
+ public static void list_warbands(ICommandSender sender) {
+ sender.addChatMessage(new ChatComponentText("List of valid warbands:"));
+ for (WarbandFaction faction : WarbandFaction.values()) {
+ sender.addChatMessage(new ChatComponentText("- " + faction.name()));
+ }
+ }
+}
diff --git a/src/main/java/com/zivilon/cinder_loe/droptables/DropTable.java b/src/main/java/com/zivilon/cinder_loe/droptables/DropTable.java
index b472e03..c980bc3 100644
--- a/src/main/java/com/zivilon/cinder_loe/droptables/DropTable.java
+++ b/src/main/java/com/zivilon/cinder_loe/droptables/DropTable.java
@@ -27,7 +27,7 @@ public class DropTable {
public static void drop_items(LOTREntityNPC entity, DropContext[] context_flags, int looting_level) {
List drops = generate_drops(entity, context_flags, looting_level);
- if (drops == null) return;
+ if (drops == null || drops.size() < 1) return;
for (ItemStack drop : drops) {
entity.npcDropItem(drop, 0.0F, false, false);
}
@@ -35,9 +35,12 @@ public class DropTable {
public static List generate_drops(LOTREntityNPC entity, DropContext[] context_flags, int looting_level) {
DropTable table = ((ILootableEntity)entity).get_drop_table();
- if (table == null) return null;
- if (context_flags == null) context_flags = new DropContext[0];
-
+ if (table == null) {
+ return null;
+ }
+ if (context_flags == null) {
+ context_flags = new DropContext[0];
+ }
List results = new ArrayList<>();
for (DropInstance drop : table.drop_list) {
ItemStack stack = get_drop(drop, looting_level, context_flags);
@@ -49,8 +52,7 @@ public class DropTable {
}
public static ItemStack get_drop(DropInstance drop, int looting_level, DropContext[] context) {
- if (!(Utilities.array_contains_array(drop.conditions, context))) return null;
-
+ if (!(Utilities.array_contains_array(context, drop.conditions))) return null;
if (drop instanceof SingleItemDrop) {
return get_single_drop((SingleItemDrop)drop, looting_level);
}
diff --git a/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptHobbit.java b/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptHobbit.java
index 36021e6..6a57528 100644
--- a/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptHobbit.java
+++ b/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptHobbit.java
@@ -1,5 +1,6 @@
package com.zivilon.cinder_loe.entity.corrupt;
+import com.zivilon.cinder_loe.CinderLoE_Config;
import lotr.common.LOTRAchievement;
import lotr.common.LOTRFoods;
import lotr.common.LOTRMod;
@@ -58,7 +59,7 @@ public class CorruptHobbit extends LOTREntityHobbitBounder {
}
@Override
public LOTRFaction getFaction() {
- return this.faction != null ? this.faction : LOTRFaction.UTUMNO;
+ return LOTRFaction.valueOf(CinderLoE_Config.corrupt_faction);
}
@Override
protected float getSoundPitch() {
diff --git a/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptMan.java b/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptMan.java
index 0a46069..ab2d75b 100644
--- a/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptMan.java
+++ b/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptMan.java
@@ -21,6 +21,8 @@ public class CorruptMan extends LOTREntityGondorMan {
public CorruptMan(World world) {
super(world);
+ ((EntityLiving) this).tasks.addTask(6, (EntityAIBase) new LOTREntityAIEat(this, LOTRFoods.ORC, 8000));
+ ((EntityLiving) this).tasks.addTask(6, (EntityAIBase) new LOTREntityAIDrink(this, LOTRFoods.ORC_DRINK, 8000));
this.addTargetTasks(true);
}
@Override
diff --git a/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptSkeleton.java b/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptSkeleton.java
index 94777c3..fadbf8c 100644
--- a/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptSkeleton.java
+++ b/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptSkeleton.java
@@ -1,6 +1,7 @@
package com.zivilon.cinder_loe.entity.corrupt;
import com.zivilon.cinder_loe.CinderLoE_Config;
+import lotr.common.LOTRLevelData;
import lotr.common.entity.ai.LOTREntityAIAttackOnCollide;
import lotr.common.entity.npc.LOTREntityGondorMan;
import lotr.common.entity.npc.LOTRNames;
@@ -41,7 +42,15 @@ public class CorruptSkeleton extends CorruptMan {
@Override
public LOTRFaction getFaction() {
- return LOTRFaction.UTUMNO;
+ /**
+ * ok doesnt work, will need an alternative, maybe a new method
+ if (hiredNPCInfo.getHiringPlayer() != null) {
+ if (LOTRLevelData.getData(hiredNPCInfo.getHiringPlayer()).getPledgeFaction() != null) {
+ return LOTRFaction.valueOf(String.valueOf(LOTRLevelData.getData(hiredNPCInfo.getHiringPlayer()).getPledgeFaction()));
+ }
+ }
+ */
+ return LOTRFaction.valueOf(CinderLoE_Config.skeleton_faction);
}
@Override
diff --git a/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptSkeletonArcher.java b/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptSkeletonArcher.java
index 58ef61e..a6b7fe5 100644
--- a/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptSkeletonArcher.java
+++ b/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptSkeletonArcher.java
@@ -57,12 +57,6 @@ public class CorruptSkeletonArcher extends CorruptSkeleton {
}
}
-
- @Override
- public LOTRFaction getFaction() {
- return LOTRFaction.UTUMNO;
- }
-
@Override
public String getNPCName() {
return this.familyInfo.getName();
diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/MixinEntityLivingBase.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinEntityLivingBase.java
index 7f10045..ade4623 100644
--- a/src/main/java/com/zivilon/cinder_loe/mixins/MixinEntityLivingBase.java
+++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinEntityLivingBase.java
@@ -1,6 +1,9 @@
package com.zivilon.cinder_loe.mixins;
import com.zivilon.cinder_loe.util.*;
+import com.zivilon.cinder_loe.world.event.Warband;
+import com.zivilon.cinder_loe.world.event.WarbandLocationInfo;
+import com.zivilon.cinder_loe.world.event.WarbandTracker;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.*;
@@ -15,7 +18,10 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.Potion;
import net.minecraft.server.MinecraftServer;
+import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.ChatComponentTranslation;
+import net.minecraft.util.ChatStyle;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.World;
@@ -257,14 +263,36 @@ public abstract class MixinEntityLivingBase extends Entity implements IEntityLiv
}
}
+ public void setDead() {
+ super.setDead();
+ if (this.warband_uuid != null && this.warband_uuid.equals(this.getUniqueID())) {
+ WarbandLocationInfo info = WarbandTracker.locations.get(this.warband_uuid);
+ String faction_name = "";
+ if (info != null && info.warband != null && info.warband.faction != null) {
+ faction_name = info.warband.faction.faction.untranslatedFactionName();
+ }
+ ChatComponentTranslation message;
+ if (!faction_name.equals("")) {
+ message = new ChatComponentTranslation(
+ "warband.defeated.faction",
+ new ChatComponentTranslation(faction_name)
+ );
+ } else {
+ message = new ChatComponentTranslation(
+ "warband.defeated.no_faction"
+ );
+ }
+ message.setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GRAY));
+ MinecraftServer.getServer().getConfigurationManager().sendChatMsg(message);
+ WarbandTracker.remove(this.warband_uuid);
+ }
+ }
+
@Inject(method = "onUpdate", at = @At("TAIL"))
private void onUpdate(CallbackInfo ci) {
if (despawn_timer > -1) {
despawn_timer--;
if (despawn_timer == 0) {
- if (warband_uuid == ((EntityLivingBase)(Object)this).getUniqueID()) {
- MinecraftServer.getServer().getConfigurationManager().sendChatMsg(new ChatComponentText(EnumChatFormatting.GRAY + "Warband has disbanded"));
- }
((EntityLivingBase)(Object)this).setDead();
}
}
diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAIAttackOnCollide.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAIAttackOnCollide.java
index a4af150..c1fbe49 100644
--- a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAIAttackOnCollide.java
+++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAIAttackOnCollide.java
@@ -4,6 +4,7 @@ import com.zivilon.cinder_loe.CinderLoE;
import com.zivilon.cinder_loe.client.model.*;
import com.zivilon.cinder_loe.entity.Renegade;
import com.zivilon.cinder_loe.util.IEntityLivingBase;
+import com.zivilon.cinder_loe.util.Utilities;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -27,35 +28,39 @@ import java.util.UUID;
@Mixin(LOTREntityAIAttackOnCollide.class)
public class MixinLOTREntityAIAttackOnCollide {
- @Shadow
+ @Shadow(remap = false)
protected World worldObj;
- @Shadow
+ @Shadow(remap = false)
protected EntityCreature theOwner;
- @Shadow
+ @Shadow(remap = false)
protected EntityLivingBase attackTarget;
- @Shadow
+ @Shadow(remap = false)
protected int attackTick;
- @Shadow
+ @Shadow(remap = false)
protected void updateLookAndPathing() {}
public UUID leader_id;
public Entity leader;
@Overwrite
public void updateTask() {
+ if (warband_task()) return;
+ update_vanilla_task();
+ }
+
+ private boolean warband_task() {
EntityCreature entity = this.theOwner;
UUID leader_id = ((IEntityLivingBase)entity).get_warband_uuid();
if (leader_id != null) {
if (leader == null)
- leader = find_entity_by_uuid(entity.worldObj, leader_id);
+ leader = Utilities.find_entity_by_uuid(entity.worldObj, leader_id);
if (leader != null && entity.getDistanceSqToEntity(leader) > 576.0D) {
entity.setAttackTarget(null);
entity.getNavigator().tryMoveToEntityLiving(leader, 1.3D);
- return; // Return here to not run default logic
+ return true; // Return here to not run default logic
}
}
-
- update_vanilla_task();
+ return false;
}
private void update_vanilla_task() {
@@ -95,13 +100,4 @@ public class MixinLOTREntityAIAttackOnCollide {
this.theOwner.swingItem();
}
}
-
- private Entity find_entity_by_uuid(World world, UUID uuid) {
- for (Object obj : world.loadedEntityList) {
- if (obj instanceof Entity && uuid.equals(((Entity) obj).getUniqueID())) {
- return (Entity)obj;
- }
- }
- return null;
- }
}
diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAINearestAttackableTargetBasic.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAINearestAttackableTargetBasic.java
index d52413c..7101456 100644
--- a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAINearestAttackableTargetBasic.java
+++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAINearestAttackableTargetBasic.java
@@ -3,6 +3,7 @@ package com.zivilon.cinder_loe.mixins;
import com.zivilon.cinder_loe.entity.Renegade;
import com.zivilon.cinder_loe.potion.LoEPotions;
import com.zivilon.cinder_loe.util.IEntityLivingBase;
+import com.zivilon.cinder_loe.util.Utilities;
import lotr.common.LOTRLevelData;
import lotr.common.LOTRMod;
@@ -52,25 +53,29 @@ public abstract class MixinLOTREntityAINearestAttackableTargetBasic extends Enti
@Overwrite(remap = true)
public boolean shouldExecute() {
+ if (warband_should_execute()) return false;
+ return original_should_execute();
+ }
+
+ private boolean warband_should_execute() {
EntityCreature self = taskOwner;
- if (!(self instanceof IEntityLivingBase)) return original_should_execute();
+ if (!(self instanceof IEntityLivingBase)) return false;
UUID leader_id = ((IEntityLivingBase) self).get_warband_uuid();
- if (leader_id == null) return original_should_execute();
+ if (leader_id == null) return false;
- Entity leader = find_entity_by_uuid(self.worldObj, leader_id);
- if (leader == null) return original_should_execute();
+ Entity leader = Utilities.find_entity_by_uuid(self.worldObj, leader_id);
+ if (leader == null) return false;
double distance_squared = self.getDistanceSqToEntity(leader);
if (distance_squared > 576.0D) {
self.setAttackTarget(null);
self.getNavigator().tryMoveToEntityLiving(leader, 1.3D);
- return false;
+ return true;
}
- return original_should_execute();
+ return false;
}
-
public boolean original_should_execute() {
if (this.targetChance > 0 && this.taskOwner.getRNG().nextInt(this.targetChance) != 0)
return false;
@@ -97,15 +102,6 @@ public abstract class MixinLOTREntityAINearestAttackableTargetBasic extends Enti
return true;
}
- private Entity find_entity_by_uuid(World world, UUID uuid) {
- for (Object obj : world.loadedEntityList) {
- if (obj instanceof Entity && uuid.equals(((Entity) obj).getUniqueID())) {
- return (Entity)obj;
- }
- }
- return null;
- }
-
/**
* @author Shinare
* @reason Added corrupting potion effect that makes all NPCs hostile
diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAIOrcSkirmish.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAIOrcSkirmish.java
new file mode 100644
index 0000000..3d56d18
--- /dev/null
+++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAIOrcSkirmish.java
@@ -0,0 +1,26 @@
+package com.zivilon.cinder_loe.mixins;
+
+import com.zivilon.cinder_loe.util.IEntityLivingBase;
+
+import lotr.common.entity.npc.LOTREntityOrc;
+import lotr.common.entity.ai.LOTREntityAIOrcSkirmish;
+
+import net.minecraft.entity.EntityLivingBase;
+
+import org.spongepowered.asm.mixin.*;
+import org.spongepowered.asm.mixin.injection.*;
+import org.spongepowered.asm.mixin.injection.callback.*;
+
+@Mixin(LOTREntityAIOrcSkirmish.class)
+public class MixinLOTREntityAIOrcSkirmish {
+
+ @Overwrite(remap = false)
+ private boolean canOrcSkirmish(EntityLivingBase entity) {
+ if (entity instanceof LOTREntityOrc) {
+ LOTREntityOrc orc = (LOTREntityOrc)entity;
+ if (((IEntityLivingBase)orc).get_warband_uuid() != null) return false;
+ return (!orc.isTrader() && !orc.hiredNPCInfo.isActive && orc.ridingEntity == null && orc.canOrcSkirmish());
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAIRangedAttack.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAIRangedAttack.java
new file mode 100644
index 0000000..dad0ebb
--- /dev/null
+++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAIRangedAttack.java
@@ -0,0 +1,119 @@
+package com.zivilon.cinder_loe.mixins;
+
+import com.zivilon.cinder_loe.CinderLoE;
+import com.zivilon.cinder_loe.client.model.*;
+import com.zivilon.cinder_loe.entity.Renegade;
+import com.zivilon.cinder_loe.util.IEntityLivingBase;
+import com.zivilon.cinder_loe.util.Utilities;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.Overwrite;
+
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLiving;
+import net.minecraft.entity.EntityCreature;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.IEntityLivingData;
+import net.minecraft.entity.IRangedAttackMob;
+import net.minecraft.item.ItemStack;
+import net.minecraft.world.World;
+import net.minecraft.util.MathHelper;
+import net.minecraft.util.Vec3;
+
+import lotr.common.entity.npc.LOTREntityNPC;
+import lotr.common.entity.ai.LOTREntityAIRangedAttack;
+import lotr.common.item.LOTRItemSpear;
+import lotr.common.item.LOTRWeaponStats;
+
+import java.util.UUID;
+
+@Mixin(LOTREntityAIRangedAttack.class)
+public class MixinLOTREntityAIRangedAttack {
+
+ @Shadow(remap = false)
+ private EntityLiving theOwner;
+ @Shadow(remap = false)
+ private IRangedAttackMob theOwnerRanged;
+ @Shadow(remap = false)
+ private EntityLivingBase attackTarget;
+ @Shadow(remap = false)
+ private int rangedAttackTime;
+ @Shadow(remap = false)
+ private double moveSpeed;
+ @Shadow(remap = false)
+ private double moveSpeedFlee = 1.5D;
+ @Shadow(remap = false)
+ private int repathDelay;
+ @Shadow(remap = false)
+ private int attackTimeMin;
+ @Shadow(remap = false)
+ private int attackTimeMax;
+ @Shadow(remap = false)
+ private float attackRange;
+ @Shadow(remap = false)
+ private float attackRangeSq;
+ @Shadow(remap = false)
+ public static Vec3 findPositionAwayFrom(EntityLivingBase entity, EntityLivingBase target, int min, int max) {return null;}
+
+ public UUID leader_id;
+ public Entity leader;
+
+ @Overwrite
+ public void updateTask() {
+ if (warband_task()) return;
+ update_vanilla_task();
+ }
+
+ private boolean warband_task() {
+ EntityLiving entity = this.theOwner;
+ UUID leader_id = ((IEntityLivingBase)entity).get_warband_uuid();
+
+ if (leader_id != null) {
+ if (leader == null)
+ leader = Utilities.find_entity_by_uuid(entity.worldObj, leader_id);
+ if (leader != null && entity.getDistanceSqToEntity(leader) > 576.0D) {
+ entity.setAttackTarget(null);
+ entity.getNavigator().tryMoveToEntityLiving(leader, 1.3D);
+ return true; // Return here to not run default logic
+ }
+ }
+ return false;
+ }
+
+ private void update_vanilla_task() {
+ double distanceSq = this.theOwner.getDistanceSq(this.attackTarget.posX, this.attackTarget.boundingBox.minY, this.attackTarget.posZ);
+ boolean canSee = this.theOwner.getEntitySenses().canSee((Entity)this.attackTarget);
+ if (canSee) {
+ this.repathDelay++;
+ } else {
+ this.repathDelay = 0;
+ }
+ if (distanceSq <= this.attackRangeSq) {
+ if (this.theOwner.getDistanceSqToEntity((Entity)this.attackTarget) < 25.0D) {
+ Vec3 vec = findPositionAwayFrom((EntityLivingBase)this.theOwner, this.attackTarget, 8, 16);
+ if (vec != null)
+ this.theOwner.getNavigator().tryMoveToXYZ(vec.xCoord, vec.yCoord, vec.zCoord, this.moveSpeedFlee);
+ } else if (this.repathDelay >= 20) {
+ this.theOwner.getNavigator().clearPathEntity();
+ this.repathDelay = 0;
+ }
+ } else {
+ this.theOwner.getNavigator().tryMoveToEntityLiving((Entity)this.attackTarget, this.moveSpeed);
+ }
+ this.theOwner.getLookHelper().setLookPositionWithEntity((Entity)this.attackTarget, 30.0F, 30.0F);
+ this.rangedAttackTime--;
+ if (this.rangedAttackTime == 0) {
+ if (distanceSq > this.attackRangeSq || !canSee)
+ return;
+ float distanceRatio = MathHelper.sqrt_double(distanceSq) / this.attackRange;
+ float power = distanceRatio;
+ power = MathHelper.clamp_float(power, 0.1F, 1.0F);
+ this.theOwnerRanged.attackEntityWithRangedAttack(this.attackTarget, power);
+ this.rangedAttackTime = MathHelper.floor_float(distanceRatio * (this.attackTimeMax - this.attackTimeMin) + this.attackTimeMin);
+ } else if (this.rangedAttackTime < 0) {
+ float distanceRatio = MathHelper.sqrt_double(distanceSq) / this.attackRange;
+ this.rangedAttackTime = MathHelper.floor_float(distanceRatio * (this.attackTimeMax - this.attackTimeMin) + this.attackTimeMin);
+ }
+ }
+}
diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTRGuiMap.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTRGuiMap.java
new file mode 100644
index 0000000..3a89dea
--- /dev/null
+++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTRGuiMap.java
@@ -0,0 +1,139 @@
+package com.zivilon.cinder_loe.mixins;
+
+import com.zivilon.cinder_loe.world.event.Warband;
+import com.zivilon.cinder_loe.world.event.WarbandTracker;
+import com.zivilon.cinder_loe.world.event.WarbandLocationInfo;
+
+import lotr.client.gui.LOTRGuiMap;
+import lotr.client.gui.LOTRGuiMenuBase;
+import lotr.client.LOTRClientProxy;
+import lotr.common.LOTRLevelData;
+import lotr.common.fac.LOTRFaction;
+
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.StatCollector;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.lwjgl.opengl.GL11;
+
+import org.spongepowered.asm.mixin.*;
+import org.spongepowered.asm.mixin.injection.*;
+import org.spongepowered.asm.mixin.injection.callback.*;
+
+
+@Mixin(LOTRGuiMap.class)
+public abstract class MixinLOTRGuiMap extends LOTRGuiMenuBase {
+ private static Map warband_locations = WarbandTracker.locations;
+ private static ResourceLocation WARBAND_ICON = new ResourceLocation("cinderloe", "textures/gui/alignment.png");
+
+ @Shadow(remap = false)
+ private boolean loadingConquestGrid;
+ @Shadow(remap = false)
+ private boolean hasOverlay;
+ @Shadow(remap = false)
+ private static int mapXMin;
+ @Shadow(remap = false)
+ private static int mapXMax;
+ @Shadow(remap = false)
+ private static int mapYMin;
+ @Shadow(remap = false)
+ private static int mapYMax;
+ @Shadow(remap = false)
+ private void drawFancyRect(int x1, int y1, int x2, int y2) {}
+ @Shadow(remap = false)
+ public float[] transformCoords(float x, float z) { return null;}
+
+ @Inject(method = "func_73863_a", at = @At("HEAD"), remap = false)
+ public void inject_head(int mouseX, int mouseY, float partialTicks, CallbackInfo ci) {
+ System.out.println("[MixinLOTRGuiMap] Inject at HEAD");
+ }
+ @Inject(method = "func_73863_a", at = @At( value = "INVOKE", target = "renderPlayers(II)V", shift = At.Shift.AFTER), remap = false)
+ public void inject_render_warbands(int mouseX, int mouseY, float partialTicks, CallbackInfo ci) {
+ System.out.println("[MixinLOTRGuiMap] Running wrapper");
+ render_warbands(mouseX, mouseY);
+ }
+
+ @Dynamic
+ private void render_warbands(int cursor_x, int cursor_y) {
+ System.out.println("[MixinLOTRGuiMap] Rendering warband icon");
+ String mouse_over_warband_name = null;
+ double mouse_over_warband_x = 0.0D;
+ double mouse_over_warband_y = 0.0D;
+ double shortest_distance_to_cursor = Double.MAX_VALUE;
+ int icon_width_half = 4;
+ for (Map.Entry entry : warband_locations.entrySet()) {
+ System.out.println("[MixinLOTRGuiMap] Iterated");
+ WarbandLocationInfo info = entry.getValue();
+ Warband warband = info.warband;
+ String warband_name = warband.faction.warband_name;
+ float[] pos = transformCoords((float)info.x, (float)info.z);
+ int map_x = Math.round(pos[0]);
+ int map_y = Math.round(pos[1]);
+
+ double distance_to_icon = render_warband_icon(warband, map_x, map_y, cursor_x, cursor_y);
+ if (distance_to_icon <= (icon_width_half + 3)) {
+ if (distance_to_icon <= shortest_distance_to_cursor) {
+ mouse_over_warband_name = StatCollector.translateToLocal(warband_name);
+ mouse_over_warband_x = map_x;
+ mouse_over_warband_y = map_y;
+ shortest_distance_to_cursor = distance_to_icon;
+ }
+ }
+ }
+ if (mouse_over_warband_name != null && !this.hasOverlay && !this.loadingConquestGrid) {
+ int name_width = this.mc.fontRenderer.getStringWidth(mouse_over_warband_name);
+ int name_height = this.mc.fontRenderer.FONT_HEIGHT;
+ int namebox_x = (int)Math.round(mouse_over_warband_x);
+ int namebox_y = (int)Math.round(mouse_over_warband_y);
+ namebox_y += icon_width_half + 3;
+ int border = 3;
+ int namebox_width = name_width + border * 2;
+ namebox_x -= namebox_width / 2;
+ int namebox_height = name_height + border * 2;
+ int map_border = 2;
+ namebox_x = Math.max(namebox_x, mapXMin + map_border);
+ namebox_x = Math.min(namebox_x, mapXMax - map_border - namebox_width);
+ namebox_y = Math.max(namebox_y, mapYMin + map_border);
+ namebox_y = Math.min(namebox_y, mapYMax - map_border - namebox_height);
+ GL11.glTranslatef(0.0F, 0.0F, 300.0F);
+ drawFancyRect(namebox_x, namebox_y, namebox_x + namebox_width, namebox_y + namebox_height);
+ this.mc.fontRenderer.drawString(mouse_over_warband_name, namebox_x + border, namebox_y + border, 16777215);
+ GL11.glTranslatef(0.0F, 0.0F, -300.0F);
+ }
+ }
+
+ @Dynamic
+ private double render_warband_icon(Warband warband, double map_x, double map_y, int mouse_x, int mouse_y) {
+ int icon_half = 4;
+ int icon_border = icon_half + 1;
+
+ map_x = Math.max(mapXMin + icon_border, Math.min(mapXMax - icon_border - 1, map_x));
+ map_y = Math.max(mapYMin + icon_border, Math.min(mapYMax - icon_border - 1, map_y));
+
+ // Determine ally/enemy icon
+ LOTRFaction faction = warband.faction.faction;
+ float alignment = LOTRLevelData.getData(mc.thePlayer).getAlignment(faction);
+ boolean is_ally = alignment > 0.0F;
+
+ load_warband_icon(is_ally, (int) map_x, (int) map_y);
+
+ // Return mouse distance to icon
+ double dx = map_x - mouse_x;
+ double dy = map_y - mouse_y;
+ return Math.hypot(dx, dy);
+ }
+
+
+ @Dynamic
+ private void load_warband_icon(boolean ally, int x, int y) {
+ System.out.println("[MixinLOTRGuiMap] Loading warband icon: " + (ally ? "ally" : "enemy"));
+ mc.getTextureManager().bindTexture(LOTRClientProxy.alignmentTexture);
+ GL11.glColor4f(1F, 1F, 1F, 1F);
+ int variant = ally ? 16 : 0;
+ drawTexturedModalRect(x - 8, y - 8, variant, 228, 16, 16);
+ }
+
+}
diff --git a/src/main/java/com/zivilon/cinder_loe/network/PacketRegistration.java b/src/main/java/com/zivilon/cinder_loe/network/PacketRegistration.java
new file mode 100644
index 0000000..e2a9114
--- /dev/null
+++ b/src/main/java/com/zivilon/cinder_loe/network/PacketRegistration.java
@@ -0,0 +1,12 @@
+package com.zivilon.cinder_loe.network;
+
+import com.zivilon.cinder_loe.network.PacketWarbandLocations.Handler;
+import lotr.common.network.LOTRPacketHandler;
+import cpw.mods.fml.relauncher.Side;
+
+public class PacketRegistration {
+ public static void register() {
+ int id = 200;
+ LOTRPacketHandler.networkWrapper.registerMessage(PacketWarbandLocations.Handler.class, PacketWarbandLocations.class, id++, Side.CLIENT);
+ }
+}
diff --git a/src/main/java/com/zivilon/cinder_loe/network/PacketWarbandLocations.java b/src/main/java/com/zivilon/cinder_loe/network/PacketWarbandLocations.java
new file mode 100644
index 0000000..d1e08e5
--- /dev/null
+++ b/src/main/java/com/zivilon/cinder_loe/network/PacketWarbandLocations.java
@@ -0,0 +1,115 @@
+package com.zivilon.cinder_loe.network;
+
+import com.zivilon.cinder_loe.world.event.Warband;
+import com.zivilon.cinder_loe.world.event.WarbandFaction;
+import com.zivilon.cinder_loe.world.event.WarbandLocationInfo;
+import com.zivilon.cinder_loe.world.event.WarbandTracker;
+
+import cpw.mods.fml.common.FMLLog;
+import cpw.mods.fml.common.network.simpleimpl.IMessage;
+import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
+import cpw.mods.fml.common.network.simpleimpl.MessageContext;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import lotr.common.LOTRMod;
+import lotr.common.network.LOTRPacketHandler;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTUtil;
+import net.minecraft.network.PacketBuffer;
+import net.minecraft.world.World;
+
+public class PacketWarbandLocations implements IMessage {
+ public List locations = WarbandTracker.get_all();
+
+ @Override
+ public void toBytes(ByteBuf buf) {
+ buf.writeShort(locations.size());
+ for (WarbandLocationInfo loc : locations) {
+ buf.writeLong(loc.warband.warband_uuid.getMostSignificantBits());
+ buf.writeLong(loc.warband.warband_uuid.getLeastSignificantBits());
+ buf.writeDouble(loc.x);
+ buf.writeDouble(loc.z);
+ PacketBuffer packet = new PacketBuffer(buf);
+ write_string_to_buffer(packet, loc.warband.faction.name());
+ }
+ }
+
+ @Override
+
+ public void fromBytes(ByteBuf buf) {
+ locations.clear();
+ int count = buf.readShort();
+ for (int i = 0; i < count; i++) {
+ long msb = buf.readLong();
+ long lsb = buf.readLong();
+ UUID uuid = new UUID(msb, lsb);
+ double x = buf.readDouble();
+ double z = buf.readDouble();
+
+ PacketBuffer packet = new PacketBuffer(buf);
+ String faction_name = read_string_from_buffer(packet, Short.MAX_VALUE);
+
+ WarbandFaction faction = WarbandFaction.get_warband_by_name(faction_name);
+
+ Warband dummy = new Warband();
+ dummy.warband_uuid = uuid;
+ dummy.faction = faction;
+ dummy.x = (int) x;
+ dummy.z = (int) z;
+ locations.add(new WarbandLocationInfo(dummy, x, z));
+ }
+ }
+
+ public static class Handler implements IMessageHandler {
+ @Override
+ public IMessage onMessage(PacketWarbandLocations message, MessageContext ctx) {
+ if (ctx.side.isServer()) {
+ System.out.println("[PacketWarbandLocations] WARNING: Client tried to update locations on server!");
+ return null;
+ }
+
+ WarbandTracker.clear_locations();
+ for (WarbandLocationInfo info : message.locations) {
+ WarbandTracker.add(info);
+ }
+ return null;
+ }
+ }
+
+ public static void send_warband_locations(World world) {
+ for (int i = 0; i < world.playerEntities.size(); i++) {
+ EntityPlayer entityplayer = (EntityPlayer)world.playerEntities.get(i);
+ send_location(entityplayer, world);
+ }
+ }
+
+ public static void send_location(EntityPlayer player, World world) {
+ PacketWarbandLocations locations = new PacketWarbandLocations();
+ LOTRPacketHandler.networkWrapper.sendTo((IMessage)locations, (EntityPlayerMP)player);
+ }
+ public static void write_string_to_buffer(PacketBuffer buffer, String string) {
+ try {
+ buffer.writeStringToBuffer(string);
+ } catch (IOException e) {
+ throw new RuntimeException("[PacketWarbandLocations] WARNING: Failed to write warband faction", e);
+ }
+ }
+
+ public static String read_string_from_buffer(PacketBuffer buffer, int max_length) {
+ try {
+ return buffer.readStringFromBuffer(max_length);
+ } catch (IOException e) {
+ throw new RuntimeException("[PacketWarbandLocations] WARNING: Failed to read warband faction", e);
+ }
+ }
+
+}
diff --git a/src/main/java/com/zivilon/cinder_loe/util/Utilities.java b/src/main/java/com/zivilon/cinder_loe/util/Utilities.java
index 5f9c676..d38ee6b 100644
--- a/src/main/java/com/zivilon/cinder_loe/util/Utilities.java
+++ b/src/main/java/com/zivilon/cinder_loe/util/Utilities.java
@@ -3,6 +3,7 @@ package com.zivilon.cinder_loe.util;
import com.zivilon.cinder_loe.CinderLoE;
import com.zivilon.cinder_loe.client.render.item.RenderHelper;
import com.zivilon.cinder_loe.mixins.MixinEntity;
+import com.zivilon.cinder_loe.droptables.*;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
@@ -46,6 +47,7 @@ import net.minecraft.nbt.NBTTagString;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.server.MinecraftServer;
+import net.minecraft.world.World;
public class Utilities {
@@ -328,4 +330,12 @@ public class Utilities {
}
return true;
}
+ public static Entity find_entity_by_uuid(World world, UUID uuid) {
+ for (Object obj : world.loadedEntityList) {
+ if (obj instanceof Entity && uuid.equals(((Entity) obj).getUniqueID())) {
+ return (Entity)obj;
+ }
+ }
+ return null;
+ }
}
diff --git a/src/main/java/com/zivilon/cinder_loe/world/event/Warband.java b/src/main/java/com/zivilon/cinder_loe/world/event/Warband.java
index 6de85ef..cddfa70 100644
--- a/src/main/java/com/zivilon/cinder_loe/world/event/Warband.java
+++ b/src/main/java/com/zivilon/cinder_loe/world/event/Warband.java
@@ -18,12 +18,17 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.util.*;
import net.minecraft.world.World;
+import cpw.mods.fml.common.FMLCommonHandler;
+
import lotr.common.LOTRDimension;
import lotr.common.LOTRMod;
import lotr.common.entity.npc.LOTRSpeech;
import lotr.common.entity.npc.LOTREntityNPC;
+import lotr.common.fac.LOTRFaction;
import lotr.common.world.biome.LOTRBiome;
import lotr.common.world.map.LOTRWaypoint;
+import lotr.common.world.map.LOTRConquestGrid;
+import lotr.common.world.map.LOTRConquestZone;
import java.util.ArrayList;
import java.util.List;
@@ -32,13 +37,19 @@ import java.util.UUID;
public class Warband {
public static Random random = new Random();
- public static World world = MinecraftServer.getServer().worldServerForDimension(LOTRDimension.MIDDLE_EARTH.dimensionID);
- public static long last_warband_timestamp = System.currentTimeMillis() / 1000L - (60*60*4);
+ public static World world;;
+ public static long last_warband_timestamp = System.currentTimeMillis() / 1000L - (60*60*2); // Initialize at 2 hour cooldown on server startup
+
+ static {
+ if (FMLCommonHandler.instance().getSide().isServer()) {
+ world = MinecraftServer.getServer().worldServerForDimension(LOTRDimension.MIDDLE_EARTH.dimensionID);
+ }
+ }
public int x = 0;
public int z = 0;
- public String direction = "null";
- public String waypoint_name = "null";
+ public String direction = null;
+ public String waypoint_name = null;
public WarbandFaction faction = null;
public UUID warband_uuid = null;
@@ -52,32 +63,50 @@ public class Warband {
}
public static void initialize_warband() {
+ LOTRWaypoint waypoint = get_random_waypoint();
+ initialize_warband(null, waypoint, true, null, null);
+ }
+ public static void initialize_warband(WarbandFaction faction, LOTRWaypoint waypoint) {
+ initialize_warband(faction, waypoint, true, null, null);
+ }
+ public static void initialize_warband(WarbandFaction faction, Integer x, Integer z) {
+ initialize_warband(faction, null, false, x, z);
+ }
+ public static void initialize_warband(WarbandFaction faction, LOTRWaypoint waypoint, Integer x, Integer z) {
+ initialize_warband(faction, waypoint, false, x, z);
+ }
+ public static void initialize_warband(WarbandFaction faction, LOTRWaypoint waypoint, boolean randomize, Integer x, Integer z) {
if (MinecraftServer.getServer().getConfigurationManager().playerEntityList.size() < 1)
return;
Warband warband = new Warband();
- LOTRWaypoint waypoint = get_random_waypoint();
- warband.waypoint_name = "lotr.waypoint." + waypoint.getCodeName();
-
- warband.x = waypoint.getXCoord();
- warband.z = waypoint.getZCoord();
-
- switch (random.nextInt(8)) {
- case 0: warband.direction = "North"; warband.z += random.nextInt(701) - 1000; break;
- case 1: warband.direction = "South"; warband.z += random.nextInt(701) + 300; break;
- case 2: warband.direction = "East"; warband.x += random.nextInt(701) + 300; break;
- case 3: warband.direction = "West"; warband.x += random.nextInt(701) - 1000; break;
- case 4: warband.direction = "North-East"; warband.z += random.nextInt(701) - 1000; warband.x += random.nextInt(701) + 300; break;
- case 5: warband.direction = "North-West"; warband.z += random.nextInt(701) - 1000; warband.x += random.nextInt(701) - 1000; break;
- case 6: warband.direction = "South-East"; warband.z += random.nextInt(701) + 300; warband.x += random.nextInt(701) + 300; break;
- case 7: warband.direction = "South-West"; warband.z += random.nextInt(701) + 300; warband.x += random.nextInt(701) - 1000; break;
- default: warband.direction = "none"; break;
+ if (waypoint != null) warband.waypoint_name = "lotr.waypoint." + waypoint.getCodeName();
+
+ if ((x == null || z == null) && waypoint == null) waypoint = get_random_waypoint();
+ if (x == null) x = waypoint.getXCoord();
+ if (z == null) z = waypoint.getZCoord();
+ warband.x = x;
+ warband.z = z;
+
+ if (randomize) {
+ switch (random.nextInt(8)) {
+ case 0: warband.direction = "North"; warband.z += random.nextInt(701) - 1000; break;
+ case 1: warband.direction = "South"; warband.z += random.nextInt(701) + 300; break;
+ case 2: warband.direction = "East"; warband.x += random.nextInt(701) + 300; break;
+ case 3: warband.direction = "West"; warband.x += random.nextInt(701) - 1000; break;
+ case 4: warband.direction = "North-East"; warband.z += random.nextInt(701) - 1000; warband.x += random.nextInt(701) + 300; break;
+ case 5: warband.direction = "North-West"; warband.z += random.nextInt(701) - 1000; warband.x += random.nextInt(701) - 1000; break;
+ case 6: warband.direction = "South-East"; warband.z += random.nextInt(701) + 300; warband.x += random.nextInt(701) + 300; break;
+ case 7: warband.direction = "South-West"; warband.z += random.nextInt(701) + 300; warband.x += random.nextInt(701) - 1000; break;
+ default: warband.direction = "none"; break;
+ }
}
- System.out.println("Loading warband chunks at " + warband.x + "," + warband.z);
load_chunks_at(warband.x, warband.z);
- warband.faction = get_warband_faction_by_biome(warband);
+ if (faction == null) faction = get_warband_faction_by_biome(warband);
+ warband.faction = faction;
spawn_warband(warband);
+ WarbandTracker.add(warband);
}
public static void load_chunks_at(int block_x, int block_z) {
@@ -121,6 +150,7 @@ public class Warband {
}
}).start();
broadcast_warband(world, warband.faction.warband_name, warband.direction, warband.waypoint_name);
+ do_radial_conquest(world, warband.x, warband.z, warband.faction.faction, 50);
last_warband_timestamp = System.currentTimeMillis() / 1000L;
}
public static void spawn_boss_entity(Warband warband, int x, int y, int z) {
@@ -192,13 +222,56 @@ public class Warband {
}
public static void broadcast_warband(World world, String faction_key, String direction, String waypoint_key) {
- IChatComponent message = new ChatComponentTranslation(
- "warband.found",
- new ChatComponentTranslation(faction_key).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD)),
- new ChatComponentText(direction).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.YELLOW)),
- new ChatComponentTranslation(waypoint_key).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.AQUA))
- );
+ IChatComponent message;
+ if (waypoint_key != null && direction != null) {
+ message = new ChatComponentTranslation(
+ "warband.found",
+ new ChatComponentTranslation(faction_key).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD)),
+ new ChatComponentText(direction).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.YELLOW)),
+ new ChatComponentTranslation(waypoint_key).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.AQUA))
+ );
+ } else if (waypoint_key == null){
+ message = new ChatComponentTranslation(
+ "warband.found.no_waypoint",
+ new ChatComponentTranslation(faction_key).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD))
+ );
+ } else {
+ message = new ChatComponentTranslation(
+ "warband.found.no_direction",
+ new ChatComponentTranslation(faction_key).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD)),
+ new ChatComponentTranslation(waypoint_key).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.AQUA))
+ );
+ }
LOTRSpeech.messageAllPlayersInWorld(world, message);
}
+
+ public static void do_radial_conquest(World world, int posX, int posZ, LOTRFaction faction, float amount) {
+ if (!LOTRConquestGrid.conquestEnabled(world)) {
+ return;
+ }
+
+ LOTRConquestZone zone = LOTRConquestGrid.getZoneByWorldCoords(posX, posZ);
+ if (zone == null || zone.isDummyZone) {
+ return;
+ }
+
+ float current_strength = zone.getConquestStrength(faction, world);
+ float target_strength = current_strength + amount;
+ if (target_strength > 100000.0F) {
+ amount = 100000.0F - current_strength;
+ } else if (target_strength < 0.0F) {
+ amount = -current_strength;
+ }
+
+ if (amount == 0.0F) {
+ return;
+ }
+
+ if (amount < 0.0F) {
+ LOTRConquestGrid.doRadialConquest(world, zone, null, null, faction, -amount, -amount);
+ } else {
+ LOTRConquestGrid.doRadialConquest(world, zone, null, faction, null, amount, amount);
+ }
+ }
}
diff --git a/src/main/java/com/zivilon/cinder_loe/world/event/WarbandFaction.java b/src/main/java/com/zivilon/cinder_loe/world/event/WarbandFaction.java
index ab410fd..2964835 100644
--- a/src/main/java/com/zivilon/cinder_loe/world/event/WarbandFaction.java
+++ b/src/main/java/com/zivilon/cinder_loe/world/event/WarbandFaction.java
@@ -885,6 +885,14 @@ public enum WarbandFaction {
}
}
+ public static WarbandFaction get_warband_by_name(String name) {
+ for (WarbandFaction faction : values()) {
+ if (faction.name().equals(name))
+ return faction;
+ }
+ return null;
+ }
+
public static class Troop {
public Class entity_class;
public int amount;
diff --git a/src/main/java/com/zivilon/cinder_loe/world/event/WarbandLocationInfo.java b/src/main/java/com/zivilon/cinder_loe/world/event/WarbandLocationInfo.java
new file mode 100644
index 0000000..741af51
--- /dev/null
+++ b/src/main/java/com/zivilon/cinder_loe/world/event/WarbandLocationInfo.java
@@ -0,0 +1,13 @@
+package com.zivilon.cinder_loe.world.event;
+
+public class WarbandLocationInfo {
+ public Warband warband;
+ public double x;
+ public double z;
+
+ public WarbandLocationInfo(Warband warband, double x, double z) {
+ this.warband = warband;
+ this.x = x;
+ this.z = z;
+ }
+}
diff --git a/src/main/java/com/zivilon/cinder_loe/world/event/WarbandTickHandler.java b/src/main/java/com/zivilon/cinder_loe/world/event/WarbandTickHandler.java
index 57d87ff..1378811 100644
--- a/src/main/java/com/zivilon/cinder_loe/world/event/WarbandTickHandler.java
+++ b/src/main/java/com/zivilon/cinder_loe/world/event/WarbandTickHandler.java
@@ -7,8 +7,7 @@ import cpw.mods.fml.common.gameevent.TickEvent.ServerTickEvent;
public class WarbandTickHandler {
public int tick_counter = 0;
-// public static int INTERVAL_TICKS = 12000; // 10 minutes at 20 TPS
- public static int INTERVAL_TICKS = 1200; // 1 minutes at 20 TPS
+ public static int INTERVAL_TICKS = 12000; // 10 minutes at 20 TPS
@SubscribeEvent
public void onServerTick(ServerTickEvent event) {
@@ -22,10 +21,8 @@ public class WarbandTickHandler {
}
public void run_task() {
- System.out.println("Warband ticked");
- if (Warband.last_warband_timestamp > (System.currentTimeMillis() / 1000L) - 7200) return; // Do not spawn warband if less than 2 hours since last one
-// if (Warband.random.nextInt(10) != 0) return;
- System.out.println("Warband starting");
+ if (Warband.last_warband_timestamp > (System.currentTimeMillis() / 1000L) - (60*60*4)) return; // Do not spawn warband if less than 4 hours since last one
+ if (Warband.random.nextInt(10) != 0) return;
Warband.initialize_warband();
}
}
diff --git a/src/main/java/com/zivilon/cinder_loe/world/event/WarbandTracker.java b/src/main/java/com/zivilon/cinder_loe/world/event/WarbandTracker.java
new file mode 100644
index 0000000..19928be
--- /dev/null
+++ b/src/main/java/com/zivilon/cinder_loe/world/event/WarbandTracker.java
@@ -0,0 +1,30 @@
+package com.zivilon.cinder_loe.world.event;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+public class WarbandTracker {
+ public static Map locations = new HashMap<>();
+
+ public static void clear_locations() {
+ locations.clear();
+ }
+
+ public static void add(Warband warband) {
+ locations.put(warband.warband_uuid, new WarbandLocationInfo(warband, warband.x, warband.z));
+ }
+ public static void add(WarbandLocationInfo info) {
+ locations.put(info.warband.warband_uuid, info);
+ }
+
+ public static void remove(UUID uuid) {
+ locations.remove(uuid);
+ }
+
+ public static List get_all() {
+ return new ArrayList<>(locations.values());
+ }
+}
diff --git a/src/main/resources/assets/cinder_loe/lang/en_US.lang b/src/main/resources/assets/cinder_loe/lang/en_US.lang
index ac0897b..d34e855 100644
--- a/src/main/resources/assets/cinder_loe/lang/en_US.lang
+++ b/src/main/resources/assets/cinder_loe/lang/en_US.lang
@@ -366,7 +366,11 @@ lotr.unitinfo.Rhudaur=To Hire this unit you must have the Rhudaur Objective comp
lotr.unitinfo.Dale=To Hire this unit you must have the Dalish Objective complete.
lotr.unitinfo.Lindon=To Hire this unit you must have the Lindon Objective complete.
-warband.found=Warband of %s has been found %s of %s
+warband.found=Warband of %s was spotted %s of %s!
+warband.found.no_direction=Warband of %s was spotted by %s!
+warband.found.no_waypoint=Warband of %s has been found!
+warband.defeated.faction=Warband of %s has been defeated!
+warband.defeated.no_faction=Warband has been defeated!
warband.fac.MORGUL_VALE=Morgul Vale
warband.fac.WOOD_ELF_SCOUT=Woodland Realm scouts
warband.fac.RED_MOUNTAINS=Red Mountains
diff --git a/src/main/resources/assets/lotr/textures/blocks/ivory_block_side_0.png b/src/main/resources/assets/lotr/textures/blocks/ivory_block_side_0.png
index e427528..373ac6a 100644
Binary files a/src/main/resources/assets/lotr/textures/blocks/ivory_block_side_0.png and b/src/main/resources/assets/lotr/textures/blocks/ivory_block_side_0.png differ
diff --git a/src/main/resources/assets/lotr/textures/blocks/ivory_block_side_90.png b/src/main/resources/assets/lotr/textures/blocks/ivory_block_side_90.png
index b6c0bfe..4f4fddd 100644
Binary files a/src/main/resources/assets/lotr/textures/blocks/ivory_block_side_90.png and b/src/main/resources/assets/lotr/textures/blocks/ivory_block_side_90.png differ
diff --git a/src/main/resources/assets/lotr/textures/blocks/ivory_block_top.png b/src/main/resources/assets/lotr/textures/blocks/ivory_block_top.png
index 74ac7de..72e33ce 100644
Binary files a/src/main/resources/assets/lotr/textures/blocks/ivory_block_top.png and b/src/main/resources/assets/lotr/textures/blocks/ivory_block_top.png differ
diff --git a/src/main/resources/mixins.cinder_loe.json b/src/main/resources/mixins.cinder_loe.json
index cb9b9ce..c378be0 100644
--- a/src/main/resources/mixins.cinder_loe.json
+++ b/src/main/resources/mixins.cinder_loe.json
@@ -52,8 +52,13 @@
"MixinLOTREntityNPC",
"MixinFoodStats",
"MixinLOTRItemMug",
+<<<<<<< HEAD
"MixinLOTRNPCTargetSelector",
"MixinLOTREntityHorse"
+=======
+ "MixinLOTRGuiMap",
+ "MixinLOTREntityAIOrcSkirmish"
+>>>>>>> b62b012e70ebb6eea11d071eb443e10f77f855ce
],
"client": []
}