diff --git a/.gitignore b/.gitignore index 12ddda9..00feb8e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ build .gradle +.vs +.git .idea 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 f5aa482..2e6e07c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,153 +1,31 @@ modName = CinderLoE -modVersion = 1.3.0 - -# This is a case-sensitive string to identify your mod. Convention is to use lower case. +modVersion = 1.4.1 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/CinderAchievement.java b/src/main/java/com/zivilon/cinder_loe/CinderAchievement.java new file mode 100644 index 0000000..d7ba2f0 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/CinderAchievement.java @@ -0,0 +1,17 @@ +package com.zivilon.cinder_loe; + +import lotr.common.LOTRAchievement; +import lotr.common.LOTRMod; +import net.minecraft.init.Items; + +public class CinderAchievement { + + public static LOTRAchievement tameMonkey; + public static LOTRAchievement pickOlog; + + public static void createAchievements() { + tameMonkey = new LOTRAchievement(LOTRAchievement.Category.GENERAL, 78, LOTRMod.banana, "tameMonkey"); + pickOlog = new LOTRAchievement(LOTRAchievement.Category.GENERAL, 79, Items.skull, "pickpocketOlog"); + } + +} diff --git a/src/main/java/com/zivilon/cinder_loe/CinderDimension.java b/src/main/java/com/zivilon/cinder_loe/CinderDimension.java new file mode 100644 index 0000000..3f73fa1 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/CinderDimension.java @@ -0,0 +1,138 @@ +package com.zivilon.cinder_loe; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lotr.common.LOTRAchievement; +import lotr.common.fac.LOTRFaction; +import lotr.common.world.LOTRWorldProvider; +import lotr.common.world.LOTRWorldProviderMiddleEarth; +import lotr.common.world.LOTRWorldProviderUtumno; +import lotr.common.world.biome.LOTRBiome; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; +import net.minecraft.world.WorldProvider; +import net.minecraftforge.common.DimensionManager; +import net.minecraftforge.common.config.Configuration; + +import java.util.*; + +public enum CinderDimension { + ISLAND("Island", 101, LOTRWorldProviderMiddleEarth.class, false, 500, EnumSet.of(DimensionRegion.REG)); + + public String dimensionName; + private int defaultID; + public int dimensionID; + private Class providerClass; + private boolean loadSpawn; + public LOTRBiome[] biomeList = new LOTRBiome[256]; + public Map colorsToBiomeIDs = new HashMap(); + public List majorBiomes = new ArrayList(); + public List achievementCategories = new ArrayList(); + public List allAchievements = new ArrayList(); + public List factionList = new ArrayList(); + public List dimensionRegions = new ArrayList(); + public int spawnCap; + + private CinderDimension(String s, int i, Class c, boolean flag, int spawns, EnumSet regions) { + this.dimensionName = s; + this.defaultID = i; + this.providerClass = c; + this.loadSpawn = flag; + this.spawnCap = spawns; + this.dimensionRegions.addAll(regions); + for (DimensionRegion r : this.dimensionRegions) { + r.setDimension(this); + } + } + public String getUntranslatedDimensionName() { + return "lotr.dimension." + this.dimensionName; + } + + public String getDimensionName() { + return StatCollector.translateToLocal((String)this.getUntranslatedDimensionName()); + } + + public static void configureDimensions(Configuration config, String category) { + for (CinderDimension dim : CinderDimension.values()) { + dim.dimensionID = config.get(category, "Dimension ID: " + dim.dimensionName, dim.defaultID).getInt(); + } + } + + public static void registerDimensions() { + for (CinderDimension dim : CinderDimension.values()) { + DimensionManager.registerProviderType((int)dim.dimensionID, (Class)dim.providerClass, (boolean)dim.loadSpawn); + DimensionManager.registerDimension((int)dim.dimensionID, (int)dim.dimensionID); + } + } + + public static CinderDimension getCurrentDimension(World world) { + WorldProvider provider; + if (world != null && (provider = world.provider) instanceof LOTRWorldProvider) { + return ((LOTRWorldProvider)provider).getLOTRDimension(); + } + return null; + } + + public static CinderDimension getCurrentDimensionWithFallback(World world) { + CinderDimension dim = CinderDimension.getCurrentDimension(world); + if (dim == null) { + return ISLAND; + } + return dim; + } + + public static CinderDimension forName(String s) { + for (CinderDimension dim : CinderDimension.values()) { + if (!dim.dimensionName.equals(s)) continue; + return dim; + } + return null; + } + + public static enum DimensionRegion { + REG("island"); + + private String regionName; + private CinderDimension dimension; + public List factionList = new ArrayList(); + + private DimensionRegion(String s) { + this.regionName = s; + } + + public void setDimension(CinderDimension dim) { + this.dimension = dim; + } + + public CinderDimension getDimension() { + return this.dimension; + } + + public String codeName() { + return this.regionName; + } + + public String getRegionName() { + return StatCollector.translateToLocal((String)("lotr.dimension." + this.dimension.dimensionName + "." + this.codeName())); + } + + public static DimensionRegion forName(String regionName) { + for (DimensionRegion r : DimensionRegion.values()) { + if (!r.codeName().equals(regionName)) continue; + return r; + } + return null; + } + + public static DimensionRegion forID(int ID) { + for (DimensionRegion r : DimensionRegion.values()) { + if (r.ordinal() != ID) continue; + return r; + } + return null; + } + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/CinderDrinkRecipe.java b/src/main/java/com/zivilon/cinder_loe/CinderDrinkRecipe.java new file mode 100644 index 0000000..6fc70b4 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/CinderDrinkRecipe.java @@ -0,0 +1,29 @@ +package com.zivilon.cinder_loe; + +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.world.World; + +public class CinderDrinkRecipe +implements IRecipe { + @Override + public boolean matches(InventoryCrafting inv, World world) { + return false; + } + + @Override + public ItemStack getCraftingResult(InventoryCrafting p_77572_1_) { + return null; + } + + @Override + public int getRecipeSize() { + return 0; + } + + @Override + public ItemStack getRecipeOutput() { + return null; + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/CinderEventHandler.java b/src/main/java/com/zivilon/cinder_loe/CinderEventHandler.java index 56e75ee..90629d6 100644 --- a/src/main/java/com/zivilon/cinder_loe/CinderEventHandler.java +++ b/src/main/java/com/zivilon/cinder_loe/CinderEventHandler.java @@ -1,37 +1,32 @@ 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.items.specials.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.*; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.DataWatcher; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.*; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagString; -import net.minecraft.network.Packet; -import net.minecraft.network.play.server.S04PacketEntityEquipment; -import net.minecraft.network.play.server.S09PacketHeldItemChange; -import net.minecraft.network.play.server.S1CPacketEntityMetadata; -import net.minecraft.network.play.server.S19PacketEntityStatus; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.util.ChatComponentText; 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 +42,24 @@ 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 f127abe..a476009 100644 --- a/src/main/java/com/zivilon/cinder_loe/CinderLoE.java +++ b/src/main/java/com/zivilon/cinder_loe/CinderLoE.java @@ -11,7 +11,9 @@ import com.zivilon.cinder_loe.client.render.entity.*; import com.zivilon.cinder_loe.client.render.projectile.*; import com.zivilon.cinder_loe.client.render.tileentity.*; 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.animals.Monkey; import com.zivilon.cinder_loe.entity.corrupt.*; import com.zivilon.cinder_loe.entity.effect.*; import com.zivilon.cinder_loe.entity.npc.*; @@ -26,14 +28,18 @@ 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.items.specials.*; +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; +import com.zivilon.cinder_loe.world.biome.CinderBiome; +import com.zivilon.cinder_loe.world.event.*; import com.zivilon.cindercore.CinderCore; -import lotr.common.item.*; -import net.minecraft.potion.Potion; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; + import org.objectweb.asm.ClassReader; import org.objectweb.asm.util.TraceClassVisitor; @@ -60,15 +66,13 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import lotr.client.render.entity.*; -import lotr.client.render.entity.LOTRRenderSauron; import lotr.client.render.tileentity.LOTRRenderUtumnoPortal; import lotr.common.LOTRCreativeTabs; import lotr.common.LOTRMod; import lotr.common.entity.animal.*; import lotr.common.entity.npc.*; -import lotr.common.entity.npc.LOTREntityBarrowWight; -import lotr.common.entity.npc.LOTREntitySauron; import lotr.common.entity.projectile.LOTREntityGandalfFireball; +import lotr.common.item.*; import lotr.common.world.biome.LOTRBiome; import lotr.common.world.spawning.LOTRBiomeSpawnList; import lotr.common.world.spawning.LOTRSpawnEntry; @@ -82,30 +86,26 @@ import net.minecraft.entity.passive.EntityWolf; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; +import net.minecraft.potion.Potion; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.world.WorldEvent; import static lotr.common.LOTRMod.horseArmorIron; -import static lotr.common.item.LOTRMaterial.GONDOR; - -import net.minecraft.command.ICommandSender; -import net.minecraft.command.CommandBase; -import net.minecraft.util.ChatComponentText; -import net.minecraftforge.client.ClientCommandHandler; @Mod( modid = "cinder_loe", - version = "1.3.0", + version = "1.4.0", name = "CinderLoE", dependencies = "required-after:spongemixins@[1.1.0,);required-after:lotr", acceptedMinecraftVersions = "[1.7.10]", - acceptableRemoteVersions = "[1.3.0]") + acceptableRemoteVersions = "[1.4.0]") public class CinderLoE { @Instance("cinder_loe") public static CinderLoE instance; public static Logger LOG = LogManager.getLogger(Tags.MODID); + public static boolean DEBUG = false; // LOTR Materials public static LOTRMaterial MATERIAL_RED_DWARF; @@ -189,6 +189,17 @@ public class CinderLoE { // public static Item honey; public static Item doner_kebab; + // Brews + public static Item mugElfBrew; + public static Item mugHumanBrew; + public static Item mugOrcBrew; + public static Item mugDwarfBrew; + public static Item spiceElven; + public static Item spiceHuman; + public static Item spiceOrcish; + public static Item spiceDwarven; + + // Event/special public static Item frostblade; public static Item daggervoid; @@ -332,14 +343,17 @@ public class CinderLoE { public static Item pallandoStaff; public static Item alatarStaff; public static Item sarumanStaff; + public static Item sarumanWhiteStaff; // Relics public static Item welfRelic; + public static Item ulukai; // Spawn eggs public static Item spawnEgg; public static Item unitLevelTool; // Spawn lists + public static LOTRSpawnList RED_DWARF; public static LOTRSpawnList LIMWAITH; public static LOTRSpawnList RHUDAUR; @@ -353,6 +367,7 @@ public class CinderLoE { registerBlocks(); registerItems(); ItemRegistration.registerItems(); + PacketRegistration.register(); registerEntities(); modEventHandler = new CinderEventHandler(); LoEPotions.registerPotions(); @@ -367,6 +382,10 @@ public class CinderLoE { } MinecraftForge.EVENT_BUS.register(this); new CharacterEventListener(); + FMLCommonHandler.instance().bus().register(new WarbandTickHandler()); + MinecraftForge.EVENT_BUS.register(new SwiftnessHandler()); + FMLCommonHandler.instance().bus().register(new com.zivilon.cinder_loe.world.event.UlukaiCurseHandler()); + CinderAchievement.createAchievements(); } @@ -394,9 +413,11 @@ public class CinderLoE { public void serverStarting(FMLServerStartingEvent event) { CharacterRoleAPI.loadRolesFromFile(); event.registerServerCommand(new CommandCinderCharacter()); + event.registerServerCommand(new CommandWarband()); + // event.registerServerCommand(new CommandMobileSound()); } - public void registerEntities() { // Last ID added: 58 + public void registerEntities() { // Last ID added: 63 ///GameRegistry.registerTileEntity(TileEntityMistBlock.class, "TileEntityMistBlock"); ///.registerBlock(TileEntityRustedSword, "TileEntityRustedSword"); GameRegistry.registerTileEntity(TileEntityShadowTile.class, "TileEntityShadowTile"); @@ -427,12 +448,18 @@ public class CinderLoE { EntityRegistry.registerModEntity(FangornElk.class, "FangornElk", (entityID + 9), this, 64, 1, true); EntityRegistry.registerModEntity(FangornWolf.class, "FangornWolf", (entityID + 10), this, 64, 1, true); EntityRegistry.registerModEntity(Wraith.class, "Wraith", (entityID + 15), this, 64, 1, true); + EntityRegistry.registerModEntity(CorruptSkeleton.class, "CorruptSkeleton", (entityID + 59), this, 64, 1, true); + EntityRegistry.registerModEntity(CorruptSkeletonArcher.class, "CorruptSkeletonArcher", (entityID + 60), this, 64, 1, true); //Misc EntityRegistry.registerModEntity(EntityWarDart.class, "WarDart", (entityID + 44), this, 64, 1, true); EntityRegistry.registerModEntity(SarumanFireball.class, "SarumanFireball", entityID + 0, this, 64, 10, true); + EntityRegistry.registerModEntity(SarumanWhiteFireball.class, "SarumanWhiteFireball", entityID + 61, this, 64, 10, true); EntityRegistry.registerModEntity(LOTREntitySauron.class, "LOTREntitySauron", (entityID + 28), this, 64, 1, true); EntityRegistry.registerModEntity(UtumnoSlaveTrader.class, "UtumnoSlaveTrader", (entityID + 30), this, 64, 1, true); + EntityRegistry.registerModEntity(Monkey.class, "Monkey", (entityID + 62), this, 64, 1, true); + + // Faction Units EntityRegistry.registerModEntity(RedDwarfWarrior.class, "RedDwarfWarrior", (entityID + 2), this, 64, 1, true); @@ -468,6 +495,7 @@ public class CinderLoE { EntityRegistry.registerModEntity(EsgarothSoldier.class, "EsgarothSoldier", (entityID + 56), this, 64, 1, true); EntityRegistry.registerModEntity(TauredainTrueBlood.class, "TauredainTrueBlood", (entityID + 57), this, 64, 1, true); EntityRegistry.registerModEntity(Sirrandrai.class, "Sirrandrai", (entityID + 58), this, 64, 1, true); + EntityRegistry.registerModEntity(UmbarUsurper.class, "Usurper", (entityID + 63), this, 64, 1, true); // Frozen Dungeon EntityRegistry.registerModEntity(Nex.class, "Nex", (entityID + 45), this, 64, 1, true); @@ -617,6 +645,18 @@ public class CinderLoE { halva = new LOTRItemFood (7, 4.0f, false).setUnlocalizedName("lotr:halva").setTextureName("lotr:halva"); doner_kebab = new LOTRItemFood (6, 6.0f, false).setUnlocalizedName("lotr:doner_kebab").setTextureName("lotr:doner_kebab"); // honey = new LOTRItemFood(3, 0.4f, false).setPotionEffect(Potion.regeneration.id, 5, 0, 100).setUnlocalizedName("lotr:honey").setTextureName("lotr:honey"); + spiceElven = new Item().setUnlocalizedName("lotr:spice_elven").setTextureName("lotr:spice_elven"); + spiceHuman = new Item().setUnlocalizedName("lotr:spice_human").setTextureName("lotr:spice_human"); + spiceOrcish = new Item().setUnlocalizedName("lotr:spice_orcish").setTextureName("lotr:spice_orcish"); + spiceDwarven = new Item().setUnlocalizedName("lotr:spice_dwarven").setTextureName("lotr:spice_dwarven"); + mugElfBrew = (new LoEItemMug(0.0F)).setDrinkStats(20, 1.0F).addPotionEffect(Potion.moveSpeed.id, 60, 1).toxic().setUnlocalizedName("lotr:mugElfBrew"); + mugHumanBrew = (new LoEItemMug(0.0F)).setDrinkStats(20, 1.0F).addPotionEffect(Potion.regeneration.id, 60, 1).toxic().setUnlocalizedName("lotr:mugHumanBrew"); + mugOrcBrew = (new LoEItemMug(0.0F)).setDrinkStats(20, 1.0F).addPotionEffect(Potion.damageBoost.id, 60, 1).toxic().setUnlocalizedName("lotr:mugOrcBrew"); + mugDwarfBrew = (new LoEItemMug(0.0F)).setDrinkStats(20, 1.0F).addPotionEffect(Potion.field_76443_y.id, 120).toxic().setUnlocalizedName("lotr:mugDwarfBrew"); + ((LoEItemMug)mugElfBrew).setTextureNameFromUnlocalizedName(); + ((LoEItemMug)mugHumanBrew).setTextureNameFromUnlocalizedName(); + ((LoEItemMug)mugOrcBrew).setTextureNameFromUnlocalizedName(); + ((LoEItemMug)mugDwarfBrew).setTextureNameFromUnlocalizedName(); spawnEgg = new CinderLoESpawnEgg(); @@ -625,8 +665,10 @@ public class CinderLoE { pallandoStaff = (new PallandoStaff()).setUnlocalizedName("lotr:pallandoStaff").setTextureName("lotr:pallandoStaff"); alatarStaff = (new AlatarStaff()).setUnlocalizedName("lotr:alatarStaff").setTextureName("lotr:alatarStaff"); sarumanStaff = (new SarumanStaff()).setUnlocalizedName("lotr:sarumanStaff").setTextureName("lotr:sarumanStaff"); + sarumanWhiteStaff = (new SarumanWhiteStaff()).setUnlocalizedName("lotr:sarumanWhiteStaff").setTextureName("lotr:sarumanStaff"); // Relics welfRelic = (new WoodElfRelic()).setUnlocalizedName("lotr:welfRelic").setTextureName("lotr:welfRelic"); + ulukai = (new Ulukai()).setUnlocalizedName("lotr:ulukai").setTextureName("lotr:ulukai"); unitLevelTool = (new unitLevelTool()).setUnlocalizedName("lotr:unitLevelTool").setTextureName("stick"); /** @@ -683,6 +725,14 @@ public class CinderLoE { ItemRegistration.register(halva, "halva", 6911); ItemRegistration.register(doner_kebab, "doner_kebab", 6912); ItemRegistration.register(lightStew, "lightStew", 6913); + ItemRegistration.register(mugElfBrew, "mugElfBrew",6914); + ItemRegistration.register(mugHumanBrew, "mugHumanBrew",6915); + ItemRegistration.register(mugOrcBrew, "mugOrcBrew",6916); + ItemRegistration.register(mugDwarfBrew, "mugDwarfBrew",6917); + ItemRegistration.register(spiceElven, "spiceElven",6918); + ItemRegistration.register(spiceHuman, "spiceHuman",6919); + ItemRegistration.register(spiceOrcish, "spiceOrcish",6920); + ItemRegistration.register(spiceDwarven, "spiceDwarven",6921); ItemRegistration.register(spawnEgg, "spawnEgg", 6003); @@ -691,14 +741,17 @@ public class CinderLoE { ItemRegistration.register(pallandoStaff, "pallandoStaff", 6701); ItemRegistration.register(alatarStaff, "alatarStaff", 6702); ItemRegistration.register(sarumanStaff, "sarumanStaff", 6703); + ItemRegistration.register(sarumanWhiteStaff, "sarumanWhiteStaff", 6705); linkLOTRWeapon(radagastStaff, "radagastStaff"); linkLOTRWeapon(pallandoStaff, "pallandoStaff"); linkLOTRWeapon(alatarStaff, "alatarStaff"); linkLOTRWeapon(sarumanStaff, "sarumanStaff"); + linkLOTRWeapon(sarumanWhiteStaff, "sarumanWhiteStaff"); //Relics ItemRegistration.register(welfRelic, "welfRelic", 6704); + ItemRegistration.register(ulukai, "ulukai", 6706); linkLOTRWeapon(welfRelic, "welfRelic"); @@ -1099,11 +1152,15 @@ public class CinderLoE { RenderingRegistry.registerEntityRenderingHandler(CorruptHobbit.class, new RenderCorruptHobbit()); RenderingRegistry.registerEntityRenderingHandler(CorruptMan.class, new RenderCorruptMan()); RenderingRegistry.registerEntityRenderingHandler(CorruptOrc.class, new RenderCorruptOrc()); + RenderingRegistry.registerEntityRenderingHandler(CorruptSkeleton.class, new RenderCorruptSkeleton()); + RenderingRegistry.registerEntityRenderingHandler(CorruptSkeletonArcher.class, new RenderCorruptSkeleton()); RenderingRegistry.registerEntityRenderingHandler(SarumanFireball.class, new RenderSarumanFireball()); + RenderingRegistry.registerEntityRenderingHandler(SarumanWhiteFireball.class, new RenderSarumanWhiteFireball()); RenderingRegistry.registerEntityRenderingHandler(Renegade.class, new RenderRenegade()); RenderingRegistry.registerEntityRenderingHandler(RenegadeCaptain.class, new RenderRenegade()); RenderingRegistry.registerEntityRenderingHandler(Wraith.class, new RenderWraith()); + RenderingRegistry.registerEntityRenderingHandler(Monkey.class, new RenderMonkey()); RenderingRegistry.registerEntityRenderingHandler(RedDwarfWarrior.class, new LOTRRenderDwarf()); RenderingRegistry.registerEntityRenderingHandler(RedDwarfArbalest.class, new LOTRRenderDwarf()); @@ -1341,6 +1398,7 @@ public class CinderLoE { CinderCore.registerItemFallback(Item.getIdFromItem(pallandoStaff), Item.getIdFromItem(LOTRMod.gandalfStaffWhite), "cinder_loe", "1.0"); CinderCore.registerItemFallback(Item.getIdFromItem(alatarStaff), Item.getIdFromItem(LOTRMod.gandalfStaffWhite), "cinder_loe", "1.0"); CinderCore.registerItemFallback(Item.getIdFromItem(sarumanStaff), Item.getIdFromItem(LOTRMod.gandalfStaffWhite), "cinder_loe", "1.0"); + CinderCore.registerItemFallback(Item.getIdFromItem(sarumanWhiteStaff), Item.getIdFromItem(LOTRMod.gandalfStaffWhite), "cinder_loe", "1.4"); // == Relics == CinderCore.registerItemFallback(Item.getIdFromItem(welfRelic), Item.getIdFromItem(LOTRMod.rhinoHorn), "cinder_loe", "1.2"); // == Specials == @@ -1412,6 +1470,7 @@ public class CinderLoE { CinderCore.registerEntityFallback(CorruptOrc.class, LOTREntityGundabadOrc.class, "cinder_loe", "1.2.3"); CinderCore.registerEntityFallback(SarumanFireball.class, LOTREntityGandalfFireball.class, "cinder_loe", "1.0"); + CinderCore.registerEntityFallback(SarumanWhiteFireball.class, LOTREntityGandalfFireball.class, "cinder_loe", "1.4"); CinderCore.registerEntityFallback(Renegade.class, LOTREntityBandit.class, "cinder_loe", "1.0"); CinderCore.registerEntityFallback(RenegadeCaptain.class, LOTREntityBandit.class, "cinder_loe", "1.1"); CinderCore.registerEntityFallback(Wraith.class, LOTREntityMarshWraith.class, "cinder_loe", "1.0"); 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..92a742d 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,8 @@ 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 String ulukai_faction; public static boolean objective_lindon; public static boolean objective_arnor; @@ -24,6 +26,8 @@ public class CinderLoE_Config { public static boolean objective_dale; public static boolean objective_rhudaur; + public static boolean warbands_enabled; + public static void init(FMLPreInitializationEvent event) { File configFile = new File(event.getModConfigurationDirectory(), "CinderLoE.cfg"); @@ -41,7 +45,10 @@ 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"); + + ulukai_faction = config.getString("UlukaiFaction", Configuration.CATEGORY_GENERAL, "GUNDABAD", "Configure the faction the Ulukai Assists"); 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"); @@ -53,6 +60,7 @@ public class CinderLoE_Config { objective_dale = config.getBoolean("Dale", Configuration.CATEGORY_GENERAL, false, "set true if Dalish Objective Complete"); objective_rhudaur = config.getBoolean("Rhudaur", Configuration.CATEGORY_GENERAL, false, "set true if Rhudaur Objective Complete"); + warbands_enabled = config.getBoolean("Warbands", Configuration.CATEGORY_GENERAL, true, "Set false to disable warbands"); // Save the configuration if it has changed if (config.hasChanged()) { config.save(); diff --git a/src/main/java/com/zivilon/cinder_loe/Materials.java b/src/main/java/com/zivilon/cinder_loe/Materials.java index 8cc5e7a..02d4012 100644 --- a/src/main/java/com/zivilon/cinder_loe/Materials.java +++ b/src/main/java/com/zivilon/cinder_loe/Materials.java @@ -14,7 +14,7 @@ public class Materials { public static void registerMaterials() { modifyMaterial("RED_DWARF", 700, 3.0F, 0.7F, 3, 7.0F, 10, CinderLoE.redDwarfSteel); modifyMaterial("WIZARD", 1000, 3.0F, 0.7F, 3, 7.0F, 10, null); - modifyMaterial("BONEMOLD", 674, 2.0F, 0.6F, 2, 6.0F, 10, CinderLoE.bonemold); //Original Durability = 350 | Add 162 | 2/4 + modifyMaterial("BONEMOLD", 512, 2.5F, 0.6F, 2, 6.0F, 10, CinderLoE.bonemold); //Original Durability = 350 | Add 81 | 162 if Upgraded Armory | 2/4 (Unupgraded) modifyMaterial("LIMWAITH_WOOD", 230, 1.5F, 0.5F, 2, 5.0F, 10, Item.getItemFromBlock(LOTRMod.driedReeds)); modifyMaterial("EVENT", 2400, 5.0F, 0.8F, 0, 9.0F, 10, LOTRMod.emerald); modifyMaterial("BREE", 350, 2.5F, 0.6F, 2, 6.0F, 10, Items.iron_ingot); diff --git a/src/main/java/com/zivilon/cinder_loe/ShapelessDurabilityRecipe.java b/src/main/java/com/zivilon/cinder_loe/ShapelessDurabilityRecipe.java index 4e8bb1c..0fe77ba 100644 --- a/src/main/java/com/zivilon/cinder_loe/ShapelessDurabilityRecipe.java +++ b/src/main/java/com/zivilon/cinder_loe/ShapelessDurabilityRecipe.java @@ -28,7 +28,6 @@ public class ShapelessDurabilityRecipe implements IRecipe { @Override public boolean matches(InventoryCrafting inv, World worldIn) { - System.out.println("[CinderLoE] Checking matches for ShapelessDurabilityRecipe"); boolean hasTool = false; List ingredientsCopy = new ArrayList<>(this.recipeItems); @@ -48,7 +47,6 @@ public class ShapelessDurabilityRecipe implements IRecipe { } } if (!matched) { - System.out.println("[CinderLoE] Ingredient did not match: " + stack); return false; } } @@ -56,13 +54,11 @@ public class ShapelessDurabilityRecipe implements IRecipe { } boolean matches = hasTool && ingredientsCopy.isEmpty(); - System.out.println("[CinderLoE] ShapelessDurabilityRecipe match result: " + matches + ", has tool: " + hasTool); return matches; } @Override public ItemStack getCraftingResult(InventoryCrafting inv) { - System.out.println("[CinderLoE] Getting crafting result for ShapelessDurabilityRecipe"); return this.recipeOutput.copy(); } @@ -77,7 +73,6 @@ public class ShapelessDurabilityRecipe implements IRecipe { } public ItemStack[] getRemainingItems(InventoryCrafting inv) { - System.out.println("[CinderLoE] Getting remaining items for ShapelessDurabilityRecipe"); ItemStack[] remainingItems = new ItemStack[inv.getSizeInventory()]; for (int i = 0; i < remainingItems.length; ++i) { @@ -86,16 +81,13 @@ public class ShapelessDurabilityRecipe implements IRecipe { if (itemstack != null && itemstack.getItem() == toolItem) { ItemStack tool = itemstack.copy(); tool.setItemDamage(tool.getItemDamage() + 1); - System.out.println("[CinderLoE] Damaging tool: " + tool.getUnlocalizedName() + " | New Damage: " + tool.getItemDamage()); if (tool.getItemDamage() >= tool.getMaxDamage()) { - System.out.println("[CinderLoE] Tool is out of durability, breaking: " + tool.getUnlocalizedName()); tool = null; } remainingItems[i] = tool; } else if (itemstack != null && itemstack.getItem().hasContainerItem(itemstack)) { - System.out.println("[CinderLoE] Consuming non-tool item " + itemstack.getUnlocalizedName()); remainingItems[i] = itemstack.getItem().getContainerItem(itemstack); } else { remainingItems[i] = itemstack; diff --git a/src/main/java/com/zivilon/cinder_loe/SwiftnessHandler.java b/src/main/java/com/zivilon/cinder_loe/SwiftnessHandler.java new file mode 100644 index 0000000..d4f32f7 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/SwiftnessHandler.java @@ -0,0 +1,56 @@ +// File: SwiftnessHandler.java +package com.zivilon.cinder_loe; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.attributes.AttributeModifier; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraftforge.event.entity.living.LivingEvent; +import lotr.common.enchant.LOTREnchantment; +import lotr.common.enchant.LOTREnchantmentHelper; +import net.minecraft.entity.ai.attributes.IAttributeInstance; + +import java.util.UUID; + +public class SwiftnessHandler { + // Use fixed UUIDs to prevent stacking + private static final UUID[] SWIFTNESS_UUIDS = new UUID[]{ + UUID.fromString("123e4567-e89b-12d3-a456-426614174001"), // boots + UUID.fromString("123e4567-e89b-12d3-a456-426614174002"), // leggings + UUID.fromString("123e4567-e89b-12d3-a456-426614174003"), // chestplate + UUID.fromString("123e4567-e89b-12d3-a456-426614174004") // helmet + }; + private static final String[] MODIFIER_NAMES = new String[]{ + "SwiftnessBoots", "SwiftnessLegs", "SwiftnessChest", "SwiftnessHelm" + }; + + @SubscribeEvent + public void onPlayerTick(LivingEvent.LivingUpdateEvent event) { + if (!(event.entityLiving instanceof EntityPlayer)) return; + + EntityPlayer player = (EntityPlayer) event.entityLiving; + + for (int i = 0; i < player.inventory.armorInventory.length; i++) { + ItemStack armor = player.inventory.armorInventory[i]; + UUID uuid = SWIFTNESS_UUIDS[i]; + String label = MODIFIER_NAMES[i]; + + // Get movement speed attribute + IAttributeInstance attr = player.getEntityAttribute(SharedMonsterAttributes.movementSpeed); +AttributeModifier existingMod = attr.getModifier(uuid); + +if (armor != null && LOTREnchantmentHelper.hasEnchant(armor, LOTREnchantment.getEnchantmentByName("swiftness"))) { + if (existingMod == null) { + AttributeModifier mod = new AttributeModifier(uuid, label, 0.05, 1); + attr.applyModifier(mod); + } +} else { + if (existingMod != null) { + attr.removeModifier(existingMod); + } +} + + } + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/client/model/ModelSunkenSkeleton.java b/src/main/java/com/zivilon/cinder_loe/client/model/ModelSunkenSkeleton.java new file mode 100644 index 0000000..7c9ac1b --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/client/model/ModelSunkenSkeleton.java @@ -0,0 +1,37 @@ +package com.zivilon.cinder_loe.client.model; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; + +/** + * ModelSunkenSkeleton - Cleric_red + * Created using Tabula 4.1.1 + */ +public class ModelSunkenSkeleton + extends ModelBiped { + public ModelSunkenSkeleton() { + this(0.0f); + } + + public ModelSunkenSkeleton(float f) { + super(f, 0.0f, 64, 32); + if (f == 0.0f) { + this.bipedRightArm = new ModelRenderer((ModelBase)this, 40, 16); + this.bipedRightArm.addBox(-1.0f, -2.0f, -1.0f, 2, 12, 2, f); + this.bipedRightArm.setRotationPoint(-5.0f, 2.0f, 0.0f); + this.bipedLeftArm = new ModelRenderer((ModelBase)this, 40, 16); + this.bipedLeftArm.mirror = true; + this.bipedLeftArm.addBox(-1.0f, -2.0f, -1.0f, 2, 12, 2, f); + this.bipedLeftArm.setRotationPoint(5.0f, 2.0f, 0.0f); + this.bipedRightLeg = new ModelRenderer((ModelBase)this, 0, 16); + this.bipedRightLeg.addBox(-1.0f, 0.0f, -1.0f, 2, 12, 2, f); + this.bipedRightLeg.setRotationPoint(-2.0f, 12.0f, 0.0f); + this.bipedLeftLeg = new ModelRenderer((ModelBase)this, 0, 16); + this.bipedLeftLeg.mirror = true; + this.bipedLeftLeg.addBox(-1.0f, 0.0f, -1.0f, 2, 12, 2, f); + this.bipedLeftLeg.setRotationPoint(2.0f, 12.0f, 0.0f); + } + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/client/render/RenderMonkey.java b/src/main/java/com/zivilon/cinder_loe/client/render/RenderMonkey.java new file mode 100644 index 0000000..85936e0 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/client/render/RenderMonkey.java @@ -0,0 +1,45 @@ +package com.zivilon.cinder_loe.client.render; + +import com.zivilon.cinder_loe.entity.Wraith; +import lotr.client.LOTRSpeechClient; +import lotr.client.model.LOTRModelGollum; +import lotr.client.model.LOTRModelMarshWraith; +import lotr.client.render.entity.LOTRNPCRendering; +import lotr.common.entity.npc.LOTREntityGollum; +import net.minecraft.client.Minecraft; +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.entity.RenderLiving; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; + +public class RenderMonkey extends RenderLiving { + private static ResourceLocation skin = new ResourceLocation("cinder_loe:mob/monkey.png"); + + public RenderMonkey() { + super((ModelBase) new LOTRModelGollum(), 0.5f); + } + + protected ResourceLocation getEntityTexture(Entity entity) { + return skin; + } + + protected void preRenderCallback(EntityLivingBase entity, float f) { + float scale = 0.85f; + GL11.glScalef((float) scale, (float) scale, (float) scale); + } + + public void doRender(EntityLiving entity, double d, double d1, double d2, float f, float f1) { + LOTREntityGollum gollum = (LOTREntityGollum)entity; + super.doRender((EntityLiving)gollum, d, d1, d2, f, f1); + if (Minecraft.isGuiEnabled()) { + if (gollum.getGollumOwner() == Minecraft.getMinecraft().thePlayer) { + LOTRNPCRendering.renderNPCHealthBar((EntityLivingBase)entity, d, d1 + 0.5, d2); + } + } + + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/client/render/RenderSarumanWhiteFireball.java b/src/main/java/com/zivilon/cinder_loe/client/render/RenderSarumanWhiteFireball.java new file mode 100644 index 0000000..ec581ab --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/client/render/RenderSarumanWhiteFireball.java @@ -0,0 +1,50 @@ +package com.zivilon.cinder_loe.client.render; + +import lotr.client.LOTRClientProxy; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.entity.Entity; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; + +import com.zivilon.cinder_loe.entity.SarumanWhiteFireball; + +public class RenderSarumanWhiteFireball extends Render { + public static final ResourceLocation particlesTexture = new ResourceLocation("cinder_loe:misc/particles.png"); + + protected ResourceLocation getEntityTexture(Entity entity) { + return particlesTexture; + } + + public void doRender(Entity entity, double d, double d1, double d2, float f, float f1) { + GL11.glPushMatrix(); + GL11.glTranslatef((float)d, (float)d1, (float)d2); + GL11.glEnable(32826); + bindEntityTexture(entity); + Tessellator tessellator = Tessellator.instance; + drawSprite(tessellator, 32 + ((SarumanWhiteFireball)entity).animationTick); + GL11.glDisable(32826); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glPopMatrix(); + } + + private void drawSprite(Tessellator tessellator, int index) { + float f = (index % 8 * 16 + 0) / 128.0F; + float f1 = (index % 8 * 16 + 16) / 128.0F; + float f2 = (index / 8 * 16 + 0) / 128.0F; + float f3 = (index / 8 * 16 + 16) / 128.0F; + float f4 = 1.0F; + float f5 = 0.5F; + float f6 = 0.25F; + GL11.glRotatef(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-this.renderManager.playerViewX, 1.0F, 0.0F, 0.0F); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + tessellator.setBrightness(15728880); + tessellator.addVertexWithUV((0.0F - f5), (0.0F - f6), 0.0D, f, f3); + tessellator.addVertexWithUV((f4 - f5), (0.0F - f6), 0.0D, f1, f3); + tessellator.addVertexWithUV((f4 - f5), (f4 - f6), 0.0D, f1, f2); + tessellator.addVertexWithUV((0.0F - f5), (f4 - f6), 0.0D, f, f2); + tessellator.draw(); + } +} \ No newline at end of file diff --git a/src/main/java/com/zivilon/cinder_loe/client/render/corrupt/RenderCorruptSkeleton.java b/src/main/java/com/zivilon/cinder_loe/client/render/corrupt/RenderCorruptSkeleton.java new file mode 100644 index 0000000..f827d0b --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/client/render/corrupt/RenderCorruptSkeleton.java @@ -0,0 +1,36 @@ +package com.zivilon.cinder_loe.client.render.corrupt; + +import com.zivilon.cinder_loe.client.model.ModelFangornElk; +import com.zivilon.cinder_loe.client.model.ModelSunkenSkeleton; +import com.zivilon.cinder_loe.entity.corrupt.CorruptMan; +import lotr.client.model.LOTRModelHuman; +import lotr.client.model.LOTRModelSkeleton; +import lotr.client.render.entity.LOTRRandomSkins; +import lotr.client.render.entity.LOTRRenderBiped; +import lotr.client.render.entity.LOTRRenderGondorMan; +import lotr.client.render.entity.LOTRRenderSkeleton; +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.renderer.entity.RenderBiped; +import net.minecraft.client.renderer.entity.RenderLiving; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.util.ResourceLocation; + +public class RenderCorruptSkeleton extends RenderBiped { + + private static ResourceLocation skin = new ResourceLocation("textures/entity/skeleton/skeleton.png"); + + public RenderCorruptSkeleton() { + super(new ModelSunkenSkeleton(), 0.5F); + } + + protected void func_82421_b() { + this.field_82423_g = new ModelSunkenSkeleton(1.0F); + this.field_82425_h = new ModelSunkenSkeleton(0.5F); + } + + protected ResourceLocation func_110775_a(Entity entity) { + return skin; + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/command/CommandMobileSound.java b/src/main/java/com/zivilon/cinder_loe/command/CommandMobileSound.java new file mode 100644 index 0000000..46793b9 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/command/CommandMobileSound.java @@ -0,0 +1,43 @@ +package com.zivilon.cinder_loe.command; + +import com.zivilon.cinder_loe.world.sounds.MobileSoundHandler; +import net.minecraft.client.Minecraft; +import net.minecraft.command.CommandBase; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.ChatComponentText; + +public class CommandMobileSound extends CommandBase { + + private boolean active = false; + + @Override + public String getCommandName() { + return "movesound"; + } + + @Override + public String getCommandUsage(ICommandSender sender) { + return "/movesound - turns you into a walking jukebox (toggle command)"; + } + + @Override + public void processCommand(ICommandSender sender, String[] args) { + EntityPlayer player = getCommandSenderAsPlayer(sender); + + if (!player.worldObj.isRemote) { + return; + } + if (!active) { + Minecraft.getMinecraft().getSoundHandler().playSound(new MobileSoundHandler(player, "soundname")); + active = true; + player.addChatMessage(new ChatComponentText("You are a walking jukebox")); + } else { + active = false; + player.addChatMessage(new ChatComponentText("You are no longer a walking jukebox")); + } + + } + +} 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..787ff35 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/command/CommandWarband.java @@ -0,0 +1,157 @@ +package com.zivilon.cinder_loe.command; + +import com.zivilon.cinder_loe.CinderLoE_Config; +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; + case "on": + CinderLoE_Config.warbands_enabled = true; + sender.addChatMessage(new ChatComponentText("Warbands have been enabled!")); + return; + case "off": + CinderLoE_Config.warbands_enabled = true; + sender.addChatMessage(new ChatComponentText("Warbands have been disabled!")); + 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 + "\"")); + return; + } + 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) { + if (args.length < 1) return false; + String action = ""; + if (args[0].equals("summon") || args[0].equals("reset") || args[0].equals("list") || args[0].equals("on") || args[0].equals("off")) { + action = args[0]; + } else { + return false; + } + if (action.equals("summon")) { + if (args.length < 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/coremod/LOTRMaterialTransformer.java b/src/main/java/com/zivilon/cinder_loe/coremod/LOTRMaterialTransformer.java index 63aa60c..980d7b9 100644 --- a/src/main/java/com/zivilon/cinder_loe/coremod/LOTRMaterialTransformer.java +++ b/src/main/java/com/zivilon/cinder_loe/coremod/LOTRMaterialTransformer.java @@ -20,38 +20,38 @@ public class LOTRMaterialTransformer implements IClassTransformer { reader.accept(classNode, 0); - modifyMaterial("ANGMAR", 480, 0.6F, classNode); //Original Durability = 350 | Add 162 | 1/4 - modifyMaterial("URUK", 662, 0.7F, classNode); //Original Durability = 550 | Add 112 | 1/4 - modifyMaterial("BLACK_URUK", 774, 0.7F, classNode); //Original Durability = 550 | Add 112 | 2/4 - modifyMaterial("HALF_TROLL", 475, 0.6F, classNode); //Original Durability = 300 | Add 175 | 1/4 + modifyMaterial("ANGMAR", 431, 0.6F, classNode); //Original Durability = 350 | Add 81 | 162 if Upgraded Armory | 1/4 (Unupgraded) + modifyMaterial("URUK", 606, 0.7F, classNode); //Original Durability = 550 | Add 56 | 112 if Upgraded Armory | 1/4 (Unupgraded) + modifyMaterial("BLACK_URUK", 662, 0.7F, classNode); //Original Durability = 550 | Add 56 | 112 if Upgraded Armory | 2/4 (Unupgraded) + modifyMaterial("HALF_TROLL", 387, 0.6F, classNode); //Original Durability = 300 | Add 87 | 175 if Upgraded Armory | 1/4 (Unupgraded) // Good Humans - modifyMaterial("DALE", 475, 0.6F, classNode); //Original Durability = 300 | Add 175 | 1/4 - modifyMaterial("GONDOR", 861, 0.6F, classNode); //Original Durability = 450 | Add 137 | 3/4 - modifyMaterial("DORWINION_ELF", 875, 0.6F, classNode); //Original Durability = 500 | Add 125 | 3/4 - modifyMaterial("ROHAN", 300, 0.6F, classNode); //Original Durability = 300 | Add 175 | 0/4 - modifyMaterial("TAUREDAIN", 300, 0.6F, classNode); //Original Durability = 300 | Add 175 | 0/4 - modifyMaterial("DORWINION", 400, 0.6F, classNode); //Original Durability = 400 | Add 150 | 0/4 - modifyMaterial("LOSSARNACH", 300, 0.6F, classNode); //Original Durability = 300 | Add 175 | 0/4 - modifyMaterial("LAMEDON", 300, 0.6F, classNode); //Original Durability = 300 | Add 175 | 0/4 + modifyMaterial("DALE", 387, 0.6F, classNode); //Original Durability = 300 | Add 87 | 175 if Upgraded Armory | 1/4 (Unupgraded) + modifyMaterial("GONDOR", 654, 0.6F, classNode); //Original Durability = 450 | Add 68 | 137 if Upgraded Armory | 3/4 (Unupgraded) + modifyMaterial("DORWINION_ELF", 692, 0.6F, classNode); //Original Durability = 500 | Add 62 | 125 if Upgraded Armory | 3/4 (Unupgraded) + modifyMaterial("ROHAN", 300, 0.6F, classNode); //Original Durability = 300 | Add 87 | 175 if Upgraded Armory | 0/4 + modifyMaterial("TAUREDAIN", 300, 0.6F, classNode); //Original Durability = 300 | Add 87 | 175 if Upgraded Armory | 0/4 + modifyMaterial("DORWINION", 400, 0.6F, classNode); //Original Durability = 400 | Add 75 | 150 if Upgraded Armory | 0/4 + modifyMaterial("LOSSARNACH", 300, 0.6F, classNode); //Original Durability = 300 | Add 87 | 175 if Upgraded Armory 0/4 + modifyMaterial("LAMEDON", 300, 0.6F, classNode); //Original Durability = 300 | Add 87 | 175 if Upgraded Armory | 0/4 // Evil Humans - modifyMaterial("RHUN_GOLD", 450, 0.6F, classNode); //Original Durability = 450 | Add 137 | 0/4 - modifyMaterial("RHUN", 400, 0.6F, classNode); //Original Durability = 400 | Add 150 | 0/4 - modifyMaterial("DUNLENDING", 437, 0.6F, classNode); //Original Durability = 250 | Add 187 | 1/4 - modifyMaterial("NEAR_HARAD", 825, 0.6F, classNode); //Original Durability = 300 | Add 175 | 3/4 - modifyMaterial("HARNEDOR", 250, 0.6F, classNode); //Original Durability = 250 | Add 187 | 0/4 - modifyMaterial("CORSAIR", 300, 0.6F, classNode); //Original Durability = 300 | Add 175 | 0/4 - modifyMaterial("GULF_HARAD", 350, 0.6F, classNode); //Original Durability = 350 | Add 162 | 0/4 - modifyMaterial("UMBAR", 724, 0.6F, classNode); //Original Durability = 450 | Add 137 | 2/4 - modifyMaterial("MOREDAIN", 250, 0.6F, classNode); //Original Durability = 250 | Add 187 | 0/4 + modifyMaterial("RHUN_GOLD", 450, 0.6F, classNode); //Original Durability = 450 | Add 68 | 137 if Upgraded Armory | 0/4 + modifyMaterial("RHUN", 400, 0.6F, classNode); //Original Durability = 400 | Add 75 | 150 if Upgraded Armory | 0/4 + modifyMaterial("DUNLENDING", 343, 0.6F, classNode); //Original Durability = 250 | Add 93 | 187 if Upgraded Armory | 1/4 (Unupgraded) + modifyMaterial("NEAR_HARAD", 561, 0.6F, classNode); //Original Durability = 300 | Add 87 | 175 if Upgraded Armory | 3/4 (Unupgraded) + modifyMaterial("HARNEDOR", 250, 0.6F, classNode); //Original Durability = 250 | Add 93 | 187 if Upgraded Armory | 0/4 + modifyMaterial("CORSAIR", 300, 0.6F, classNode); //Original Durability = 300 | Add 87 | 175 if Upgraded Armory | 0/4 + modifyMaterial("GULF_HARAD", 350, 0.6F, classNode); //Original Durability = 350 | Add 81 | 162 if Upgraded Armory | 0/4 + modifyMaterial("UMBAR", 586, 0.6F, classNode); //Original Durability = 450 | Add 68 | 137 if Upgraded Armory | 2/4 (Unupgraded) + modifyMaterial("MOREDAIN", 250, 0.6F, classNode); //Original Durability = 250 | Add 93 | 187 if Upgraded Armory | 0/4 //Elves - modifyMaterial("WOOD_ELVEN", 1000, 0.6F, classNode); //Original Durability = 500 | Add 125 | 4/4 + modifyMaterial("WOOD_ELVEN", 748, 0.6F, classNode); //Original Durability = 500 | Add 62 | 125 if Upgraded Armory | 4/4 (Unupgraded) // Custom - modifyMaterial("UTUMNO", 1500, 0.7F, classNode); //Original Durability = 250 | Add 187 | 0/4 + modifyMaterial("UTUMNO", 1500, 0.7F, classNode); addMaterial("RED_DWARF", classNode); addMaterial("WIZARD", classNode); diff --git a/src/main/java/com/zivilon/cinder_loe/coremod/LOTRWeaponLinker.java b/src/main/java/com/zivilon/cinder_loe/coremod/LOTRWeaponLinker.java index db60d07..d50ded9 100644 --- a/src/main/java/com/zivilon/cinder_loe/coremod/LOTRWeaponLinker.java +++ b/src/main/java/com/zivilon/cinder_loe/coremod/LOTRWeaponLinker.java @@ -20,7 +20,7 @@ public class LOTRWeaponLinker implements IClassTransformer { // Can add any number of items, append with comma return addLinks(basicClass, "spearRedDwarf", "crossbowRedDwarf", "swordRedDwarf", "battleaxeRedDwarf", "pikeRedDwarf", "daggerRedDwarf", "daggerRedDwarfPoisoned", "hammerRedDwarf", - "radagastStaff", "alatarStaff", "pallandoStaff", "sarumanStaff", "maceWarlord", + "radagastStaff", "alatarStaff", "pallandoStaff", "sarumanStaff", "maceWarlord", "sarumanWhiteStaff", "spearLimwaith", "tridentLimwaith", "daggerLimwaith", "daggerLimwaithPoisoned", "truncheonLimwaith", "battleaxeLimwaith", "blowgunLimwaith", "frostblade", "spearsolidgold", "whip", "spearUnnamed", "welfRelic", "daggerVoid", "swordBree", diff --git a/src/main/java/com/zivilon/cinder_loe/droptables/DropContext.java b/src/main/java/com/zivilon/cinder_loe/droptables/DropContext.java new file mode 100644 index 0000000..90548eb --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/droptables/DropContext.java @@ -0,0 +1,13 @@ +package com.zivilon.cinder_loe.droptables; + +public enum DropContext { + KILLED, + KILLED_BY_PLAYER, + KILLED_BY_ENTITY, + KILLED_BY_FIRE, + KILLED_BY_WITHER, + KILLED_BY_DROWNING, + KILLED_BY_EXPLOSION, + PICKPOCKET, + LOOTING_ACTIVE; +} diff --git a/src/main/java/com/zivilon/cinder_loe/droptables/DropTable.java b/src/main/java/com/zivilon/cinder_loe/droptables/DropTable.java new file mode 100644 index 0000000..e6d6350 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/droptables/DropTable.java @@ -0,0 +1,280 @@ +package com.zivilon.cinder_loe.droptables; + +import com.zivilon.cinder_loe.util.ILootableEntity; +import com.zivilon.cinder_loe.util.Utilities; +import com.zivilon.cinder_loe.CinderLoE; + +import net.minecraft.nbt.*; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +import cpw.mods.fml.common.registry.FMLControlledNamespacedRegistry; + +import lotr.common.entity.npc.LOTREntityNPC; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +public class DropTable { + public static Random random = new Random(); + public List drop_list; + + public DropTable() { + drop_list = new ArrayList(); + } + + 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 || drops.size() < 1) return; + for (ItemStack drop : drops) { + entity.npcDropItem(drop, 0.0F, false, false); + } + } + + 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]; + } + List results = new ArrayList<>(); + for (DropInstance drop : table.drop_list) { + ItemStack stack = get_drop(drop, looting_level, context_flags); + if (stack != null) { + results.add(stack); + } + } + return results; + } + + public static ItemStack get_drop(DropInstance drop, int looting_level, DropContext[] context) { + if (!(Utilities.array_contains_array(context, drop.conditions))) return null; + if (drop instanceof SingleItemDrop) { + return get_single_drop((SingleItemDrop)drop, looting_level); + } + if (drop instanceof ItemGroup) { + return get_group_drop((ItemGroup)drop, looting_level); + } + return null; + } + + public static ItemStack get_single_drop(SingleItemDrop drop, int looting_level) { + float chance = drop.drop_chance; + if (drop.looting_affects_chance) + chance = 1.0F - (float)Math.pow(1.0F - chance, 1.0F + 0.1F * looting_level); + if (chance < random.nextFloat()) return null; + + int range = drop.max_amount - drop.min_amount + 1; + if (drop.looting_affects_quantity && looting_level > 0) + range = (int)Math.ceil(range * (1.25F * looting_level)); + int count = random.nextInt(range) + drop.min_amount; + ItemStack stack = new ItemStack(drop.item, count); + if (drop.nbt != null) + stack.setTagCompound((NBTTagCompound)drop.nbt.copy()); + return stack; + } + + public static ItemStack get_group_drop(ItemGroup drop, int looting_level) { + float chance = drop.drop_chance; + if (drop.looting_affects_chance) + chance = 1.0F - (float)Math.pow(1.0F - chance, 1.0F + 0.1F * looting_level); + if (chance < random.nextFloat()) return null; + + int total_weight = drop.entries.stream().mapToInt(e -> e.weight).sum(); + int pick = random.nextInt(total_weight); + for (ItemGroupEntry entry : drop.entries) { + if (pick < entry.weight) { + int range = entry.max_amount - entry.min_amount + 1; + if (entry.looting_affects_quantity && looting_level > 0) + range = (int)Math.ceil(range * (1.25F * looting_level)); + int count = random.nextInt(range) + entry.min_amount; + ItemStack stack = new ItemStack(entry.item, count); + if (entry.nbt != null) + stack.setTagCompound((NBTTagCompound)entry.nbt.copy()); + return stack; + } + pick -= entry.weight; + } + return null; + } + + public static NBTTagCompound serialize_to_nbt(DropTable table) { + NBTTagCompound nbt = new NBTTagCompound(); + NBTTagList drop_list = new NBTTagList(); + for (DropInstance drop : table.drop_list) { + NBTTagCompound drop_tag = new NBTTagCompound(); + drop_tag.setString("type", drop instanceof ItemGroup ? "group" : "single"); + drop_tag.setFloat("drop_chance", drop.drop_chance); + drop_tag.setInteger("min_amount", drop.min_amount); + drop_tag.setInteger("max_amount", drop.max_amount); + drop_tag.setBoolean("looting_affects_chance", drop.looting_affects_chance); + NBTTagList condition_list = new NBTTagList(); + if (drop instanceof SingleItemDrop) { + SingleItemDrop single = (SingleItemDrop)drop; + Item drop_item = single.item; + drop_tag.setBoolean("looting_affects_quantity", single.looting_affects_quantity); + drop_tag.setInteger("id", ((FMLControlledNamespacedRegistry)Item.itemRegistry).getId(drop_item)); + if (single.nbt != null) + drop_tag.setTag("nbt", single.nbt); + } + if (drop instanceof ItemGroup) { + ItemGroup group = (ItemGroup) drop; + NBTTagList entries = new NBTTagList(); + for (ItemGroupEntry entry : group.entries) { + NBTTagCompound entry_tag = new NBTTagCompound(); + entry_tag.setInteger("id", Item.getIdFromItem(entry.item)); + entry_tag.setInteger("weight", entry.weight); + entry_tag.setInteger("min", entry.min_amount); + entry_tag.setInteger("max", entry.max_amount); + entry_tag.setBoolean("looting_quantity", entry.looting_affects_quantity); + if (entry.nbt != null) { + entry_tag.setTag("nbt", entry.nbt.copy()); + } + entries.appendTag(entry_tag); + } + drop_tag.setTag("entries", entries); + } + for (DropContext condition : drop.conditions) { + condition_list.appendTag(new NBTTagString(condition.name())); + } + drop_tag.setTag("conditions", condition_list); + drop_list.appendTag(drop_tag); + nbt.setTag("Drops", drop_list); + } + return nbt; + } + + public static DropTable deserialize_from_nbt(NBTTagCompound tag) { + DropTable table = new DropTable(); + + if (!tag.hasKey("Drops")) return table; + + NBTTagList drop_list = tag.getTagList("Drops", 10); + + for (int i = 0; i < drop_list.tagCount(); i++) { + NBTTagCompound drop_tag = drop_list.getCompoundTagAt(i); + String type = drop_tag.getString("type"); + + float drop_chance = drop_tag.getFloat("drop_chance"); + int min = drop_tag.getInteger("min_amount"); + int max = drop_tag.getInteger("max_amount"); + boolean looting_chance = drop_tag.getBoolean("looting_affects_chance"); + + // Read conditions + DropContext[] conditions; + if (drop_tag.hasKey("conditions")) { + NBTTagList cond_list = drop_tag.getTagList("conditions", 8); + conditions = new DropContext[cond_list.tagCount()]; + for (int j = 0; j < cond_list.tagCount(); j++) { + String ctx = cond_list.getStringTagAt(j); + conditions[j] = DropContext.valueOf(ctx); + } + } else { + conditions = new DropContext[0]; + } + + // Construct drop + if (type.equals("single")) { + Item item = Item.getItemById(drop_tag.getInteger("id")); + boolean looting_quantity = drop_tag.hasKey("looting_affects_quantity") && drop_tag.getBoolean("looting_affects_quantity"); + NBTTagCompound nbt = drop_tag.hasKey("nbt") ? drop_tag.getCompoundTag("nbt") : null; + SingleItemDrop single = new SingleItemDrop(item, nbt, drop_chance, min, max, looting_quantity, looting_chance, conditions); + if (single != null) table.drop_list.add(single); + if (single == null) System.out.println("[DropTable_deserializer] WARNING: Single drop was null!"); + } else if (type.equals("group")) { + List entries = new ArrayList<>(); + if (drop_tag.hasKey("entries")) { + NBTTagList entry_list = drop_tag.getTagList("entries", 10); // 10 = compound + for (int j = 0; j < entry_list.tagCount(); j++) { + NBTTagCompound entry_tag = entry_list.getCompoundTagAt(j); + Item item = Item.getItemById(entry_tag.getInteger("id")); + int weight = entry_tag.getInteger("weight"); + int minAmt = entry_tag.getInteger("min"); + int maxAmt = entry_tag.getInteger("max"); + boolean lootQty = entry_tag.getBoolean("looting_quantity"); + NBTTagCompound nbt = entry_tag.hasKey("nbt") ? entry_tag.getCompoundTag("nbt") : null; + entries.add(new ItemGroupEntry(item, nbt, weight, minAmt, maxAmt, lootQty)); + } + } + ItemGroup group = new ItemGroup(drop_chance, min, max, looting_chance, conditions, entries.toArray(new ItemGroupEntry[0])); + if (group != null) table.drop_list.add(group); + if (group == null) System.out.println("[DropTable_deserializer] WARNING: Group drop was null!"); + } + } + + return table; + } + + + public static class DropInstance { + public float drop_chance; + public int min_amount; + public int max_amount; + public boolean looting_affects_chance; + public DropContext[] conditions; + + public DropInstance(float drop_chance, int min_amount, int max_amount, boolean looting_chance, DropContext[] conditions) { + this.drop_chance = drop_chance; + this.min_amount = min_amount; + this.max_amount = max_amount; + this.looting_affects_chance = looting_chance; + this.conditions = conditions; + } + } + public static class SingleItemDrop extends DropInstance { + public Item item; + public NBTTagCompound nbt; + boolean looting_affects_quantity; + + public SingleItemDrop(Item item, NBTTagCompound nbt, float chance, int min, int max, boolean looting_quantity, boolean looting_chance, DropContext[] conditions) { + super(chance, min, max, looting_chance, conditions); + this.item = item; + this.nbt = nbt; + this.looting_affects_quantity = looting_quantity; + } + public SingleItemDrop(Item item, NBTTagCompound nbt, float chance, DropContext[] conditions) { + super(chance, 1, 1, false, conditions); + this.item = item; + this.nbt = nbt; + this.looting_affects_quantity = false; + } + } + public static class ItemGroup extends DropInstance { + public List entries; + + public ItemGroup(float chance, int min, int max, boolean looting_chance, DropContext[] conditions, ItemGroupEntry... drops) { + super(chance, min, max, looting_chance, conditions); + this.entries = Arrays.asList(drops); + } + } + + public static class ItemGroupEntry { + public Item item; + public int min_amount; + public int max_amount; + public NBTTagCompound nbt; + public int weight; + public boolean looting_affects_quantity; + + public ItemGroupEntry(Item item, NBTTagCompound nbt, int weight, int min_amount, int max_amount, boolean looting_quantity) { + this.item = item; + this.nbt = nbt; + this.weight = weight; + this.min_amount = min_amount; + this.max_amount = max_amount; + this.looting_affects_quantity = looting_quantity; + } + public ItemGroupEntry(Item item, NBTTagCompound nbt, int weight) { + this.item = item; + this.nbt = nbt; + this.weight = weight; + this.min_amount = 1; + this.max_amount = 1; + this.looting_affects_quantity = false; + } + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/droptables/DropTableHandler.java b/src/main/java/com/zivilon/cinder_loe/droptables/DropTableHandler.java new file mode 100644 index 0000000..f4ddd6b --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/droptables/DropTableHandler.java @@ -0,0 +1,5 @@ +package com.zivilon.cinder_loe.droptables; + +public class DropTableHandler { + +} diff --git a/src/main/java/com/zivilon/cinder_loe/enchants/LOTREnchantmentArmorSpecial.java b/src/main/java/com/zivilon/cinder_loe/enchants/LOTREnchantmentArmorSpecial.java new file mode 100644 index 0000000..5c47a42 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/enchants/LOTREnchantmentArmorSpecial.java @@ -0,0 +1,80 @@ +package com.zivilon.cinder_loe.enchants; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import lotr.common.LOTRDamage; +import lotr.common.enchant.LOTREnchantment; +import lotr.common.enchant.LOTREnchantmentBane; +import lotr.common.enchant.LOTREnchantmentType; +import lotr.common.item.LOTRWeaponStats; +import lotr.common.network.LOTRPacketHandler; +import lotr.common.network.LOTRPacketWeaponFX; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.Item; +import net.minecraft.item.ItemArmor; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.StatCollector; +import net.minecraft.item.ItemStack; + +public class LOTREnchantmentArmorSpecial extends LOTREnchantment { + private boolean compatibleBane = true; + + private boolean compatibleOtherSpecial = false; + + public LOTREnchantmentArmorSpecial(String s) { + super(s, new LOTREnchantmentType[] { LOTREnchantmentType.ARMOR, LOTREnchantmentType.ARMOR_FEET, LOTREnchantmentType.ARMOR_LEGS, LOTREnchantmentType.ARMOR_BODY, LOTREnchantmentType.ARMOR_HEAD, }); + setValueModifier(3.0F); + setBypassAnvilLimit(); + } + + public LOTREnchantmentArmorSpecial setIncompatibleBane() { + this.compatibleBane = false; + return this; + } + + public LOTREnchantmentArmorSpecial setCompatibleOtherSpecial() { + this.compatibleOtherSpecial = true; + return this; + } + + public String getDescription(ItemStack itemstack) { + return StatCollector.translateToLocalFormatted("lotr.enchant." + this.enchantName + ".desc", new Object[0]); +} + + public boolean isBeneficial() { + return true; + } + + public boolean canApply(ItemStack itemstack, boolean considering) { + if (super.canApply(itemstack, considering)) { + Item item = itemstack.getItem(); + /*if (item instanceof lotr.common.item.LOTRItemBalrogWhip && (this == LOTREnchantment.fire || this == LOTREnchantment.chill))*/ + return true; + } + return false; + } + + public boolean isCompatibleWith(LOTREnchantment other) { + if (!this.compatibleBane) + if (other instanceof LOTREnchantmentBane) + return false; + if (!this.compatibleOtherSpecial) + if (other instanceof LOTREnchantmentArmorSpecial && !((LOTREnchantmentArmorSpecial)other).compatibleOtherSpecial) + return false; + return true; + } + + public static int getFireAmount() { + return 2; + } + + /*public static void doChillAttack(EntityLivingBase entity) { + if (entity instanceof EntityPlayerMP) + LOTRDamage.doFrostDamage((EntityPlayerMP)entity); + int duration = 5; + entity.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, duration * 20, 1)); + LOTRPacketWeaponFX packet = new LOTRPacketWeaponFX(LOTRPacketWeaponFX.Type.CHILLING, (Entity)entity); + LOTRPacketHandler.networkWrapper.sendToAllAround((IMessage)packet, LOTRPacketHandler.nearEntity((Entity)entity, 64.0D));*/ + } \ No newline at end of file diff --git a/src/main/java/com/zivilon/cinder_loe/entity/MonkeyBananaAI.java b/src/main/java/com/zivilon/cinder_loe/entity/MonkeyBananaAI.java new file mode 100644 index 0000000..f5189ef --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/entity/MonkeyBananaAI.java @@ -0,0 +1,139 @@ +package com.zivilon.cinder_loe.entity; + +import java.util.Random; + +import lotr.common.LOTRMod; +import lotr.common.entity.npc.LOTREntityGollum; +import lotr.common.entity.npc.LOTRSpeech; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.entity.Entity; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.MathHelper; +import net.minecraft.util.Vec3; +import net.minecraft.world.World; + +public class MonkeyBananaAI extends EntityAIBase { + private LOTREntityGollum theGollum; + private double moveSpeed; + private boolean avoidsWater; + private World theWorld; + private double xPosition; + private double yPosition; + private double zPosition; + private int moveTick; + private int fishTick; + private boolean finished; + + public MonkeyBananaAI(LOTREntityGollum entity, double d) { + this.theGollum = entity; + this.moveSpeed = d; + this.theWorld = entity.worldObj; + this.setMutexBits(3); + } + + public boolean shouldExecute() { + if (this.theGollum.getGollumOwner() == null) { + return false; + } + if (this.theGollum.isGollumSitting()) { + return false; + } + if (this.theGollum.prevFishTime > 0) { + return false; + } + if (this.theGollum.isFishing) { + return false; + } + if (this.theGollum.getEquipmentInSlot(0) != null) { + return false; + } + if (this.theGollum.getRNG().nextInt(60) == 0) { + Vec3 vec3 = this.findPossibleFishingLocation(); + if (vec3 == null) { + return false; + } + this.xPosition = vec3.xCoord; + this.yPosition = vec3.yCoord; + this.zPosition = vec3.zCoord; + return true; + } + return false; + } + + private Vec3 findPossibleFishingLocation() { + Random random = this.theGollum.getRNG(); + int range = 16; + for (int l = 0; l < 32; ++l) { + int x = MathHelper.floor_double((double)this.theGollum.posX) - range + random.nextInt(range * 2 + 1); + int y = MathHelper.floor_double((double)this.theGollum.boundingBox.minY) - 8 + random.nextInt(17); + int z = MathHelper.floor_double((double)this.theGollum.posZ) - range + random.nextInt(range * 2 + 1); + Block banana = theWorld.getBlock(x, y, z); + + if (banana == LOTRMod.bananaBlock) { + return Vec3.createVectorHelper(((double)x + 0.5), ((double)y + 0.5), (double)z + 0.5); + } + } + return null; + } + + public boolean continueExecuting() { + return this.theGollum.getGollumOwner() + != null && !this.theGollum.isGollumSitting() + && this.moveTick < 300 + && !this.finished; + } + + public void startExecuting() { + this.avoidsWater = this.theGollum.getNavigator().getAvoidsWater(); + this.theGollum.getNavigator().setAvoidsWater(false); + this.finished = false; + } + + public void resetTask() { + this.theGollum.getNavigator().clearPathEntity(); + this.theGollum.getNavigator().setAvoidsWater(this.avoidsWater); + this.moveTick = 0; + + this.fishTick = 0; + if (this.finished) { + this.finished = false; + this.theGollum.prevFishTime = 3000; + } else { + this.theGollum.prevFishTime = 600; + } + this.theGollum.isFishing = false; + } + + public void updateTask() { + if (theGollum.getDistance(xPosition, yPosition, zPosition) < 4.0) { + int x = MathHelper.floor_double((double)this.theGollum.posX); + int y = MathHelper.floor_double((double)this.theGollum.boundingBox.minY); + int z = MathHelper.floor_double((double)this.theGollum.posZ); + + if (theWorld.getBlock(x, y, z) == LOTRMod.bananaBlock) { + theWorld.setBlockToAir(x, y, z); + LOTRMod.bananaBlock.dropBlockAsItem(theWorld, x, y, z, theWorld.getBlockMetadata(x, y, z), 0); + + finished = true; + LOTRSpeech.sendSpeech(this.theGollum.getGollumOwner(), this.theGollum, LOTRSpeech.getRandomSpeechForPlayer(this.theGollum, "monkey/say", this.theGollum.getGollumOwner())); + } else { + theGollum.getNavigator().tryMoveToXYZ(xPosition, yPosition, zPosition, moveSpeed); + moveTick++; + } + } + } + + private boolean atFishingLocation() { + if (this.theGollum.getDistanceSq(this.xPosition, this.yPosition, this.zPosition) < 4.0) { + int k; + int j; + int i = MathHelper.floor_double((double)this.theGollum.posX); + return this.theWorld.getBlock(i, j = MathHelper.floor_double((double)this.theGollum.boundingBox.minY), k = MathHelper.floor_double((double)this.theGollum.posZ)).getMaterial() == Material.water || this.theWorld.getBlock(i, j - 1, k).getMaterial() == Material.water; + } + return false; + } +} + diff --git a/src/main/java/com/zivilon/cinder_loe/entity/Renegade.java b/src/main/java/com/zivilon/cinder_loe/entity/Renegade.java index 2f02a1d..e58ed9d 100644 --- a/src/main/java/com/zivilon/cinder_loe/entity/Renegade.java +++ b/src/main/java/com/zivilon/cinder_loe/entity/Renegade.java @@ -129,43 +129,33 @@ public class Renegade extends LOTREntityMan { }, /* * () -> { - * System.out.println("[CinderCore] Executing GondorName"); * this.familyInfo.setName(LOTRNames.getDunlendingName(this.rand, this.familyInfo.isMale())), * } * () -> { - * System.out.println("[CinderCore] Executing GondorName"); * this.familyInfo.setName(LOTRNames.getDorwinionName(this.rand, this.familyInfo.isMale())), * } * () -> { - * System.out.println("[CinderCore] Executing GondorName"); * this.familyInfo.setName(LOTRNames.getDalishName(this.rand, this.familyInfo.isMale())), * } * () -> { - * System.out.println("[CinderCore] Executing GondorName"); * this.familyInfo.setName(LOTRNames.getRhunicName(this.rand, this.familyInfo.isMale())), * } * () -> { - * System.out.println("[CinderCore] Executing GondorName"); * this.familyInfo.setName(LOTRNames.getUmbarName(this.rand, this.familyInfo.isMale())), * } * () -> { - * System.out.println("[CinderCore] Executing GondorName"); * this.familyInfo.setName(LOTRNames.getHarnennorName(this.rand, this.familyInfo.isMale())), * } * () -> { - * System.out.println("[CinderCore] Executing GondorName"); * this.familyInfo.setName(LOTRNames.getSouthronCoastName(this.rand, this.familyInfo.isMale())), * } * () -> { - * System.out.println("[CinderCore] Executing GondorName"); * this.familyInfo.setName(LOTRNames.getNomadName(this.rand, this.familyInfo.isMale())), * } * () -> { - * System.out.println("[CinderCore] Executing GondorName"); * this.familyInfo.setName(LOTRNames.getGulfHaradName(this.rand, this.familyInfo.isMale())), * } * () -> { - * System.out.println("[CinderCore] Executing GondorName"); * this.familyInfo.setName(LOTRNames.getMoredainName(this.rand, this.familyInfo.isMale())), * } */ diff --git a/src/main/java/com/zivilon/cinder_loe/entity/SarumanWhiteFireball.java b/src/main/java/com/zivilon/cinder_loe/entity/SarumanWhiteFireball.java new file mode 100644 index 0000000..f1882f2 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/entity/SarumanWhiteFireball.java @@ -0,0 +1,92 @@ +package com.zivilon.cinder_loe.entity; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; + +import lotr.common.LOTRLevelData; +import lotr.common.LOTRMod; +import lotr.common.entity.npc.LOTREntityNPC; +import lotr.common.entity.animal.LOTREntityHorse; +import lotr.common.entity.projectile.LOTREntityGandalfFireball; +import lotr.common.fac.LOTRFaction; +import lotr.common.network.LOTRPacketHandler; +import lotr.common.network.LOTRPacketWeaponFX; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.attributes.IAttributeInstance; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityThrowable; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.world.World; + +import java.util.ArrayList; +import java.util.List; + +public class SarumanWhiteFireball extends LOTREntityGandalfFireball { + public SarumanWhiteFireball(World world) { + super(world); + } + + public SarumanWhiteFireball(World world, EntityLivingBase entityliving) { + super(world, entityliving); + } + + public SarumanWhiteFireball(World world, double d, double d1, double d2) { + super(world, d, d1, d2); + } + + protected void onImpact(MovingObjectPosition m) { + if (!this.worldObj.isRemote) + if (m.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { + explode((Entity)null); + } else if (m.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY) { + Entity entity = m.entityHit; + if (isEntityVulnerable(entity)) + explode(entity); + } + } + + private void explode(Entity target) { + if (this.worldObj.isRemote) + return; + this.worldObj.playSoundAtEntity((Entity)this, "lotr:item.gandalfFireball", 4.0F, (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F); + LOTRPacketWeaponFX packet = new LOTRPacketWeaponFX(LOTRPacketWeaponFX.Type.MACE_SAURON, (Entity)this); + LOTRPacketHandler.networkWrapper.sendToAllAround((IMessage)packet, LOTRPacketHandler.nearEntity((Entity)this, 64.0D)); + if (target != null && isEntityVulnerable(target)) + target.attackEntityFrom(DamageSource.causeMobDamage(getThrower()), 10.0F); + List entities = this.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, this.boundingBox.expand(6.0D, 6.0D, 6.0D)); + if (!entities.isEmpty()) + for (int i = 0; i < entities.size(); i++) { + EntityLivingBase entity = entities.get(i); + if (entity != target && isEntityVulnerable((Entity)entity)) { + float damage = 10.0F - getDistanceToEntity((Entity)entity) * 0.5F; + if (damage > 0.0F) + entity.attackEntityFrom(DamageSource.causeMobDamage(getThrower()), damage); + } + } + setDead(); + } + + private boolean isEntityVulnerable(Entity entity) { + if (entity == getThrower()) + return false; + if (!(entity instanceof EntityLivingBase)) + return false; + if (entity instanceof EntityPlayer) + return (LOTRLevelData.getData((EntityPlayer)entity).getAlignment(LOTRFaction.HIGH_ELF) < 0.0F); + return !LOTRFaction.HIGH_ELF.isGoodRelation(LOTRMod.getNPCFaction(entity)); + } + + protected float func_70182_d() { + return 1.5F; + } + + protected float getGravityVelocity() { + return 0.0F; + } +} \ No newline at end of file diff --git a/src/main/java/com/zivilon/cinder_loe/entity/SpeechBankModifier.java b/src/main/java/com/zivilon/cinder_loe/entity/SpeechBankModifier.java index 41e8133..32217e8 100644 --- a/src/main/java/com/zivilon/cinder_loe/entity/SpeechBankModifier.java +++ b/src/main/java/com/zivilon/cinder_loe/entity/SpeechBankModifier.java @@ -79,6 +79,8 @@ public class SpeechBankModifier { speechBanks.put("arnorSoldier/soldier/hostile", loadSpeechLines("arnorSoldier/soldier/hostile")); speechBanks.put("corruptSpeak/all/neutral", loadSpeechLines("corruptSpeak/all/neutral")); speechBanks.put("corruptSpeak/all/hostile", loadSpeechLines("corruptSpeak/all/hostile")); + speechBanks.put("corruptSpeak/all/skeleton", loadSpeechLines("corruptSpeak/all/skeleton")); + speechBanks.put("monkey/say", loadSpeechLines("monkey/say")); return speechBanks; } diff --git a/src/main/java/com/zivilon/cinder_loe/entity/ai/LoEPreciseAttackOnCollide.java b/src/main/java/com/zivilon/cinder_loe/entity/ai/LoEPreciseAttackOnCollide.java index 693fc7a..aa9265d 100644 --- a/src/main/java/com/zivilon/cinder_loe/entity/ai/LoEPreciseAttackOnCollide.java +++ b/src/main/java/com/zivilon/cinder_loe/entity/ai/LoEPreciseAttackOnCollide.java @@ -5,6 +5,7 @@ import lotr.common.entity.npc.LOTREntityNPC; import lotr.common.entity.projectile.LOTREntitySpear; import lotr.common.item.LOTRItemSpear; import lotr.common.item.LOTRWeaponStats; + import net.minecraft.item.ItemStack; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityCreature; diff --git a/src/main/java/com/zivilon/cinder_loe/entity/animals/Monkey.java b/src/main/java/com/zivilon/cinder_loe/entity/animals/Monkey.java new file mode 100644 index 0000000..79dae6b --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/entity/animals/Monkey.java @@ -0,0 +1,249 @@ +package com.zivilon.cinder_loe.entity.animals; + +import com.zivilon.cinder_loe.CinderAchievement; +import com.zivilon.cinder_loe.entity.MonkeyBananaAI; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import lotr.common.LOTRAchievement; +import lotr.common.LOTRLevelData; +import lotr.common.LOTRMod; +import lotr.common.entity.ai.*; +import lotr.common.entity.npc.LOTRCharacter; +import lotr.common.entity.npc.LOTREntityGollum; +import lotr.common.entity.npc.LOTREntityNPC; +import lotr.common.entity.npc.LOTRSpeech; +import lotr.common.inventory.LOTRInventoryNPC; +import net.minecraft.entity.*; +import net.minecraft.entity.ai.*; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.ItemFood; +import net.minecraft.item.ItemStack; +import net.minecraft.util.*; +import net.minecraft.world.World; + +import java.util.List; + +public class Monkey extends LOTREntityGollum { + + public static int INV_ROWS = 1; + private int eatingTick; + public int prevFishTime = 400; + public boolean isFishing; + public LOTRInventoryNPC inventory = new LOTRInventoryNPC("gollum", this, INV_ROWS * 9); + public int prevFishRequired; + public int fishRequired = this.prevFishRequired = 32; + + public Monkey(World world) { + super(world); + this.setSize(0.6f, 1.2f); + this.getNavigator().setAvoidsWater(true); + this.tasks.addTask(0, (EntityAIBase)new EntityAISwimming((EntityLiving)this)); + this.tasks.addTask(1, (EntityAIBase)new LOTREntityAIGollumRemainStill(this)); + this.tasks.addTask(2, (EntityAIBase)new LOTREntityAIGollumPanic(this, 1.4)); + this.tasks.addTask(3, (EntityAIBase)new LOTREntityAIGollumAvoidEntity(this, LOTREntityNPC.class, 8.0f, 1.2, 1.4)); + this.tasks.addTask(4, (EntityAIBase)new MonkeyBananaAI(this, 1.5)); + this.tasks.addTask(5, (EntityAIBase)new LOTREntityAIGollumFollowOwner(this, 1.2, 6.0f, 4.0f)); + this.tasks.addTask(6, (EntityAIBase)new EntityAIWander((EntityCreature)this, 1.0)); + this.tasks.addTask(7, (EntityAIBase)new EntityAIWatchClosest((EntityLiving)this, EntityPlayer.class, 8.0f, 0.1f)); + this.tasks.addTask(8, (EntityAIBase)new EntityAILookIdle((EntityLiving)this)); + + } + + @Override + public void onLivingUpdate() { + double d; + super.onLivingUpdate(); + if (!this.worldObj.isRemote && this.rand.nextInt(500) == 0) { + this.heal(1.0f); + } + if (this.eatingTick > 0) { + if (this.eatingTick % 4 == 0) { + this.worldObj.playSoundAtEntity((Entity)this, "random.eat", 0.5f + 0.5f * (float)this.rand.nextInt(2), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2f + 1.0f); + } + --this.eatingTick; + } + if (this.prevFishTime > 0) { + --this.prevFishTime; + } + if (this.isGollumSitting() && !this.worldObj.isRemote && this.onGround) { + this.getJumpHelper().setJumping(); + } + if (!this.worldObj.isRemote && this.getEquipmentInSlot(0) != null && this.getGollumOwner() != null && (d = this.getDistanceSqToEntity((Entity)this.getGollumOwner())) < 4.0) { + this.getLookHelper().setLookPositionWithEntity((Entity)this.getGollumOwner(), 100.0f, 100.0f); + this.getLookHelper().onUpdateLook(); + EntityItem entityitem = new EntityItem(this.worldObj, this.posX, this.posY + (double)this.getEyeHeight(), this.posZ, this.getEquipmentInSlot(0)); + entityitem.delayBeforeCanPickup = 40; + float f = 0.3f; + entityitem.motionX = -MathHelper.sin((float)(this.rotationYawHead / 180.0f * (float)Math.PI)) * MathHelper.cos((float)(this.rotationPitch / 180.0f * (float)Math.PI)) * f; + entityitem.motionZ = MathHelper.cos((float)(this.rotationYawHead / 180.0f * (float)Math.PI)) * MathHelper.cos((float)(this.rotationPitch / 180.0f * (float)Math.PI)) * f; + entityitem.motionY = -MathHelper.sin((float)(this.rotationPitch / 180.0f * (float)Math.PI)) * f + 0.1f; + f = 0.02f; + float f1 = this.rand.nextFloat() * (float)Math.PI * 2.0f; + entityitem.motionX += Math.cos(f1) * (double)(f *= this.rand.nextFloat()); + entityitem.motionY += (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.1f); + entityitem.motionZ += Math.sin(f1) * (double)f; + this.worldObj.spawnEntityInWorld((Entity)entityitem); + this.setCurrentItemOrArmor(0, null); + } + if (!this.worldObj.isRemote && StringUtils.isNullOrEmpty((String)this.getGollumOwnerUUID()) && this.rand.nextInt(40) == 0) { + List nearbyPlayers = this.worldObj.getEntitiesWithinAABB(EntityPlayer.class, this.boundingBox.expand(80.0, 80.0, 80.0)); + for (Object entityplayer : nearbyPlayers) { + double d2 = this.getDistanceToEntity((Entity)entityplayer); + int chance = (int)(d2 / 8.0); + if (this.rand.nextInt(chance = Math.max(2, chance)) != 0) continue; + this.worldObj.playSoundAtEntity((Entity)entityplayer, this.getLivingSound(), this.getSoundVolume(), this.getSoundPitch()); + } + } + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(10.0); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25); + } + + private boolean canGollumEat(ItemStack itemstack) { + if (itemstack.getItem() == LOTRMod.mango || itemstack.getItem() == LOTRMod.banana) { + return true; + } + ItemFood food = (ItemFood)itemstack.getItem(); + return food.isWolfsFavoriteMeat(); + } + + @Override + public boolean interact(EntityPlayer entityplayer) { + if (!this.worldObj.isRemote) { + if (this.getGollumOwner() != null && entityplayer == this.getGollumOwner()) { + ItemStack itemstack = entityplayer.inventory.getCurrentItem(); + if (itemstack != null && itemstack.getItem() instanceof ItemFood && this.canGollumEat(itemstack) && this.getHealth() < this.getMaxHealth()) { + if (!entityplayer.capabilities.isCreativeMode) { + --itemstack.stackSize; + if (itemstack.stackSize <= 0) { + entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, null); + } + } + this.heal(((ItemFood)itemstack.getItem()).func_150905_g(itemstack)); + this.eatingTick = 20; + return true; + } + if (entityplayer.isSneaking()) { + entityplayer.openGui((Object)LOTRMod.instance, 10, this.worldObj, this.getEntityId(), 0, 0); + return true; + } + this.setGollumSitting(!this.isGollumSitting()); + if (this.isGollumSitting()) { + LOTRSpeech.sendSpeech(this.getGollumOwner(), this, LOTRSpeech.getRandomSpeechForPlayer(this, "monkey/say", this.getGollumOwner())); + } else { + LOTRSpeech.sendSpeech(this.getGollumOwner(), this, LOTRSpeech.getRandomSpeechForPlayer(this, "monkey/say", this.getGollumOwner())); + } + return true; + } + ItemStack itemstack = entityplayer.inventory.getCurrentItem(); + if (itemstack != null && itemstack.getItem() == LOTRMod.banana) { + boolean tamed = false; + if (itemstack.stackSize >= this.fishRequired) { + if (!entityplayer.capabilities.isCreativeMode) { + itemstack.stackSize -= this.fishRequired; + if (itemstack.stackSize <= 0) { + entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, null); + } + } + this.fishRequired = 0; + } else { + this.fishRequired -= itemstack.stackSize; + if (!entityplayer.capabilities.isCreativeMode) { + entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, null); + } + } + this.eatingTick = 20; + if (this.fishRequired <= 0) { + this.setGollumOwnerUUID(entityplayer.getUniqueID().toString()); + + LOTRLevelData.getData(entityplayer).addAchievement(CinderAchievement.tameMonkey); + LOTRSpeech.messageAllPlayers((IChatComponent)new ChatComponentTranslation("chat.lotr.tameMonkey", new Object[]{entityplayer.getCommandSenderName(), this.getCommandSenderName()})); + LOTRSpeech.sendSpeech(entityplayer, this, LOTRSpeech.getRandomSpeechForPlayer(this, "monkey/say", entityplayer)); + + this.spawnHearts(); + this.prevFishRequired = this.fishRequired = Math.round((float)this.prevFishRequired * (1.5f + this.rand.nextFloat() * 0.25f)); + } else { + LOTRSpeech.sendSpeech(entityplayer, this, LOTRSpeech.getRandomSpeechForPlayer(this, "monkey/say", entityplayer)); + } + return true; + } + } + return super.interact(entityplayer); + } + + @Override + public String getSpeechBank(EntityPlayer entityplayer) { + if (!this.isGollumFleeing()) { + return "monkey/say"; + } + return super.getSpeechBank(entityplayer); + } + + @Override + public void onDeath(DamageSource damagesource) { + if (!this.worldObj.isRemote && !StringUtils.isNullOrEmpty((String)this.getGollumOwnerUUID())) { + LOTRSpeech.messageAllPlayers(this.func_110142_aN().func_151521_b()); + } + super.onDeath(damagesource); + if (!this.worldObj.isRemote) { + this.inventory.dropAllItems(); + } + } + + public String getLivingSound() { + return "cinder_loe:monkey.idle"; + } + + public String getHurtSound() { + return "cinder_loe:monkey.hurt"; + } + + public String getDeathSound() { + return "cinder_loe:monkey.death"; + } + + public String getSplashSound() { + return "lotr:ent.mallorn.summonEnt"; + } + + @SideOnly(value= Side.CLIENT) + public void handleHealthUpdate(byte b) { + if (b == 15) { + for (int i = 0; i < 4; ++i) { + double d = this.rand.nextGaussian() * 0.02; + double d1 = this.rand.nextGaussian() * 0.02; + double d2 = this.rand.nextGaussian() * 0.02; + this.worldObj.spawnParticle(this.rand.nextBoolean() ? "bubble" : "splash", this.posX + (double)(this.rand.nextFloat() * this.width * 2.0f) - (double)this.width, this.posY + 0.5 + (double)(this.rand.nextFloat() * this.height), this.posZ + (double)(this.rand.nextFloat() * this.width * 2.0f) - (double)this.width, d, d1, d2); + } + } else { + super.handleHealthUpdate(b); + } + } + + @Override + public void attackEntityWithRangedAttack(EntityLivingBase p_82196_1_, float p_82196_2_) { + + } + + @Override + public boolean attackEntityFrom(DamageSource damagesource, float f) { + EntityPlayer owner = this.getGollumOwner(); + if (owner != null && damagesource.getEntity() == owner) { + f = 0.0f; + if (!this.worldObj.isRemote) { + LOTRSpeech.sendSpeech(owner, this, LOTRSpeech.getRandomSpeechForPlayer(this, "monkey/say", owner)); + } + } + if (super.attackEntityFrom(damagesource, f)) { + this.setGollumSitting(false); + return true; + } + return false; + } +} 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 a61ff5b..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,16 +21,14 @@ 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 public ItemStack getPickedResult(MovingObjectPosition target) { return null; } - @Override - protected EntityAIBase createGondorAttackAI() { - return new LOTREntityAIAttackOnCollide(this, 1.45, true); - } @Override public void setupNPCName() { 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 new file mode 100644 index 0000000..fadbf8c --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptSkeleton.java @@ -0,0 +1,96 @@ +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; +import lotr.common.fac.LOTRFaction; +import lotr.common.quest.LOTRMiniQuest; +import lotr.common.quest.LOTRMiniQuestFactory; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.IEntityLivingData; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.world.World; + +public class CorruptSkeleton extends CorruptMan { + + public CorruptSkeleton(World world) { + super(world); + this.addTargetTasks(true); + } + @Override + public void setupNPCName() { + this.familyInfo.setName(LOTRNames.getGondorName(this.rand, this.familyInfo.isMale())); + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(70.0); + } + + @Override + public IEntityLivingData onSpawnWithEgg(IEntityLivingData data) { + return null; + } + + @Override + public LOTRFaction getFaction() { + /** + * 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 + public String getNPCName() { + return this.familyInfo.getName(); + } + @Override + protected float getSoundPitch() { + return super.getSoundPitch() * 0.65f; + } + @Override + public String getHurtSound() { + return "mob.skeleton.hurt"; + } + @Override + public String getDeathSound() { + return "mob.skeleton.death"; + } + + public String getLivingSound() { + return "mob.skeleton.say"; + } + + @Override + public String getAttackSound() { + return "mob.skeleton.say"; + } + @Override + public String getSpeechBank(EntityPlayer entityplayer) { + if (this.isFriendlyAndAligned(entityplayer)) { + return "corruptSpeak/all/skeleton"; + } + return "corruptSpeak/all/skeleton"; + } + @Override + protected void dropFewItems(boolean flag, int i) { + super.dropFewItems(flag, i); + int bones = this.rand.nextInt(3) + this.rand.nextInt(i + 1); + for (int l = 0; l < bones; ++l) { + this.dropItem(Items.bone, 1); + } + } +} 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 new file mode 100644 index 0000000..a6b7fe5 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/entity/corrupt/CorruptSkeletonArcher.java @@ -0,0 +1,75 @@ +package com.zivilon.cinder_loe.entity.corrupt; + +import com.zivilon.cinder_loe.CinderLoE_Config; +import lotr.common.LOTRMod; +import lotr.common.entity.ai.LOTREntityAIAttackOnCollide; +import lotr.common.entity.ai.LOTREntityAIRangedAttack; +import lotr.common.entity.npc.LOTREntityNPC; +import lotr.common.entity.npc.LOTRNames; +import lotr.common.fac.LOTRFaction; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.IEntityLivingData; +import net.minecraft.entity.ai.EntityAIAvoidEntity; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +public class CorruptSkeletonArcher extends CorruptSkeleton { + + public CorruptSkeletonArcher(World world) { + super(world); + ((EntityLiving)this).tasks.addTask(0, (EntityAIBase)new LOTREntityAIRangedAttack(this, 1.4, 30, 50, 16.0f)); + } + + + @Override + public void setupNPCName() { + this.familyInfo.setName(LOTRNames.getGondorName(this.rand, this.familyInfo.isMale())); + } + + public void attackEntityWithRangedAttack(EntityLivingBase target, float f) { + npcArrowAttack(target, f); + } + @Override + public IEntityLivingData onSpawnWithEgg(IEntityLivingData data) { + data = super.onSpawnWithEgg(data); + this.npcItemsInv.setRangedWeapon(new ItemStack(Items.bow)); + this.npcItemsInv.setIdleItem(this.npcItemsInv.getRangedWeapon()); + return data; + } + + @Override + protected void dropFewItems(boolean flag, int i) { + super.dropFewItems(flag, i); + this.dropNPCArrows(i); + } + + @Override + protected void onAttackModeChange(LOTREntityNPC.AttackMode mode, boolean mounted) { + if (mode == LOTREntityNPC.AttackMode.IDLE) { + this.setCurrentItemOrArmor(0, this.npcItemsInv.getIdleItem()); + } else { + this.setCurrentItemOrArmor(0, this.npcItemsInv.getRangedWeapon()); + } + } + + @Override + public String getNPCName() { + return this.familyInfo.getName(); + } + @Override + protected float getSoundPitch() { + return super.getSoundPitch() * 0.65f; + } + @Override + public String getSpeechBank(EntityPlayer entityplayer) { + if (this.isFriendlyAndAligned(entityplayer)) { + return "corruptSpeak/all/skeleton"; + } + return "corruptSpeak/all/skeleton"; + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/entity/npc/evil_human/UmbarUsurper.java b/src/main/java/com/zivilon/cinder_loe/entity/npc/evil_human/UmbarUsurper.java new file mode 100644 index 0000000..fe31917 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/entity/npc/evil_human/UmbarUsurper.java @@ -0,0 +1,64 @@ +package com.zivilon.cinder_loe.entity.npc.evil_human; + +import com.zivilon.cinder_loe.CinderLoE; +import lotr.common.LOTRMod; +import lotr.common.LOTRShields; +import lotr.common.entity.npc.LOTREntityAngmarHillmanWarrior; +import lotr.common.entity.npc.LOTREntityUmbarWarrior; +import net.minecraft.entity.IEntityLivingData; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + + +public class UmbarUsurper extends LOTREntityUmbarWarrior { + + private static ItemStack[] weapons = new ItemStack[]{new ItemStack(LOTRMod.poleaxeNearHarad), new ItemStack(LOTRMod.scimitarNearHarad), new ItemStack(LOTRMod.polearmRhun)}; + private static ItemStack[] helmets = new ItemStack[]{new ItemStack(CinderLoE.helmetUsurper)}; + private static ItemStack[] bodies = new ItemStack[]{new ItemStack(CinderLoE.bodyUsurper)}; + private static ItemStack[] legs = new ItemStack[]{new ItemStack(CinderLoE.legsUsurper)}; + private static ItemStack[] boots = new ItemStack[]{new ItemStack(CinderLoE.bootsUsurper)}; + + public UmbarUsurper(World world) { + super(world); + this.npcShield = LOTRShields.ALIGNMENT_UMBAR; + } + + @Override + public IEntityLivingData onSpawnWithEgg(IEntityLivingData data) { + data = super.onSpawnWithEgg(data); + int i = this.rand.nextInt(weapons.length); + this.npcItemsInv.setMeleeWeapon(weapons[i].copy()); + this.npcItemsInv.setIdleItem(this.npcItemsInv.getMeleeWeapon()); + i = this.rand.nextInt(boots.length); + this.setCurrentItemOrArmor(1, boots[i].copy()); + i = this.rand.nextInt(legs.length); + this.setCurrentItemOrArmor(2, legs[i].copy()); + i = this.rand.nextInt(bodies.length); + this.setCurrentItemOrArmor(3, bodies[i].copy()); + if (this.rand.nextInt(5) != 0) { + i = this.rand.nextInt(helmets.length); + this.setCurrentItemOrArmor(4, helmets[i].copy()); + } + return data; + } + + @Override + public String getSpeechBank(EntityPlayer entityplayer) { + if (this.isFriendlyAndAligned(entityplayer)) { + if (this.hiredNPCInfo.getHiringPlayer() == entityplayer) { + return "nearHarad/umbar/warrior/hired"; + } + return "nearHarad/umbar/warrior/friendly"; + } + return "nearHarad/umbar/warrior/hostile"; + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.2); + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/items/BrokenHalo.java b/src/main/java/com/zivilon/cinder_loe/items/BrokenHalo.java deleted file mode 100644 index 1c59bd7..0000000 --- a/src/main/java/com/zivilon/cinder_loe/items/BrokenHalo.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.zivilon.cinder_loe.items; - -import com.zivilon.cinder_loe.CinderLoE; -import com.zivilon.cinder_loe.entity.corrupt.CorruptMan; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import lotr.common.item.LOTRItemArmor; -import lotr.common.item.LOTRMaterial; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.IEntityLivingData; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.potion.Potion; -import net.minecraft.potion.PotionEffect; -import net.minecraft.world.World; -import net.minecraftforge.event.entity.living.LivingEvent; -import net.minecraftforge.event.entity.living.LivingHurtEvent; - -import java.util.Random; - -public class BrokenHalo extends LOTRItemArmor { - - public BrokenHalo(LOTRMaterial material, int slotType, String s) { - super(material, slotType, s); - - } -} diff --git a/src/main/java/com/zivilon/cinder_loe/items/LoEItemMug.java b/src/main/java/com/zivilon/cinder_loe/items/LoEItemMug.java index 26fc1bc..6900eb0 100644 --- a/src/main/java/com/zivilon/cinder_loe/items/LoEItemMug.java +++ b/src/main/java/com/zivilon/cinder_loe/items/LoEItemMug.java @@ -1,18 +1,26 @@ package com.zivilon.cinder_loe.items; import com.zivilon.cinder_loe.LoECreativeTabs; +import com.zivilon.cinder_loe.potion.LoEPotions; import lotr.common.item.LOTRItemMug; import lotr.common.item.LOTRItemMug.Vessel; import lotr.client.render.LOTRDrinkIcons; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.item.ItemStack; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; import net.minecraft.util.IIcon; +import net.minecraft.world.World; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class LoEItemMug extends LOTRItemMug { + public boolean is_toxic = false; + @SideOnly(Side.CLIENT) public IIcon[] drinkIcons; @@ -37,7 +45,17 @@ public class LoEItemMug extends LOTRItemMug { this.setTextureName(textureName); } + public LoEItemMug addPotionEffect(int effect_id, int seconds) { + return (LoEItemMug)super.addPotionEffect(effect_id, seconds); + } + public LoEItemMug addPotionEffect(int effect_id, int seconds, int amplifier) { + this.potionEffects.add(new PotionEffect(effect_id, seconds * 20, amplifier)); + return this; + } + public LoEItemMug setDrinkStats(int i, float f) { + return (LoEItemMug)super.setDrinkStats(i, f); + } public void registerIcons(IIconRegister iconregister) { if (this.isFullMug) { this.drinkIcons = new IIcon[(Vessel.values()).length]; @@ -66,4 +84,20 @@ public class LoEItemMug extends LOTRItemMug { int i = damage / vesselMeta; return Vessel.forMeta(i); } + public LoEItemMug toxic() { + is_toxic = true; + return this; + } + public ItemStack onEaten(ItemStack itemstack, World world, EntityPlayer entityplayer) { + if (is_toxic) + increment_toxin(entityplayer); + return super.onEaten(itemstack, world, entityplayer); + } + public void increment_toxin(EntityPlayer player) { + int effect_duration = 7200; // 360 seconds * 20 ticks + int effect_potency = 0; // Default to level 1 effect + PotionEffect potion = player.getActivePotionEffect(LoEPotions.overdose); + if (potion != null) effect_potency = potion.getAmplifier() + 1; + player.addPotionEffect(new PotionEffect(LoEPotions.overdose.id, effect_duration, effect_potency)); + } } diff --git a/src/main/java/com/zivilon/cinder_loe/items/specials/BrokenHalo.java b/src/main/java/com/zivilon/cinder_loe/items/specials/BrokenHalo.java new file mode 100644 index 0000000..ba0fcbb --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/items/specials/BrokenHalo.java @@ -0,0 +1,12 @@ +package com.zivilon.cinder_loe.items.specials; + +import lotr.common.item.LOTRItemArmor; +import lotr.common.item.LOTRMaterial; + +public class BrokenHalo extends LOTRItemArmor { + + public BrokenHalo(LOTRMaterial material, int slotType, String s) { + super(material, slotType, s); + + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/items/PallandoStaff.java b/src/main/java/com/zivilon/cinder_loe/items/specials/PallandoStaff.java similarity index 92% rename from src/main/java/com/zivilon/cinder_loe/items/PallandoStaff.java rename to src/main/java/com/zivilon/cinder_loe/items/specials/PallandoStaff.java index 6c06934..008d26a 100644 --- a/src/main/java/com/zivilon/cinder_loe/items/PallandoStaff.java +++ b/src/main/java/com/zivilon/cinder_loe/items/specials/PallandoStaff.java @@ -1,27 +1,23 @@ -package com.zivilon.cinder_loe.items; +package com.zivilon.cinder_loe.items.specials; import cpw.mods.fml.common.network.simpleimpl.IMessage; import java.util.List; -import lotr.common.LOTRCreativeTabs; + import lotr.common.LOTRLevelData; import lotr.common.LOTRMod; import lotr.common.fac.LOTRFaction; import lotr.common.network.LOTRPacketHandler; import lotr.common.network.LOTRPacketWeaponFX; -import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.EnumAction; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.potion.PotionEffect; import net.minecraft.potion.Potion; import net.minecraft.server.MinecraftServer; -import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; import net.minecraft.world.World; import com.zivilon.cinder_loe.items.WizardStaff; diff --git a/src/main/java/com/zivilon/cinder_loe/items/RadagastStaff.java b/src/main/java/com/zivilon/cinder_loe/items/specials/RadagastStaff.java similarity index 97% rename from src/main/java/com/zivilon/cinder_loe/items/RadagastStaff.java rename to src/main/java/com/zivilon/cinder_loe/items/specials/RadagastStaff.java index 8a469e9..d970ca3 100644 --- a/src/main/java/com/zivilon/cinder_loe/items/RadagastStaff.java +++ b/src/main/java/com/zivilon/cinder_loe/items/specials/RadagastStaff.java @@ -1,6 +1,7 @@ -package com.zivilon.cinder_loe.items; +package com.zivilon.cinder_loe.items.specials; +import com.zivilon.cinder_loe.items.WizardStaff; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.passive.EntityAnimal; diff --git a/src/main/java/com/zivilon/cinder_loe/items/SarumanStaff.java b/src/main/java/com/zivilon/cinder_loe/items/specials/SarumanStaff.java similarity index 72% rename from src/main/java/com/zivilon/cinder_loe/items/SarumanStaff.java rename to src/main/java/com/zivilon/cinder_loe/items/specials/SarumanStaff.java index 46f3878..dbc68bd 100644 --- a/src/main/java/com/zivilon/cinder_loe/items/SarumanStaff.java +++ b/src/main/java/com/zivilon/cinder_loe/items/specials/SarumanStaff.java @@ -1,27 +1,14 @@ -package com.zivilon.cinder_loe.items; +package com.zivilon.cinder_loe.items.specials; import cpw.mods.fml.common.network.simpleimpl.IMessage; -import java.util.List; -import lotr.common.LOTRCreativeTabs; -import lotr.common.LOTRLevelData; -import lotr.common.LOTRMod; -import lotr.common.fac.LOTRFaction; import lotr.common.network.LOTRPacketHandler; import lotr.common.network.LOTRPacketWeaponFX; -import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.EnumAction; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.potion.PotionEffect; -import net.minecraft.potion.Potion; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; import net.minecraft.world.World; import com.zivilon.cinder_loe.items.WizardStaff; diff --git a/src/main/java/com/zivilon/cinder_loe/items/specials/SarumanWhiteStaff.java b/src/main/java/com/zivilon/cinder_loe/items/specials/SarumanWhiteStaff.java new file mode 100644 index 0000000..a141bbb --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/items/specials/SarumanWhiteStaff.java @@ -0,0 +1,32 @@ +package com.zivilon.cinder_loe.items.specials; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import lotr.common.network.LOTRPacketHandler; +import lotr.common.network.LOTRPacketWeaponFX; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import com.zivilon.cinder_loe.items.WizardStaff; +import com.zivilon.cinder_loe.entity.SarumanWhiteFireball; + +public class SarumanWhiteStaff extends WizardStaff { + public SarumanWhiteStaff() { + super(); + } + + public ItemStack onEaten(ItemStack itemstack, World world, EntityPlayer entityplayer) { + entityplayer.swingItem(); + itemstack.damageItem(2, (EntityLivingBase)entityplayer); + world.playSoundAtEntity((Entity)entityplayer, "mob.ghast.fireball", 2.0F, (itemRand.nextFloat() - itemRand.nextFloat()) * 0.2F + 1.0F); + if (!world.isRemote) { + world.spawnEntityInWorld((Entity)new SarumanWhiteFireball(world, (EntityLivingBase)entityplayer)); + LOTRPacketWeaponFX packet = new LOTRPacketWeaponFX(LOTRPacketWeaponFX.Type.MACE_SAURON, (Entity)entityplayer); + LOTRPacketHandler.networkWrapper.sendToAllAround((IMessage)packet, LOTRPacketHandler.nearEntity((Entity)entityplayer, 64.0D)); + } + return itemstack; + } +} \ No newline at end of file diff --git a/src/main/java/com/zivilon/cinder_loe/items/specials/Ulukai.java b/src/main/java/com/zivilon/cinder_loe/items/specials/Ulukai.java new file mode 100644 index 0000000..9667f1d --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/items/specials/Ulukai.java @@ -0,0 +1,272 @@ +package com.zivilon.cinder_loe.items.specials; + +import com.zivilon.cinder_loe.CinderLoE_Config; +import com.zivilon.cinder_loe.LoECreativeTabs; +import com.zivilon.cinder_loe.entity.npc.orc.NorthernOrc; +import com.zivilon.cinder_loe.entity.npc.radagast.FangornAnimal; +import com.zivilon.cinder_loe.util.BlockPos; +import lotr.common.LOTRMod; +import lotr.common.entity.npc.*; +import lotr.common.fac.LOTRFaction; +import lotr.common.fac.LOTRFactionRelations; +import net.minecraft.entity.*; +import net.minecraft.entity.ai.attributes.AttributeModifier; +import net.minecraft.entity.ai.attributes.IAttributeInstance; +import net.minecraft.entity.passive.EntityAnimal; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumAction; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.World; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.UUID; + + +public class Ulukai extends Item { + private static final String ULUKAI_TAG = "UlukaiModifiers"; + LOTRFaction gundabad = LOTRFaction.valueOf(CinderLoE_Config.ulukai_faction); + + public Ulukai() { + super(); + this.setCreativeTab(LoECreativeTabs.tabCharacterLoE); + } + + public int getMaxItemUseDuration(ItemStack itemstack) { + return 400; + } //20 second usage before it spawns anything + + public EnumAction getItemUseAction(ItemStack itemstack) { + return EnumAction.bow; + } + + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) { + entityplayer.setItemInUse(itemstack, getMaxItemUseDuration(itemstack)); + return itemstack; + } + + @Override + public ItemStack onEaten(ItemStack stack, World world, EntityPlayer player) { + if (!world.isRemote) { + if (isAreaCrowded(world, player)) { + world.playSoundAtEntity(player, "lotr:item.puff", 1.0F, 2.0F); + } else { + for (int i = 0; i < 5; i++) { + BlockPos spawnPos = BlockPos.findSafeSpawnLocation(world, player); + if (spawnPos != null) { + spawnRandomGundabad(world, spawnPos); + } + } + + world.playSoundAtEntity(player, "lotr:dwarf.kill", 2.0F, + (Item.itemRand.nextFloat() - Item.itemRand.nextFloat()) * 0.1F + 0.5F); + } + } + + return stack; + } + + + + public boolean isAreaCrowded(World world, EntityPlayer player) { + int radius = 30; // Check within 30 blocks + int maxEntities = 50; // Maximum allowed nearby entities + + AxisAlignedBB checkArea = AxisAlignedBB.getBoundingBox( + player.posX - radius, player.posY - radius, player.posZ - radius, + player.posX + radius, player.posY + radius, player.posZ + radius + ); + + List nearbyNpcs = world.getEntitiesWithinAABB(LOTREntityNPC.class, checkArea); + int gundabadCount = 0; + for (LOTREntityNPC npc : nearbyNpcs) { + LOTRFaction faction = LOTRMod.getNPCFaction(npc); + if (faction == gundabad) { + gundabadCount++; + } + } + return gundabadCount >= maxEntities; + } + + + @Override + public void onUsingTick(ItemStack stack, EntityPlayer player, int count) { + if (player.worldObj.isRemote) return; + + int ticksUsed = getMaxItemUseDuration(stack) - count; + + // Avoid triggering at tick 0 + if (ticksUsed > 0 && ticksUsed % 20 == 0) { + applyAllyHealing(player.worldObj, player); + } + + if (ticksUsed > 0 && ticksUsed % 200 == 0) { + applyEnemyMaxHealthReduction(player.worldObj, player); + } + } + + public void spawnRandomGundabad(World world, BlockPos location) { + Random rand = new Random(); + int choice = rand.nextInt(7); // 0 to 6 + + EntityLiving entity; + + switch (choice) { + case 0: + entity = new LOTREntityGundabadOrc(world); + break; + case 1: + entity = new LOTREntityGundabadOrcArcher(world); + break; + case 2: + entity = new LOTREntityGundabadWarg(world); + break; + case 3: + entity = new LOTREntityGundabadUruk(world); + break; + case 4: + entity = new LOTREntityGundabadUrukArcher(world); + break; + case 5: + entity = new LOTREntityGundabadBannerBearer(world); + break; + case 6: + entity = new NorthernOrc(world); + break; + default: + entity = new LOTREntityGundabadOrc(world); + break; + } + + entity.setPosition(location.x + 0.5, location.y, location.z + 0.5); // Center the entity on the block + entity.onSpawnWithEgg((IEntityLivingData) null); + world.spawnEntityInWorld(entity); + } + + + private void applyEnemyMaxHealthReduction(World world, EntityPlayer player) { + LOTRFaction gundabad = LOTRFaction.GUNDABAD; + + List nearbyEntities = world.getEntitiesWithinAABB( + EntityLivingBase.class, player.boundingBox.expand(10.0D, 10.0D, 10.0D)); + + for (EntityLivingBase target : nearbyEntities) { + if (target == player || target instanceof EntityPlayer) continue; + + if (target instanceof LOTREntityNPC) { + LOTRFaction targetFaction = LOTRMod.getNPCFaction((LOTREntityNPC) target); + if (targetFaction != null) { + LOTRFactionRelations.Relation relation = LOTRFactionRelations.getRelations(gundabad, targetFaction); + + if (relation == LOTRFactionRelations.Relation.ENEMY || relation == LOTRFactionRelations.Relation.MORTAL_ENEMY) { + IAttributeInstance attribute = target.getEntityAttribute(SharedMonsterAttributes.maxHealth); + double currentMax = attribute.getAttributeValue(); + double newMax = currentMax - 1.0D; + + if (newMax >= 10.0D) { + AttributeModifier mod = new AttributeModifier(UUID.randomUUID(), "Ulukai Curse", -1.0D, 0); + attribute.applyModifier(mod); + + // Save UUID + timestamp + NBTTagCompound data = target.getEntityData(); + NBTTagList list = data.getTagList(ULUKAI_TAG, 10); // 10 = compound + + NBTTagCompound entry = new NBTTagCompound(); + entry.setString("UUID", mod.getID().toString()); + entry.setLong("AppliedAt", player.ticksExisted); // or use world.getTotalWorldTime() + + list.appendTag(entry); + data.setTag(ULUKAI_TAG, list); + System.out.println("Ulukai Curse applied to: " + target.getCommandSenderName() + + " UUID=" + mod.getID() + " Tick=" + player.ticksExisted); + + world.playSoundAtEntity(player, "lotr:wraith.marshWraith_shoot", 1F,1F); + + for(int l = 0; l < 16; ++l) { + LOTRMod.proxy.spawnParticle("morgulPortal", + target.posX, target.posY + 1.0D, target.posZ, + 0.0D, 0.02D, 0.0D); + } + } + } + } + } + } + } + + + + private void applyAllyHealing(World world, EntityPlayer player) { + + List nearbyEntities = world.getEntitiesWithinAABB( + EntityLivingBase.class, player.boundingBox.expand(10.0D, 10.0D, 10.0D)); + + List validTargets = new ArrayList<>(); + + for (EntityLivingBase target : nearbyEntities) { + if (target == player || target instanceof EntityPlayer) continue; + + if (target instanceof LOTREntityNPC) { + LOTRFaction targetFaction = LOTRMod.getNPCFaction((LOTREntityNPC) target); + if (targetFaction == gundabad && target.getHealth() < target.getMaxHealth()) { + validTargets.add(target); + } + } + } + + // Heal a random wounded ally, if any exist + if (!validTargets.isEmpty()) { + EntityLivingBase toHeal = validTargets.get(world.rand.nextInt(validTargets.size())); + toHeal.heal(1.0F); // 0.5 heart + world.playSoundAtEntity(toHeal, "mob.zombie.unfect", 0.25F,1F); + + for(int l = 0; l < 8; ++l) { + LOTRMod.proxy.spawnParticle("heart", + toHeal.posX, toHeal.posY + 1.0D, toHeal.posZ, + 0.0D, 0.02D, 0.0D); + } + + } else { + // Fizzle + world.playSoundAtEntity(player, "lotr:swan.hiss", 0.1F, 0.1F + world.rand.nextFloat() * 0.5F); + } + } + + + public static void removeExpiredUlukaiModifiers(EntityLivingBase entity, long currentTick) { + IAttributeInstance attr = entity.getEntityAttribute(SharedMonsterAttributes.maxHealth); + NBTTagCompound data = entity.getEntityData(); + NBTTagList oldList = data.getTagList(ULUKAI_TAG, 10); // 10 = compound tag + NBTTagList newList = new NBTTagList(); + + for (int i = 0; i < oldList.tagCount(); i++) { + NBTTagCompound entry = oldList.getCompoundTagAt(i); + long applied = entry.getLong("AppliedAt"); + String uuidStr = entry.getString("UUID"); + + if (currentTick - applied >= 72000L) { // 1 hour in ticks + try { + UUID uuid = UUID.fromString(uuidStr); + AttributeModifier mod = attr.getModifier(uuid); + if (mod != null) { + attr.removeModifier(mod); + System.out.println("Ulukai Curse expired: " + entity.getCommandSenderName() + + " UUID=" + uuid + " Tick=" + currentTick); + } + } catch (IllegalArgumentException e) { + // Invalid UUID format — skip + } + } else { + newList.appendTag(entry); // Keep active ones + } + } + + data.setTag(ULUKAI_TAG, newList); + } + + +} \ No newline at end of file diff --git a/src/main/java/com/zivilon/cinder_loe/items/UnnamedSpear.java b/src/main/java/com/zivilon/cinder_loe/items/specials/UnnamedSpear.java similarity index 94% rename from src/main/java/com/zivilon/cinder_loe/items/UnnamedSpear.java rename to src/main/java/com/zivilon/cinder_loe/items/specials/UnnamedSpear.java index 877da04..fc971c3 100644 --- a/src/main/java/com/zivilon/cinder_loe/items/UnnamedSpear.java +++ b/src/main/java/com/zivilon/cinder_loe/items/specials/UnnamedSpear.java @@ -1,7 +1,6 @@ -package com.zivilon.cinder_loe.items; +package com.zivilon.cinder_loe.items.specials; import lotr.common.item.LOTRItemSpear; -import lotr.common.item.LOTRItemSword; import lotr.common.item.LOTRMaterial; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; diff --git a/src/main/java/com/zivilon/cinder_loe/items/VoidDagger.java b/src/main/java/com/zivilon/cinder_loe/items/specials/VoidDagger.java similarity index 94% rename from src/main/java/com/zivilon/cinder_loe/items/VoidDagger.java rename to src/main/java/com/zivilon/cinder_loe/items/specials/VoidDagger.java index 96f7c06..595e54c 100644 --- a/src/main/java/com/zivilon/cinder_loe/items/VoidDagger.java +++ b/src/main/java/com/zivilon/cinder_loe/items/specials/VoidDagger.java @@ -1,27 +1,17 @@ -package com.zivilon.cinder_loe.items; +package com.zivilon.cinder_loe.items.specials; import com.zivilon.cinder_loe.entity.corrupt.*; import lotr.common.LOTRLevelData; import lotr.common.entity.npc.*; import lotr.common.fac.LOTRFaction; import lotr.common.item.LOTRItemDagger; -import lotr.common.item.LOTRItemSword; import lotr.common.item.LOTRMaterial; -import lotr.common.item.LOTRWeaponStats; -import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IEntityLivingData; -import net.minecraft.entity.monster.EntityZombie; -import net.minecraft.entity.passive.EntityVillager; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.EnumAction; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.world.EnumDifficulty; -import net.minecraft.world.World; public class VoidDagger extends LOTRItemDagger { public VoidDagger(LOTRMaterial material) { diff --git a/src/main/java/com/zivilon/cinder_loe/items/WoodElfRelic.java b/src/main/java/com/zivilon/cinder_loe/items/specials/WoodElfRelic.java similarity index 94% rename from src/main/java/com/zivilon/cinder_loe/items/WoodElfRelic.java rename to src/main/java/com/zivilon/cinder_loe/items/specials/WoodElfRelic.java index 60e0fe1..44c1cd9 100644 --- a/src/main/java/com/zivilon/cinder_loe/items/WoodElfRelic.java +++ b/src/main/java/com/zivilon/cinder_loe/items/specials/WoodElfRelic.java @@ -1,12 +1,10 @@ -package com.zivilon.cinder_loe.items; +package com.zivilon.cinder_loe.items.specials; -import com.zivilon.cinder_loe.CinderLoE; +import com.zivilon.cinder_loe.items.WizardStaff; import cpw.mods.fml.common.network.simpleimpl.IMessage; import lotr.common.LOTRLevelData; import lotr.common.LOTRMod; import lotr.common.fac.LOTRFaction; -import lotr.common.item.LOTRItemSword; -import lotr.common.item.LOTRStoryItem; import lotr.common.network.LOTRPacketHandler; import lotr.common.network.LOTRPacketWeaponFX; import net.minecraft.entity.Entity; 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 f1d815b..2af5376 100644 --- a/src/main/java/com/zivilon/cinder_loe/mixins/MixinEntityLivingBase.java +++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinEntityLivingBase.java @@ -1,33 +1,46 @@ package com.zivilon.cinder_loe.mixins; import com.zivilon.cinder_loe.util.*; - import com.zivilon.cinder_loe.entity.npc.frozen_dungeon.*; +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.*; import org.spongepowered.asm.mixin.injection.callback.*; -import net.minecraft.potion.Potion; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.effect.EntityLightningBolt; import net.minecraft.entity.passive.EntityTameable; import net.minecraft.entity.player.EntityPlayer; 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; -import net.minecraft.entity.effect.EntityLightningBolt; import net.minecraftforge.common.ForgeHooks; import java.lang.reflect.*; import java.util.List; +import java.util.UUID; @Mixin(EntityLivingBase.class) -public abstract class MixinEntityLivingBase extends Entity { +public abstract class MixinEntityLivingBase extends Entity implements IEntityLivingBase { private static boolean checked_cauldron = false; private static Method cauldron_method; + public int despawn_timer = -1; + public UUID warband_uuid = null; + @Shadow protected int entityAge; @Shadow @@ -109,7 +122,6 @@ public abstract class MixinEntityLivingBase extends Entity { } } - if (!(checked_cauldron)) { check_cauldron(); checked_cauldron = true; @@ -221,15 +233,12 @@ public abstract class MixinEntityLivingBase extends Entity { private void check_cauldron() { try { Class target_class = EntityLivingBase.class; + Method[] methods = target_class.getDeclaredMethods(); - while (target_class != null) { - Method[] methods = target_class.getDeclaredMethods(); - - for (Method method : methods) { - if (method.getName().equals("damageEntity_CB")) { - cauldron_method = method; - return; - } + for (Method method : methods) { + if (method.getName().equals("damageEntity_CB")) { + cauldron_method = method; + return; } } } catch (Exception e) { @@ -253,4 +262,69 @@ public abstract class MixinEntityLivingBase extends Entity { } return return_value; } + + /** + * Add support for despawn after specified time loaded + * Add support for following a warband leader + */ + @Inject(method = "writeEntityToNBT", at = @At("TAIL")) + private void writeWarbandNBT(NBTTagCompound compound, CallbackInfo ci) { + compound.setInteger("DespawnTimer", despawn_timer); + compound.setString("WarbandLeader", warband_uuid != null ? warband_uuid.toString() : ""); + } + @Inject(method = "readEntityFromNBT", at = @At("TAIL")) + private void readWarbandNBT(NBTTagCompound compound, CallbackInfo ci) { + despawn_timer = compound.getInteger("DespawnTimer"); + if (compound.hasKey("WarbandLeader")) { + String idStr = compound.getString("WarbandLeader"); + if (!idStr.isEmpty()) warband_uuid = UUID.fromString(idStr); + } + } + + 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) { + ((EntityLivingBase)(Object)this).setDead(); + } + } + } + @Override + public void set_despawn_timer(int ticks) { + this.despawn_timer = ticks; + } + @Override + public void set_warband_uuid(UUID uuid) { + this.warband_uuid = uuid; + } + @Override + public UUID get_warband_uuid() { + return this.warband_uuid; + } } diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/MixinEntityPlayer.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinEntityPlayer.java index e644b74..8599d7e 100644 --- a/src/main/java/com/zivilon/cinder_loe/mixins/MixinEntityPlayer.java +++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinEntityPlayer.java @@ -1,38 +1,123 @@ package com.zivilon.cinder_loe.mixins; +import com.zivilon.cinder_loe.CinderLoE; import com.zivilon.cinder_loe.util.Pair; import com.zivilon.cinder_loe.util.DamageEvent; +import com.zivilon.cinder_loe.util.IMixinEntityPlayer; +import com.zivilon.cinder_loe.potion.LoEPotions; +import com.zivilon.cinder_loe.potion.PotionHerbPoison; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import net.minecraft.potion.Potion; +import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.*; +import net.minecraft.entity.boss.EntityDragonPart; +import net.minecraft.entity.effect.EntityLightningBolt; import net.minecraft.entity.player.*; +import net.minecraft.entity.projectile.EntityFishHook; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.InventoryEnderChest; import net.minecraft.item.ItemStack; -import net.minecraft.util.DamageSource; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.stats.*; +import net.minecraft.util.*; +import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; -import net.minecraft.entity.effect.EntityLightningBolt; +import net.minecraft.enchantment.EnchantmentHelper; import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.ISpecialArmor.ArmorProperties; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.player.AttackEntityEvent; import com.mojang.authlib.GameProfile; +import java.util.HashMap; import java.util.List; @Mixin(EntityPlayer.class) -public abstract class MixinEntityPlayer extends EntityLivingBase { +public abstract class MixinEntityPlayer extends EntityLivingBase implements IMixinEntityPlayer { + public int last_pickpocket_attempt = 0; public MixinEntityPlayer(World world, GameProfile p_i45324_2_) { super(world); } @Shadow - public abstract void addExhaustion(float p_71020_1_); + public static final String PERSISTED_NBT_TAG = "PlayerPersisted"; + @Shadow + private HashMap spawnChunkMap; + @Shadow + private HashMap spawnForcedMap; @Shadow public InventoryPlayer inventory; + @Shadow + private InventoryEnderChest theInventoryEnderChest; + @Shadow + public Container inventoryContainer; + @Shadow + public Container openContainer; + @Shadow + protected FoodStats foodStats; + @Shadow + protected int flyToggleTimer; + @Shadow + public float prevCameraYaw; + @Shadow + public float cameraYaw; + @Shadow + public int xpCooldown; + @Shadow + protected boolean sleeping; + @Shadow + public ChunkCoordinates playerLocation; + @Shadow + private int sleepTimer; + @Shadow + private ChunkCoordinates spawnChunk; + @Shadow + private boolean spawnForced; + @Shadow + private ChunkCoordinates startMinecartRidingCoordinate; + @Shadow + public PlayerCapabilities capabilities; + @Shadow + public int experienceLevel; + @Shadow + public int experienceTotal; + @Shadow + public float experience; + @Shadow + private ItemStack itemInUse; + @Shadow + private int itemInUseCount; + @Shadow + protected float speedOnGround; + @Shadow + protected float speedInAir; + @Shadow + public EntityFishHook fishEntity; + @Shadow + public void destroyCurrentEquippedItem() {} + @Shadow + public void addStat(StatBase p_71064_1_, int p_71064_2_) {} + @Shadow + public ItemStack getCurrentEquippedItem() { return null;} + @Shadow + public void onEnchantmentCritical(Entity p_71047_1_) {} + @Shadow + public void onCriticalHit(Entity p_71009_1_) {} + @Shadow + public void triggerAchievement(StatBase p_71029_1_) {} + @Shadow + public abstract void addExhaustion(float p_71020_1_); /** * @author Shinare @@ -61,4 +146,169 @@ public abstract class MixinEntityPlayer extends EntityLivingBase { } } } + @Override + public void set_last_pickpocket_attempt(int i) { + this.last_pickpocket_attempt = i; + } + @Override + public int get_last_pickpocket_attempt() { + return this.last_pickpocket_attempt; + } + + @Overwrite + public void attackTargetEntityWithCurrentItem(Entity p_71059_1_) + { + if (MinecraftForge.EVENT_BUS.post(new AttackEntityEvent(((EntityPlayer)(Object)this), p_71059_1_))) + { + return; + } + ItemStack stack = getCurrentEquippedItem(); + if (stack != null && stack.getItem().onLeftClickEntity(stack, ((EntityPlayer)(Object)this), p_71059_1_)) + { + return; + } + if (p_71059_1_.canAttackWithItem()) + { + if (!p_71059_1_.hitByEntity(this)) + { + float f = (float)this.getEntityAttribute(SharedMonsterAttributes.attackDamage).getAttributeValue(); + int i = 0; + float f1 = 0.0F; + + if (p_71059_1_ instanceof EntityLivingBase) + { + f1 = EnchantmentHelper.getEnchantmentModifierLiving(this, (EntityLivingBase)p_71059_1_); + i += EnchantmentHelper.getKnockbackModifier(this, (EntityLivingBase)p_71059_1_); + } + + if (this.isSprinting()) + { + ++i; + } + + if (f > 0.0F || f1 > 0.0F) + { + boolean flag = this.fallDistance > 0.0F && !this.onGround && !this.isOnLadder() && !this.isInWater() && !this.isPotionActive(Potion.blindness) && this.ridingEntity == null && p_71059_1_ instanceof EntityLivingBase; + if (PotionHerbPoison.should_cancel_crit((EntityPlayer)(Object)this)) { + flag = false; + } + + if (flag && f > 0.0F) + { + f *= 1.5F; + } + + f += f1; + boolean flag1 = false; + int j = EnchantmentHelper.getFireAspectModifier(((EntityPlayer)(Object)this)); + + if (p_71059_1_ instanceof EntityLivingBase && j > 0 && !p_71059_1_.isBurning()) + { + flag1 = true; + p_71059_1_.setFire(1); + } + + boolean flag2 = p_71059_1_.attackEntityFrom(DamageSource.causePlayerDamage(((EntityPlayer)(Object)this)), f); + + if (flag2) + { + if (i > 0) + { + p_71059_1_.addVelocity((double)(-MathHelper.sin(this.rotationYaw * (float)Math.PI / 180.0F) * (float)i * 0.5F), 0.1D, (double)(MathHelper.cos(((EntityPlayer)(Object)this).rotationYaw * (float)Math.PI / 180.0F) * (float)i * 0.5F)); + ((EntityPlayer)(Object)this).motionX *= 0.6D; + ((EntityPlayer)(Object)this).motionZ *= 0.6D; + ((EntityPlayer)(Object)this).setSprinting(false); + } + + if (flag) + { + this.onCriticalHit(p_71059_1_); + } + + if (f1 > 0.0F) + { + this.onEnchantmentCritical(p_71059_1_); + } + + if (f >= 18.0F) + { + this.triggerAchievement(AchievementList.overkill); + } + + ((EntityPlayer)(Object)this).setLastAttacker(p_71059_1_); + + if (p_71059_1_ instanceof EntityLivingBase) + { + EnchantmentHelper.func_151384_a((EntityLivingBase)p_71059_1_, ((EntityPlayer)(Object)this)); + } + + EnchantmentHelper.func_151385_b(((EntityPlayer)(Object)this), p_71059_1_); + ItemStack itemstack = ((EntityPlayer)(Object)this).getCurrentEquippedItem(); + Object object = p_71059_1_; + + if (p_71059_1_ instanceof EntityDragonPart) + { + IEntityMultiPart ientitymultipart = ((EntityDragonPart)p_71059_1_).entityDragonObj; + + if (ientitymultipart != null && ientitymultipart instanceof EntityLivingBase) + { + object = (EntityLivingBase)ientitymultipart; + } + } + + if (itemstack != null && object instanceof EntityLivingBase) + { + itemstack.hitEntity((EntityLivingBase)object, ((EntityPlayer)(Object)this)); + + if (itemstack.stackSize <= 0) + { + ((EntityPlayer)(Object)this).destroyCurrentEquippedItem(); + } + } + + if (p_71059_1_ instanceof EntityLivingBase) + { + this.addStat(StatList.damageDealtStat, Math.round(f * 10.0F)); + + if (j > 0) + { + p_71059_1_.setFire(j * 4); + } + } + + this.addExhaustion(0.3F); + } + else if (flag1) + { + p_71059_1_.extinguish(); + } + } + } + } + } + + @Inject(method = "onLivingUpdate", at = @At("TAIL")) + public void disableHotbarSlotsOverdose(CallbackInfo ci) { + EntityPlayer player = (EntityPlayer)(Object)this; + PotionEffect effect = player.getActivePotionEffect(LoEPotions.overdose); + + if (effect != null && effect.getAmplifier() >= 2) { + int slot = player.inventory.currentItem; + if (slot >= 3 && slot <= 8) { + player.inventory.currentItem = 0; + } + } + } + public boolean canAttackWithItem() { + EntityPlayer player = (EntityPlayer)(Object)this; + PotionEffect effect = player.getActivePotionEffect(LoEPotions.overdose); + + if (effect != null && effect.getAmplifier() >= 2) { + int slot = player.inventory.currentItem; + if (slot >= 3 && slot <= 8) { + return false; + } + } + return super.canAttackWithItem(); + } } diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/MixinFoodStats.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinFoodStats.java new file mode 100644 index 0000000..424201f --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinFoodStats.java @@ -0,0 +1,74 @@ +package com.zivilon.cinder_loe.mixins; + +import com.zivilon.cinder_loe.potion.*; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemFood; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.EnumDifficulty; +import net.minecraft.potion.*; +import net.minecraft.util.*; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Overwrite; + +@Mixin(FoodStats.class) +public class MixinFoodStats { + @Shadow + private int foodLevel = 20; + @Shadow + private float foodSaturationLevel = 5.0F; + @Shadow + private float foodExhaustionLevel; + @Shadow + private int foodTimer; + @Shadow + private int prevFoodLevel = 20; + @Shadow + public void addExhaustion(float p_71020_1_) {}; + + @Overwrite + public void onUpdate(EntityPlayer player) { + EnumDifficulty enumdifficulty = player.worldObj.difficultySetting; + this.prevFoodLevel = this.foodLevel; + + if (this.foodExhaustionLevel > 4.0F) { + this.foodExhaustionLevel -= 4.0F; + + if (this.foodSaturationLevel > 0.0F) { + this.foodSaturationLevel = Math.max(this.foodSaturationLevel - 1.0F, 0.0F); + } else if (enumdifficulty != EnumDifficulty.PEACEFUL) { + this.foodLevel = Math.max(this.foodLevel - 1, 0); + } + } + + if (player.worldObj.getGameRules().getGameRuleBooleanValue("naturalRegeneration") && this.foodLevel >= 18 && player.shouldHeal()) { + ++this.foodTimer; + + if (this.foodTimer >= 80) { + PotionEffect potion = player.getActivePotionEffect(LoEPotions.overdose); + if (potion == null || potion.getAmplifier() < 1) + player.heal(1.0F); + this.addExhaustion(3.0F); + this.foodTimer = 0; + } + } else if (this.foodLevel <= 0) { + ++this.foodTimer; + + if (this.foodTimer >= 80) { + if (player.getHealth() > 10.0F || enumdifficulty == EnumDifficulty.HARD || player.getHealth() > 1.0F && enumdifficulty == EnumDifficulty.NORMAL) { + player.attackEntityFrom(DamageSource.starve, 1.0F); + } + + this.foodTimer = 0; + } + } else { + this.foodTimer = 0; + } + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREnchantment.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREnchantment.java index aa9678f..c08d748 100644 --- a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREnchantment.java +++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREnchantment.java @@ -1,11 +1,10 @@ package com.zivilon.cinder_loe.mixins; import com.zivilon.cinder_loe.enchants.LOTREnchantmentWeakProtectionRanged; +import com.zivilon.cinder_loe.enchants.LOTREnchantmentArmorSpecial; import com.zivilon.cinder_loe.util.Utilities; -import lotr.common.enchant.LOTREnchantment; -import lotr.common.enchant.LOTREnchantmentDamage; -import lotr.common.enchant.LOTREnchantmentProtectionRanged; -import lotr.common.enchant.LOTREnchantmentRangedDamage; +import lotr.common.enchant.*; +import net.minecraft.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; @@ -29,11 +28,30 @@ public class MixinLOTREnchantment { LOTREnchantment protectRangedWeak2 = new LOTREnchantmentWeakProtectionRanged("protectRangedWeak2", -2).setEnchantWeight(0); LOTREnchantment rangedWeak3 = new LOTREnchantmentRangedDamage("rangedWeak3", 0.25f); LOTREnchantment weak4 = new LOTREnchantmentDamage("weak4", -3.0f).setEnchantWeight(0); + LOTREnchantment chill = new LOTREnchantmentDamage("strong5", 3.25f).setEnchantWeight(0); + LOTREnchantment rangedStrong4 = new LOTREnchantmentRangedDamage("rangedStrong4", 1.4f).setEnchantWeight(0).setSkilful(); + LOTREnchantment meleeReach2 = new LOTREnchantmentMeleeReach("meleeReach2", 1.33f).setEnchantWeight(0).setSkilful(); + LOTREnchantment meleeSpeed2 = new LOTREnchantmentMeleeSpeed("meleeSpeed2", 1.33f).setEnchantWeight(0).setSkilful(); + LOTREnchantment Shinare = new LOTREnchantmentArmorSpecial("Shinare").setEnchantWeight(0).setSkilful(); + LOTREnchantment swiftness = new LOTREnchantmentArmorSpecial("swiftness").setEnchantWeight(0).setSkilful(); + LOTREnchantment fireRepair = new LOTREnchantmentArmorSpecial("fireRepair").setEnchantWeight(0).setSkilful(); + LOTREnchantment mountArmor = new LOTREnchantmentArmorSpecial("mountArmor").setEnchantWeight(0).setSkilful(); + LOTREnchantment stealth = new LOTREnchantmentArmorSpecial("stealth").setEnchantWeight(0).setSkilful(); + LOTREnchantment.allEnchantments.add(protectRangedWeak1); LOTREnchantment.allEnchantments.add(protectRangedWeak2); rangedWeak3.allEnchantments.add(rangedWeak3); LOTREnchantment.allEnchantments.add(weak4); + LOTREnchantment.allEnchantments.add(chill); + LOTREnchantment.allEnchantments.add(rangedStrong4); + LOTREnchantment.allEnchantments.add(meleeReach2); + LOTREnchantment.allEnchantments.add(meleeSpeed2); + LOTREnchantment.allEnchantments.add(Shinare); + LOTREnchantment.allEnchantments.add(swiftness); + LOTREnchantment.allEnchantments.add(fireRepair); + LOTREnchantment.allEnchantments.add(mountArmor); + LOTREnchantment.allEnchantments.add(stealth); Field enchantsByNameField = LOTREnchantment.class.getDeclaredField("enchantsByName"); enchantsByNameField.setAccessible(true); @@ -44,6 +62,15 @@ public class MixinLOTREnchantment { enchantsByName.put(protectRangedWeak2.enchantName, protectRangedWeak2); enchantsByName.put(rangedWeak3.enchantName, rangedWeak3); enchantsByName.put(weak4.enchantName, weak4); + enchantsByName.put(chill.enchantName, chill); + enchantsByName.put(rangedStrong4.enchantName, rangedStrong4); + enchantsByName.put(meleeReach2.enchantName, meleeReach2); + enchantsByName.put(meleeSpeed2.enchantName, meleeSpeed2); + enchantsByName.put(Shinare.enchantName, Shinare); + enchantsByName.put(swiftness.enchantName, swiftness); + enchantsByName.put(fireRepair.enchantName, fireRepair); + enchantsByName.put(mountArmor.enchantName, mountArmor); + enchantsByName.put(stealth.enchantName, stealth); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); @@ -51,7 +78,7 @@ public class MixinLOTREnchantment { } /** - * @author Shinare + * @author MrJeep20 * @reason Bad enchantments will not count towards 3 modifier limit now **/ @Overwrite(remap = false) diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAIAttackOnCollide.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAIAttackOnCollide.java new file mode 100644 index 0000000..c1fbe49 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAIAttackOnCollide.java @@ -0,0 +1,103 @@ +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.EntityCreature; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.IEntityLivingData; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import lotr.common.entity.npc.LOTREntityNPC; +import lotr.common.entity.projectile.LOTREntitySpear; +import lotr.common.entity.ai.LOTREntityAIAttackOnCollide; +import lotr.common.item.LOTRItemSpear; +import lotr.common.item.LOTRWeaponStats; + +import java.util.UUID; + +@Mixin(LOTREntityAIAttackOnCollide.class) +public class MixinLOTREntityAIAttackOnCollide { + + @Shadow(remap = false) + protected World worldObj; + @Shadow(remap = false) + protected EntityCreature theOwner; + @Shadow(remap = false) + protected EntityLivingBase attackTarget; + @Shadow(remap = false) + protected int attackTick; + @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 = 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() { + updateLookAndPathing(); + if (this.attackTick > 0) + this.attackTick--; + ItemStack weapon = this.theOwner.getHeldItem(); + if (weapon != null && weapon.getItem() instanceof LOTRItemSpear && this.attackTick <= 0 && this.theOwner instanceof LOTREntityNPC) { + LOTREntityNPC theNPC = (LOTREntityNPC)this.theOwner; + ItemStack spearBackup = theNPC.npcItemsInv.getSpearBackup(); + if (spearBackup != null) { + LOTRItemSpear spearItem = (LOTRItemSpear)weapon.getItem(); + double d = this.theOwner.getDistanceToEntity((Entity)this.attackTarget); + double range = this.theOwner.getNavigator().getPathSearchRange(); + if (d > 5.0D && d < range * 0.75D) { + LOTREntitySpear spear = new LOTREntitySpear(this.worldObj, (EntityLivingBase)this.theOwner, this.attackTarget, weapon.copy(), 0.75F + (float)d * 0.025F, 0.5F); + this.worldObj.playSoundAtEntity((Entity)this.theOwner, "random.bow", 1.0F, 1.0F / (this.worldObj.rand.nextFloat() * 0.4F + 1.2F) + 0.25F); + this.worldObj.spawnEntityInWorld((Entity)spear); + this.attackTick = 30 + this.theOwner.getRNG().nextInt(20); + if (ItemStack.areItemStacksEqual(theNPC.npcItemsInv.getIdleItem(), theNPC.npcItemsInv.getMeleeWeapon())) + theNPC.npcItemsInv.setIdleItem(spearBackup); + theNPC.npcItemsInv.setMeleeWeapon(spearBackup); + theNPC.npcItemsInv.setSpearBackup(null); + return; + } + } + } + float weaponReach = 1.0F; + if (this.theOwner.ridingEntity != null) + weaponReach = LOTREntityNPC.MOUNT_RANGE_BONUS; + weaponReach *= LOTRWeaponStats.getMeleeReachFactor(this.theOwner.getHeldItem()); + float meleeRange = (float)this.theOwner.boundingBox.getAverageEdgeLength() + weaponReach; + if (this.theOwner.getDistanceSqToEntity((Entity)this.attackTarget) <= (meleeRange * meleeRange)) + if (this.attackTick <= 0) { + this.attackTick = LOTRWeaponStats.getAttackTimeMob(weapon); + this.theOwner.attackEntityAsMob((Entity)this.attackTarget); + this.theOwner.swingItem(); + } + } +} 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 c351181..7802fe5 100644 --- a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAINearestAttackableTargetBasic.java +++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityAINearestAttackableTargetBasic.java @@ -1,35 +1,140 @@ package com.zivilon.cinder_loe.mixins; -import com.zivilon.cinder_loe.potion.LoEPotions; // Needs to be implemented +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; import lotr.common.entity.ai.LOTREntityAINearestAttackableTargetBasic; +import lotr.common.entity.ai.LOTREntityAINearestAttackableTargetBasic.TargetSorter; +import lotr.common.entity.npc.LOTREntityNPC; +import lotr.common.entity.npc.LOTREntityNPCRideable; +import lotr.common.item.LOTRItemArmor; +import net.minecraft.command.IEntitySelector; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.ai.EntityAITarget; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.injection.*; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Collections; +import java.util.List; +import java.util.UUID; +import net.minecraft.util.ChatComponentText; +import lotr.common.enchant.LOTREnchantment; +import lotr.common.enchant.LOTREnchantmentHelper; @Mixin(LOTREntityAINearestAttackableTargetBasic.class) public abstract class MixinLOTREntityAINearestAttackableTargetBasic extends EntityAITarget { + @Shadow private final Class targetClass; + @Shadow private EntityLivingBase targetEntity; + @Shadow private final TargetSorter targetSorter; + @Shadow private final IEntitySelector targetSelector; + @Shadow private final int targetChance; + public MixinLOTREntityAINearestAttackableTargetBasic(EntityCreature p_i1669_1_, boolean p_i1669_2_) { super(p_i1669_1_, p_i1669_2_); + targetClass = null; + targetEntity = null; + targetSorter = null; + targetSelector = null; + targetChance = 0; + } + + @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 false; + + UUID leader_id = ((IEntityLivingBase) self).get_warband_uuid(); + if (leader_id == null) return false; + + 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 true; + } + return false; + } + public boolean original_should_execute() { + if (this.targetChance > 0 && this.taskOwner.getRNG().nextInt(this.targetChance) != 0) + return false; + if (this.taskOwner instanceof LOTREntityNPC) { + LOTREntityNPC npc = (LOTREntityNPC)this.taskOwner; + if (npc.hiredNPCInfo.isActive && npc.hiredNPCInfo.isHalted()) + return false; + if (npc.isChild()) + return false; + } + if (this.taskOwner instanceof LOTREntityNPCRideable) { + LOTREntityNPCRideable rideable = (LOTREntityNPCRideable)this.taskOwner; + if (rideable.isNPCTamed() || rideable.riddenByEntity instanceof EntityPlayer) + return false; + } + double range = getTargetDistance(); + double rangeY = Math.min(range, 8.0D); + List entities = this.taskOwner.worldObj.selectEntitiesWithinAABB(this.targetClass, this.taskOwner.boundingBox.expand(range, rangeY, range), this.targetSelector); + List entity_list = (List)entities; + Collections.sort(entity_list, this.targetSorter); + if (entities.isEmpty()) + return false; + this.targetEntity = (EntityLivingBase)entities.get(0); + return true; } /** - * @author Shinare - * @reason Added corrupting potion effect that makes all NPCs hostile - */ + * @author Shinare + * @reason Added corrupting potion effect that makes all NPCs hostile + */ @Overwrite(remap = false) protected boolean isPlayerSuitableAlignmentTarget(EntityPlayer entityplayer) { float alignment = LOTRLevelData.getData(entityplayer).getAlignment(LOTRMod.getNPCFaction((Entity)this.taskOwner)); if (entityplayer == null || LoEPotions.corrupting == null) return alignment < 0.0F; - boolean corrupting = entityplayer.isPotionActive(LoEPotions.corrupting); // Needs to be implemented + boolean corrupting = entityplayer.isPotionActive(LoEPotions.corrupting); return (alignment < 0.0F || corrupting); } + + @Inject(method = "isPlayerSuitableTarget", at = @At("HEAD"), cancellable = true, remap = false) + private void cinderloe$applyStealthModifier(EntityPlayer player, CallbackInfoReturnable cir) { + int stealthPieces = 0; + + for (ItemStack armor : player.inventory.armorInventory) { + if (armor != null && armor.getItem() instanceof LOTRItemArmor && armor.stackTagCompound != null) { + if (LOTREnchantmentHelper.hasEnchant(armor, LOTREnchantment.getEnchantmentByName("stealth"))) { + stealthPieces++; + } + } + } + + if (stealthPieces > 0 && taskOwner != null) { + double baseDetectionRange = taskOwner.getEntityAttribute(net.minecraft.entity.SharedMonsterAttributes.followRange).getAttributeValue(); + double multiplier = 1.0 - (0.15 * stealthPieces); + double effectiveRangeSq = (baseDetectionRange * multiplier) * (baseDetectionRange * multiplier); + double distanceSq = taskOwner.getDistanceSqToEntity(player); + + if (distanceSq > effectiveRangeSq) { + cir.setReturnValue(false); + } + } + } } 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/MixinLOTREntityBear.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityBear.java new file mode 100644 index 0000000..99d81f2 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityBear.java @@ -0,0 +1,63 @@ +package com.zivilon.cinder_loe.mixins; + +import com.zivilon.cinder_loe.CinderLoE; +import lotr.common.LOTRMod; +import lotr.common.entity.animal.LOTREntityBear; +import lotr.common.entity.npc.LOTREntityWarg; +import net.minecraft.entity.Entity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + + +@Mixin(LOTREntityBear.class) +public abstract class MixinLOTREntityBear extends Entity { + + public MixinLOTREntityBear(World worldIn) { + super(worldIn); + } + + /** + * @author KeyLime17 + * @reason Mevans + */ + + @Shadow + public abstract LOTREntityBear.BearType getBearType(); + + @Overwrite(remap = false) + protected void func_70628_a(boolean flag, int i) { + Item furItem = null; + int furMeta = 0; + switch(getBearType().bearID) { + case 0: + furItem = LOTRMod.fur; + break; + case 1: + furItem = CinderLoE.cinderFurItem; + furMeta = 5; + break; + case 2: + furItem = CinderLoE.cinderFurItem; + furMeta = 4; + break; + } + + int furs = 1 + this.rand.nextInt(3) + this.rand.nextInt(i + 1); + for (int l = 0; l < furs; l++) + entityDropItem(new ItemStack(furItem, 1, furMeta), 0.0F); + int bones = 2 + this.rand.nextInt(2) + this.rand.nextInt(i + 1); + for (int j = 0; j < bones; j++) + dropItem(LOTRMod.wargBone, 1); + if (flag) { + int rugChance = 50 - i * 8; + rugChance = Math.max(rugChance, 1); + if (this.rand.nextInt(rugChance) == 0) + entityDropItem(new ItemStack(LOTRMod.wargskinRug, 1, (getBearType()).bearID), 0.0F); + } + } + +} diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityHorse.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityHorse.java new file mode 100644 index 0000000..7f5d7da --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityHorse.java @@ -0,0 +1,38 @@ +package com.zivilon.cinder_loe.mixins; + +import lotr.common.entity.animal.LOTREntityHorse; +import lotr.common.enchant.LOTREnchantment; +import lotr.common.enchant.LOTREnchantmentHelper; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import lotr.common.item.LOTRItemArmor; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(LOTREntityHorse.class) +public class MixinLOTREntityHorse { + + @Inject(method = "func_70658_aO", at = @At("RETURN"), cancellable = true, remap = false) + private void cinderloe$boostArmorFromRider(CallbackInfoReturnable cir) { + LOTREntityHorse horse = (LOTREntityHorse)(Object)this; + + if (horse.riddenByEntity instanceof EntityPlayer) { + EntityPlayer rider = (EntityPlayer) horse.riddenByEntity; + + int bonus = 0; + for (ItemStack armor : rider.inventory.armorInventory) { + if (armor != null && LOTREnchantmentHelper.hasEnchant(armor, LOTREnchantment.getEnchantmentByName("mountArmor"))) { + bonus++; + } + } + + if (bonus > 0) { + int newArmorValue = cir.getReturnValue() + bonus; + cir.setReturnValue(newArmorValue); + } + } + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityLioness.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityLioness.java new file mode 100644 index 0000000..76d5261 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityLioness.java @@ -0,0 +1,48 @@ +package com.zivilon.cinder_loe.mixins; + +import com.zivilon.cinder_loe.CinderLoE; +import lotr.common.LOTRMod; +import lotr.common.entity.animal.LOTREntityBear; +import lotr.common.item.LOTRItemLionRug; +import net.minecraft.entity.Entity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + + +@Mixin(LOTREntityBear.class) +public abstract class MixinLOTREntityLioness extends Entity { + + public MixinLOTREntityLioness(World worldIn) { + super(worldIn); + } + + /** + * @author KeyLime17 + * @reason Mevans + */ + + + protected LOTRItemLionRug.LionRugType getLionRugType() { + return LOTRItemLionRug.LionRugType.LIONESS; + } + + @Overwrite(remap = false) + protected void func_70628_a(boolean flag, int i) { + Item furItem = CinderLoE.cinderFurItem; + int furMeta = 6; + + int furs = 1 + this.rand.nextInt(3) + this.rand.nextInt(i + 1); + for (int l = 0; l < furs; l++) + entityDropItem(new ItemStack(furItem, 1, furMeta), 0.0F); + if (flag) { + int rugChance = 50 - i * 8; + rugChance = Math.max(rugChance, 1); + if (this.rand.nextInt(rugChance) == 0) + entityDropItem(new ItemStack(LOTRMod.lionRug, 1, (getLionRugType()).lionID), 0.0F); + } + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityNPC.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityNPC.java new file mode 100644 index 0000000..88f9530 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityNPC.java @@ -0,0 +1,150 @@ +package com.zivilon.cinder_loe.mixins; + +import com.zivilon.cinder_loe.CinderAchievement; +import com.zivilon.cinder_loe.droptables.DropTable; +import com.zivilon.cinder_loe.droptables.DropContext; +import com.zivilon.cinder_loe.util.ILootableEntity; +import com.zivilon.cinder_loe.util.IMixinEntityPlayer; +import com.zivilon.cinder_loe.util.PickpocketUtils; +import com.zivilon.cinder_loe.CinderLoE; + +import lotr.common.LOTRLevelData; +import lotr.common.entity.npc.LOTREntityOlogHai; +import lotr.common.entity.npc.LOTRSpeech; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.IEntityLivingData; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.*; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.IChatComponent; +import net.minecraft.world.World; + +import lotr.common.entity.npc.LOTREntityNPC; +import lotr.common.entity.npc.LOTREntityQuestInfo; + +import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.injection.*; +import org.spongepowered.asm.mixin.injection.callback.*; + +import java.util.ArrayList; +import java.util.List; + +@Mixin(LOTREntityNPC.class) +public abstract class MixinLOTREntityNPC extends EntityCreature implements ILootableEntity { + public DropTable drop_table = null; + public int last_pickpocket = 0; + public float pickpocket_chance = 0.0F; + + @Shadow + public LOTREntityQuestInfo questInfo; + @Shadow + public boolean speakTo(EntityPlayer entityplayer) {return false;} + @Shadow + public boolean canNPCTalk() {return false;} + + public MixinLOTREntityNPC(World world) { + super(world); + } + + /** + * @author + * @reason + */ + @Overwrite + public boolean interact(EntityPlayer entityplayer) { + if (PickpocketUtils.can_pickpocket(entityplayer, (LOTREntityNPC)(Object)this)) { + boolean success = PickpocketUtils.pickpocket(entityplayer, (LOTREntityNPC)(Object)this); + ((IMixinEntityPlayer)entityplayer).set_last_pickpocket_attempt((int)(System.currentTimeMillis() / 1000L)); + if (success) { + List drops = DropTable.generate_drops((LOTREntityNPC)(Object)this, new DropContext[]{DropContext.PICKPOCKET}, 0); + ItemStack item = drops.get(DropTable.random.nextInt(drops.size())); + if ((LOTREntityNPC)(Object)this instanceof LOTREntityOlogHai) { + + } + if (entityplayer.inventory.addItemStackToInventory(item)) { + last_pickpocket = (int)(System.currentTimeMillis() / 1000L); + } else { + } + } else { + last_pickpocket = (int)(System.currentTimeMillis() / 1000L); + ((LOTREntityNPC)(Object)this).setRevengeTarget(entityplayer); + LOTRLevelData.getData(entityplayer).addAchievement(CinderAchievement.pickOlog); + } + return true; + } + if (!this.worldObj.isRemote && canNPCTalk()) { + if (this.questInfo.interact(entityplayer)) + return true; + if (getAttackTarget() == null) + if (speakTo(entityplayer)) + return true; + } + return super.interact(entityplayer); + } + + @Inject(method = "func_110161_a", at = @At("HEAD"), remap = false) // onSpawnWithEgg + private void onSpawned(IEntityLivingData entity, CallbackInfoReturnable cir) { + PickpocketUtils.assign_drop_table((LOTREntityNPC)(Object)this); + } + + /** + * Add support for DropTables + */ + @Inject(method = "func_70628_a", at = @At("HEAD"), remap = false) // dropFewItems + private void loot_drop_table(boolean flag, int i, CallbackInfo ci) { + DropContext[] context = new DropContext[3]; + int len = 0; + context[len++] = DropContext.KILLED; + + if (((LOTREntityNPC)(Object)this).isBurning()) { + context[len++] = DropContext.KILLED_BY_FIRE; + } + if (flag) { + context[len++] = DropContext.KILLED_BY_PLAYER; + } + DropTable.drop_items((LOTREntityNPC)(Object)this, context, i); + } + @Inject(method = "func_70014_b", at = @At("TAIL"), remap = false) // writeEntityToNBT + private void write_drop_table(NBTTagCompound tag, CallbackInfo ci) { + if (drop_table != null) { + tag.setTag("DropTable", DropTable.serialize_to_nbt(drop_table)); + } + tag.setTag("last_pickpocket", new NBTTagInt(last_pickpocket)); + tag.setTag("pickpocket_chance", new NBTTagFloat(pickpocket_chance)); + } + @Inject(method = "func_70037_a", at = @At("TAIL"), remap = false) // readEntityFromNBT + private void read_drop_table(NBTTagCompound tag, CallbackInfo ci) { + if (tag.hasKey("DropTable")) { + this.drop_table = DropTable.deserialize_from_nbt(tag.getCompoundTag("DropTable")); + } + this.last_pickpocket = tag.getInteger("last_pickpocket"); + this.pickpocket_chance = tag.getFloat("pickpocket_chance"); + } + + @Override + public void set_drop_table(DropTable table) { + drop_table = table; + } + @Override + public DropTable get_drop_table() { + return drop_table; + } + @Override + public void set_last_pickpocket(int i) { + this.last_pickpocket = i; + } + @Override + public int get_last_pickpocket() { + return this.last_pickpocket; + } + @Override + public void set_pickpocket_chance(Float f) { + this.pickpocket_chance = f; + } + @Override + public Float get_pickpocket_chance() { + return this.pickpocket_chance; + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityProjectileBase.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityProjectileBase.java index 329c8f4..47862ab 100644 --- a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityProjectileBase.java +++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityProjectileBase.java @@ -3,9 +3,11 @@ package com.zivilon.cinder_loe.mixins; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Overwrite; + import lotr.common.item.LOTRWeaponStats; import lotr.common.enchant.LOTREnchantmentHelper; import lotr.common.entity.projectile.LOTREntityProjectileBase; + import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.Entity; diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTREntityWarg.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityWarg.java similarity index 65% rename from src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTREntityWarg.java rename to src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityWarg.java index ea7db5a..f5e23cb 100644 --- a/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTREntityWarg.java +++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREntityWarg.java @@ -1,4 +1,4 @@ -package com.zivilon.cinder_loe.mixins.overrides; +package com.zivilon.cinder_loe.mixins; import com.zivilon.cinder_loe.CinderLoE; import lotr.common.LOTRMod; @@ -9,7 +9,16 @@ import net.minecraft.item.ItemStack; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.Shadow; +import lotr.common.entity.animal.LOTREntityHorse; +import lotr.common.enchant.LOTREnchantment; +import lotr.common.enchant.LOTREnchantmentHelper; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import lotr.common.item.LOTRItemArmor; @Mixin(LOTREntityWarg.class) @@ -73,5 +82,22 @@ public abstract class MixinLOTREntityWarg extends Entity { entityDropItem(new ItemStack(LOTRMod.wargskinRug, 1, (getWargType()).wargID), 0.0F); } } + @Inject(method = "func_70658_aO", at = @At("RETURN"), cancellable = true, remap = false) + private void cinderloe$boostArmorFromRider(CallbackInfoReturnable cir) { + if (this.riddenByEntity instanceof EntityPlayer) { + EntityPlayer rider = (EntityPlayer) this.riddenByEntity; + + int bonus = 0; + for (ItemStack armor : rider.inventory.armorInventory) { + if (armor != null && LOTREnchantmentHelper.hasEnchant(armor, LOTREnchantment.getEnchantmentByName("mountArmor"))) { + bonus++; + } + } + if (bonus > 0) { + int newArmorValue = cir.getReturnValue() + bonus; + cir.setReturnValue(newArmorValue); + } + } + } } 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..29c8e42 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTRGuiMap.java @@ -0,0 +1,131 @@ +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( 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) { + render_warbands(mouseX, mouseY); + } + + @Dynamic + private void render_warbands(int cursor_x, int cursor_y) { + 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()) { + 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) { + 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/mixins/MixinLOTRItemMug.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTRItemMug.java new file mode 100644 index 0000000..f5e3958 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTRItemMug.java @@ -0,0 +1,38 @@ + +package com.zivilon.cinder_loe.mixins; + +import com.zivilon.cinder_loe.potion.*; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import lotr.common.item.LOTRItemMug; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemFood; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.EnumDifficulty; +import net.minecraft.potion.*; +import net.minecraft.util.*; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Overwrite; + +import java.util.*; + +@Mixin(LOTRItemMug.class) +public class MixinLOTRItemMug { + @Shadow + protected List potionEffects = new ArrayList(); + + @Overwrite(remap = false) + private List convertPotionEffectsForStrength(float strength) { + List list = new ArrayList(); + for (int i = 0; i < this.potionEffects.size(); i++) { + PotionEffect base = this.potionEffects.get(i); + PotionEffect modified = new PotionEffect(base.getPotionID(), (int)(base.getDuration() * strength), base.getAmplifier()); + list.add(modified); + } + return list; + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRBiome.java b/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRBiome.java new file mode 100644 index 0000000..113bfd9 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRBiome.java @@ -0,0 +1,20 @@ +package com.zivilon.cinder_loe.mixins.overrides; + +import com.zivilon.cinder_loe.world.biome.CinderBiome; +import com.zivilon.cinder_loe.world.biome.GenMistyForest; +import lotr.common.world.biome.LOTRBiome; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(LOTRBiome.class) +public class MixinLOTRBiome { +//public static void initBiomes() { + // + @Inject(method = "initBiomes", at = @At("TAIL"), remap = false) + private static void cinder_biome_init(CallbackInfo ci) { + CinderBiome.mistyforest = new GenMistyForest(171, true).setTemperatureRainfall(1.2f, 1.2f).setMinMaxHeight(0.7f, 0.4f).setColor(3168544).setBiomeName("mistyForest"); + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRTradeEntriesOverrides.java b/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRTradeEntriesOverrides.java index a994822..0cf1491 100644 --- a/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRTradeEntriesOverrides.java +++ b/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRTradeEntriesOverrides.java @@ -133,6 +133,26 @@ public abstract class MixinLOTRTradeEntriesOverrides { */ @Inject(method = "setupTrades1", at = @At("RETURN"), remap = false) private static void newTrades(CallbackInfo ci) { + + DWARF_MINER_SELL = new LOTRTradeEntries(TradeType.SELL, + new LOTRTradeEntry(new ItemStack(Items.cooked_beef), 3), + new LOTRTradeEntry(new ItemStack(Items.cooked_porkchop), 3), + new LOTRTradeEntry(new ItemStack(LOTRMod.muttonCooked), 3), + new LOTRTradeEntry(new ItemStack(Items.cooked_chicken), 3), + new LOTRTradeEntry(new ItemStack(LOTRMod.gammon), 3), + new LOTRTradeEntry(new ItemStack(Items.cooked_fished), 3), + new LOTRTradeEntry(new ItemStack(LOTRMod.rabbitCooked), 3), + new LOTRTradeEntry(new ItemStack(LOTRMod.deerCooked), 3), + new LOTRTradeEntry(new ItemStack(Items.bread), 2), + new LOTRTradeEntry(new ItemStack(LOTRMod.cram), 6), + new LOTRTradeEntry(new ItemStack(LOTRMod.mugAle, 1, Short.MAX_VALUE), 8), + new LOTRTradeEntry(new ItemStack(LOTRMod.mugMead, 1, Short.MAX_VALUE), 8), + new LOTRTradeEntry(new ItemStack(LOTRMod.mugCider, 1, Short.MAX_VALUE), 8), + new LOTRTradeEntry(new ItemStack(LOTRMod.mugPerry, 1, Short.MAX_VALUE), 8), + new LOTRTradeEntry(new ItemStack(LOTRMod.mugDwarvenAle, 1, Short.MAX_VALUE), 12), + new LOTRTradeEntry(new ItemStack(LOTRMod.pickaxeDwarven), 10)); + + MORDOR_TRADER_BUY = new LOTRTradeEntries(TradeType.BUY, new LOTRTradeEntry(new ItemStack(LOTRMod.morgulTable), 100), new LOTRTradeEntry(new ItemStack(LOTRMod.helmetOrc), 20), diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRUnitTradeEntries.java b/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRUnitTradeEntries.java index 5070c85..700f333 100644 --- a/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRUnitTradeEntries.java +++ b/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRUnitTradeEntries.java @@ -4,6 +4,7 @@ import com.zivilon.cinder_loe.CinderUnitTradeEntry; import com.zivilon.cinder_loe.entity.npc.HobbitBannerBearer; import com.zivilon.cinder_loe.entity.npc.elf.Sirrandrai; import com.zivilon.cinder_loe.entity.npc.evil_human.RhudaurSoldier; +import com.zivilon.cinder_loe.entity.npc.evil_human.UmbarUsurper; import com.zivilon.cinder_loe.entity.npc.good_human.BattleNun; import com.zivilon.cinder_loe.entity.npc.good_human.EsgarothSoldier; import com.zivilon.cinder_loe.entity.npc.good_human.TauredainTrueBlood; @@ -12,9 +13,12 @@ import com.zivilon.cinder_loe.entity.npc.orc.NorthernOrc; import lotr.common.LOTRMod; import lotr.common.entity.animal.*; import lotr.common.entity.npc.*; +import net.minecraft.item.Item; +import net.minecraft.item.ItemArmor; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; @Mixin(LOTRUnitTradeEntries.class) public class MixinLOTRUnitTradeEntries { @@ -131,6 +135,18 @@ public class MixinLOTRUnitTradeEntries { new LOTRUnitTradeEntry(LOTREntityMordorOrcArcher.class, LOTREntityMordorSpider.class, "MordorOrcArcher_Spider", 250, 100.0f).setPledgeExclusive(), new LOTRUnitTradeEntry(LOTREntityNanUngolBannerBearer.class, 150, 150.0f), new LOTRUnitTradeEntry(LOTREntityNanUngolBannerBearer.class, LOTREntityMordorSpider.class, "MordorOrcArcher_Spider", 250, 250.0f).setPledgeExclusive()); +// @Unique +// +// //Lets give Gundies a chance to spawn with warg armor +// private static Item randomWargArmor() { +// Item[] options = { +// LOTRMod.wargArmorMordor, +// LOTRMod.wargArmorUruk, +// LOTRMod.wargArmorAngmar +// }; +// return options[LOTRMod.proxy.getClientWorld().rand.nextInt(options.length)]; +// } + @Shadow public static LOTRUnitTradeEntries GUNDABAD_ORC_MERCENARY_CAPTAIN = new LOTRUnitTradeEntries(100.0f, new LOTRUnitTradeEntry(LOTREntityGundabadOrc.class, 100, 0.0f), @@ -334,7 +350,8 @@ public class MixinLOTRUnitTradeEntries { new LOTRUnitTradeEntry(LOTREntityUmbarArcher.class, 250, 50.0f), new LOTRUnitTradeEntry(LOTREntityUmbarWarrior.class, LOTREntityHorse.class, "UmbarWarrior_Horse", 350, 100.0f).setMountArmor(LOTRMod.horseArmorUmbar).setPledgeExclusive(), new LOTRUnitTradeEntry(LOTREntityUmbarBannerBearer.class, 250, 150.0f), - new LOTRUnitTradeEntry(LOTREntityUmbarBannerBearer.class, LOTREntityHorse.class, "Banner_Horse", 350, 250.0f).setMountArmor(LOTRMod.horseArmorUmbar).setPledgeExclusive()); + new LOTRUnitTradeEntry(LOTREntityUmbarBannerBearer.class, LOTREntityHorse.class, "Banner_Horse", 350, 250.0f).setMountArmor(LOTRMod.horseArmorUmbar).setPledgeExclusive(), + new LOTRUnitTradeEntry(UmbarUsurper.class, 400, 500.0f).setPledgeExclusive()); @Shadow public static LOTRUnitTradeEntries CORSAIR_CAPTAIN = new LOTRUnitTradeEntries(150.0f, new LOTRUnitTradeEntry(LOTREntityCorsair.class, 200, 0.0f).setExtraInfo("Corsair")); diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinSepiaOverride.java b/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinSepiaOverride.java new file mode 100644 index 0000000..ae02778 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinSepiaOverride.java @@ -0,0 +1,17 @@ +package com.zivilon.cinder_loe.mixins.overrides; + +import lotr.client.gui.LOTRGuiMap; +import net.minecraft.util.ResourceLocation; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + + +@Mixin(LOTRGuiMap.class) +public class MixinSepiaOverride { + + + +} 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/potion/LoEPotions.java b/src/main/java/com/zivilon/cinder_loe/potion/LoEPotions.java index 34339c3..c68e9ac 100644 --- a/src/main/java/com/zivilon/cinder_loe/potion/LoEPotions.java +++ b/src/main/java/com/zivilon/cinder_loe/potion/LoEPotions.java @@ -6,23 +6,11 @@ import net.minecraft.entity.EntityLivingBase; public class LoEPotions { public static Potion corrupting; + public static Potion overdose; public static void registerPotions() { corrupting = new PotionCorrupting(31, false, 0x7F0000).setPotionName("potion.corrupting"); + overdose = new PotionHerbPoison(29, false, 0x114023).setPotionName("potion.overdose"); } } -class PotionCorrupting extends Potion { - public PotionCorrupting(int id, boolean isBadEffect, int liquidColor) { - super(id, isBadEffect, liquidColor); - } - - @Override - public void performEffect(EntityLivingBase entity, int amplifier) { - } - - @Override - public boolean isReady(int duration, int amplifier) { - return false; - } -} diff --git a/src/main/java/com/zivilon/cinder_loe/potion/PotionCorrupting.java b/src/main/java/com/zivilon/cinder_loe/potion/PotionCorrupting.java new file mode 100644 index 0000000..910ce13 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/potion/PotionCorrupting.java @@ -0,0 +1,20 @@ +package com.zivilon.cinder_loe.potion; + +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.entity.EntityLivingBase; + +public class PotionCorrupting extends Potion { + public PotionCorrupting(int id, boolean isBadEffect, int liquidColor) { + super(id, isBadEffect, liquidColor); + } + + @Override + public void performEffect(EntityLivingBase entity, int amplifier) { + } + + @Override + public boolean isReady(int duration, int amplifier) { + return false; + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/potion/PotionHerbPoison.java b/src/main/java/com/zivilon/cinder_loe/potion/PotionHerbPoison.java new file mode 100644 index 0000000..cb5defd --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/potion/PotionHerbPoison.java @@ -0,0 +1,49 @@ +package com.zivilon.cinder_loe.potion; + +import com.zivilon.cinder_loe.CinderLoE; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +public class PotionHerbPoison extends Potion { + public static ResourceLocation OVERDOSE_ICON = new ResourceLocation("cinder_loe", "misc/overdose.png"); + + public PotionHerbPoison(int id, boolean isBadEffect, int liquidColor) { + super(id, isBadEffect, liquidColor); + } + + @Override + public void performEffect(EntityLivingBase entity, int amplifier) { + } + + @Override + public boolean isReady(int duration, int amplifier) { + return false; + } + + public static boolean should_cancel_crit(EntityPlayer player) { + PotionEffect poison = player.getActivePotionEffect(LoEPotions.overdose); + if (poison != null && poison.getAmplifier() >= 1) { + return true; + } + return false; + } + @Override + public void renderInventoryEffect(int x, int y, PotionEffect effect, Minecraft mc) { + // Currently not implemented + } + + @Override + public boolean hasStatusIcon() { + return false; + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/recipe/CinderBrewingRecipes.java b/src/main/java/com/zivilon/cinder_loe/recipe/CinderBrewingRecipes.java new file mode 100644 index 0000000..28201a3 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/recipe/CinderBrewingRecipes.java @@ -0,0 +1,22 @@ +package com.zivilon.cinder_loe.recipe; + +import net.minecraft.item.ItemStack; + +import java.lang.reflect.Method; + +public class CinderBrewingRecipes { + public static void addCustomBrewingRecipe(ItemStack result, Object... ingredients) { + try { + Class brewingRecipesClass = Class.forName("lotr.common.recipe.LOTRBrewingRecipes"); + Method addBrewingRecipeMethod = brewingRecipesClass.getDeclaredMethod("addBrewingRecipe", ItemStack.class, Object[].class); + + addBrewingRecipeMethod.setAccessible(true); + + addBrewingRecipeMethod.invoke(null, result, ingredients); + + + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/recipes.java b/src/main/java/com/zivilon/cinder_loe/recipes.java index 2527bab..884e02e 100644 --- a/src/main/java/com/zivilon/cinder_loe/recipes.java +++ b/src/main/java/com/zivilon/cinder_loe/recipes.java @@ -2,13 +2,11 @@ package com.zivilon.cinder_loe; import cpw.mods.fml.common.registry.GameRegistry; import lotr.common.LOTRMod; -import lotr.common.recipe.LOTRBrewingRecipes; -import lotr.common.recipe.LOTRMillstoneRecipes; -import lotr.common.recipe.LOTRRecipePoisonWeapon; -import lotr.common.recipe.LOTRRecipes; +import lotr.common.recipe.*; import com.zivilon.cinder_loe.CinderLoE; import com.zivilon.cinder_loe.recipe.*; import com.zivilon.cinder_loe.mixins.MixinLOTRBrewingRecipes; +import com.zivilon.cinder_loe.recipe.CinderBrewingRecipes; import lotr.common.item.LOTRItemFood; import net.minecraft.init.Blocks; @@ -141,10 +139,10 @@ public class recipes { GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(CinderLoE.fruitsalad), Items.bowl, "fruit1", "fruit2", "fruit3")); GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(CinderLoE.pasta, 4), new ItemStack(LOTRMod.rollingPin, 1, OreDictionary.WILDCARD_VALUE), CinderLoE.dough, CinderLoE.dough)); GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(CinderLoE.halva), Items.sugar, CinderLoE.dough, CinderLoE.spice, LOTRMod.almond)); - + GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(CinderLoE.doner_kebab), CinderLoE.dough, "vegetable2", CinderLoE.spice, LOTRMod.kebab)); GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(CinderLoE.chocolatebar, 2), LOTRMod.mugChocolate)); - GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(CinderLoE.pelmen), Items.wheat, "meat", LOTRMod.salt)); + GameRegistry.addRecipe(new LOTRRecipesPoisonDrinks()); GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(CinderLoE.cinderBlock), "XXX", "XYX", "XXX", 'X', Blocks.stone, 'Y', LOTRMod.balrogFire)); @@ -181,6 +179,10 @@ public class recipes { // Cinder Stony Blocks GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(CinderLoE.cindercobble, 4, 1), "XY", "YX", 'X', new ItemStack(LOTRMod.rock, 1, 0), 'Y', LOTRMod.mordorGravel)); + GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(CinderLoE.cindercobble, 4, 2), "XX", "XX", + 'X', new ItemStack(LOTRMod.silver))); + GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(CinderLoE.cindercobble, 4, 3), "XX", "XX", + 'X', new ItemStack(CinderLoE.cindercobble, 1, 2))); GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(LOTRMod.banner, 1, 44), " Y ", " X ", " Z ", 'X', "stickWood", 'Y', new ItemStack(Blocks.wool, 1, 14), 'Z', "plankWood")); @@ -372,7 +374,41 @@ public class recipes { new ItemStack(LOTRMod.doubleFlower, 1, 2), new ItemStack(LOTRMod.doubleFlower, 1, 3), new ItemStack(LOTRMod.mugMilk)); - + CinderBrewingRecipes.addCustomBrewingRecipe(new ItemStack(LOTRMod.mugTauredainCocoa, BARREL_CAPACITY), + new ItemStack(Items.dye, 1, 3), + new ItemStack(Items.dye, 1, 3), + new ItemStack(Items.dye, 1, 3), + new ItemStack(LOTRMod.doubleFlower, 1, 2), + new ItemStack(LOTRMod.doubleFlower, 1, 3), + new ItemStack(LOTRMod.mugMilk)); + CinderBrewingRecipes.addCustomBrewingRecipe(new ItemStack(CinderLoE.mugElfBrew, BARREL_CAPACITY), + new ItemStack(LOTRMod.elanor), + new ItemStack(LOTRMod.niphredil), + new ItemStack(LOTRMod.mallornNut), + new ItemStack(LOTRMod.mallornNut), + new ItemStack(CinderLoE.spiceElven), + new ItemStack(CinderLoE.spiceElven)); + CinderBrewingRecipes.addCustomBrewingRecipe(new ItemStack(CinderLoE.mugHumanBrew, BARREL_CAPACITY), + new ItemStack(LOTRMod.athelas), + new ItemStack(LOTRMod.athelas), + new ItemStack(LOTRMod.athelas), + new ItemStack(LOTRMod.athelas), + new ItemStack(CinderLoE.spiceHuman), + new ItemStack(CinderLoE.spiceHuman)); + CinderBrewingRecipes.addCustomBrewingRecipe(new ItemStack(CinderLoE.mugOrcBrew, BARREL_CAPACITY), + new ItemStack(LOTRMod.morgulShroom), + new ItemStack(LOTRMod.nauriteGem), + new ItemStack(LOTRMod.morgulShroom), + new ItemStack(LOTRMod.guldurilCrystal), + new ItemStack(CinderLoE.spiceOrcish), + new ItemStack(CinderLoE.spiceOrcish)); + CinderBrewingRecipes.addCustomBrewingRecipe(new ItemStack(CinderLoE.mugDwarfBrew, BARREL_CAPACITY), + new ItemStack(LOTRMod.dwarfHerb), + new ItemStack(LOTRMod.dwarfHerb), + new ItemStack(LOTRMod.dwarfHerb), + new ItemStack(LOTRMod.dwarfHerb), + new ItemStack(CinderLoE.spiceDwarven), + new ItemStack(CinderLoE.spiceDwarven)); MixinLOTRBrewingRecipes.addRecipe(new ItemStack(CinderLoE.mugDemonicHealthPotion, 2), new Object[] { CinderLoE.demonbloodVial, new ItemStack(LOTRMod.tallGrass, 1, 4), diff --git a/src/main/java/com/zivilon/cinder_loe/util/DamageEvent.java b/src/main/java/com/zivilon/cinder_loe/util/DamageEvent.java index 7cef160..20c1e6d 100644 --- a/src/main/java/com/zivilon/cinder_loe/util/DamageEvent.java +++ b/src/main/java/com/zivilon/cinder_loe/util/DamageEvent.java @@ -3,6 +3,11 @@ package com.zivilon.cinder_loe.util; import net.minecraft.entity.*; import net.minecraft.entity.player.*; import net.minecraft.util.DamageSource; + +import com.zivilon.cinder_loe.mixins.MixinLOTREnchantment; +import lotr.common.enchant.LOTREnchantment; +import lotr.common.enchant.LOTREnchantmentHelper; + import lotr.common.item.*; import net.minecraft.item.*; import net.minecraft.world.World; @@ -67,7 +72,22 @@ public class DamageEvent { } } } - + if (event.source.isFireDamage() && event.defender instanceof EntityPlayer) { + EntityPlayer player = (EntityPlayer) event.defender; + for (ItemStack armor : player.inventory.armorInventory) { + if (armor != null && LOTREnchantmentHelper.hasEnchant(armor, LOTREnchantment.getEnchantmentByName("fireRepair"))) { + int currentDamage = armor.getItemDamage(); + int reduction = (int) event.damage; + int newDamage = currentDamage - 2*reduction; + + if (newDamage < 0) { + newDamage = 0; + } + + armor.setItemDamage(newDamage); + } + } + } return new Pair<>(event, cancel); } } diff --git a/src/main/java/com/zivilon/cinder_loe/util/IEntityLivingBase.java b/src/main/java/com/zivilon/cinder_loe/util/IEntityLivingBase.java new file mode 100644 index 0000000..8b92153 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/util/IEntityLivingBase.java @@ -0,0 +1,12 @@ +package com.zivilon.cinder_loe.util; + +import net.minecraft.entity.EntityLivingBase; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import java.util.UUID; + +public interface IEntityLivingBase { + void set_despawn_timer(int ticks); + void set_warband_uuid(UUID uuid); + UUID get_warband_uuid(); +} diff --git a/src/main/java/com/zivilon/cinder_loe/util/ILootableEntity.java b/src/main/java/com/zivilon/cinder_loe/util/ILootableEntity.java new file mode 100644 index 0000000..80877c4 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/util/ILootableEntity.java @@ -0,0 +1,12 @@ +package com.zivilon.cinder_loe.util; + +import com.zivilon.cinder_loe.droptables.DropTable; + +public interface ILootableEntity { + DropTable get_drop_table(); + void set_drop_table(DropTable table); + int get_last_pickpocket(); + void set_last_pickpocket(int i); + Float get_pickpocket_chance(); + void set_pickpocket_chance(Float f); +} diff --git a/src/main/java/com/zivilon/cinder_loe/util/IMixinEntityPlayer.java b/src/main/java/com/zivilon/cinder_loe/util/IMixinEntityPlayer.java new file mode 100644 index 0000000..54cf0e0 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/util/IMixinEntityPlayer.java @@ -0,0 +1,8 @@ +package com.zivilon.cinder_loe.util; + +import com.zivilon.cinder_loe.droptables.DropTable; + +public interface IMixinEntityPlayer { + int get_last_pickpocket_attempt(); + void set_last_pickpocket_attempt(int i); +} diff --git a/src/main/java/com/zivilon/cinder_loe/util/PickpocketUtils.java b/src/main/java/com/zivilon/cinder_loe/util/PickpocketUtils.java new file mode 100644 index 0000000..1587552 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/util/PickpocketUtils.java @@ -0,0 +1,208 @@ +package com.zivilon.cinder_loe.util; + +import com.zivilon.cinder_loe.CinderLoE; +import com.zivilon.cinder_loe.entity.npc.dwarf.*; +import com.zivilon.cinder_loe.mixins.MixinLOTREntityNPC; +import com.zivilon.cinder_loe.droptables.*; +import com.zivilon.cinder_loe.droptables.DropTable.*; +import com.zivilon.cinder_loe.util.IMixinEntityPlayer; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.init.Items; +import net.minecraft.nbt.*; +import net.minecraft.potion.Potion; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ChatComponentTranslation; + +import lotr.common.LOTRMod; +import lotr.common.item.LOTRItemArmor; +import lotr.common.item.LOTRMaterial; +import lotr.common.entity.npc.*; + +import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class PickpocketUtils { + public static Random random = new Random(); + + public static boolean can_pickpocket(EntityPlayer player, LOTREntityNPC target) { + if (!player.isSneaking()) return false; + + DropTable table = ((ILootableEntity)(Object)target).get_drop_table(); + if (table == null) { + return false; + } + + List drops = table.drop_list; + boolean has_pickpocket_drops = drops.stream().anyMatch(drop -> + drop.conditions != null && + Arrays.stream(drop.conditions).anyMatch(DropContext.PICKPOCKET::equals) + ); + + if (!has_pickpocket_drops) { + return false; + } + + if (((IMixinEntityPlayer)player).get_last_pickpocket_attempt() > (int)(System.currentTimeMillis() / 1000L - 1) || ((ILootableEntity)(Object)target).get_last_pickpocket() > (int)(System.currentTimeMillis() / 1000L - 4)) { + if (random.nextInt(10000) == 1) { + player.addChatMessage(new ChatComponentTranslation("pickpocket.cooldown_alt")); + } else { + player.addChatMessage(new ChatComponentTranslation("pickpocket.cooldown")); + } + return false; + } + + return true; + } + public static boolean pickpocket(EntityPlayer player, LOTREntityNPC target) { + ILootableEntity npc = (ILootableEntity)(Object)target; + float penalty = 1.0F; + if (!is_behind(player, (EntityLivingBase)target)) penalty -= 0.4F; + if (npc.get_last_pickpocket() > (int)(System.currentTimeMillis() / 1000L - 60)) penalty -= 0.4F; + if (is_invisible(player)) penalty += 0.4F; + if (is_cloaked(player)) penalty += 0.2F; + boolean success = random.nextFloat() < npc.get_pickpocket_chance() * penalty; + return success; + } + + public static boolean is_behind(EntityPlayer player, EntityLivingBase entity) { + float npcYaw = entity.rotationYaw % 360; + float playerYaw = player.rotationYaw % 360; + float angleDiff = MathHelper.wrapAngleTo180_float(npcYaw - playerYaw); + boolean is_behind = Math.abs(angleDiff) < 30F; + return is_behind; + } + + public static boolean is_invisible(EntityPlayer player) { + boolean invisible = player.isPotionActive(Potion.invisibility); + return (invisible && !wearing_armor(player)); + + } + public static boolean is_cloaked(EntityPlayer player) { + ItemStack[] equipment = player.inventory.armorInventory; + for (ItemStack armor : equipment) { + if (armor == null) return false; + Item item = armor.getItem(); + if (!(item instanceof LOTRItemArmor) || ((LOTRItemArmor)item).getLOTRArmorMaterial() != LOTRMaterial.HITHLAIN) + return false; + } + return true; + } + public static boolean wearing_armor(EntityPlayer player) { + ItemStack[] equipment = player.inventory.armorInventory; + for (ItemStack armor : equipment) { + if (armor != null) return true; + } + return false; + } + + /* Comment when done. Here only for reference + public SingleItemDrop(Item item, NBTTagCompound nbt, float chance, int min, int max, boolean looting_quantity, boolean looting_chance, DropContext[] conditions) { + public SingleItemDrop(Item item, NBTTagCompound nbt, float chance, DropContext[] conditions) { + public ItemGroup(float chance, int min, int max, boolean looting_chance, DropContext[] conditions, ItemGroupEntry... drops) { + public ItemGroupEntry(Item item, NBTTagCompound nbt, int weight, int min_amount, int max_amount, boolean looting_quantity) { + public ItemGroupEntry(Item item, NBTTagCompound nbt, int weight) { + */ + + public static void assign_drop_table(LOTREntityNPC entity) { + if (entity instanceof LOTRTradeable || entity instanceof LOTRUnitTradeable) return; + ((ILootableEntity)entity).set_pickpocket_chance(0.8F); + + DropTable table = new DropTable(); + DropContext[] default_context = new DropContext[] {DropContext.PICKPOCKET}; + table.drop_list.add(new SingleItemDrop(LOTRMod.silverCoin, null, 1.0F, 8, 32, false, false, default_context)); + if (entity instanceof LOTREntityMan) { + table.drop_list.add(new SingleItemDrop(Items.cooked_chicken, null, 0.2F, 1, 3, false, false, default_context)); + table.drop_list.add(new SingleItemDrop(Items.book, null, 0.2F, 1, 3, false, false, default_context)); + table.drop_list.add(new SingleItemDrop(Items.bread, null, 0.2F, default_context)); + table.drop_list.add(new SingleItemDrop(CinderLoE.spiceHuman, null, 0.01F, default_context)); + } else if (entity instanceof LOTREntityOrc) { + table.drop_list.add(new SingleItemDrop(LOTRMod.orcSteel, null, 0.05F, 1, 3, false, false, default_context)); + table.drop_list.add(new SingleItemDrop(LOTRMod.maggotyBread, null, 0.2F, default_context)); + table.drop_list.add(new SingleItemDrop(LOTRMod.manFlesh, null, 0.2F, default_context)); + table.drop_list.add(new SingleItemDrop(LOTRMod.elfBone, null, 0.2F, default_context)); + table.drop_list.add(new SingleItemDrop(Items.bone, null, 0.2F, default_context)); + table.drop_list.add(new SingleItemDrop(CinderLoE.spiceOrcish, null, 0.01F, default_context)); + } else if (entity instanceof LOTREntityElf) { + table.drop_list.add(new SingleItemDrop(LOTRMod.quenditeCrystal, null, 0.01F, default_context)); + table.drop_list.add(new SingleItemDrop(LOTRMod.lembas, null, 0.05F, default_context)); + table.drop_list.add(new SingleItemDrop(Item.getItemFromBlock(LOTRMod.niphredil), null, 0.1F, default_context)); + table.drop_list.add(new SingleItemDrop(Item.getItemFromBlock(LOTRMod.elanor), null, 0.1F, default_context)); + table.drop_list.add(new SingleItemDrop(LOTRMod.mallornNut, null, 0.05F, default_context)); + table.drop_list.add(new SingleItemDrop(CinderLoE.spiceElven, null, 0.01F, default_context)); + } else if (entity instanceof LOTREntityDwarf) { + table.drop_list.add(new SingleItemDrop(CinderLoE.spiceDwarven, null, 0.01F, default_context)); + ItemGroupEntry amethyst = new ItemGroupEntry(LOTRMod.amethyst, null, 5); + ItemGroupEntry topaz = new ItemGroupEntry(LOTRMod.topaz, null, 4); + ItemGroupEntry amber = new ItemGroupEntry(LOTRMod.amber, null, 4); + ItemGroupEntry opal = new ItemGroupEntry(LOTRMod.opal, null, 4); + ItemGroupEntry sapphire = new ItemGroupEntry(LOTRMod.sapphire, null, 3); + ItemGroupEntry ruby = new ItemGroupEntry(LOTRMod.ruby, null, 3); + ItemGroupEntry emerald = new ItemGroupEntry(LOTRMod.emerald, null, 2); + ItemGroupEntry diamond = new ItemGroupEntry(LOTRMod.diamond, null, 1); + ItemGroup gem_drop = new ItemGroup(0.1F, 1, 1, false, default_context, amethyst, topaz, amber, opal, sapphire, ruby, emerald, diamond); + table.drop_list.add(new SingleItemDrop(Items.coal, null, 0.1F, default_context)); + table.drop_list.add(new SingleItemDrop(Items.gold_nugget, null, 0.025F, default_context)); + table.drop_list.add(new SingleItemDrop(LOTRMod.ironNugget, null, 0.1F, default_context)); + } + if (entity instanceof LOTREntityTauredain) { + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setTag("display", new NBTTagCompound()); + nbt.getCompoundTag("display").setString("Name", "§fChocolate chip cookie"); + table.drop_list.add(new SingleItemDrop(Items.cookie, nbt, 0.001F, default_context)); + } else if (entity instanceof LOTREntityRanger || entity instanceof LOTREntityGulfHaradrim || entity instanceof LOTREntityHarnedhrim || entity instanceof LOTREntityRohanMan) { + table.drop_list.add(new SingleItemDrop(Items.leather, null, 1.0F, 1, 3, false, false, default_context)); + } else if (entity instanceof LOTREntityNomad) { + table.drop_list.add(new SingleItemDrop(Item.getItemFromBlock(LOTRMod.driedReeds), null, 1.0F, 1, 3, false, false, default_context)); + table.drop_list.add(new SingleItemDrop(LOTRMod.camelRaw, null, 1.0F, 1, 3, false, false, default_context)); + table.drop_list.add(new SingleItemDrop(LOTRMod.camelCooked, null, 1.0F, 1, 3, false, false, default_context)); + } + if (entity instanceof LOTREntityNearHaradrimBase || entity instanceof LOTREntityMoredain || entity instanceof LOTREntityTauredain) { + table.drop_list.add(new SingleItemDrop(LOTRMod.bronze, null, 1.0F, 1, 3, false, false, default_context)); + } else if (entity instanceof LOTREntityAngmarHillman || entity instanceof LOTREntityBreeMan || entity instanceof LOTREntityDaleMan || entity instanceof LOTREntityDorwinionMan || entity instanceof LOTREntityDunedain || entity instanceof LOTREntityDunlending || entity instanceof LOTREntityEasterling || entity instanceof LOTREntityGondorMan || entity instanceof LOTREntityRohanMan) { + table.drop_list.add(new SingleItemDrop(Items.iron_ingot, null, 1.0F, 1, 3, false, false, default_context)); + } else if (entity instanceof LOTREntityHalfTroll) { + table.drop_list.add(new SingleItemDrop(LOTRMod.gemsbokHide, null, 1.0F, 1, 3, false, false, default_context)); + table.drop_list.add(new SingleItemDrop(LOTRMod.gemsbokHorn, null, 1.0F, 1, 3, false, false, default_context)); + table.drop_list.add(new SingleItemDrop(Items.string, null, 1.0F, 2, 8, false, false, default_context)); + } else if (entity instanceof LOTREntityMordorOrc) { + table.drop_list.add(new SingleItemDrop(LOTRMod.nauriteGem, null, 1.0F, default_context)); + table.drop_list.add(new SingleItemDrop(LOTRMod.blackUrukSteel, null, 1.0F, 1, 3, false, false, default_context)); + } else if (entity instanceof LOTREntityDolGuldurOrc) { + table.drop_list.add(new SingleItemDrop(LOTRMod.mysteryWeb, null, 1.0F, default_context)); + } else if (entity instanceof LOTREntityGundabadOrc) { + table.drop_list.add(new SingleItemDrop(LOTRMod.urukSteel, null, 1.0F, 1, 3, false, false, default_context)); + table.drop_list.add(new SingleItemDrop(LOTRMod.dwarfBone, null, 1.0F, default_context)); + } else if (entity instanceof LOTREntityUrukHai) { + table.drop_list.add(new SingleItemDrop(LOTRMod.urukSteel, null, 1.0F, 1, 3, false, false, default_context)); + } else if (entity instanceof LOTREntityDwarf && !(entity instanceof LOTREntityBlueDwarf) && !(entity instanceof RedDwarfWarrior) && !(entity instanceof RedDwarfBannerBearer) && !(entity instanceof RedDwarfArbalest)) { + table.drop_list.add(new SingleItemDrop(LOTRMod.dwarfSteel, null, 1.0F, 1, 3, false, false, default_context)); + } else if (entity instanceof LOTREntityBlueDwarf) { + table.drop_list.add(new SingleItemDrop(LOTRMod.blueDwarfSteel, null, 1.0F, 1, 3, false, false, default_context)); + } else if (entity instanceof RedDwarfWarrior || entity instanceof RedDwarfBannerBearer || entity instanceof RedDwarfArbalest) { + table.drop_list.add(new SingleItemDrop(CinderLoE.redDwarfSteel, null, 1.0F, 1, 3, false, false, default_context)); + } else if (entity instanceof LOTREntityTree) { + table.drop_list.add(new SingleItemDrop(Items.stick, null, 1.0F, 8, 32, false, false, default_context)); + table.drop_list.add(new SingleItemDrop(Item.getItemFromBlock(LOTRMod.fangornPlant), null, 1.0F, 1, 3, false, false, default_context)); + table.drop_list.add(new SingleItemDrop(Item.getItemFromBlock(LOTRMod.fangornRiverweed), null, 1.0F, 1, 3, false, false, default_context)); + } else if (entity instanceof LOTREntityHobbit || entity instanceof LOTREntityGandalf) { + table.drop_list.add(new SingleItemDrop(LOTRMod.hobbitPipe, null, 1.0F, default_context)); + table.drop_list.add(new SingleItemDrop(LOTRMod.pipeweed, null, 1.0F, 1, 3, false, false, default_context)); + table.drop_list.add(new SingleItemDrop(LOTRMod.hobbitPancake, null, 1.0F, 1, 3, false, false, default_context)); + table.drop_list.add(new SingleItemDrop(LOTRMod.mugCider, null, 1.0F, 1, 3, false, false, default_context)); + table.drop_list.add(new SingleItemDrop(LOTRMod.mushroomPie, null, 1.0F, 1, 3, false, false, default_context)); + table.drop_list.add(new SingleItemDrop(Items.mushroom_stew, null, 1.0F, 1, 3, false, false, default_context)); + table.drop_list.add(new SingleItemDrop(Items.apple, null, 1.0F, 1, 3, false, false, default_context)); + table.drop_list.add(new SingleItemDrop(Items.cake, null, 1.0F, 1, 3, false, false, default_context)); + } else if (entity instanceof LOTREntityUtumnoOrc) { + table.drop_list.add(new SingleItemDrop(LOTRMod.mithrilNugget, null, 1.0F, default_context)); + table.drop_list.add(new SingleItemDrop(LOTRMod.chilling, null, 0.0001F, default_context)); + } + ((ILootableEntity)entity).set_drop_table(table); + } +} 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 9e7fe34..381474d 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; @@ -13,12 +14,13 @@ import java.io.OutputStream; import java.lang.reflect.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.UUID; -import java.util.Vector; +import java.util.Arrays; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Vector; +import java.util.UUID; import lotr.common.LOTRCreativeTabs; import lotr.common.world.biome.LOTRBiome; @@ -45,12 +47,14 @@ 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 { public static int[] LOTRIntCache = null; public static LOTRBiome reflected_river; + public static LOTRBiome reflected_taiga; public static LOTRCreativeTabs reflected_tab_block; public static List badEnchants = new ArrayList<>(); public static Map upgradedEnchants = new HashMap<>(); @@ -95,8 +99,10 @@ public class Utilities { public static void initialize_reflects() { try { - Field riverField = LOTRBiome.class.getField("river"); - reflected_river = (LOTRBiome)riverField.get(null); + Field river_field = LOTRBiome.class.getField("river"); + reflected_river = (LOTRBiome)river_field.get(null); + Field taiga_field = LOTRBiome.class.getField("taiga"); + reflected_taiga = (LOTRBiome)taiga_field.get(null); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); @@ -185,7 +191,6 @@ public class Utilities { EntityPlayer player = getPlayerByName(player_name); if (player == null) { - System.out.println("[CinderLoE] Warning! Player not found: " + player_name); return false; } @@ -349,4 +354,20 @@ public class Utilities { } return return_value; } + public static boolean array_contains_array(T[] superarray, T[] subarray) { + for (T subobj : subarray) { + if (subobj == null || Arrays.stream(superarray).anyMatch(subobj::equals)) continue; + return false; + } + return true; + } + public static Entity find_entity_by_uuid(World world, UUID uuid) { + List snapshot = new ArrayList<>(world.loadedEntityList); // Safe copy + for (Entity entity : snapshot) { + if (uuid.equals(entity.getUniqueID())) { + return entity; + } + } + return null; + } } diff --git a/src/main/java/com/zivilon/cinder_loe/world/CinderWorldProviderIsland.java b/src/main/java/com/zivilon/cinder_loe/world/CinderWorldProviderIsland.java new file mode 100644 index 0000000..13101cb --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/world/CinderWorldProviderIsland.java @@ -0,0 +1,39 @@ +package com.zivilon.cinder_loe.world; + +import com.zivilon.cinder_loe.CinderDimension; +import lotr.common.LOTRDimension; +import lotr.common.LOTRLevelData; +import lotr.common.world.LOTRChunkProvider; +import lotr.common.world.LOTRWorldProvider; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.world.chunk.IChunkProvider; + +public class CinderWorldProviderIsland extends LOTRWorldProvider { + + + + public IChunkProvider createChunkGenerator() { + return new LOTRChunkProvider(this.worldObj, this.worldObj.getSeed()); + } + + @Override + public String getDimensionName() { + return ""; + } + + public ChunkCoordinates getSpawnPoint() { + return new ChunkCoordinates(LOTRLevelData.middleEarthPortalX, LOTRLevelData.middleEarthPortalY, LOTRLevelData.middleEarthPortalZ); + } + + public void setSpawnPoint(int i, int j, int k) { + } + + public void setRingPortalLocation(int i, int j, int k) { + LOTRLevelData.markMiddleEarthPortalLocation(i, j, k); + } + + @Override + public LOTRDimension getLOTRDimension() { + return CinderDimension.ISLAND; + } +} \ No newline at end of file diff --git a/src/main/java/com/zivilon/cinder_loe/world/biome/CinderBiome.java b/src/main/java/com/zivilon/cinder_loe/world/biome/CinderBiome.java new file mode 100644 index 0000000..3657ce5 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/world/biome/CinderBiome.java @@ -0,0 +1,57 @@ +package com.zivilon.cinder_loe.world.biome; + +import lotr.common.LOTRDimension; +import lotr.common.entity.animal.*; +import lotr.common.world.biome.LOTRBiome; +import lotr.common.world.biome.LOTRBiomeDecorator; +import lotr.common.world.biome.LOTRMusicRegion; +import lotr.common.world.spawning.LOTREventSpawner; +import net.minecraft.entity.passive.*; +import net.minecraft.world.biome.BiomeGenBase; + +public abstract class CinderBiome extends LOTRBiome { + public static LOTRBiome mistyforest; + + public CinderBiome(int i, boolean major) { + super(i, major, LOTRDimension.MIDDLE_EARTH); + } + + public CinderBiome(int i, boolean major, LOTRDimension dim) { + super(i, false); + this.biomeDimension = dim; + if (this.biomeDimension.biomeList[i] != null) { + throw new IllegalArgumentException("LOTR biome already exists at index " + i + " for dimension " + this.biomeDimension.dimensionName + "!"); + } + this.biomeDimension.biomeList[i] = this; + if (major) { + this.biomeDimension.majorBiomes.add(this); + } + this.decorator = new LOTRBiomeDecorator(this); + this.spawnableCreatureList.clear(); + this.spawnableWaterCreatureList.clear(); + this.spawnableMonsterList.clear(); + this.spawnableCaveCreatureList.clear(); + if (this.hasDomesticAnimals()) { + this.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(EntitySheep.class, 12, 4, 4)); + this.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(EntityPig.class, 10, 4, 4)); + this.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(EntityChicken.class, 10, 4, 4)); + this.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(EntityCow.class, 8, 4, 4)); + this.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(LOTREntityDeer.class, 5, 4, 4)); + } else { + this.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(EntitySheep.class, 12, 4, 4)); + this.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(LOTREntityWildBoar.class, 10, 4, 4)); + this.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(EntityChicken.class, 8, 4, 4)); + this.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(LOTREntityDeer.class, 10, 4, 4)); + this.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(LOTREntityAurochs.class, 6, 4, 4)); + } + this.spawnableWaterCreatureList.add(new BiomeGenBase.SpawnListEntry(LOTREntityFish.class, 10, 4, 4)); + this.spawnableLOTRAmbientList.add(new BiomeGenBase.SpawnListEntry(LOTREntityButterfly.class, 8, 4, 4)); + this.spawnableLOTRAmbientList.add(new BiomeGenBase.SpawnListEntry(LOTREntityRabbit.class, 8, 4, 4)); + this.spawnableLOTRAmbientList.add(new BiomeGenBase.SpawnListEntry(LOTREntityBird.class, 10, 4, 4)); + this.spawnableCaveCreatureList.add(new BiomeGenBase.SpawnListEntry(EntityBat.class, 10, 8, 8)); + this.setBanditChance(LOTREventSpawner.EventChance.NEVER); + } + + @Override + public abstract LOTRMusicRegion.Sub getBiomeMusic(); +} diff --git a/src/main/java/com/zivilon/cinder_loe/world/biome/GenMistyForest.java b/src/main/java/com/zivilon/cinder_loe/world/biome/GenMistyForest.java new file mode 100644 index 0000000..a759a80 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/world/biome/GenMistyForest.java @@ -0,0 +1,94 @@ +package com.zivilon.cinder_loe.world.biome; + +import com.zivilon.cinder_loe.entity.animals.Monkey; +import lotr.common.entity.animal.*; +import lotr.common.world.LOTRWorldChunkManager; +import lotr.common.world.biome.LOTRBiomeGenFarHaradCloudForest; +import lotr.common.world.biome.LOTRMusicRegion; +import lotr.common.world.biome.variant.LOTRBiomeVariant; +import lotr.common.world.feature.LOTRTreeType; +import lotr.common.world.feature.LOTRWorldGenDoubleFlower; +import lotr.common.world.map.LOTRWaypoint; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.world.gen.feature.WorldGenAbstractTree; +import net.minecraft.world.gen.feature.WorldGenerator; + +import java.util.Random; + +public class GenMistyForest extends CinderBiome { + + public GenMistyForest(int i, boolean major) { + super(i, major); + this.spawnableCreatureList.clear(); + this.spawnableCreatureList.add(new BiomeGenBase.SpawnListEntry(LOTREntityFlamingo.class, 10, 4, 4)); + this.spawnableLOTRAmbientList.clear(); + this.spawnableLOTRAmbientList.add(new BiomeGenBase.SpawnListEntry(LOTREntityBird.class, 10, 4, 4)); + this.spawnableLOTRAmbientList.add(new BiomeGenBase.SpawnListEntry(LOTREntityButterfly.class, 10, 4, 4)); + this.spawnableMonsterList.add(new BiomeGenBase.SpawnListEntry(LOTREntityJungleScorpion.class, 30, 4, 4)); + this.spawnableLOTRAmbientList.add(new BiomeGenBase.SpawnListEntry(LOTREntityWhiteOryx.class, 10, 4, 4)); + this.spawnableMonsterList.add(new BiomeGenBase.SpawnListEntry(Monkey.class, 1, 4, 4)); + this.addBiomeVariantSet(LOTRBiomeVariant.SET_FOREST); + this.decorator.treesPerChunk = 10; + this.decorator.vinesPerChunk = 50; + this.decorator.flowersPerChunk = 4; + this.decorator.doubleFlowersPerChunk = 4; + this.decorator.grassPerChunk = 15; + this.decorator.doubleGrassPerChunk = 10; + this.decorator.enableFern = true; + this.decorator.melonPerChunk = 0.1f; + this.decorator.clearTrees(); + this.decorator.addTree(LOTRTreeType.JUNGLE_CLOUD, 4000); + this.decorator.addTree(LOTRTreeType.JUNGLE, 500); + this.decorator.addTree(LOTRTreeType.JUNGLE_SHRUB, 1000); + this.decorator.addTree(LOTRTreeType.MANGO, 20); + this.decorator.addTree(LOTRTreeType.BANANA, 20); + this.registerJungleFlowers(); + this.biomeColors.setGrass(2007124); + this.biomeColors.setFoliage(428338); + this.biomeColors.setSky(11452859); + this.biomeColors.setFoggy(true); + } + + @Override + public LOTRWaypoint.Region getBiomeWaypoints() { + return null; + } + + @Override + public LOTRMusicRegion.Sub getBiomeMusic() { + return LOTRMusicRegion.FAR_HARAD_JUNGLE.getSubregion("cloudForest"); + } + + @Override + public float getChanceToSpawnAnimals() { + return super.getChanceToSpawnAnimals() * 0.5f; + } + + @Override + public WorldGenerator getRandomWorldGenForDoubleFlower(Random random) { + LOTRWorldGenDoubleFlower doubleFlowerGen = new LOTRWorldGenDoubleFlower(); + if (random.nextInt(5) == 0) { + doubleFlowerGen.setFlowerType(3); + } else { + doubleFlowerGen.setFlowerType(2); + } + return doubleFlowerGen; + } + + @Override + public void decorate(World world, Random random, int i, int k) { + super.decorate(world, random, i, k); + LOTRBiomeVariant variant = ((LOTRWorldChunkManager)world.getWorldChunkManager()).getBiomeVariantAt(i + 8, k + 8); + if (variant == LOTRBiomeVariant.RIVER && random.nextInt(3) == 0) { + WorldGenAbstractTree bananaTree = LOTRTreeType.BANANA.create(false, random); + int bananas = 3 + random.nextInt(8); + for (int l = 0; l < bananas; ++l) { + int i1 = i + random.nextInt(16) + 8; + int k1 = k + random.nextInt(16) + 8; + int j1 = world.getTopSolidOrLiquidBlock(i1, k1); + bananaTree.generate(world, random, i1, j1, k1); + } + } + } +} diff --git a/src/main/java/com/zivilon/cinder_loe/world/event/UlukaiCurseHandler.java b/src/main/java/com/zivilon/cinder_loe/world/event/UlukaiCurseHandler.java new file mode 100644 index 0000000..2640251 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/world/event/UlukaiCurseHandler.java @@ -0,0 +1,38 @@ +package com.zivilon.cinder_loe.world.event; + +import com.zivilon.cinder_loe.items.specials.Ulukai; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.world.World; +import net.minecraftforge.common.DimensionManager; + +public class UlukaiCurseHandler { + private int tickCounter = 0; + public static final int INTERVAL_TICKS = 72000; // 1 hour ~~10 minutes at 20 TPS~~ + + @SubscribeEvent + public void onServerTick(TickEvent.ServerTickEvent event) { + if (event.phase == TickEvent.Phase.END) { + tickCounter++; + if (tickCounter >= INTERVAL_TICKS) { + tickCounter = 0; + runUlukaiCleanup(); + } + } + } + + private void runUlukaiCleanup() { + for (World world : DimensionManager.getWorlds()) { + if (world == null || world.isRemote) continue; + + for (Object obj : world.loadedEntityList) { + if (obj instanceof EntityLivingBase entity && + entity.getEntityData().hasKey("UlukaiModifiers")) { + + Ulukai.removeExpiredUlukaiModifiers(entity, world.getTotalWorldTime()); + } + } + } + } +} \ No newline at end of file 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 new file mode 100644 index 0000000..99e4f2e --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/world/event/Warband.java @@ -0,0 +1,277 @@ +package com.zivilon.cinder_loe.world.event; + +import com.zivilon.cinder_loe.droptables.DropTable; +import com.zivilon.cinder_loe.droptables.DropContext; +import com.zivilon.cinder_loe.droptables.DropTable.SingleItemDrop; +import com.zivilon.cinder_loe.entity.*; +import com.zivilon.cinder_loe.util.*; +import com.zivilon.cinder_loe.world.event.WarbandFaction.Troop; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.IEntityLivingData; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.nbt.*; + +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; +import java.util.Random; +import java.util.UUID; + +public class Warband { + public static Random random = new Random(); + 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 WarbandFaction faction = null; + public UUID warband_uuid = null; + + public Warband() { + return; + } + + public static LOTRWaypoint get_random_waypoint() { + LOTRWaypoint[] waypoints = LOTRWaypoint.values(); + return waypoints[random.nextInt(waypoints.length)]; + } + + 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(); + + 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; + } + } + load_chunks_at(warband.x, warband.z); + 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) { + int chunk_x = block_x >> 4; + int chunk_z = block_z >> 4; + + for (int x = chunk_x - 1; x <= chunk_x + 1; x++) { + for (int z = chunk_z - 1; z <= chunk_z + 1; z++) { + world.getChunkProvider().loadChunk(x, z); + } + } + } + + public static WarbandFaction get_warband_faction_by_biome(Warband warband) { + LOTRBiome biome = (LOTRBiome)world.getBiomeGenForCoords(warband.x, warband.z); + List valid_factions = new ArrayList<>(); + for (WarbandFaction faction : WarbandFaction.values()) { + if (faction.valid_biomes.contains(biome)) + valid_factions.add(faction); + } + if (valid_factions.size() < 1) + return WarbandFaction.RENEGADE; + return valid_factions.get(random.nextInt(valid_factions.size())); + } + + public static void spawn_warband(Warband warband) { + if (warband.faction == null) return; + int x = warband.x; + int z = warband.z; + int y = world.getTopSolidOrLiquidBlock(x, z) + 2; + spawn_boss_entity(warband, x, y, z); + System.out.println("Warband at " + x + "," + y + "," + z); + new Thread(() -> { + for (Troop troop : warband.faction.troops) { + int DEBUG_spawn_count = 0; + for (int i = 0; i < troop.amount; i++) { + DEBUG_spawn_count++; + spawn_entity_by_class(troop.entity_class, world, x, y, z, warband); + } + System.out.println("Summoned " + DEBUG_spawn_count + " of " + troop.entity_class.getName()); + } + }).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) { + Entity boss_entity = WarbandFaction.get_boss_entity(warband.faction, world); + warband.warband_uuid = boss_entity.getUniqueID(); + boss_entity.setLocationAndAngles(x, y, z, world.rand.nextFloat() * 360F, 0F); + ((IEntityLivingBase)boss_entity).set_despawn_timer(12000); + ((IEntityLivingBase)boss_entity).set_warband_uuid(warband.warband_uuid); + if (boss_entity instanceof EntityLiving) { + ((EntityLiving)boss_entity).setHealth(((EntityLiving)boss_entity).getMaxHealth()); + ((EntityLiving)boss_entity).func_110163_bv(); + } + if (boss_entity instanceof LOTREntityNPC) { + ((LOTREntityNPC)boss_entity).isNPCPersistent = true; + DropTable table = new DropTable(); + String modifier = ""; + switch (random.nextInt(4)) { + case 0: + modifier = "fireRepair"; + break; + case 1: + modifier = "stealth"; + break; + case 2: + modifier = "mountArmor"; + break; + case 3: + modifier = "swiftness"; + break; + } + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setString("ScrollModifier", modifier); + table.drop_list.add(new SingleItemDrop(LOTRMod.modTemplate, nbt, 1.0F, new DropContext[] {DropContext.KILLED})); + try { + ((ILootableEntity)(Object)boss_entity).set_drop_table(table); + } catch (Exception e) { + } + } + world.spawnEntityInWorld(boss_entity); + } + public static Entity spawn_entity_by_class(Class entity_class, World world, double x, double y, double z, Warband warband) { + try { + Entity entity = entity_class.getConstructor(World.class).newInstance(world); + entity.setLocationAndAngles(x, y, z, world.rand.nextFloat() * 360F, 0F); + + if (entity instanceof EntityLiving) { + EntityLiving living = (EntityLiving) entity; + + // This triggers onSpawnWithEgg, applying armor/weapon logic + living.onSpawnWithEgg((IEntityLivingData) null); + + living.func_110163_bv(); // mark as persistent + living.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(50.0D); + } + + if (entity instanceof Renegade) + WarbandFaction.equip_renegade((Renegade)entity); + if (entity instanceof LOTREntityNPC) + ((LOTREntityNPC)entity).isNPCPersistent = true; + + ((IEntityLivingBase)entity).set_despawn_timer(12000); + ((IEntityLivingBase)entity).set_warband_uuid(warband.warband_uuid); + world.spawnEntityInWorld(entity); + return entity; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static void broadcast_warband(World world, String faction_key, String direction, String waypoint_key) { + 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 new file mode 100644 index 0000000..ec1fb59 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/world/event/WarbandFaction.java @@ -0,0 +1,894 @@ +package com.zivilon.cinder_loe.world.event; + +import com.zivilon.cinder_loe.CinderLoE; +import com.zivilon.cinder_loe.entity.*; +import com.zivilon.cinder_loe.entity.npc.*; +import com.zivilon.cinder_loe.entity.npc.dwarf.*; +import com.zivilon.cinder_loe.entity.npc.evil_human.*; +import com.zivilon.cinder_loe.entity.npc.good_human.*; +import com.zivilon.cinder_loe.entity.npc.orc.*; +import com.zivilon.cinder_loe.entity.npc.elf.*; +import com.zivilon.cinder_loe.util.Utilities; + +import net.minecraft.entity.*; +import net.minecraft.item.*; +import net.minecraft.init.Items; +import net.minecraft.world.World; + +import lotr.common.world.biome.LOTRBiome; +import lotr.common.fac.LOTRFaction; +import lotr.common.LOTRMod; +import lotr.common.entity.npc.*; +import lotr.common.enchant.*; + +import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; + +public enum WarbandFaction { + MORDOR(LOTRFaction.MORDOR, "lotr.faction.MORDOR.name", Arrays.asList(LOTRBiome.gondor, LOTRBiome.emynMuil, LOTRBiome.dorwinion, LOTRBiome.rohan, LOTRBiome.imlothMelui, LOTRBiome.pinnathGelin, LOTRBiome.whiteMountains, LOTRBiome.whiteMountainsFoothills, LOTRBiome.lossarnach, LOTRBiome.lamedon, LOTRBiome.lamedonHills, LOTRBiome.brownLands, LOTRBiome.gondorWoodlands, LOTRBiome.anduinMouth)), + BLACK_URUK(LOTRFaction.MORDOR, "lotr.invasion.MORDOR_blackUruk", Arrays.asList(LOTRBiome.dorwinion, LOTRBiome.dagorlad, LOTRBiome.pelennor, LOTRBiome.blackrootVale)), + MORGUL_VALE(LOTRFaction.MORDOR, "warband.fac.MORGUL_VALE", Arrays.asList(LOTRBiome.ithilien, LOTRBiome.ithilienHills, LOTRBiome.ithilienWasteland)), + GONDOR(LOTRFaction.GONDOR, "lotr.faction.GONDOR.name", Arrays.asList(LOTRBiome.dagorlad, LOTRBiome.udun, LOTRBiome.ithilien, LOTRBiome.mordor, LOTRBiome.gorgoroth, LOTRBiome.nurn, LOTRBiome.nurnen, LOTRBiome.mordorMountains, LOTRBiome.nurnMarshes, LOTRBiome.anduinMouth)), + PELARGIR(LOTRFaction.GONDOR, "lotr.invasion.GONDOR_pelargir", Arrays.asList(LOTRBiome.nearHarad, LOTRBiome.harondor, LOTRBiome.umbar, LOTRBiome.umbarForest, LOTRBiome.umbarHills)), + DOL_AMROTH(LOTRFaction.GONDOR, "lotr.invasion.GONDOR_dolAmroth", Arrays.asList(LOTRBiome.tolfalas, LOTRBiome.island)), + ROHAN(LOTRFaction.ROHAN, "lotr.faction.ROHAN.name", Arrays.asList(LOTRBiome.rohanUrukHighlands, LOTRBiome.nanCurunir, LOTRBiome.dunland, LOTRBiome.adornland)), + RIVENDELL(LOTRFaction.HIGH_ELF, "lotr.invasion.HIGH_ELF_rivendell", Arrays.asList(LOTRBiome.trollshaws, LOTRBiome.loneLands, LOTRBiome.loneLandsHills, LOTRBiome.eregion, LOTRBiome.angmar, LOTRBiome.angmarMountains)), + LINDON(LOTRFaction.HIGH_ELF, "lotr.invasion.HIGH_ELF_lindon", Arrays.asList(LOTRBiome.towerHills, LOTRBiome.island)), + BREE(LOTRFaction.BREE, "lotr.faction.BREE.name", Arrays.asList(LOTRBiome.chetwood, LOTRBiome.oldForest, LOTRBiome.midgewater, LOTRBiome.barrowDowns)), + ARNOR(LOTRFaction.RANGER_NORTH, "lotr.faction.RANGER_NORTH.name", Arrays.asList(LOTRBiome.angmar, LOTRBiome.eriador, LOTRBiome.eriadorDowns, LOTRBiome.erynVorn, LOTRBiome.minhiriath, LOTRBiome.enedwaith, LOTRBiome.angle, LOTRBiome.mistyMountainsFoothills, LOTRBiome.loneLands, LOTRBiome.loneLandsHills, LOTRBiome.swanfleet)), + GUNDABAD(LOTRFaction.GUNDABAD, "lotr.faction.GUNDABAD.name", Arrays.asList(LOTRBiome.swanfleet, LOTRBiome.eregion, LOTRBiome.gladdenFields, LOTRBiome.mistyMountains)), + ANGMAR(LOTRFaction.ANGMAR, "lotr.faction.ANGMAR.name", Arrays.asList(LOTRBiome.rivendell, LOTRBiome.ettenmoors, LOTRBiome.coldfells, LOTRBiome.angle)), + RHUDAUR(LOTRFaction.ANGMAR, "lotr.title.ANGMAR_rhudaur", Arrays.asList(LOTRBiome.ettenmoors, LOTRBiome.coldfells, LOTRBiome.angle)), + WOOD_ELF(LOTRFaction.WOOD_ELF, "lotr.faction.WOOD_ELF.name", Arrays.asList(LOTRBiome.dolGuldur, LOTRBiome.mirkwoodMountains)), + WOOD_ELF_SCOUT(LOTRFaction.WOOD_ELF, "warband.fac.WOOD_ELF_SCOUT", Arrays.asList(LOTRBiome.mirkwoodCorrupted, LOTRBiome.mirkwoodNorth)), + DOL_GULDUR(LOTRFaction.DOL_GULDUR, "lotr.faction.DOL_GULDUR.name", Arrays.asList(LOTRBiome.lothlorien, LOTRBiome.lothlorienEdge, LOTRBiome.woodlandRealm, LOTRBiome.eastBight, LOTRBiome.anduinVale, LOTRBiome.anduinHills, LOTRBiome.celebrant, LOTRBiome.dale, LOTRBiome.ironHills, LOTRBiome.erebor)), + DALE(LOTRFaction.DALE, "lotr.faction.DALE.name", Arrays.asList(LOTRBiome.wilderland)), + DURINS_FOLK(LOTRFaction.DURINS_FOLK, "lotr.faction.DURINS_FOLK.name", Arrays.asList(LOTRBiome.mistyMountains, LOTRBiome.mistyMountainsFoothills, LOTRBiome.tundra, Utilities.reflected_taiga, LOTRBiome.greyMountains, LOTRBiome.greyMountainsFoothills)), + BLUE_MOUNTAINS(LOTRFaction.BLUE_MOUNTAINS, "lotr.faction.BLUE_MOUNTAINS.name", Arrays.asList(LOTRBiome.mistyMountains, LOTRBiome.mistyMountainsFoothills)), + RED_MOUNTAINS(LOTRFaction.DURINS_FOLK, "warband.fac.RED_MOUNTAINS", Arrays.asList(LOTRBiome.rhunForest, LOTRBiome.windMountains, LOTRBiome.windMountainsFoothills)), + DUNLAND(LOTRFaction.DUNLAND, "lotr.faction.DUNLAND.name", Arrays.asList(LOTRBiome.rohan, LOTRBiome.wold, LOTRBiome.pukel, LOTRBiome.enedwaith)), + ISENGARD(LOTRFaction.ISENGARD, "lotr.faction.ISENGARD.name", Arrays.asList(LOTRBiome.rohan, LOTRBiome.wold, LOTRBiome.rohanWoodlands)), + ISENGARD_SNAGA(LOTRFaction.ISENGARD, "lotr.faction.ISENGARD.name", Arrays.asList(LOTRBiome.fangornWasteland)), + FANGORN(LOTRFaction.FANGORN, "lotr.faction.FANGORN.name", Arrays.asList(LOTRBiome.fangornWasteland)), + DORWINION(LOTRFaction.DORWINION, "lotr.faction.DORWINION.name", Arrays.asList(LOTRBiome.rhunLandSteppe, LOTRBiome.rhunLand, LOTRBiome.rhunLandHills, LOTRBiome.rhunRedForest, LOTRBiome.rhunIsland, LOTRBiome.rhunIslandForest)), + RHUDEL(LOTRFaction.RHUDEL, "lotr.faction.RHUDEL.name", Arrays.asList(LOTRBiome.dorwinion, LOTRBiome.dorwinionHills, LOTRBiome.rhun, LOTRBiome.rhunForest, LOTRBiome.rhunRedForest, LOTRBiome.rhunIsland, LOTRBiome.rhunIslandForest)), + RHUDEL_GOLDEN(LOTRFaction.RHUDEL, "warband.fac.RHUDEL_GOLDEN", Arrays.asList(LOTRBiome.dorwinion)), + UMBAR(LOTRFaction.NEAR_HARAD, "lotr.invasion.NEAR_HARAD_umbar", Arrays.asList(LOTRBiome.pelargir, LOTRBiome.tolfalas, LOTRBiome.andrast, LOTRBiome.lebennin, LOTRBiome.dorEnErnil, LOTRBiome.dorEnErnilHills)), + HARNENNOR(LOTRFaction.NEAR_HARAD, "lotr.invasion.NEAR_HARAD_harnedor", Arrays.asList(LOTRBiome.harnedor, LOTRBiome.lostladen)), + GULFEN(LOTRFaction.NEAR_HARAD, "lotr.invasion.NEAR_HARAD_gulf", Arrays.asList(LOTRBiome.farHaradArid)), + MORWAITH(LOTRFaction.MORWAITH, "lotr.faction.MORWAITH.name", Arrays.asList(LOTRBiome.farHaradJungle, LOTRBiome.farHaradJungleEdge, LOTRBiome.farHaradJungleMountains, LOTRBiome.farHaradSwamp)), + LIMWAITH(LOTRFaction.MORWAITH, "warband.fac.LIMWAITH", Arrays.asList(LOTRBiome.farHaradKanuka, LOTRBiome.farHarad, LOTRBiome.farHaradForest)), + TAURETHRIM(LOTRFaction.TAURETHRIM, "lotr.faction.TAURETHRIM.name", Arrays.asList(LOTRBiome.farHarad, LOTRBiome.farHaradForest, LOTRBiome.halfTrollForest, LOTRBiome.pertorogwaith, LOTRBiome.farHaradVolcano, LOTRBiome.farHaradArid, LOTRBiome.farHaradAridHills, LOTRBiome.farHaradBushland, LOTRBiome.farHaradBushlandHills, LOTRBiome.farHaradSwamp, LOTRBiome.farHaradCloudForest)), + HALF_TROLL(LOTRFaction.HALF_TROLL, "lotr.faction.HALF_TROLL.name", Arrays.asList(LOTRBiome.halfTrollForest, LOTRBiome.farHaradMangrove)), + UTUMNO(LOTRFaction.UTUMNO, "lotr.faction.UTUMNO.name", Arrays.asList(LOTRBiome.forodwaith, LOTRBiome.forodwaithMountains)), + RENEGADE(LOTRFaction.UTUMNO, "warband.fac.RENEGADE", Arrays.asList(Utilities.reflected_river)); + + public LOTRFaction faction; + public List valid_biomes; + public List troops; + public String warband_name; + + WarbandFaction(LOTRFaction lotrfaction, String name, List biomes) { + this.faction = lotrfaction; + this.warband_name = name; + valid_biomes = biomes; + troops = new ArrayList(); + } + + /** + * Intialize troops to enums + */ + static { + MORDOR.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityOlogHai.class, 5), new Troop(LOTREntityMordorOrc.class, 80), new Troop(LOTREntityMordorWarg.class, 30), new Troop(LOTREntityMordorOrcArcher.class, 25))); + BLACK_URUK.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityBlackUruk.class, 70), new Troop(LOTREntityBlackUrukArcher.class, 30), new Troop(LOTREntityBlackUrukBannerBearer.class, 20))); + MORGUL_VALE.troops = new ArrayList<>(Arrays.asList(new Troop(MorgulOrc.class, 80), new Troop(LOTREntityMinasMorgulBannerBearer.class, 20), new Troop(LOTREntityMordorOrcArcher.class, 30))); + GONDOR.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityGondorSoldier.class, 60), new Troop(LOTREntityGondorTowerGuard.class, 15), new Troop(LOTREntityGondorBannerBearer.class, 20), new Troop(LOTREntityGondorArcher.class, 30))); + PELARGIR.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityPelargirMarine.class, 100), new Troop(LOTREntityPelargirBannerBearer.class, 20))); + DOL_AMROTH.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityDolAmrothSoldier.class, 60), new Troop(LOTREntityDolAmrothArcher.class, 30), new Troop(LOTREntityDolAmrothBannerBearer.class, 20), new Troop(LOTREntitySwanKnight.class, 15))); + ROHAN.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityRohirrimWarrior.class, 120), new Troop(LOTREntityRohirrimArcher.class, 30))); + RIVENDELL.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityRivendellWarrior.class, 100), new Troop(LOTREntityRivendellBannerBearer.class, 20))); + LINDON.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityHighElfWarrior.class, 70), new Troop(Sirrandrai.class, 30), new Troop(LOTREntityHighElfBannerBearer.class, 20))); + BREE.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityBreeGuard.class, 60), new Troop(BreeCrossbowman.class, 30), new Troop(BreeOutrider.class, 10), new Troop(LOTREntityBreeBannerBearer.class, 20))); + ARNOR.troops = new ArrayList<>(Arrays.asList(new Troop(ArnorSoldier.class, 50), new Troop(BattleNun.class, 10), new Troop(ArnorSoldierArcher.class, 30), new Troop(ArnorBannerBearer.class, 20))); + GUNDABAD.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityGundabadOrc.class, 90), new Troop(LOTREntityGundabadWarg.class, 40), new Troop(LOTREntityGundabadUruk.class, 20), new Troop(LOTREntityGundabadOrcArcher.class, 40))); + ANGMAR.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityAngmarOrc.class, 60), new Troop(LOTREntityAngmarWarg.class, 30), new Troop(LOTREntityTroll.class, 8), new Troop(LOTREntityMountainTroll.class, 8), new Troop(LOTREntityAngmarBannerBearer.class, 10))); + RHUDAUR.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityAngmarHillmanWarrior.class, 120), new Troop(LOTREntityAngmarHillmanAxeThrower.class, 40))); + WOOD_ELF.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityWoodElfWarrior.class, 100), new Troop(LOTREntityWoodElfBannerBearer.class, 20))); + WOOD_ELF_SCOUT.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityWoodElfScout.class, 120))); + DOL_GULDUR.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityDolGuldurOrc.class, 70), new Troop(LOTREntityDolGuldurOrcArcher.class, 15), new Troop(LOTREntityMirkTroll.class, 5), new Troop(LOTREntityMirkwoodSpider.class, 40))); + DALE.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityDaleSoldier.class, 30), new Troop(LOTREntityDaleArcher.class, 50), new Troop(LOTREntityDaleLevyman.class, 60), new Troop(LOTREntityDaleBannerBearer.class, 20))); + DURINS_FOLK.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityDwarfWarrior.class, 60), new Troop(LOTREntityDwarfAxeThrower.class, 40), new Troop(LOTREntityDwarfBannerBearer.class, 20))); + BLUE_MOUNTAINS.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityBlueDwarfWarrior.class, 70), new Troop(LOTREntityBlueDwarfAxeThrower.class, 30), new Troop(LOTREntityBlueDwarfBannerBearer.class, 20))); + RED_MOUNTAINS.troops = new ArrayList<>(Arrays.asList(new Troop(RedDwarfWarrior.class, 50), new Troop(RedDwarfArbalest.class, 50), new Troop(RedDwarfBannerBearer.class, 20))); + DUNLAND.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityDunlendingWarrior.class, 60), new Troop(LOTREntityDunlendingAxeThrower.class, 30), new Troop(LOTREntityDunlendingBerserker.class, 20))); + ISENGARD.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityUrukHai.class, 60), new Troop(LOTREntityUrukHaiCrossbower.class, 20), new Troop(LOTREntityUrukHaiBerserker.class, 20), new Troop(LOTREntityUrukHaiBannerBearer.class, 20))); + ISENGARD_SNAGA.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityIsengardSnaga.class, 60), new Troop(LOTREntityIsengardSnagaArcher.class, 40), new Troop(LOTREntityUrukWarg.class, 30))); + FANGORN.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityEnt.class, 30), new Troop(LOTREntityHuorn.class, 40))); + DORWINION.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityDorwinionGuard.class, 40), new Troop(LOTREntityDorwinionCrossbower.class, 30), new Troop(LOTREntityDorwinionElfWarrior.class, 10), new Troop(LOTREntityDorwinionElfArcher.class, 10), new Troop(LOTREntityDorwinionBannerBearer.class, 20))); + RHUDEL.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityEasterlingWarrior.class, 60), new Troop(LOTREntityEasterlingArcher.class, 30), new Troop(LOTREntityEasterlingBannerBearer.class, 20))); + RHUDEL_GOLDEN.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityEasterlingGoldWarrior.class, 120), new Troop(LOTREntityEasterlingBannerBearer.class, 20))); + UMBAR.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityUmbarWarrior.class, 70), new Troop(LOTREntityCorsair.class, 30), new Troop(LOTREntityUmbarArcher.class, 30), new Troop(LOTREntityUmbarBannerBearer.class, 20))); + HARNENNOR.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityHarnedorWarrior.class, 70), new Troop(LOTREntityHarnedorArcher.class, 30), new Troop(LOTREntityHarnedorBannerBearer.class, 20))); + GULFEN.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityGulfHaradWarrior.class, 70), new Troop(LOTREntityGulfHaradArcher.class, 30), new Troop(LOTREntityGulfHaradBannerBearer.class, 20))); + MORWAITH.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityMoredainWarrior.class, 100), new Troop(LOTREntityMoredainBannerBearer.class, 20))); + LIMWAITH.troops = new ArrayList<>(Arrays.asList(new Troop(LimwaithWarrior.class, 60), new Troop(LimwaithBoneWarrior.class, 20), new Troop(LimwaithBlowgunner.class, 30), new Troop(LimwaithBannerBearer.class, 15))); + TAURETHRIM.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityTauredainWarrior.class, 60), new Troop(LOTREntityTauredainBlowgunner.class, 50), new Troop(TauredainTrueBlood.class, 25))); + HALF_TROLL.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityHalfTrollWarrior.class, 80), new Troop(LOTREntityHalfTrollBannerBearer.class, 20))); + UTUMNO.troops = new ArrayList<>(Arrays.asList(new Troop(LOTREntityUtumnoOrc.class, 90), new Troop(LOTREntityUtumnoOrcArcher.class, 40), new Troop(LOTREntityUtumnoSnowTroll.class, 15), new Troop(LOTREntityUtumnoFireWarg.class, 15), new Troop(LOTREntityUtumnoIceWarg.class, 15), new Troop(LOTREntityUtumnoObsidianWarg.class, 15), new Troop(LOTREntityUtumnoTroll.class, 10))); + RENEGADE.troops = new ArrayList<>(Arrays.asList(new Troop(Renegade.class, 140))); + } + + public static Entity get_boss_entity(WarbandFaction faction, World world) { + switch (faction) { + case MORDOR: + return get_mordor_boss(world); + case BLACK_URUK: + return get_black_uruk_boss(world); + case MORGUL_VALE: + return get_morgul_vale_boss(world); + case GONDOR: + return get_gondor_boss(world); + case PELARGIR: + return get_pelargir_boss(world); + case DOL_AMROTH: + return get_dol_amroth_boss(world); + case ROHAN: + return get_rohan_boss(world); + case RIVENDELL: + return get_rivendell_boss(world); + case LINDON: + return get_lindon_boss(world); + case BREE: + return get_bree_boss(world); + case ARNOR: + return get_arnor_boss(world); + case GUNDABAD: + return get_gundabad_boss(world); + case ANGMAR: + return get_angmar_boss(world); + case RHUDAUR: + return get_rhudaur_boss(world); + case WOOD_ELF: + return get_wood_elf_boss(world); + case WOOD_ELF_SCOUT: + return get_wood_elf_scout_boss(world); + case DOL_GULDUR: + return get_dol_guldur_boss(world); + case DALE: + return get_dale_boss(world); + case DURINS_FOLK: + return get_durins_folk_boss(world); + case BLUE_MOUNTAINS: + return get_blue_mountains_boss(world); + case RED_MOUNTAINS: + return get_red_mountains_boss(world); + case DUNLAND: + return get_dunland_boss(world); + case ISENGARD: + return get_isengard_boss(world); + case ISENGARD_SNAGA: + return get_isengard_snaga_boss(world); + case FANGORN: + return get_fangorn_boss(world); + case DORWINION: + return get_dorwinion_boss(world); + case RHUDEL: + return get_rhudel_boss(world); + case RHUDEL_GOLDEN: + return get_rhudel_golden_boss(world); + case UMBAR: + return get_umbar_boss(world); + case HARNENNOR: + return get_harnennor_boss(world); + case GULFEN: + return get_gulfen_boss(world); + case MORWAITH: + return get_morwaith_boss(world); + case LIMWAITH: + return get_limwaith_boss(world); + case TAURETHRIM: + return get_taurethrim_boss(world); + case HALF_TROLL: + return get_half_troll_boss(world); + case UTUMNO: + return get_utumno_boss(world); + case RENEGADE: + return get_renegade_boss(world); + } + return get_renegade_boss(world); + } + + public static double default_boss_hp = 200.0D; + public static double default_boss_speed = 0.22D; + public static double default_boss_damage_boost = 10.0D; + + public static Entity get_mordor_boss(World world) { + LOTREntityBlackUruk boss_entity = new LOTREntityBlackUruk(world); + ItemStack boots = item(LOTRMod.bootsBlackUruk, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsBlackUruk, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyBlackUruk, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetBlackUruk, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(4)) { + case 0: weapon = item(LOTRMod.scimitarBlackUruk, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearBlackUruk, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(LOTRMod.hammerBlackUruk, LOTREnchantment.knockback2); break; + case 3: weapon = item(LOTRMod.battleaxeBlackUruk, LOTREnchantment.strong4, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_black_uruk_boss(World world) { + LOTREntityBlackUruk boss_entity = new LOTREntityBlackUruk(world); + ItemStack boots = item(LOTRMod.bootsBlackUruk, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsBlackUruk, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyBlackUruk, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetBlackUruk, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(4)) { + case 0: weapon = item(LOTRMod.scimitarBlackUruk, LOTREnchantment.strong4, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearBlackUruk, LOTREnchantment.strong4, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(LOTRMod.hammerBlackUruk, LOTREnchantment.strong4, LOTREnchantment.knockback2); break; + case 3: weapon = item(LOTRMod.battleaxeBlackUruk, LOTREnchantment.strong4, LOTREnchantment.meleeReach1, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, 0.23D, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_morgul_vale_boss(World world) { + MorgulOrc boss_entity = new MorgulOrc(world); + ItemStack boots = item(LOTRMod.bootsBlackUruk, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsBlackUruk, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyBlackUruk, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetMorgul, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = item(LOTRMod.morgulBlade, LOTREnchantment.strong4, LOTREnchantment.meleeReach1, LOTREnchantment.meleeSpeed1); + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_gondor_boss(World world) { + LOTREntityGondorTowerGuard boss_entity = new LOTREntityGondorTowerGuard(world); + ItemStack boots = item(LOTRMod.bootsGondor, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsGondor, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyGondor, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetGondorWinged, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(3)) { + case 0: weapon = item(LOTRMod.swordGondor, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearGondor, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(LOTRMod.hammerGondor, LOTREnchantment.knockback2); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_pelargir_boss(World world) { + LOTREntityPelargirMarine boss_entity = new LOTREntityPelargirMarine(world); + ItemStack boots = item(LOTRMod.bootsPelargir, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsPelargir, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyPelargir, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetPelargir, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(2)) { + case 0: weapon = item(LOTRMod.swordPelargir, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.tridentPelargir, LOTREnchantment.meleeReach1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_dol_amroth_boss(World world) { + LOTREntitySwanKnight boss_entity = new LOTREntitySwanKnight(world); + ItemStack boots = item(LOTRMod.bootsDolAmroth, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsDolAmroth, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyDolAmroth, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetDolAmroth, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = item(LOTRMod.swordDolAmroth, LOTREnchantment.strong4, LOTREnchantment.meleeSpeed1); + ItemStack mount_weapon = item(LOTRMod.lanceDolAmroth, LOTREnchantment.knockback2, LOTREnchantment.meleeReach1); + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + boss_entity.npcItemsInv.setIdleItemMounted(mount_weapon); + boss_entity.npcItemsInv.setMeleeWeaponMounted(mount_weapon); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_rohan_boss(World world) { + LOTREntityRohirrimWarrior boss_entity = null; + switch (Warband.random.nextInt(2)) { + case 0: boss_entity = new LOTREntityRohirrimWarrior(world); break; + case 1: boss_entity = new LOTREntityRohirrimArcher(world); break; + } + ItemStack boots = item(LOTRMod.bootsRohanMarshal, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsRohanMarshal, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyRohanMarshal, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetRohanMarshal, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + if (boss_entity instanceof LOTREntityRohirrimArcher) { + weapon = item(LOTRMod.rohanBow, LOTREnchantment.rangedStrong3, LOTREnchantment.rangedStrong3); + } else { + switch (Warband.random.nextInt(2)) { + case 0: weapon = item(LOTRMod.swordRohan, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearRohan, LOTREnchantment.meleeReach1); break; + } + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_rivendell_boss(World world) { + LOTREntityRivendellWarrior boss_entity = new LOTREntityRivendellWarrior(world); + ItemStack boots = item(LOTRMod.bootsGondolin, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsGondolin, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyGondolin, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetGondolin, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack ranged_weapon = item(LOTRMod.rivendellBow, LOTREnchantment.rangedStrong3, LOTREnchantment.rangedStrong2); + ItemStack melee_weapon = null; + switch (Warband.random.nextInt(3)) { + case 0: melee_weapon = item(LOTRMod.swordRivendell, LOTREnchantment.meleeSpeed1); break; + case 1: melee_weapon = item(LOTRMod.spearRivendell, LOTREnchantment.meleeReach1); break; + case 2: melee_weapon = item(LOTRMod.polearmRivendell, LOTREnchantment.strong3); break; + } + set_equipment(boss_entity, melee_weapon, boots, legs, body, helmet); + set_equipment(boss_entity, ranged_weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_lindon_boss(World world) { + LOTREntityHighElfWarrior boss_entity = new Sirrandrai(world); + ItemStack boots = item(LOTRMod.bootsGondolin, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsGondolin, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyGondolin, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetGondolin, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack melee_weapon = item(LOTRMod.swordGondolin, LOTREnchantment.meleeSpeed1); + set_equipment(boss_entity, melee_weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_bree_boss(World world) { + LOTREntityBreeGuard boss_entity = new LOTREntityBreeGuard(world); + ItemStack boots = item(CinderLoE.bootsBree, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(CinderLoE.legsBree, LOTREnchantment.protectRanged3); + ItemStack body = item(CinderLoE.bodyBree, LOTREnchantment.protectFire3); + ItemStack helmet = item(CinderLoE.helmetBreeKettle, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = item(CinderLoE.swordBree, LOTREnchantment.meleeSpeed1); + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_arnor_boss(World world) { + ArnorSoldier boss_entity = new ArnorSoldier(world); + ItemStack boots = item(LOTRMod.bootsArnor, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsArnor, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyArnor, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetArnor, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(2)) { + case 0: weapon = item(LOTRMod.swordArnor, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearArnor, LOTREnchantment.meleeReach1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_gundabad_boss(World world) { + LOTREntityGundabadUruk boss_entity = new LOTREntityGundabadUruk(world); + ItemStack boots = item(LOTRMod.bootsGundabadUruk, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsGundabadUruk, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyGundabadUruk, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetGundabadUruk, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(4)) { + case 0: weapon = item(LOTRMod.swordGundabadUruk, LOTREnchantment.strong4, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearGundabadUruk, LOTREnchantment.strong4, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(LOTRMod.hammerGundabadUruk, LOTREnchantment.strong4, LOTREnchantment.knockback2); break; + case 3: weapon = item(LOTRMod.battleaxeGundabadUruk, LOTREnchantment.strong4, LOTREnchantment.meleeReach1, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_angmar_boss(World world) { + LOTREntityAngmarOrc boss_entity = new LOTREntityAngmarOrc(world); + ItemStack boots = item(LOTRMod.bootsMorgul, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsMorgul, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyMorgul, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetAngmar, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(5)) { + case 0: weapon = item(LOTRMod.swordAngmar, LOTREnchantment.strong4, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearAngmar, LOTREnchantment.strong4, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(LOTRMod.hammerAngmar, LOTREnchantment.strong4, LOTREnchantment.knockback2); break; + case 3: weapon = item(LOTRMod.battleaxeAngmar, LOTREnchantment.strong4, LOTREnchantment.meleeSpeed1, LOTREnchantment.knockback1); break; + case 4: weapon = item(LOTRMod.polearmAngmar, LOTREnchantment.strong4, LOTREnchantment.meleeReach1, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_rhudaur_boss(World world) { + LOTREntityAngmarOrc boss_entity = new LOTREntityAngmarOrc(world); + ItemStack boots = item(CinderLoE.bootsRhudaur, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(CinderLoE.legsRhudaur, LOTREnchantment.protectRanged3); + ItemStack body = item(CinderLoE.bodyRhudaur, LOTREnchantment.protectFire3); + ItemStack helmet = item(CinderLoE.helmetRhudaur, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(5)) { + case 0: weapon = item(LOTRMod.swordAngmar, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearAngmar, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(LOTRMod.hammerAngmar, LOTREnchantment.knockback2); break; + case 3: weapon = item(LOTRMod.battleaxeAngmar, LOTREnchantment.strong4, LOTREnchantment.knockback1); break; + case 4: weapon = item(LOTRMod.polearmAngmar, LOTREnchantment.strong4, LOTREnchantment.meleeReach1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_wood_elf_boss(World world) { + LOTREntityWoodElfWarrior boss_entity = new LOTREntityWoodElfWarrior(world); + ItemStack boots = item(LOTRMod.bootsWoodElven, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsWoodElven, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyWoodElven, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetWoodElven, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack ranged_weapon = item(LOTRMod.mirkwoodBow, LOTREnchantment.rangedStrong3, LOTREnchantment.rangedStrong2); + ItemStack melee_weapon = null; + switch (Warband.random.nextInt(2)) { + case 0: melee_weapon = item(LOTRMod.swordWoodElven, LOTREnchantment.meleeSpeed1); break; + case 1: melee_weapon = item(LOTRMod.spearWoodElven, LOTREnchantment.meleeReach1); break; + } + set_equipment(boss_entity, melee_weapon, boots, legs, body, helmet); + set_equipment(boss_entity, ranged_weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_wood_elf_scout_boss(World world) { + LOTREntityWoodElfWarrior boss_entity = new LOTREntityWoodElfWarrior(world); + ItemStack boots = item(LOTRMod.bootsWoodElvenScout, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsWoodElvenScout, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyWoodElvenScout, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetWoodElvenScout, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack ranged_weapon = item(LOTRMod.mirkwoodBow, LOTREnchantment.rangedStrong3, LOTREnchantment.rangedStrong2); + ItemStack melee_weapon = null; + switch (Warband.random.nextInt(2)) { + case 0: melee_weapon = item(LOTRMod.swordWoodElven, LOTREnchantment.meleeSpeed1); break; + case 1: melee_weapon = item(LOTRMod.spearWoodElven, LOTREnchantment.meleeReach1); break; + } + set_equipment(boss_entity, melee_weapon, boots, legs, body, helmet); + set_equipment(boss_entity, ranged_weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, 0.25D, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_dol_guldur_boss(World world) { + LOTREntityDolGuldurOrc boss_entity = new LOTREntityDolGuldurOrc(world); + ItemStack boots = item(LOTRMod.bootsDolGuldur, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsDolGuldur, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyDolGuldur, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetDolGuldur, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(4)) { + case 0: weapon = item(LOTRMod.swordDolGuldur, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearDolGuldur, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(LOTRMod.hammerDolGuldur, LOTREnchantment.knockback2); break; + case 3: weapon = item(LOTRMod.battleaxeDolGuldur, LOTREnchantment.strong4, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_dale_boss(World world) { + LOTREntityDaleSoldier boss_entity = new LOTREntityDaleSoldier(world); + ItemStack boots = item(LOTRMod.bootsDale, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsDale, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyDale, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetDale, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(3)) { + case 0: weapon = item(LOTRMod.swordDale, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearDale, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(LOTRMod.battleaxeDale, LOTREnchantment.strong4, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_durins_folk_boss(World world) { + LOTREntityDwarfWarrior boss_entity = new LOTREntityDwarfWarrior(world); + ItemStack boots = item(LOTRMod.bootsDwarvenGold, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsDwarvenGold, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyDwarvenGold, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetDwarvenGold, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(3)) { + case 0: weapon = item(LOTRMod.swordDwarven, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearDwarven, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(LOTRMod.battleaxeDwarven, LOTREnchantment.strong4, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_blue_mountains_boss(World world) { + LOTREntityBlueDwarfWarrior boss_entity = new LOTREntityBlueDwarfWarrior(world); + ItemStack boots = item(LOTRMod.bootsBlueDwarven, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsBlueDwarven, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyBlueDwarven, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetBlueDwarven, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(3)) { + case 0: weapon = item(LOTRMod.swordBlueDwarven, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearBlueDwarven, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(LOTRMod.battleaxeBlueDwarven, LOTREnchantment.strong4, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_red_mountains_boss(World world) { + RedDwarfWarrior boss_entity = new RedDwarfWarrior(world); + ItemStack boots = item(CinderLoE.bootsRedDwarf, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(CinderLoE.legsRedDwarf, LOTREnchantment.protectRanged3); + ItemStack body = item(CinderLoE.bodyRedDwarf, LOTREnchantment.protectFire3); + ItemStack helmet = item(CinderLoE.helmetRedDwarf, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(3)) { + case 0: weapon = item(CinderLoE.swordRedDwarf, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(CinderLoE.spearRedDwarf, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(CinderLoE.battleaxeRedDwarf, LOTREnchantment.strong4, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_dunland_boss(World world) { + LOTREntityDunlendingWarrior boss_entity = new LOTREntityDunlendingWarrior(world); + ItemStack boots = item(LOTRMod.bootsDunlending, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsDunlending, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyDunlending, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetDunlending, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(2)) { + case 0: weapon = item(LOTRMod.dunlendingTrident, LOTREnchantment.meleeReach1); break; + case 1: weapon = item(LOTRMod.battleaxeIron, LOTREnchantment.strong4, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_isengard_boss(World world) { + LOTREntityUrukHai boss_entity = new LOTREntityUrukHai(world); + ItemStack boots = item(LOTRMod.bootsUruk, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsUruk, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyUruk, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetUrukBerserker, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = item(LOTRMod.scimitarUrukBerserker, LOTREnchantment.strong4, LOTREnchantment.meleeSpeed1); + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_isengard_snaga_boss(World world) { + LOTREntityIsengardSnaga boss_entity = new LOTREntityIsengardSnaga(world); + ItemStack boots = item(LOTRMod.bootsUruk, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsUruk, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyUruk, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetUrukBerserker, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = item(CinderLoE.whip, LOTREnchantment.strong4, LOTREnchantment.meleeReach1, LOTREnchantment.meleeSpeed1); + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, 15.0D); + return boss_entity; + } + public static Entity get_fangorn_boss(World world) { + LOTREntityMallornEnt boss_entity = new LOTREntityMallornEnt(world); + set_attributes(boss_entity, 300.0D, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_dorwinion_boss(World world) { + LOTREntityDorwinionElfWarrior boss_entity = new LOTREntityDorwinionElfWarrior(world); + ItemStack boots = item(LOTRMod.bootsDorwinionElf, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsDorwinionElf, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyDorwinionElf, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetDorwinionElf, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = item(LOTRMod.spearBladorthin, LOTREnchantment.strong4, LOTREnchantment.meleeReach1, LOTREnchantment.meleeSpeed1); + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_rhudel_boss(World world) { + LOTREntityEasterlingGoldWarrior boss_entity = new LOTREntityEasterlingGoldWarrior(world); + ItemStack boots = item(LOTRMod.bootsRhunGold, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsRhunGold, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyRhunGold, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetRhunGold, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(3)) { + case 0: weapon = item(LOTRMod.swordRhun, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearRhun, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(LOTRMod.polearmRhun, LOTREnchantment.strong4, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_rhudel_golden_boss(World world) { + LOTREntityEasterlingGoldWarrior boss_entity = new LOTREntityEasterlingGoldWarrior(world); + ItemStack boots = item(LOTRMod.bootsRhunGold, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsRhunGold, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyRhunGold, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetRhunWarlord, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(3)) { + case 0: weapon = item(LOTRMod.swordRhun, LOTREnchantment.strong4, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearRhun, LOTREnchantment.strong4, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(LOTRMod.polearmRhun, LOTREnchantment.strong4, LOTREnchantment.meleeReach1, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_umbar_boss(World world) { + LOTREntityUmbarWarrior boss_entity = new LOTREntityUmbarWarrior(world); + ItemStack boots = item(LOTRMod.bootsBlackNumenorean, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsBlackNumenorean, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyBlackNumenorean, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetBlackNumenorean, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(3)) { + case 0: weapon = item(LOTRMod.swordBlackNumenorean, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearBlackNumenorean, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(LOTRMod.maceBlackNumenorean, LOTREnchantment.knockback2); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_harnennor_boss(World world) { + LOTREntityHarnedorWarrior boss_entity = new LOTREntityHarnedorWarrior(world); + ItemStack boots = item(LOTRMod.bootsHarnedor, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsHarnedor, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyHarnedor, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetNearHaradWarlord, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(2)) { + case 0: weapon = item(LOTRMod.swordHarad, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearHarad, LOTREnchantment.meleeReach1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_gulfen_boss(World world) { + LOTREntityGulfHaradWarrior boss_entity = new LOTREntityGulfHaradWarrior(world); + ItemStack boots = item(LOTRMod.bootsGulfHarad, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsGulfHarad, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyGulfHarad, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetNearHaradWarlord, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(2)) { + case 0: weapon = item(LOTRMod.swordGulfHarad, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearHarad, LOTREnchantment.meleeReach1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_morwaith_boss(World world) { + LOTREntityMoredainWarrior boss_entity = new LOTREntityMoredainWarrior(world); + ItemStack boots = item(LOTRMod.bootsMoredainLion, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsMoredainLion, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyMoredainLion, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetMoredainLion, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(3)) { + case 0: weapon = item(LOTRMod.swordMoredain, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearMoredain, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(LOTRMod.battleaxeMoredain, LOTREnchantment.strong4, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, 0.25D, 15.0D); + return boss_entity; + } + public static Entity get_limwaith_boss(World world) { + LimwaithWarrior boss_entity = new LimwaithWarrior(world); + ItemStack boots = item(CinderLoE.bootsboneLimwaith, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(CinderLoE.legsboneLimwaith, LOTREnchantment.protectRanged3); + ItemStack body = item(CinderLoE.bodyboneLimwaith, LOTREnchantment.protectFire3); + ItemStack helmet = item(CinderLoE.helmetboneLimwaith, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(3)) { + case 0: weapon = item(CinderLoE.truncheonLimwaith, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(CinderLoE.spearLimwaith, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(CinderLoE.battleaxeLimwaith, LOTREnchantment.strong4, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_taurethrim_boss(World world) { + LOTREntityTauredainWarrior boss_entity = new LOTREntityTauredainWarrior(world); + ItemStack boots = item(LOTRMod.bootsTauredainGold, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsTauredainGold, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyTauredainGold, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetTauredainGold, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(3)) { + case 0: weapon = item(LOTRMod.swordTauredain, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearTauredain, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(LOTRMod.battleaxeTauredain, LOTREnchantment.strong4, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_half_troll_boss(World world) { + LOTREntityHalfTrollWarrior boss_entity = new LOTREntityHalfTrollWarrior(world); + ItemStack boots = item(LOTRMod.bootsHalfTroll, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsHalfTroll, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyHalfTroll, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetHalfTroll, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(3)) { + case 0: weapon = item(LOTRMod.scimitarHalfTroll, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.maceHalfTroll, LOTREnchantment.knockback2); break; + case 2: weapon = item(LOTRMod.battleaxeHalfTroll, LOTREnchantment.strong4, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_utumno_boss(World world) { + LOTREntityUtumnoOrc boss_entity = new LOTREntityUtumnoOrc(world); + ItemStack boots = item(LOTRMod.bootsUtumno, LOTREnchantment.protect1, LOTREnchantment.protectRanged3); + ItemStack legs = item(LOTRMod.legsUtumno, LOTREnchantment.protectRanged3); + ItemStack body = item(LOTRMod.bodyUtumno, LOTREnchantment.protectFire3); + ItemStack helmet = item(LOTRMod.helmetUtumno, LOTREnchantment.protect1, LOTREnchantment.protectFire3); + ItemStack weapon = null; + switch (Warband.random.nextInt(3)) { + case 0: weapon = item(LOTRMod.swordUtumno, LOTREnchantment.meleeSpeed1); break; + case 1: weapon = item(LOTRMod.spearUtumno, LOTREnchantment.meleeReach1); break; + case 2: weapon = item(LOTRMod.battleaxeUtumno, LOTREnchantment.strong4, LOTREnchantment.knockback1); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, default_boss_hp, default_boss_speed, default_boss_damage_boost); + return boss_entity; + } + public static Entity get_renegade_boss(World world) { + RenegadeCaptain boss_entity = new RenegadeCaptain(world); + ItemStack boots = null; + ItemStack legs = null; + ItemStack body = null; + ItemStack helmet = null; + ItemStack weapon = null; + switch (Warband.random.nextInt(3)) { + case 0: weapon = item(LOTRMod.dunlendingClub, LOTREnchantment.meleeReach1, LOTREnchantment.meleeSpeed1, LOTREnchantment.knockback2, LOTREnchantment.knockback2); break; + case 1: weapon = item(LOTRMod.dunlendingTrident, LOTREnchantment.meleeReach1, LOTREnchantment.meleeSpeed1); break; + case 2: weapon = item(LOTRMod.daggerArnorPoisoned, LOTREnchantment.meleeReach1, LOTREnchantment.meleeSpeed1); break; + } + switch (Warband.random.nextInt(5)) { + case 0: boots = item(Items.leather_boots); break; + case 1: boots = item(Items.iron_boots); break; + case 2: boots = item(LOTRMod.bootsArnor); break; + case 3: boots = item(LOTRMod.bootsAngmar); break; + case 4: boots = item(LOTRMod.bootsDunlending); break; + } + switch (Warband.random.nextInt(5)) { + case 0: legs = item(Items.leather_leggings); break; + case 1: legs = item(Items.iron_leggings); break; + case 2: legs = item(LOTRMod.legsArnor); break; + case 3: legs = item(LOTRMod.legsAngmar); break; + case 4: legs = item(LOTRMod.legsDunlending); break; + } + switch (Warband.random.nextInt(5)) { + case 0: body = item(Items.leather_chestplate); break; + case 1: body = item(Items.iron_chestplate); break; + case 2: body = item(LOTRMod.bodyArnor); break; + case 3: body = item(LOTRMod.bodyAngmar); break; + case 4: body = item(LOTRMod.bodyDunlending); break; + } + switch (Warband.random.nextInt(5)) { + case 0: helmet = item(Items.leather_helmet); break; + case 1: helmet = item(Items.iron_helmet); break; + case 2: helmet = item(LOTRMod.helmetArnor); break; + case 3: helmet = item(LOTRMod.helmetAngmar); break; + case 4: helmet = item(LOTRMod.helmetDunlending); break; + } + set_equipment(boss_entity, weapon, boots, legs, body, helmet); + set_attributes(boss_entity, 500.D, 0.25D, 15.0D); + return boss_entity; + } + public static void equip_renegade(Renegade renegade) { + ItemStack boots = null; + ItemStack legs = null; + ItemStack body = null; + ItemStack helmet = null; + ItemStack weapon = null; + switch (Warband.random.nextInt(3)) { + case 0: weapon = item(LOTRMod.dunlendingClub); break; + case 1: weapon = item(LOTRMod.dunlendingTrident); break; + case 2: weapon = item(LOTRMod.daggerArnorPoisoned, LOTREnchantment.strong3); break; + } + switch (Warband.random.nextInt(8)) { + case 0: boots = item(Items.leather_boots); break; + case 1: boots = item(Items.iron_boots); break; + case 2: boots = item(LOTRMod.bootsArnor); break; + case 3: boots = item(LOTRMod.bootsAngmar); break; + case 4: boots = item(LOTRMod.bootsDunlending); break; + } + switch (Warband.random.nextInt(8)) { + case 0: legs = item(Items.leather_leggings); break; + case 1: legs = item(Items.iron_leggings); break; + case 2: legs = item(LOTRMod.legsArnor); break; + case 3: legs = item(LOTRMod.legsAngmar); break; + case 4: legs = item(LOTRMod.legsDunlending); break; + } + switch (Warband.random.nextInt(8)) { + case 0: body = item(Items.leather_chestplate); break; + case 1: body = item(Items.iron_chestplate); break; + case 2: body = item(LOTRMod.bodyArnor); break; + case 3: body = item(LOTRMod.bodyAngmar); break; + case 4: body = item(LOTRMod.bodyDunlending); break; + } + switch (Warband.random.nextInt(8)) { + case 0: helmet = item(Items.leather_helmet); break; + case 1: helmet = item(Items.iron_helmet); break; + case 2: helmet = item(LOTRMod.helmetArnor); break; + case 3: helmet = item(LOTRMod.helmetAngmar); break; + case 4: helmet = item(LOTRMod.helmetDunlending); break; + } + set_equipment(renegade, weapon, boots, legs, body, helmet); + } + + /** + * Helper methods for boss creation + */ + public static void set_attributes(EntityLivingBase entity, double health, double speed, double damage_boost) { + entity.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(50.0D); + entity.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(health); + entity.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(speed); + entity.getEntityAttribute(LOTREntityNPC.npcAttackDamageExtra).setBaseValue(damage_boost); + } + public static ItemStack item(Item item, LOTREnchantment... enchants) { + ItemStack stack = new ItemStack(item); + LOTREnchantmentHelper.setEnchantList(stack, Arrays.asList(enchants)); + return stack; + } + public static void set_equipment(EntityLivingBase entity, ItemStack weapon, ItemStack boots, ItemStack legs, ItemStack body, ItemStack helmet) { + if (weapon != null) + entity.setCurrentItemOrArmor(0, weapon); + if (boots != null) + entity.setCurrentItemOrArmor(1, boots); + if (legs != null) + entity.setCurrentItemOrArmor(2, legs); + if (body != null) + entity.setCurrentItemOrArmor(3, body); + if (helmet != null) + entity.setCurrentItemOrArmor(4, helmet); + + if (entity instanceof LOTREntityNPC) { + LOTREntityNPC npc = (LOTREntityNPC) entity; + if (weapon != null) + npc.npcItemsInv.setIdleItem(weapon); + if (weapon.getItem() instanceof ItemSword) + npc.npcItemsInv.setMeleeWeapon(weapon); + if (weapon.getItem() instanceof ItemBow) + npc.npcItemsInv.setRangedWeapon(weapon); + } + } + + 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; + + public Troop(Class entity_class, int amount) { + this.entity_class = entity_class; + this.amount = 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 new file mode 100644 index 0000000..a7aff76 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/world/event/WarbandTickHandler.java @@ -0,0 +1,31 @@ +package com.zivilon.cinder_loe.world.event; + +import com.zivilon.cinder_loe.CinderLoE_Config; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent; +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 + + @SubscribeEvent + public void onServerTick(ServerTickEvent event) { + if (event.phase == TickEvent.Phase.END) { + tick_counter++; + if (tick_counter >= INTERVAL_TICKS) { + tick_counter = 0; + run_task(); + } + } + } + + public void run_task() { + 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; + if (!CinderLoE_Config.warbands_enabled) 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/java/com/zivilon/cinder_loe/world/sounds/MobileSoundHandler.java b/src/main/java/com/zivilon/cinder_loe/world/sounds/MobileSoundHandler.java new file mode 100644 index 0000000..887299e --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/world/sounds/MobileSoundHandler.java @@ -0,0 +1,61 @@ +package com.zivilon.cinder_loe.world.sounds; + +import net.minecraft.client.audio.ISound; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.ResourceLocation; + +public class MobileSoundHandler implements ISound { + private final EntityPlayer player; + private final ResourceLocation soundLocation; + + public MobileSoundHandler(EntityPlayer player, String soundName) { + this.player = player; + this.soundLocation = new ResourceLocation("cinder_loe", soundName); + } + + @Override + public ResourceLocation getPositionedSoundLocation() { + return this.soundLocation; + } + + @Override + public float getVolume() { + return 1.0F; + } + + @Override + public float getPitch() { + return 1.0F; + } + + + @Override + public float getXPosF() { + return (float) player.posX; + } + @Override + public float getYPosF() { + return (float) player.posY; + } + + @Override + public float getZPosF() { + return (float) player.posZ; + } + + @Override + public boolean canRepeat() { + return true; + } + + @Override + public int getRepeatDelay() { + return 0; + } + + @Override + public ISound.AttenuationType getAttenuationType() { + return ISound.AttenuationType.LINEAR; + } +} diff --git a/src/main/resources/assets/cinder_loe/lang/en_GB.lang b/src/main/resources/assets/cinder_loe/lang/en_GB.lang index 9206c9c..2b6899c 100644 --- a/src/main/resources/assets/cinder_loe/lang/en_GB.lang +++ b/src/main/resources/assets/cinder_loe/lang/en_GB.lang @@ -1,2 +1,3 @@ item.lotr:sarumanStaff.name=Staff of Saruman of Many Colours +item.lotr:sarumanWhiteStaff.name=Staff of Saruman the White item.lotr:boarArmorRedDwarf.name=Red Dwarven Boar Armour 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 c07630b..0faae93 100644 --- a/src/main/resources/assets/cinder_loe/lang/en_US.lang +++ b/src/main/resources/assets/cinder_loe/lang/en_US.lang @@ -77,7 +77,7 @@ item.lotr:helmetWarlord.name=Warlord Headdress item.lotr:bodyWarlord.name=Warlord Chestplate item.lotr:legsWarlord.name=Warlord Leggings item.lotr:bootsWarlord.name=Warlord Boots -item.lotr:cleaver=Cleaver +item.lotr:cleaver.name=Cleaver item.lotr:spearUnnamed.name=Drannach Oriour item.lotr:frostblade.name=Frostblade item.lotr:whip.name=Whip @@ -102,8 +102,10 @@ item.lotr:radagastStaff.name=Staff of Radagast the Brown item.lotr:pallandoStaff.name=Staff of Pallando the Blue item.lotr:alatarStaff.name=Staff of Alatar the Blue item.lotr:sarumanStaff.name=Staff of Saruman of Many Colors +item.lotr:sarumanWhiteStaff.name=Staff of Saruman the White item.lotr:welfRelic.name=Horn of the Greenwood Stag +item.lotr:ulukai.name=Ulûkai item.lotr:onion.name=Onion item.lotr:cabbage.name=Cabbage @@ -283,6 +285,8 @@ entity.cinder_loe.CorruptElf.name=Corrupt Elf entity.cinder_loe.CorruptEnt.name=Corrupt Ent entity.cinder_loe.CorruptHobit.name=Corrupt Hobbit entity.cinder_loe.CorruptOrc.name=Corrupt Orc +entity.cinder_loe.CorruptSkeleton.name=Restless Undead +entity.cinder_loe.CorruptSkeletonArcher.name=Restless Undead entity.cinder_loe.BladorthinSmith.name=Bladorthin Smith @@ -330,6 +334,8 @@ entity.cinder_loe.RhudaurSoldier.name=Rhudaur Soldier entity.cinder_loe.TauredainTrueBlood.name=Taurethrim True-Blood entity.cinder_loe.Sirrandrai.name=Rider of Sirrandrai entity.cinder_loe.NorthernOrc.name=Northern Orc +entity.cinder_loe.Monkey.name=Monkey +entity.cinder_loe.Usurper.name=Umbar Usurper lotr.enchant.protectWeak1=Dented lotr.enchant.protectWeak2=Defective @@ -337,6 +343,19 @@ lotr.enchant.protectRangedWeak1=Punctured lotr.enchant.protectRangedWeak2=Pierced lotr.enchant.weak4=Bent lotr.enchant.rangedWeak3=Cracked +lotr.enchant.strong5=Infused +lotr.enchant.meleeReach2=Lengthy +lotr.enchant.meleeSpeed2=Rapid +lotr.enchant.rangedStrong4=Forceful +lotr.enchant.fireRepair=Ashen +lotr.enchant.fireRepair.desc=Repairs durability while on fire +lotr.enchant.swiftness=Windy +lotr.enchant.swiftness.desc=1.05x movement speed +lotr.enchant.stealth=Cloaked +lotr.enchant.stealth.desc=Reduces NPC detection range +lotr.enchant.mountArmor=Heavy +lotr.enchant.mountArmor.desc=+1 mount armor + lotr.unit.Banner_Warg=Warg Rider Banner lotr.unit.Banner_Horse=Mounted Banner Bearer @@ -348,4 +367,39 @@ lotr.unitinfo.Angmar=To Hire this unit you must have the Angmar Objective comple lotr.unitinfo.Arnor=To Hire this unit you must have the Arnor Objective complete. lotr.unitinfo.Rhudaur=To Hire this unit you must have the Rhudaur Objective complete. 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. \ No newline at end of file +lotr.unitinfo.Lindon=To Hire this unit you must have the Lindon Objective complete. + +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 +warband.fac.RHUDEL_GOLDEN=Golden Easterlings +warband.fac.LIMWAITH=Limwaith +warband.fac.RENEGADE=renegades + +pickpocket.cooldown=You need to wait before pickpocketing again. +pickpocket.cooldown_alt=Maybe get your hands out of his pants first. + +item.lotr:spice_human.name=Mannish spice +item.lotr:spice_elven.name=Elven spice +item.lotr:spice_orcish.name=Orcish spice +item.lotr:spice_dwarven.name=Dwarven spice +item.lotr:mugElfBrew.name=Saturated Miruvor +item.lotr:mugOrcBrew.name=Concentrated Orc Draught +item.lotr:mugHumanBrew.name=Athelas Tea +item.lotr:mugDwarfBrew.name=Dwarven Stout + +potion.overdose=Overdose + +#Achievements +lotr.achievement.tameMonkey.title=Monkey Business +lotr.achievement.tameMonkey.desc=Tame a Monkey +lotr.achievement.pickpocketOlog.title=Minor Mistake +lotr.achievement.pickpocketOlog.desc=Attempt and Fail to pickpocket an Olog-Hai + +#Biomes +lotr.biome.mistyForest.name=Misty Forest diff --git a/src/main/resources/assets/cinder_loe/misc/overdose.png b/src/main/resources/assets/cinder_loe/misc/overdose.png new file mode 100644 index 0000000..f04b592 Binary files /dev/null and b/src/main/resources/assets/cinder_loe/misc/overdose.png differ diff --git a/src/main/resources/assets/cinder_loe/misc/particles.png b/src/main/resources/assets/cinder_loe/misc/particles.png index 49e035d..4c77142 100644 Binary files a/src/main/resources/assets/cinder_loe/misc/particles.png and b/src/main/resources/assets/cinder_loe/misc/particles.png differ diff --git a/src/main/resources/assets/cinder_loe/mob/monkey.png b/src/main/resources/assets/cinder_loe/mob/monkey.png new file mode 100644 index 0000000..0878756 Binary files /dev/null and b/src/main/resources/assets/cinder_loe/mob/monkey.png differ diff --git a/src/main/resources/assets/cinder_loe/sounds.json b/src/main/resources/assets/cinder_loe/sounds.json index 92c1501..3663352 100644 --- a/src/main/resources/assets/cinder_loe/sounds.json +++ b/src/main/resources/assets/cinder_loe/sounds.json @@ -30,5 +30,32 @@ [ "boss/spiders" ] + }, + "monkey.death": + { + "category": "neutral", + "sounds": + [ + "monkey/death" + ] + }, + "monkey.idle": + { + "category": "neutral", + "sounds": + [ + "monkey/idle1", + "monkey/idle2", + "monkey/idle3" + ] + }, + "monkey.hurt": + { + "category": "neutral", + "sounds": + [ + "monkey/hurt1", + "monkey/hurt2" + ] } } diff --git a/src/main/resources/assets/cinder_loe/sounds/monkey/death.ogg b/src/main/resources/assets/cinder_loe/sounds/monkey/death.ogg new file mode 100644 index 0000000..0f0140a Binary files /dev/null and b/src/main/resources/assets/cinder_loe/sounds/monkey/death.ogg differ diff --git a/src/main/resources/assets/cinder_loe/sounds/monkey/hurt1.ogg b/src/main/resources/assets/cinder_loe/sounds/monkey/hurt1.ogg new file mode 100644 index 0000000..a0fe841 Binary files /dev/null and b/src/main/resources/assets/cinder_loe/sounds/monkey/hurt1.ogg differ diff --git a/src/main/resources/assets/cinder_loe/sounds/monkey/hurt2.ogg b/src/main/resources/assets/cinder_loe/sounds/monkey/hurt2.ogg new file mode 100644 index 0000000..c641f2e Binary files /dev/null and b/src/main/resources/assets/cinder_loe/sounds/monkey/hurt2.ogg differ diff --git a/src/main/resources/assets/cinder_loe/sounds/monkey/idle1.ogg b/src/main/resources/assets/cinder_loe/sounds/monkey/idle1.ogg new file mode 100644 index 0000000..b5fbc1a Binary files /dev/null and b/src/main/resources/assets/cinder_loe/sounds/monkey/idle1.ogg differ diff --git a/src/main/resources/assets/cinder_loe/sounds/monkey/idle2.ogg b/src/main/resources/assets/cinder_loe/sounds/monkey/idle2.ogg new file mode 100644 index 0000000..e9bdb42 Binary files /dev/null and b/src/main/resources/assets/cinder_loe/sounds/monkey/idle2.ogg differ diff --git a/src/main/resources/assets/cinder_loe/sounds/monkey/idle3.ogg b/src/main/resources/assets/cinder_loe/sounds/monkey/idle3.ogg new file mode 100644 index 0000000..07cc1be Binary files /dev/null and b/src/main/resources/assets/cinder_loe/sounds/monkey/idle3.ogg differ diff --git a/src/main/resources/assets/cinder_loe/speech/corruptSpeak/all/skeleton.txt b/src/main/resources/assets/cinder_loe/speech/corruptSpeak/all/skeleton.txt new file mode 100644 index 0000000..7e1f2d3 --- /dev/null +++ b/src/main/resources/assets/cinder_loe/speech/corruptSpeak/all/skeleton.txt @@ -0,0 +1,6 @@ +ᛒᛟᚹ ᛒᛖᚠᛟᚱᛖ ᚦᛖ ᛞᛖᛞ! +ᛒᛖᚷ ᚠᛟᚱ ᛗᛖᚱᚲᛁ! +ᛖᛏᛖᚱᚾᚨᛚ ᛈᚨᛁᚾ ᚢᛈᛟᚾ ᛁᛟᚢ! +ᛞᛖᚦ ᚢᛈᛟᚾ ᛁᛟᚢ! +ᛈᚨᛁᚾ, ᛊᚺᚨᛗᛖ, ᚺᛟᚱᚱᛟᚱ ᛏᛟ ᛁᛟᚢ! +ᛞᚱᛟᚹᚾ ᛁᚾ ᛒᛚᛟᛟᛞ ᛊᛚᚨᚢᛖ! \ No newline at end of file diff --git a/src/main/resources/assets/cinder_loe/speech/monkey/say.txt b/src/main/resources/assets/cinder_loe/speech/monkey/say.txt new file mode 100644 index 0000000..043034f --- /dev/null +++ b/src/main/resources/assets/cinder_loe/speech/monkey/say.txt @@ -0,0 +1,6 @@ +OAAAAAAAAAAAAAO OAAOAOAOAO OAOAOOAOO +OOOOA OAAOAOAOAO OAAOAOAOAO +AOAOAOAOAOAOAOAOOOOO OAOOAAOOAOAOOA +OAOAOOAO +OOOOA OAAOAOAOAO +OOAOAOAOAO \ No newline at end of file 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/assets/lotr/textures/items/ingotAsh.png b/src/main/resources/assets/lotr/textures/items/ingotAsh.png index c2b118e..1af431e 100644 Binary files a/src/main/resources/assets/lotr/textures/items/ingotAsh.png and b/src/main/resources/assets/lotr/textures/items/ingotAsh.png differ diff --git a/src/main/resources/assets/lotr/textures/items/large/sarumanWhiteStaff.png b/src/main/resources/assets/lotr/textures/items/large/sarumanWhiteStaff.png new file mode 100644 index 0000000..0262cb5 Binary files /dev/null and b/src/main/resources/assets/lotr/textures/items/large/sarumanWhiteStaff.png differ diff --git a/src/main/resources/assets/lotr/textures/items/mugDwarfBrew_liquid.png b/src/main/resources/assets/lotr/textures/items/mugDwarfBrew_liquid.png new file mode 100644 index 0000000..e8d4e70 Binary files /dev/null and b/src/main/resources/assets/lotr/textures/items/mugDwarfBrew_liquid.png differ diff --git a/src/main/resources/assets/lotr/textures/items/mugElfBrew_liquid.png b/src/main/resources/assets/lotr/textures/items/mugElfBrew_liquid.png new file mode 100644 index 0000000..db59f80 Binary files /dev/null and b/src/main/resources/assets/lotr/textures/items/mugElfBrew_liquid.png differ diff --git a/src/main/resources/assets/lotr/textures/items/mugHumanBrew_liquid.png b/src/main/resources/assets/lotr/textures/items/mugHumanBrew_liquid.png new file mode 100644 index 0000000..5f95d9a Binary files /dev/null and b/src/main/resources/assets/lotr/textures/items/mugHumanBrew_liquid.png differ diff --git a/src/main/resources/assets/lotr/textures/items/mugOrcBrew_liquid.png b/src/main/resources/assets/lotr/textures/items/mugOrcBrew_liquid.png new file mode 100644 index 0000000..87c3075 Binary files /dev/null and b/src/main/resources/assets/lotr/textures/items/mugOrcBrew_liquid.png differ diff --git a/src/main/resources/assets/lotr/textures/items/sarumanWhiteStaff.png b/src/main/resources/assets/lotr/textures/items/sarumanWhiteStaff.png new file mode 100644 index 0000000..c5eb5b8 Binary files /dev/null and b/src/main/resources/assets/lotr/textures/items/sarumanWhiteStaff.png differ diff --git a/src/main/resources/assets/lotr/textures/items/spice_dwarven.png b/src/main/resources/assets/lotr/textures/items/spice_dwarven.png new file mode 100644 index 0000000..3b7e29b Binary files /dev/null and b/src/main/resources/assets/lotr/textures/items/spice_dwarven.png differ diff --git a/src/main/resources/assets/lotr/textures/items/spice_elven.png b/src/main/resources/assets/lotr/textures/items/spice_elven.png new file mode 100644 index 0000000..094abdc Binary files /dev/null and b/src/main/resources/assets/lotr/textures/items/spice_elven.png differ diff --git a/src/main/resources/assets/lotr/textures/items/spice_human.png b/src/main/resources/assets/lotr/textures/items/spice_human.png new file mode 100644 index 0000000..9310d7c Binary files /dev/null and b/src/main/resources/assets/lotr/textures/items/spice_human.png differ diff --git a/src/main/resources/assets/lotr/textures/items/spice_orcish.png b/src/main/resources/assets/lotr/textures/items/spice_orcish.png new file mode 100644 index 0000000..fdeb2f9 Binary files /dev/null and b/src/main/resources/assets/lotr/textures/items/spice_orcish.png differ diff --git a/src/main/resources/assets/lotr/textures/items/ulukai.png b/src/main/resources/assets/lotr/textures/items/ulukai.png new file mode 100644 index 0000000..efb5fac Binary files /dev/null and b/src/main/resources/assets/lotr/textures/items/ulukai.png differ diff --git a/src/main/resources/assets/lotr/textures/items/ulukai.png.mcmeta b/src/main/resources/assets/lotr/textures/items/ulukai.png.mcmeta new file mode 100644 index 0000000..49e167b --- /dev/null +++ b/src/main/resources/assets/lotr/textures/items/ulukai.png.mcmeta @@ -0,0 +1,50 @@ +{ + "animation": { + "frames": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 2, + 2, + 2, + 3, + 3, + 3, + 4, + 4, + 4, + 3, + 3, + 3, + 2, + 2, + 2, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } +} diff --git a/src/main/resources/mixins.cinder_loe.json b/src/main/resources/mixins.cinder_loe.json index d5f5975..b7787c5 100644 --- a/src/main/resources/mixins.cinder_loe.json +++ b/src/main/resources/mixins.cinder_loe.json @@ -40,14 +40,22 @@ "MixinRendererLivingEntity", "MixinRenderItem", "MixinSlotCrafting", - "overrides.MixinLOTREntityWarg", + "MixinLOTREntityWarg", "overrides.MixinLOTRHiredNPCInfo", "overrides.MixinLOTRItemEntDraught", "overrides.MixinLOTRReplacedMethods", "overrides.MixinLOTRTradeEntriesOverrides", "overrides.MixinLOTRUnitTradeEntries", + "overrides.MixinLOTRBiome", "MixinEntityLivingBase", - "MixinEntityPlayer" + "MixinEntityPlayer", + "MixinLOTREntityAIAttackOnCollide", + "MixinLOTREntityNPC", + "MixinFoodStats", + "MixinLOTRItemMug", + "MixinLOTREntityHorse", + "MixinLOTRGuiMap", + "MixinLOTREntityAIOrcSkirmish" ], "client": [] }