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 extends Entity> entity_list = (List extends Entity>)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 extends Entity> 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 extends LOTREntityNPC> 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": []
}