Merge pull request #4 from GTNewHorizons/unified-build-script

Unified build script
This commit is contained in:
Johann Bernhardt authored and GitHub committed 2021-12-19 23:59:30 +01:00
commit dd5a47264e
233 files changed
+884 -15808

No files matched your search

+27
View File
@@ -0,0 +1,27 @@
if [[ -d "run/crash-reports" ]]; then
echo "Crash reports detected:"
cat $directory/*
exit 1
fi
if grep --quiet "Fatal errors were detected" server.log; then
echo "Fatal errors detected:"
cat server.log
exit 1
fi
if grep --quiet "The state engine was in incorrect state ERRORED and forced into state SERVER_STOPPED" server.log; then
echo "Server force stopped:"
cat server.log
exit 1
fi
if grep --quiet 'Done .+ For help, type "help" or "?"' server.log; then
echo "Server didn't finish startup:"
cat server.log
exit 1
fi
echo "No crash reports detected"
exit 0
+45
View File
@@ -0,0 +1,45 @@
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
name: Build and test
on:
pull_request:
branches: [ master, main ]
push:
branches: [ master, main ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up JDK 8
uses: actions/setup-java@v2
with:
java-version: '8'
distribution: 'adopt'
cache: gradle
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Setup the workspace
run: ./gradlew setupCIWorkspace
- name: Build the mod
run: ./gradlew build
- name: Run server for 1.5 minutes
run: |
mkdir run
echo "eula=true" > run/eula.txt
timeout 90 ./gradlew runServer | tee --append server.log || true
- name: Test no errors reported during server run
run: |
chmod +x .github/scripts/test-no-error-reports.sh
.github/scripts/test-no-error-reports.sh
+61
View File
@@ -0,0 +1,61 @@
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
name: Release tagged build
on:
push:
tags:
- '*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set release version
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Set up JDK 8
uses: actions/setup-java@v2
with:
java-version: '8'
distribution: 'adopt'
cache: gradle
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Setup the workspace
run: ./gradlew setupCIWorkspace
- name: Build the mod
run: ./gradlew build
- name: Release under current tag
uses: "marvinpinto/action-automatic-releases@latest"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "${{ env.RELEASE_VERSION }}"
prerelease: false
title: "${{ env.RELEASE_VERSION }}"
files: build/libs/*.jar
- name: Set repository owner and name
run: |
echo "REPOSITORY_OWNER=${GITHUB_REPOSITORY%/*}" >> $GITHUB_ENV
echo "REPOSITORY_NAME=${GITHUB_REPOSITORY#*/}" >> $GITHUB_ENV
- name: Publish package
run: ./gradlew publish
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ARTIFACT_GROUP_ID: com.github.${{ env.REPOSITORY_OWNER }}
ARTIFACT_ID: "${{ env.REPOSITORY_NAME }}"
ARTIFACT_VERSION: "${{ env.RELEASE_VERSION }}"
REPOSITORY_NAME: "${{ env.REPOSITORY_NAME }}"
REPOSITORY_OWNER: "${{ env.REPOSITORY_OWNER }}"
+28 -29
View File
@@ -1,32 +1,31 @@
*.class
*.pdn
# Package Files #
*.jar
*.war
*.ear
#Forge Stuffs
/LICENSE-fml.txt
/MinecraftForge-Credits.txt
/MinecraftForge-License.txt
/README.txt
/CREDITS-fml.txt
/forge-1.7.2*
/.gradle
/build
/common
/eclipse/*
/lib/
/src/api/
#/src/api/*
/bin/*
.gradle
.settings
/.idea/
/run/
/build/
/eclipse/
.classpath
.project
.settings/*
.idea
*.bat
/bin/
/config/
/crash-reports/
/logs/
options.txt
/saves/
usernamecache.json
banned-ips.json
banned-players.json
eula.txt
ops.json
server.properties
servers.dat
usercache.json
whitelist.json
/out/
*.iml
Forbidden-Magic.ipr
Forbidden-Magic.iws
*.ipr
*.iws
src/main/resources/mixins.*.json
*.bat
*.DS_Store
!gradlew.bat
+527 -46
View File
@@ -1,81 +1,562 @@
//version: be36e1399d5622c152db7c530c48e17cde0ce1bb
/*
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/SinTh0r4s/ExampleMod1.7.10/blob/main/build.gradle for updates.
*/
import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import java.util.concurrent.TimeUnit
buildscript {
repositories {
maven {//added, fixes some of the 501 issues
name = "mavenCentral"
url = "https://repo1.maven.org/maven2/"
}
maven {
name = "gt"
url = "https://gregtech.overminddl1.com/"
name = "forge"
url = "https://maven.minecraftforge.net"
}
maven {
name = "sonatype"
url = "https://oss.sonatype.org/content/repositories/snapshots/"
}
maven {
name = "jitpack.io"
url = "https://jitpack.io"
}
maven {
name = "Scala CI dependencies"
url = "https://repo1.maven.org/maven2/"
}
maven {
name = "jitpack"
url = "https://jitpack.io"
}
}
dependencies {
classpath 'com.github.GTNH2:ForgeGradle:FG_1.2-SNAPSHOT'
classpath 'com.github.GTNewHorizons:ForgeGradle:1.2.4'
}
}
plugins {
id 'idea'
id 'scala'
id("org.ajoberstar.grgit") version("3.1.1")
id("com.github.johnrengelman.shadow") version("4.0.4")
id("com.palantir.git-version") version("0.12.3")
id("maven-publish")
}
apply plugin: 'forge'
apply plugin: 'java'
sourceCompatibility = 1.8
targetCompatibility = 1.8
def projectJavaVersion = JavaLanguageVersion.of(8)
// define the properties file
ext.configFile = file "build.properties"
configFile.withReader {
// read config. it shall from now on be referenced as simply config or as project.config
def prop = new Properties()
prop.load(it)
project.ext.config = new ConfigSlurper().parse prop
java {
toolchain {
languageVersion.set(projectJavaVersion)
}
}
version = config.minecraft_version + "-" + config.mod_version
group= "com.github.spitefulfox.forbiddenmagic" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "Forbidden Magic"
idea {
module {
inheritOutputDirs = true
downloadJavadoc = true
downloadSources = true
}
}
if(JavaVersion.current() != JavaVersion.VERSION_1_8) {
throw new GradleException("This project requires Java 8, but it's running on " + JavaVersion.current())
}
checkPropertyExists("modName")
checkPropertyExists("modId")
checkPropertyExists("modGroup")
checkPropertyExists("autoUpdateBuildScript")
checkPropertyExists("minecraftVersion")
checkPropertyExists("forgeVersion")
checkPropertyExists("replaceGradleTokenInFile")
checkPropertyExists("gradleTokenModId")
checkPropertyExists("gradleTokenModName")
checkPropertyExists("gradleTokenVersion")
checkPropertyExists("gradleTokenGroupName")
checkPropertyExists("apiPackage")
checkPropertyExists("accessTransformersFile")
checkPropertyExists("usesMixins")
checkPropertyExists("mixinPlugin")
checkPropertyExists("mixinsPackage")
checkPropertyExists("coreModClass")
checkPropertyExists("containsMixinsAndOrCoreModOnly")
checkPropertyExists("usesShadowedDependencies")
checkPropertyExists("developmentEnvironmentUserName")
String javaSourceDir = "src/main/java/"
String scalaSourceDir = "src/main/scala/"
String targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/")
String targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/")
if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) {
throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala)
}
if(apiPackage) {
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) {
throw new GradleException("Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala)
}
}
if(accessTransformersFile) {
String targetFile = "src/main/resources/META-INF/" + accessTransformersFile
if(getFile(targetFile).exists() == false) {
throw new GradleException("Could not resolve \"accessTransformersFile\"! Could not find " + targetFile)
}
}
if(usesMixins.toBoolean()) {
if(mixinsPackage.isEmpty() || mixinPlugin.isEmpty()) {
throw new GradleException("\"mixinPlugin\" requires \"mixinsPackage\" and \"mixinPlugin\" to be set!")
}
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) {
throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala)
}
String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java"
String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".scala"
String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java"
if((getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists()) == false) {
throw new GradleException("Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava)
}
}
if(coreModClass) {
String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java"
String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".scala"
String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java"
if((getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists()) == false) {
throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava)
}
}
configurations.all {
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
'git config core.fileMode false'.execute()
// Pulls version from git tag
try {
version = minecraftVersion + "-" + gitVersion()
}
catch (Exception e) {
throw new IllegalStateException("This mod must be version controlled by Git AND the repository must provide at least one tag!");
}
group = modGroup
if(project.hasProperty("customArchiveBaseName") && customArchiveBaseName) {
archivesBaseName = customArchiveBaseName
}
else {
archivesBaseName = modId
}
minecraft {
version = "1.7.10-10.13.4.1614-1.7.10"
version = minecraftVersion + "-" + forgeVersion + "-" + minecraftVersion
runDir = "run"
if (replaceGradleTokenInFile) {
replaceIn replaceGradleTokenInFile
if(gradleTokenModId) {
replace gradleTokenModId, modId
}
if(gradleTokenModName) {
replace gradleTokenModName, modName
}
if(gradleTokenVersion) {
replace gradleTokenVersion, versionDetails().lastTag
}
if(gradleTokenGroupName) {
replace gradleTokenGroupName, modGroup
}
}
}
if(file("addon.gradle").exists()) {
apply from: "addon.gradle"
}
apply from: 'repositories.gradle'
configurations {
implementation.extendsFrom(shadowImplementation)
}
repositories {
maven {
name = "Overmind forge repo mirror"
url = "https://gregtech.overminddl1.com/"
}
if(usesMixins.toBoolean()) {
maven {
name = "sponge"
url = "https://repo.spongepowered.org/repository/maven-public"
}
maven {
url = "https://jitpack.io"
}
}
}
dependencies {
compile files('libs/Thaumcraft-deobf-1.7.10-4.2.3.5.jar')
//compile fileTree(dir: 'lib', include: '*.jar')
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("org.spongepowered:mixin:0.8-SNAPSHOT")
// using 0.8 to workaround a issue in 0.7 which fails mixin application
compile("org.spongepowered:mixin:0.7.11-SNAPSHOT") {
// Mixin includes a lot of dependencies that are too up-to-date
exclude module: "launchwrapper"
exclude module: "guava"
exclude module: "gson"
exclude module: "commons-io"
exclude module: "log4j-core"
}
compile("com.github.GTNewHorizons:SpongeMixins:1.3.3:dev")
}
}
apply from: 'dependencies.gradle'
def mixingConfigRefMap = "mixins." + modId + ".refmap.json"
def refMap = "${tasks.compileJava.temporaryDir}" + File.separator + mixingConfigRefMap
def mixinSrg = "${tasks.reobf.temporaryDir}" + File.separator + "mixins.srg"
task generateAssets {
if(usesMixins.toBoolean()) {
getFile("/src/main/resources/mixins." + modId + ".json").text = """{
"required": true,
"minVersion": "0.7.11",
"package": "${modGroup}.${mixinsPackage}",
"plugin": "${modGroup}.${mixinPlugin}",
"refmap": "${mixingConfigRefMap}",
"target": "@env(DEFAULT)",
"compatibilityLevel": "JAVA_8"
}
"""
}
}
task relocateShadowJar(type: ConfigureShadowRelocation) {
target = tasks.shadowJar
prefix = modGroup + ".shadow"
}
shadowJar {
manifest {
attributes(getManifestAttributes())
}
minimize() // This will only allow shading for actually used classes
configurations = [project.configurations.shadowImplementation]
dependsOn(relocateShadowJar)
}
jar {
manifest {
attributes(getManifestAttributes())
}
if(usesShadowedDependencies.toBoolean()) {
dependsOn(shadowJar)
enabled = false
}
}
reobf {
if(usesMixins.toBoolean()) {
addExtraSrgFile mixinSrg
}
}
afterEvaluate {
if(usesMixins.toBoolean()) {
tasks.compileJava {
options.compilerArgs += [
"-AreobfSrgFile=${tasks.reobf.srg}",
"-AoutSrgFile=${mixinSrg}",
"-AoutRefMapFile=${refMap}",
// 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"
]
}
}
}
runClient {
def arguments = []
if(usesMixins.toBoolean()) {
arguments += [
"--mods=../build/libs/$modId-${version}.jar",
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
]
}
if(developmentEnvironmentUserName) {
arguments += [
"--username",
developmentEnvironmentUserName
]
}
args(arguments)
}
runServer {
def arguments = []
if (usesMixins.toBoolean()) {
arguments += [
"--mods=../build/libs/$modId-${version}.jar",
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
]
}
args(arguments)
}
tasks.withType(JavaExec).configureEach {
javaLauncher.set(
javaToolchains.launcherFor {
languageVersion = projectJavaVersion
}
)
}
processResources
{
// this will ensure that this task is redone when the versions change.
inputs.property "version", project.version
inputs.property "mcversion", project.minecraft.version
{
// this will ensure that this task is redone when the versions change.
inputs.property "version", project.version
inputs.property "mcversion", project.minecraft.version
// replace stuff in mcmod.info, nothing else
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
// replace version and mcversion
expand 'version':project.version, 'mcversion':project.minecraft.version
// replace stuff in mcmod.info, nothing else
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
// replace version and mcversion
expand "minecraftVersion": project.minecraft.version,
"modVersion": versionDetails().lastTag,
"modId": modId,
"modName": modName
}
if(usesMixins.toBoolean()) {
from refMap
}
// copy everything else, thats not the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
}
}
def getManifestAttributes() {
def manifestAttributes = [:]
if(containsMixinsAndOrCoreModOnly.toBoolean() == false && (usesMixins.toBoolean() || coreModClass)) {
manifestAttributes += ["FMLCorePluginContainsFMLMod": true]
}
// copy everything else, thats not the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
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() == false
]
}
return manifestAttributes
}
task deobfJar(type: Jar) {
task sourcesJar(type: Jar) {
from (sourceSets.main.allJava)
from (file("$projectDir/LICENSE"))
getArchiveClassifier().set('sources')
}
task shadowDevJar(type: ShadowJar) {
from sourceSets.main.output
classifier = 'deobf'
getArchiveClassifier().set("dev")
manifest {
attributes(getManifestAttributes())
}
minimize() // This will only allow shading for actually used classes
configurations = [project.configurations.shadowImplementation]
}
deobfJar.dependsOn classes
assemble.dependsOn deobfJar
task relocateShadowDevJar(type: ConfigureShadowRelocation) {
target = tasks.shadowDevJar
prefix = modGroup + ".shadow"
}
task circularResolverJar(type: Jar) {
dependsOn(relocateShadowDevJar)
dependsOn(shadowDevJar)
enabled = false
}
task devJar(type: Jar) {
from sourceSets.main.output
getArchiveClassifier().set("dev")
manifest {
attributes(getManifestAttributes())
}
if(usesShadowedDependencies.toBoolean()) {
dependsOn(circularResolverJar)
enabled = false
}
}
task apiJar(type: Jar) {
from (sourceSets.main.allJava) {
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**'
}
from (sourceSets.main.output) {
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**'
}
from (sourceSets.main.resources.srcDirs) {
include("LICENSE")
}
getArchiveClassifier().set('api')
}
artifacts {
archives sourcesJar
archives devJar
if(apiPackage) {
archives apiJar
}
}
// publishing
publishing {
publications {
maven(MavenPublication) {
artifact source: jar
artifact source: sourcesJar, classifier: "src"
artifact source: devJar, classifier: "dev"
if (apiPackage) {
archives source: apiJar, classifier: "api"
}
groupId = System.getenv("ARTIFACT_GROUP_ID") ?: group
artifactId = System.getenv("ARTIFACT_ID") ?: project.name
version = System.getenv("ARTIFACT_VERSION") ?: project.version
}
}
repositories {
maven {
String owner = System.getenv("REPOSITORY_OWNER") ?: "Unknown"
String repositoryName = System.getenv("REPOSITORY_NAME") ?: "Unknown"
String githubRepositoryUrl = "https://maven.pkg.github.com/$owner/$repositoryName"
name = "GitHubPackages"
url = githubRepositoryUrl
credentials {
username = System.getenv("GITHUB_ACTOR") ?: "NONE"
password = System.getenv("GITHUB_TOKEN") ?: "NONE"
}
}
}
}
// Updating
task updateBuildScript {
doLast {
if (performBuildScriptUpdate(projectDir.toString())) return
print("Build script already up-to-date!")
}
}
if (isNewBuildScriptVersionAvailable(projectDir.toString())) {
if (autoUpdateBuildScript.toBoolean()) {
performBuildScriptUpdate(projectDir.toString())
} else {
println("Build script update available! Run 'gradle updateBuildScript'")
}
}
static URL availableBuildScriptUrl() {
new URL("https://raw.githubusercontent.com/SinTh0r4s/ExampleMod1.7.10/main/build.gradle")
}
boolean performBuildScriptUpdate(String projectDir) {
if (isNewBuildScriptVersionAvailable(projectDir)) {
def buildscriptFile = getFile("build.gradle")
availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } }
print("Build script updated. Please REIMPORT the project or RESTART your IDE!")
return true
}
return false
}
boolean isNewBuildScriptVersionAvailable(String projectDir) {
Map parameters = ["connectTimeout": 2000, "readTimeout": 2000]
String currentBuildScript = getFile("build.gradle").getText()
String currentBuildScriptHash = getVersionHash(currentBuildScript)
String availableBuildScript = availableBuildScriptUrl().newInputStream(parameters).getText()
String availableBuildScriptHash = getVersionHash(availableBuildScript)
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 ""
}
configure(updateBuildScript) {
group = 'forgegradle'
description = 'Updates the build script to the latest version'
}
// Helper methods
def checkPropertyExists(String propertyName) {
if (project.hasProperty(propertyName) == false) {
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/SinTh0r4s/ExampleMod1.7.10/blob/main/gradle.properties")
}
}
def getFile(String relativePath) {
return new File(projectDir, relativePath)
}
-3
View File
@@ -1,3 +0,0 @@
minecraft_version=1.7.10
forge_version=10.13.4.1614
mod_version=0.575-gtnh-2
+18
View File
@@ -0,0 +1,18 @@
// Add your dependencies here
dependencies {
compile("com.github.GTNewHorizons:Baubles:master-SNAPSHOT:dev")
compile("thaumcraft:Thaumcraft:1.7.10-4.2.3.5:dev")
compileOnly("com.github.GTNewHorizons:BloodMagic:master-SNAPSHOT:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:Botania:master-SNAPSHOT:api") {
transitive = false
}
compileOnly("curse.maven:ee3-65509:2305023") {
transitive = false
}
}
+64
View File
@@ -0,0 +1,64 @@
modName = Forbidden Magic
# This is a case-sensitive string to identify your mod. Convention is to use lower case.
modId = ForbiddenMagic
modGroup = fox.spiteful.forbidden
# 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
# Select a username for testing your mod with breakpoints. You may leave this empty for a random user name 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"
# Define a source file of your project with:
# public static final String VERSION = "GRADLETOKEN_VERSION";
# The string's content will be replaced with your mods 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 =
gradleTokenModId =
gradleTokenModName =
gradleTokenVersion =
gradleTokenGroupName =
# 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. I must be placed into /src/main/resources/META-INF/
# Example value: mymodid_at.cfg
accessTransformersFile =
# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled!
usesMixins = 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 =
# 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 =
# 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
# If enabled, you may use 'shadowImplementation' 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
# 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 = Forbidden Magic
Binary file not shown.
+1 -2
View File
@@ -1,6 +1,5 @@
#Wed May 06 21:54:49 CEST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4.1-all.zip
Vendored
+77 -53
View File
@@ -1,4 +1,20 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
@@ -6,47 +22,6 @@
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -61,9 +36,49 @@ while [ -h "$PRG" ] ; do
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -90,7 +105,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -110,10 +125,11 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
@@ -154,11 +170,19 @@ if $cygwin ; then
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
APP_ARGS=$(save "$@")
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
Vendored
+20 -10
View File
@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@@ -8,14 +24,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,10 +62,9 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +75,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
+2
View File
@@ -0,0 +1,2 @@
before_install:
- ./gradlew setupCIWorkspace
Binary file not shown.
Binary file not shown.
Binary file not shown.
+10
View File
@@ -0,0 +1,10 @@
// Add any additional repositories for your dependencies here
repositories {
maven {
url "https://cursemaven.com"
}
maven {
url = "https://jitpack.io"
}
}
-7
View File
@@ -1,7 +0,0 @@
package baubles.api;
public enum BaubleType {
RING,
AMULET,
BELT
}
-41
View File
@@ -1,41 +0,0 @@
package baubles.api;
import java.lang.reflect.Method;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import cpw.mods.fml.common.FMLLog;
/**
* @author Azanor
*/
public class BaublesApi
{
static Method getBaubles;
/**
* Retrieves the baubles inventory for the supplied player
*/
public static IInventory getBaubles(EntityPlayer player)
{
IInventory ot = null;
try
{
if(getBaubles == null)
{
Class<?> fake = Class.forName("baubles.common.lib.PlayerHandler");
getBaubles = fake.getMethod("getPlayerBaubles", EntityPlayer.class);
}
ot = (IInventory) getBaubles.invoke(null, player);
}
catch(Exception ex)
{
FMLLog.warning("[Baubles API] Could not invoke baubles.common.lib.PlayerHandler method getPlayerBaubles");
}
return ot;
}
}
-45
View File
@@ -1,45 +0,0 @@
package baubles.api;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
/**
*
* This interface should be extended by items that can be worn in bauble slots
*
* @author Azanor
*/
public interface IBauble {
/**
* This method return the type of bauble this is.
* Type is used to determine the slots it can go into.
*/
public BaubleType getBaubleType(ItemStack itemstack);
/**
* This method is called once per tick if the bauble is being worn by a player
*/
public void onWornTick(ItemStack itemstack, EntityLivingBase player);
/**
* This method is called when the bauble is equipped by a player
*/
public void onEquipped(ItemStack itemstack, EntityLivingBase player);
/**
* This method is called when the bauble is unequipped by a player
*/
public void onUnequipped(ItemStack itemstack, EntityLivingBase player);
/**
* can this bauble be placed in a bauble slot
*/
public boolean canEquip(ItemStack itemstack, EntityLivingBase player);
/**
* Can this bauble be removed from a bauble slot
*/
public boolean canUnequip(ItemStack itemstack, EntityLivingBase player);
}
@@ -1,5 +0,0 @@
@API(owner = "Baubles", apiVersion = "1.0.1.10", provides = "Baubles|API")
package baubles.api;
import cpw.mods.fml.common.API;
-11
View File
@@ -1,11 +0,0 @@
package cofh.api;
public class CoFHAPIProps {
private CoFHAPIProps() {
}
public static final String VERSION = "1.7.10R1.0.2";
}
@@ -1,158 +0,0 @@
package cofh.api.energy;
import net.minecraft.nbt.NBTTagCompound;
/**
* Reference implementation of {@link IEnergyStorage}. Use/extend this or implement your own.
*
* @author King Lemming
*
*/
public class EnergyStorage implements IEnergyStorage {
protected int energy;
protected int capacity;
protected int maxReceive;
protected int maxExtract;
public EnergyStorage(int capacity) {
this(capacity, capacity, capacity);
}
public EnergyStorage(int capacity, int maxTransfer) {
this(capacity, maxTransfer, maxTransfer);
}
public EnergyStorage(int capacity, int maxReceive, int maxExtract) {
this.capacity = capacity;
this.maxReceive = maxReceive;
this.maxExtract = maxExtract;
}
public EnergyStorage readFromNBT(NBTTagCompound nbt) {
this.energy = nbt.getInteger("Energy");
if (energy > capacity) {
energy = capacity;
}
return this;
}
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
if (energy < 0) {
energy = 0;
}
nbt.setInteger("Energy", energy);
return nbt;
}
public void setCapacity(int capacity) {
this.capacity = capacity;
if (energy > capacity) {
energy = capacity;
}
}
public void setMaxTransfer(int maxTransfer) {
setMaxReceive(maxTransfer);
setMaxExtract(maxTransfer);
}
public void setMaxReceive(int maxReceive) {
this.maxReceive = maxReceive;
}
public void setMaxExtract(int maxExtract) {
this.maxExtract = maxExtract;
}
public int getMaxReceive() {
return maxReceive;
}
public int getMaxExtract() {
return maxExtract;
}
/**
* This function is included to allow for server -&gt; client sync. Do not call this externally to the containing Tile Entity, as not all IEnergyHandlers
* are guaranteed to have it.
*
* @param energy
*/
public void setEnergyStored(int energy) {
this.energy = energy;
if (this.energy > capacity) {
this.energy = capacity;
} else if (this.energy < 0) {
this.energy = 0;
}
}
/**
* This function is included to allow the containing tile to directly and efficiently modify the energy contained in the EnergyStorage. Do not rely on this
* externally, as not all IEnergyHandlers are guaranteed to have it.
*
* @param energy
*/
public void modifyEnergyStored(int energy) {
this.energy += energy;
if (this.energy > capacity) {
this.energy = capacity;
} else if (this.energy < 0) {
this.energy = 0;
}
}
/* IEnergyStorage */
@Override
public int receiveEnergy(int maxReceive, boolean simulate) {
int energyReceived = Math.min(capacity - energy, Math.min(this.maxReceive, maxReceive));
if (!simulate) {
energy += energyReceived;
}
return energyReceived;
}
@Override
public int extractEnergy(int maxExtract, boolean simulate) {
int energyExtracted = Math.min(energy, Math.min(this.maxExtract, maxExtract));
if (!simulate) {
energy -= energyExtracted;
}
return energyExtracted;
}
@Override
public int getEnergyStored() {
return energy;
}
@Override
public int getMaxEnergyStored() {
return capacity;
}
}
@@ -1,21 +0,0 @@
package cofh.api.energy;
import net.minecraftforge.common.util.ForgeDirection;
/**
* Implement this interface on TileEntities which should connect to energy transportation blocks. This is intended for blocks which generate energy but do not
* accept it; otherwise just use IEnergyHandler.
* <p>
* Note that {@link IEnergyHandler} is an extension of this.
*
* @author King Lemming
*
*/
public interface IEnergyConnection {
/**
* Returns TRUE if the TileEntity can connect on a given side.
*/
boolean canConnectEnergy(ForgeDirection from);
}
@@ -1,52 +0,0 @@
package cofh.api.energy;
import net.minecraft.item.ItemStack;
/**
* Implement this interface on Item classes that support external manipulation of their internal energy storages.
* <p>
* A reference implementation is provided {@link ItemEnergyContainer}.
*
* @author King Lemming
*
*/
public interface IEnergyContainerItem {
/**
* Adds energy to a container item. Returns the quantity of energy that was accepted. This should always return 0 if the item cannot be externally charged.
*
* @param container
* ItemStack to be charged.
* @param maxReceive
* Maximum amount of energy to be sent into the item.
* @param simulate
* If TRUE, the charge will only be simulated.
* @return Amount of energy that was (or would have been, if simulated) received by the item.
*/
int receiveEnergy(ItemStack container, int maxReceive, boolean simulate);
/**
* Removes energy from a container item. Returns the quantity of energy that was removed. This should always return 0 if the item cannot be externally
* discharged.
*
* @param container
* ItemStack to be discharged.
* @param maxExtract
* Maximum amount of energy to be extracted from the item.
* @param simulate
* If TRUE, the discharge will only be simulated.
* @return Amount of energy that was (or would have been, if simulated) extracted from the item.
*/
int extractEnergy(ItemStack container, int maxExtract, boolean simulate);
/**
* Get the amount of energy currently stored in the container item.
*/
int getEnergyStored(ItemStack container);
/**
* Get the max amount of energy that can be stored in the container item.
*/
int getMaxEnergyStored(ItemStack container);
}
@@ -1,58 +0,0 @@
package cofh.api.energy;
import net.minecraftforge.common.util.ForgeDirection;
/**
* Implement this interface on Tile Entities which should handle energy, generally storing it in one or more internal {@link IEnergyStorage} objects.
* <p>
* A reference implementation is provided {@link TileEnergyHandler}.
*
* @author King Lemming
*
*/
public interface IEnergyHandler extends IEnergyProvider, IEnergyReceiver {
// merely a convenience interface (remove these methods in 1.8; provided here for back-compat via compiler doing things)
/**
* Add energy to an IEnergyReceiver, internal distribution is left entirely to the IEnergyReceiver.
*
* @param from
* Orientation the energy is received from.
* @param maxReceive
* Maximum amount of energy to receive.
* @param simulate
* If TRUE, the charge will only be simulated.
* @return Amount of energy that was (or would have been, if simulated) received.
*/
@Override
int receiveEnergy(ForgeDirection from, int maxReceive, boolean simulate);
/**
* Remove energy from an IEnergyProvider, internal distribution is left entirely to the IEnergyProvider.
*
* @param from
* Orientation the energy is extracted from.
* @param maxExtract
* Maximum amount of energy to extract.
* @param simulate
* If TRUE, the extraction will only be simulated.
* @return Amount of energy that was (or would have been, if simulated) extracted.
*/
@Override
int extractEnergy(ForgeDirection from, int maxExtract, boolean simulate);
/**
* Returns the amount of energy currently stored.
*/
@Override
int getEnergyStored(ForgeDirection from);
/**
* Returns the maximum amount of energy that can be stored.
*/
@Override
int getMaxEnergyStored(ForgeDirection from);
}
@@ -1,38 +0,0 @@
package cofh.api.energy;
import net.minecraftforge.common.util.ForgeDirection;
/**
* Implement this interface on Tile Entities which should provide energy, generally storing it in one or more internal {@link IEnergyStorage} objects.
* <p>
* A reference implementation is provided {@link TileEnergyHandler}.
*
* @author King Lemming
*
*/
public interface IEnergyProvider extends IEnergyConnection {
/**
* Remove energy from an IEnergyProvider, internal distribution is left entirely to the IEnergyProvider.
*
* @param from
* Orientation the energy is extracted from.
* @param maxExtract
* Maximum amount of energy to extract.
* @param simulate
* If TRUE, the extraction will only be simulated.
* @return Amount of energy that was (or would have been, if simulated) extracted.
*/
int extractEnergy(ForgeDirection from, int maxExtract, boolean simulate);
/**
* Returns the amount of energy currently stored.
*/
int getEnergyStored(ForgeDirection from);
/**
* Returns the maximum amount of energy that can be stored.
*/
int getMaxEnergyStored(ForgeDirection from);
}
@@ -1,38 +0,0 @@
package cofh.api.energy;
import net.minecraftforge.common.util.ForgeDirection;
/**
* Implement this interface on Tile Entities which should receive energy, generally storing it in one or more internal {@link IEnergyStorage} objects.
* <p>
* A reference implementation is provided {@link TileEnergyHandler}.
*
* @author King Lemming
*
*/
public interface IEnergyReceiver extends IEnergyConnection {
/**
* Add energy to an IEnergyReceiver, internal distribution is left entirely to the IEnergyReceiver.
*
* @param from
* Orientation the energy is received from.
* @param maxReceive
* Maximum amount of energy to receive.
* @param simulate
* If TRUE, the charge will only be simulated.
* @return Amount of energy that was (or would have been, if simulated) received.
*/
int receiveEnergy(ForgeDirection from, int maxReceive, boolean simulate);
/**
* Returns the amount of energy currently stored.
*/
int getEnergyStored(ForgeDirection from);
/**
* Returns the maximum amount of energy that can be stored.
*/
int getMaxEnergyStored(ForgeDirection from);
}
@@ -1,46 +0,0 @@
package cofh.api.energy;
/**
* An energy storage is the unit of interaction with Energy inventories.<br>
* This is not to be implemented on TileEntities. This is for internal use only.
* <p>
* A reference implementation can be found at {@link EnergyStorage}.
*
* @author King Lemming
*
*/
public interface IEnergyStorage {
/**
* Adds energy to the storage. Returns quantity of energy that was accepted.
*
* @param maxReceive
* Maximum amount of energy to be inserted.
* @param simulate
* If TRUE, the insertion will only be simulated.
* @return Amount of energy that was (or would have been, if simulated) accepted by the storage.
*/
int receiveEnergy(int maxReceive, boolean simulate);
/**
* Removes energy from the storage. Returns quantity of energy that was removed.
*
* @param maxExtract
* Maximum amount of energy to be extracted.
* @param simulate
* If TRUE, the extraction will only be simulated.
* @return Amount of energy that was (or would have been, if simulated) extracted from the storage.
*/
int extractEnergy(int maxExtract, boolean simulate);
/**
* Returns the amount of energy currently stored.
*/
int getEnergyStored();
/**
* Returns the maximum amount of energy that can be stored.
*/
int getMaxEnergyStored();
}
@@ -1,110 +0,0 @@
package cofh.api.energy;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
/**
* Reference implementation of {@link IEnergyContainerItem}. Use/extend this or implement your own.
*
* @author King Lemming
*
*/
public class ItemEnergyContainer extends Item implements IEnergyContainerItem {
protected int capacity;
protected int maxReceive;
protected int maxExtract;
public ItemEnergyContainer() {
}
public ItemEnergyContainer(int capacity) {
this(capacity, capacity, capacity);
}
public ItemEnergyContainer(int capacity, int maxTransfer) {
this(capacity, maxTransfer, maxTransfer);
}
public ItemEnergyContainer(int capacity, int maxReceive, int maxExtract) {
this.capacity = capacity;
this.maxReceive = maxReceive;
this.maxExtract = maxExtract;
}
public ItemEnergyContainer setCapacity(int capacity) {
this.capacity = capacity;
return this;
}
public void setMaxTransfer(int maxTransfer) {
setMaxReceive(maxTransfer);
setMaxExtract(maxTransfer);
}
public void setMaxReceive(int maxReceive) {
this.maxReceive = maxReceive;
}
public void setMaxExtract(int maxExtract) {
this.maxExtract = maxExtract;
}
/* IEnergyContainerItem */
@Override
public int receiveEnergy(ItemStack container, int maxReceive, boolean simulate) {
if (container.stackTagCompound == null) {
container.stackTagCompound = new NBTTagCompound();
}
int energy = container.stackTagCompound.getInteger("Energy");
int energyReceived = Math.min(capacity - energy, Math.min(this.maxReceive, maxReceive));
if (!simulate) {
energy += energyReceived;
container.stackTagCompound.setInteger("Energy", energy);
}
return energyReceived;
}
@Override
public int extractEnergy(ItemStack container, int maxExtract, boolean simulate) {
if (container.stackTagCompound == null || !container.stackTagCompound.hasKey("Energy")) {
return 0;
}
int energy = container.stackTagCompound.getInteger("Energy");
int energyExtracted = Math.min(energy, Math.min(this.maxExtract, maxExtract));
if (!simulate) {
energy -= energyExtracted;
container.stackTagCompound.setInteger("Energy", energy);
}
return energyExtracted;
}
@Override
public int getEnergyStored(ItemStack container) {
if (container.stackTagCompound == null || !container.stackTagCompound.hasKey("Energy")) {
return 0;
}
return container.stackTagCompound.getInteger("Energy");
}
@Override
public int getMaxEnergyStored(ItemStack container) {
return capacity;
}
}
@@ -1,65 +0,0 @@
package cofh.api.energy;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
/**
* Reference implementation of {@link IEnergyHandler}. Use/extend this or implement your own.
*
* @author King Lemming
*
*/
public class TileEnergyHandler extends TileEntity implements IEnergyHandler {
protected EnergyStorage storage = new EnergyStorage(32000);
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
storage.readFromNBT(nbt);
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
storage.writeToNBT(nbt);
}
/* IEnergyConnection */
@Override
public boolean canConnectEnergy(ForgeDirection from) {
return true;
}
/* IEnergyReceiver */
@Override
public int receiveEnergy(ForgeDirection from, int maxReceive, boolean simulate) {
return storage.receiveEnergy(maxReceive, simulate);
}
/* IEnergyProvider */
@Override
public int extractEnergy(ForgeDirection from, int maxExtract, boolean simulate) {
return storage.extractEnergy(maxExtract, simulate);
}
/* IEnergyReceiver and IEnergyProvider */
@Override
public int getEnergyStored(ForgeDirection from) {
return storage.getEnergyStored();
}
@Override
public int getMaxEnergyStored(ForgeDirection from) {
return storage.getMaxEnergyStored();
}
}
@@ -1,10 +0,0 @@
/**
* (C) 2014 Team CoFH / CoFH / Cult of the Full Hub
* http://www.teamcofh.com
*/
@API(apiVersion = CoFHAPIProps.VERSION, owner = "CoFHAPI", provides = "CoFHAPI|energy")
package cofh.api.energy;
import cofh.api.CoFHAPIProps;
import cpw.mods.fml.common.API;
-9
View File
@@ -1,9 +0,0 @@
/**
* (C) 2014 Team CoFH / CoFH / Cult of the Full Hub
* http://www.teamcofh.com
*/
@API(apiVersion = CoFHAPIProps.VERSION, owner = "CoFHLib", provides = "CoFHAPI")
package cofh.api;
import cpw.mods.fml.common.API;
@@ -1,108 +0,0 @@
package thaumcraft.api;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
public class BlockCoordinates implements Comparable
{
public int x;
/** the y coordinate */
public int y;
/** the z coordinate */
public int z;
public BlockCoordinates() {}
public BlockCoordinates(int par1, int par2, int par3)
{
this.x = par1;
this.y = par2;
this.z = par3;
}
public BlockCoordinates(TileEntity tile)
{
this.x = tile.xCoord;
this.y = tile.yCoord;
this.z = tile.zCoord;
}
public BlockCoordinates(BlockCoordinates par1ChunkCoordinates)
{
this.x = par1ChunkCoordinates.x;
this.y = par1ChunkCoordinates.y;
this.z = par1ChunkCoordinates.z;
}
public boolean equals(Object par1Obj)
{
if (!(par1Obj instanceof BlockCoordinates))
{
return false;
}
else
{
BlockCoordinates coordinates = (BlockCoordinates)par1Obj;
return this.x == coordinates.x && this.y == coordinates.y && this.z == coordinates.z ;
}
}
public int hashCode()
{
return this.x + this.y << 8 + this.z << 16;
}
/**
* Compare the coordinate with another coordinate
*/
public int compareWorldCoordinate(BlockCoordinates par1)
{
return this.y == par1.y ? (this.z == par1.z ? this.x - par1.x : this.z - par1.z) : this.y - par1.y;
}
public void set(int par1, int par2, int par3, int d)
{
this.x = par1;
this.y = par2;
this.z = par3;
}
/**
* Returns the squared distance between this coordinates and the coordinates given as argument.
*/
public float getDistanceSquared(int par1, int par2, int par3)
{
float f = (float)(this.x - par1);
float f1 = (float)(this.y - par2);
float f2 = (float)(this.z - par3);
return f * f + f1 * f1 + f2 * f2;
}
/**
* Return the squared distance between this coordinates and the ChunkCoordinates given as argument.
*/
public float getDistanceSquaredToWorldCoordinates(BlockCoordinates par1ChunkCoordinates)
{
return this.getDistanceSquared(par1ChunkCoordinates.x, par1ChunkCoordinates.y, par1ChunkCoordinates.z);
}
public int compareTo(Object par1Obj)
{
return this.compareWorldCoordinate((BlockCoordinates)par1Obj);
}
public void readNBT(NBTTagCompound nbt) {
this.x = nbt.getInteger("b_x");
this.y = nbt.getInteger("b_y");
this.z = nbt.getInteger("b_z");
}
public void writeNBT(NBTTagCompound nbt) {
nbt.setInteger("b_x",x);
nbt.setInteger("b_y",y);
nbt.setInteger("b_z",z);
}
}
@@ -1,27 +0,0 @@
package thaumcraft.api;
import java.util.ArrayList;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
public interface IArchitect {
/**
* Returns a list of blocks that should be highlighted in world.
*/
public ArrayList<BlockCoordinates> getArchitectBlocks(ItemStack stack, World world,
int x, int y, int z, int side, EntityPlayer player);
/**
* which axis should be displayed.
*/
public boolean showAxis(ItemStack stack, World world, EntityPlayer player, int side, EnumAxis axis);
public enum EnumAxis {
X, // east / west
Y, // up / down
Z; // north / south
}
}
-22
View File
@@ -1,22 +0,0 @@
package thaumcraft.api;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
/**
*
* @author Azanor
*
* Equipped head slot items that extend this class will be able to perform most functions that
* goggles of revealing can apart from view nodes which is handled by IRevealer.
*
*/
public interface IGoggles {
/*
* If this method returns true things like block essentia contents will be shown.
*/
public boolean showIngamePopups(ItemStack itemstack, EntityLivingBase player);
}
@@ -1,13 +0,0 @@
package thaumcraft.api;
/**
* @author Azanor
* Items, armor and tools with this interface can receive the Repair enchantment.
* Repairs 1 point of durability every 10 seconds (2 for repair II)
*/
public interface IRepairable {
}
@@ -1,17 +0,0 @@
package thaumcraft.api;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
* @author Azanor
* Items, armor and tools with this interface can receive the Repair enchantment.
* Repairs 1 point of durability every 10 seconds (2 for repair II)
*/
public interface IRepairableExtended extends IRepairable {
public boolean doRepair(ItemStack stack, EntityPlayer player, int enchantlevel);
}
@@ -1,22 +0,0 @@
package thaumcraft.api;
import net.minecraft.item.ItemStack;
/**
*
* @author Azanor
*
* Armor or bauble slot items that implement this interface can provide runic shielding.
* Recharging, hardening, etc. is handled internally by thaumcraft.
*
*/
public interface IRunicArmor {
/**
* returns how much charge this item can provide. This is the base shielding value - any hardening is stored and calculated internally.
*/
public int getRunicCharge(ItemStack itemstack);
}
@@ -1,14 +0,0 @@
package thaumcraft.api;
/**
*
* @author Azanor
*
* Interface used to identify scribing tool items used in research table
*
*/
public interface IScribeTools {
}
@@ -1,20 +0,0 @@
package thaumcraft.api;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import thaumcraft.api.aspects.Aspect;
/**
* @author Azanor
* ItemArmor with this interface will grant a discount to the vis cost of actions the wearer performs with casting wands.
* The amount returned is the percentage by which the cost is discounted. There is a built-int max discount of 50%, but
* individual items really shouldn't have a discount more than 5%
*/
public interface IVisDiscountGear {
int getVisDiscount(ItemStack stack, EntityPlayer player, Aspect aspect);
}
@@ -1,22 +0,0 @@
package thaumcraft.api;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
*
* @author Azanor
*
* Armor, held items or bauble slot items that implement this interface add warp when equipped or held.
*
*/
public interface IWarpingGear {
/**
* returns how much warp this item adds while worn or held.
*/
public int getWarp(ItemStack itemstack, EntityPlayer player);
}
-70
View File
@@ -1,70 +0,0 @@
package thaumcraft.api;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import cpw.mods.fml.common.FMLLog;
/**
* @author Azanor
*
* This is used to gain access to the items in my mod.
* I only give some examples and it will probably still
* require a bit of work for you to get hold of everything you need.
*
*/
public class ItemApi {
public static ItemStack getItem(String itemString, int meta) {
ItemStack item = null;
try {
String itemClass = "thaumcraft.common.config.ConfigItems";
Object obj = Class.forName(itemClass).getField(itemString).get(null);
if (obj instanceof Item) {
item = new ItemStack((Item) obj,1,meta);
} else if (obj instanceof ItemStack) {
item = (ItemStack) obj;
}
} catch (Exception ex) {
FMLLog.warning("[Thaumcraft] Could not retrieve item identified by: " + itemString);
}
return item;
}
public static ItemStack getBlock(String itemString, int meta) {
ItemStack item = null;
try {
String itemClass = "thaumcraft.common.config.ConfigBlocks";
Object obj = Class.forName(itemClass).getField(itemString).get(null);
if (obj instanceof Block) {
item = new ItemStack((Block) obj,1,meta);
} else if (obj instanceof ItemStack) {
item = (ItemStack) obj;
}
} catch (Exception ex) {
FMLLog.warning("[Thaumcraft] Could not retrieve block identified by: " + itemString);
}
return item;
}
/**
*
* Some examples
*
* Casting Wands:
* itemWandCasting
*
* Resources:
* itemEssence, itemWispEssence, itemResource, itemShard, itemNugget,
* itemNuggetChicken, itemNuggetBeef, itemNuggetPork, itemTripleMeatTreat
*
* Research:
* itemResearchNotes, itemInkwell, itemThaumonomicon
*
*/
}
@@ -1,21 +0,0 @@
package thaumcraft.api;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
public class ItemRunic extends Item implements IRunicArmor {
int charge;
public ItemRunic (int charge)
{
super();
this.charge = charge;
}
@Override
public int getRunicCharge(ItemStack itemstack) {
return charge;
}
}
@@ -1,574 +0,0 @@
package thaumcraft.api;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import net.minecraft.block.Block;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.Item.ToolMaterial;
import net.minecraft.item.ItemArmor.ArmorMaterial;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.EnumHelper;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
import thaumcraft.api.crafting.CrucibleRecipe;
import thaumcraft.api.crafting.InfusionEnchantmentRecipe;
import thaumcraft.api.crafting.InfusionRecipe;
import thaumcraft.api.crafting.ShapedArcaneRecipe;
import thaumcraft.api.crafting.ShapelessArcaneRecipe;
import thaumcraft.api.internal.DummyInternalMethodHandler;
import thaumcraft.api.internal.IInternalMethodHandler;
import thaumcraft.api.internal.WeightedRandomLoot;
import thaumcraft.api.research.IScanEventHandler;
import thaumcraft.api.research.ResearchCategories;
import thaumcraft.api.research.ResearchCategoryList;
import thaumcraft.api.research.ResearchItem;
import thaumcraft.api.research.ResearchPage;
/**
* @author Azanor
*
*
* IMPORTANT: If you are adding your own aspects to items it is a good idea to do it AFTER Thaumcraft adds its aspects, otherwise odd things may happen.
*
*/
public class ThaumcraftApi {
//Materials
public static ToolMaterial toolMatThaumium = EnumHelper.addToolMaterial("THAUMIUM", 3, 400, 7F, 2, 22);
public static ToolMaterial toolMatVoid = EnumHelper.addToolMaterial("VOID", 4, 150, 8F, 3, 10);
public static ToolMaterial toolMatElemental = EnumHelper.addToolMaterial("THAUMIUM_ELEMENTAL", 3, 1500, 10F, 3, 18);
public static ArmorMaterial armorMatThaumium = EnumHelper.addArmorMaterial("THAUMIUM", 25, new int[] { 2, 6, 5, 2 }, 25);
public static ArmorMaterial armorMatSpecial = EnumHelper.addArmorMaterial("SPECIAL", 25, new int[] { 1, 3, 2, 1 }, 25);
public static ArmorMaterial armorMatThaumiumFortress = EnumHelper.addArmorMaterial("FORTRESS", 40, new int[] { 3, 7, 6, 3 }, 25);
public static ArmorMaterial armorMatVoid = EnumHelper.addArmorMaterial("VOID", 10, new int[] { 3, 7, 6, 3 }, 10);
public static ArmorMaterial armorMatVoidFortress = EnumHelper.addArmorMaterial("VOIDFORTRESS", 18, new int[] { 4, 8, 7, 4 }, 10);
//Enchantment references
public static int enchantFrugal;
public static int enchantPotency;
public static int enchantWandFortune;
public static int enchantHaste;
public static int enchantRepair;
//Miscellaneous
/**
* Portable Hole Block-id Blacklist.
* Simply add the block-id's of blocks you don't want the portable hole to go through.
*/
public static ArrayList<Block> portableHoleBlackList = new ArrayList<Block>();
//Internal (Do not alter this unless you like pretty explosions)
//Calling methods from this will only work properly once Thaumcraft is past the FMLPreInitializationEvent phase.
public static IInternalMethodHandler internalMethods = new DummyInternalMethodHandler();
//RESEARCH/////////////////////////////////////////
public static ArrayList<IScanEventHandler> scanEventhandlers = new ArrayList<IScanEventHandler>();
public static ArrayList<EntityTags> scanEntities = new ArrayList<EntityTags>();
public static class EntityTagsNBT {
public EntityTagsNBT(String name, Object value) {
this.name = name;
this.value = value;
}
public String name;
public Object value;
}
public static class EntityTags {
public EntityTags(String entityName, AspectList aspects, EntityTagsNBT... nbts) {
this.entityName = entityName;
this.nbts = nbts;
this.aspects = aspects;
}
public String entityName;
public EntityTagsNBT[] nbts;
public AspectList aspects;
}
/**
* not really working atm, so ignore it for now
* @param scanEventHandler
*/
public static void registerScanEventhandler(IScanEventHandler scanEventHandler) {
scanEventhandlers.add(scanEventHandler);
}
/**
* This is used to add aspects to entities which you can then scan using a thaumometer.
* Also used to calculate vis drops from mobs.
* @param entityName
* @param aspects
* @param nbt you can specify certain nbt keys and their values
* to differentiate between mobs. <br>For example the normal and wither skeleton:
* <br>ThaumcraftApi.registerEntityTag("Skeleton", (new AspectList()).add(Aspect.DEATH, 5));
* <br>ThaumcraftApi.registerEntityTag("Skeleton", (new AspectList()).add(Aspect.DEATH, 8), new NBTTagByte("SkeletonType",(byte) 1));
*/
public static void registerEntityTag(String entityName, AspectList aspects, EntityTagsNBT... nbt ) {
scanEntities.add(new EntityTags(entityName,aspects,nbt));
}
//RECIPES/////////////////////////////////////////
private static ArrayList craftingRecipes = new ArrayList();
private static HashMap<Object,ItemStack> smeltingBonus = new HashMap<Object,ItemStack>();
/**
* This method is used to determine what bonus items are generated when the infernal furnace smelts items
* @param in The input of the smelting operation. e.g. new ItemStack(Block.oreGold)
* @param out The bonus item that can be produced from the smelting operation e.g. new ItemStack(nuggetGold,0,0).
* Stacksize should be 0 unless you want to guarantee that at least 1 item is always produced.
*/
public static void addSmeltingBonus(ItemStack in, ItemStack out) {
smeltingBonus.put(
Arrays.asList(in.getItem(),in.getItemDamage()),
new ItemStack(out.getItem(),0,out.getItemDamage()));
}
/**
* This method is used to determine what bonus items are generated when the infernal furnace smelts items
* @param in The ore dictionary input of the smelting operation. e.g. "oreGold"
* @param out The bonus item that can be produced from the smelting operation e.g. new ItemStack(nuggetGold,0,0).
* Stacksize should be 0 unless you want to guarantee that at least 1 item is always produced.
*/
public static void addSmeltingBonus(String in, ItemStack out) {
smeltingBonus.put( in, new ItemStack(out.getItem(),0,out.getItemDamage()));
}
/**
* Returns the bonus item produced from a smelting operation in the infernal furnace
* @param in The input of the smelting operation. e.g. new ItemStack(oreGold)
* @return the The bonus item that can be produced
*/
public static ItemStack getSmeltingBonus(ItemStack in) {
ItemStack out = smeltingBonus.get(Arrays.asList(in.getItem(),in.getItemDamage()));
if (out==null) {
out = smeltingBonus.get(Arrays.asList(in.getItem(),OreDictionary.WILDCARD_VALUE));
}
if (out==null) {
String od = OreDictionary.getOreName( OreDictionary.getOreID(in));
out = smeltingBonus.get(od);
}
return out;
}
public static List getCraftingRecipes() {
return craftingRecipes;
}
/**
* @param research the research key required for this recipe to work. Leave blank if it will work without research
* @param result the recipe output
* @param aspects the vis cost per aspect.
* @param recipe The recipe. Format is exactly the same as vanilla recipes. Input itemstacks are NBT sensitive.
*/
public static ShapedArcaneRecipe addArcaneCraftingRecipe(String research, ItemStack result, AspectList aspects, Object ... recipe)
{
ShapedArcaneRecipe r= new ShapedArcaneRecipe(research, result, aspects, recipe);
craftingRecipes.add(r);
return r;
}
/**
* @param research the research key required for this recipe to work. Leave blank if it will work without research
* @param result the recipe output
* @param aspects the vis cost per aspect
* @param recipe The recipe. Format is exactly the same as vanilla shapeless recipes. Input itemstacks are NBT sensitive.
*/
public static ShapelessArcaneRecipe addShapelessArcaneCraftingRecipe(String research, ItemStack result, AspectList aspects, Object ... recipe)
{
ShapelessArcaneRecipe r = new ShapelessArcaneRecipe(research, result, aspects, recipe);
craftingRecipes.add(r);
return r;
}
/**
* @param research the research key required for this recipe to work. Leave blank if it will work without research
* @param result the recipe output. It can either be an itemstack or an nbt compound tag that will be added to the central item
* @param instability a number that represents the N in 1000 chance for the infusion altar to spawn an
* instability effect each second while the crafting is in progress
* @param aspects the essentia cost per aspect.
* @param aspects input the central item to be infused
* @param recipe An array of items required to craft this. Input itemstacks are NBT sensitive.
* Infusion crafting components are automatically "fuzzy" and the oredict will be checked for possible matches.
*
*/
public static InfusionRecipe addInfusionCraftingRecipe(String research, Object result, int instability, AspectList aspects, ItemStack input,ItemStack[] recipe)
{
if (!(result instanceof ItemStack || result instanceof Object[])) return null;
InfusionRecipe r= new InfusionRecipe(research, result, instability, aspects, input, recipe);
craftingRecipes.add(r);
return r;
}
/**
* @param research the research key required for this recipe to work. Leave blank if it will work without research
* @param enchantment the enchantment that will be applied to the item
* @param instability a number that represents the N in 1000 chance for the infusion altar to spawn an
* instability effect each second while the crafting is in progress
* @param aspects the essentia cost per aspect.
* @param recipe An array of items required to craft this. Input itemstacks are NBT sensitive.
* Infusion crafting components are automatically "fuzzy" and the oredict will be checked for possible matches.
*
*/
public static InfusionEnchantmentRecipe addInfusionEnchantmentRecipe(String research, Enchantment enchantment, int instability, AspectList aspects, ItemStack[] recipe)
{
InfusionEnchantmentRecipe r= new InfusionEnchantmentRecipe(research, enchantment, instability, aspects, recipe);
craftingRecipes.add(r);
return r;
}
/**
* @param stack the recipe result
* @return the recipe
*/
public static InfusionRecipe getInfusionRecipe(ItemStack res) {
for (Object r:getCraftingRecipes()) {
if (r instanceof InfusionRecipe) {
if (((InfusionRecipe)r).getRecipeOutput() instanceof ItemStack) {
if (((ItemStack) ((InfusionRecipe)r).getRecipeOutput()).isItemEqual(res))
return (InfusionRecipe)r;
}
}
}
return null;
}
/**
* @param key the research key required for this recipe to work.
* @param result the output result
* @param catalyst an itemstack of the catalyst or a string if it is an ore dictionary item
* @param cost the vis cost
* @param tags the aspects required to craft this
*/
public static CrucibleRecipe addCrucibleRecipe(String key, ItemStack result, Object catalyst, AspectList tags) {
CrucibleRecipe rc = new CrucibleRecipe(key, result, catalyst, tags);
getCraftingRecipes().add(rc);
return rc;
}
/**
* @param stack the recipe result
* @return the recipe
*/
public static CrucibleRecipe getCrucibleRecipe(ItemStack stack) {
for (Object r:getCraftingRecipes()) {
if (r instanceof CrucibleRecipe) {
if (((CrucibleRecipe)r).getRecipeOutput().isItemEqual(stack))
return (CrucibleRecipe)r;
}
}
return null;
}
/**
* @param hash the unique recipe code
* @return the recipe
*/
public static CrucibleRecipe getCrucibleRecipeFromHash(int hash) {
for (Object r:getCraftingRecipes()) {
if (r instanceof CrucibleRecipe) {
if (((CrucibleRecipe)r).hash==hash)
return (CrucibleRecipe)r;
}
}
return null;
}
/**
* Used by the thaumonomicon drilldown feature.
* @param stack the item
* @return the thaumcraft recipe key that produces that item.
*/
private static HashMap<int[],Object[]> keyCache = new HashMap<int[],Object[]>();
public static Object[] getCraftingRecipeKey(EntityPlayer player, ItemStack stack) {
int[] key = new int[] {Item.getIdFromItem(stack.getItem()),stack.getItemDamage()};
if (keyCache.containsKey(key)) {
if (keyCache.get(key)==null) return null;
if (ThaumcraftApiHelper.isResearchComplete(player.getCommandSenderName(), (String)(keyCache.get(key))[0]))
return keyCache.get(key);
else
return null;
}
for (ResearchCategoryList rcl:ResearchCategories.researchCategories.values()) {
for (ResearchItem ri:rcl.research.values()) {
if (ri.getPages()==null) continue;
for (int a=0;a<ri.getPages().length;a++) {
ResearchPage page = ri.getPages()[a];
if (page.recipe!=null && page.recipe instanceof CrucibleRecipe[]) {
CrucibleRecipe[] crs = (CrucibleRecipe[]) page.recipe;
for (CrucibleRecipe cr:crs) {
if (cr.getRecipeOutput().isItemEqual(stack)) {
keyCache.put(key,new Object[] {ri.key,a});
if (ThaumcraftApiHelper.isResearchComplete(player.getCommandSenderName(), ri.key))
return new Object[] {ri.key,a};
}
}
} else
if (page.recipeOutput!=null && stack !=null && page.recipeOutput.isItemEqual(stack)) {
keyCache.put(key,new Object[] {ri.key,a});
if (ThaumcraftApiHelper.isResearchComplete(player.getCommandSenderName(), ri.key))
return new Object[] {ri.key,a};
else
return null;
}
}
}
}
keyCache.put(key,null);
return null;
}
//ASPECTS////////////////////////////////////////
public static ConcurrentHashMap<List,AspectList> objectTags = new ConcurrentHashMap<List,AspectList>();
public static ConcurrentHashMap<List,int[]> groupedObjectTags = new ConcurrentHashMap<List,int[]>();
/**
* Checks to see if the passed item/block already has aspects associated with it.
* @param id
* @param meta
* @return
*/
public static boolean exists(Item item, int meta) {
AspectList tmp = ThaumcraftApi.objectTags.get(Arrays.asList(item,meta));
if (tmp==null) {
tmp = ThaumcraftApi.objectTags.get(Arrays.asList(item,OreDictionary.WILDCARD_VALUE));
if (meta==OreDictionary.WILDCARD_VALUE && tmp==null) {
int index=0;
do {
tmp = ThaumcraftApi.objectTags.get(Arrays.asList(item,index));
index++;
} while (index<16 && tmp==null);
}
if (tmp==null) return false;
}
return true;
}
/**
* Used to assign apsects to the given item/block. Here is an example of the declaration for cobblestone:<p>
* <i>ThaumcraftApi.registerObjectTag(new ItemStack(Blocks.cobblestone), (new AspectList()).add(Aspect.ENTROPY, 1).add(Aspect.EARTH, 1));</i>
* @param item the item passed. Pass OreDictionary.WILDCARD_VALUE if all damage values of this item/block should have the same aspects
* @param aspects A ObjectTags object of the associated aspects
*/
public static void registerObjectTag(ItemStack item, AspectList aspects) {
if (aspects==null) aspects=new AspectList();
try {
objectTags.put(Arrays.asList(item.getItem(),item.getItemDamage()), aspects);
} catch (Exception e) {}
}
/**
* Used to assign apsects to the given item/block. Here is an example of the declaration for cobblestone:<p>
* <i>ThaumcraftApi.registerObjectTag(new ItemStack(Blocks.cobblestone), new int[]{0,1}, (new AspectList()).add(Aspect.ENTROPY, 1).add(Aspect.EARTH, 1));</i>
* @param item
* @param meta A range of meta values if you wish to lump several item meta's together as being the "same" item (i.e. stair orientations)
* @param aspects A ObjectTags object of the associated aspects
*/
public static void registerObjectTag(ItemStack item, int[] meta, AspectList aspects) {
if (aspects==null) aspects=new AspectList();
try {
objectTags.put(Arrays.asList(item.getItem(),meta[0]), aspects);
for (int m:meta) {
groupedObjectTags.put(Arrays.asList(item.getItem(),m), meta);
}
} catch (Exception e) {}
}
/**
* Used to assign apsects to the given ore dictionary item.
* @param oreDict the ore dictionary name
* @param aspects A ObjectTags object of the associated aspects
*/
public static void registerObjectTag(String oreDict, AspectList aspects) {
if (aspects==null) aspects=new AspectList();
ArrayList<ItemStack> ores = OreDictionary.getOres(oreDict);
if (ores!=null && ores.size()>0) {
for (ItemStack ore:ores) {
try {
objectTags.put(Arrays.asList(ore.getItem(), ore.getItemDamage()), aspects);
} catch (Exception e) {}
}
}
}
/**
* Used to assign aspects to the given item/block.
* Attempts to automatically generate aspect tags by checking registered recipes.
* Here is an example of the declaration for pistons:<p>
* <i>ThaumcraftApi.registerComplexObjectTag(new ItemStack(Blocks.cobblestone), (new AspectList()).add(Aspect.MECHANISM, 2).add(Aspect.MOTION, 4));</i>
* IMPORTANT - this should only be used if you are not happy with the default aspects the object would be assigned.
* @param item, pass OreDictionary.WILDCARD_VALUE to meta if all damage values of this item/block should have the same aspects
* @param aspects A ObjectTags object of the associated aspects
*/
public static void registerComplexObjectTag(ItemStack item, AspectList aspects ) {
if (!exists(item.getItem(),item.getItemDamage())) {
AspectList tmp = ThaumcraftApiHelper.generateTags(item.getItem(), item.getItemDamage());
if (tmp != null && tmp.size()>0) {
for(Aspect tag:tmp.getAspects()) {
aspects.add(tag, tmp.getAmount(tag));
}
}
registerObjectTag(item,aspects);
} else {
AspectList tmp = ThaumcraftApiHelper.getObjectAspects(item);
for(Aspect tag:aspects.getAspects()) {
tmp.merge(tag, tmp.getAmount(tag));
}
registerObjectTag(item,tmp);
}
}
//WARP ///////////////////////////////////////////////////////////////////////////////////////
private static HashMap<Object,Integer> warpMap = new HashMap<Object,Integer>();
/**
* This method is used to determine how much warp is gained if the item is crafted. The warp
* added is "sticky" warp
* @param craftresult The item crafted
* @param amount how much warp is gained
*/
public static void addWarpToItem(ItemStack craftresult, int amount) {
warpMap.put(Arrays.asList(craftresult.getItem(),craftresult.getItemDamage()),amount);
}
/**
* This method is used to determine how much permanent warp is gained if the research is completed
* @param in The item crafted
* @param amount how much warp is gained
*/
public static void addWarpToResearch(String research, int amount) {
warpMap.put(research, amount);
}
/**
* Returns how much warp is gained from the item or research passed in
* @param in itemstack or string
* @return how much warp it will give
*/
public static int getWarp(Object in) {
if (in==null) return 0;
if (in instanceof ItemStack && warpMap.containsKey(Arrays.asList(((ItemStack)in).getItem(),((ItemStack)in).getItemDamage()))) {
return warpMap.get(Arrays.asList(((ItemStack)in).getItem(),((ItemStack)in).getItemDamage()));
} else
if (in instanceof String && warpMap.containsKey((String)in)) {
return warpMap.get((String)in);
}
return 0;
}
//LOOT BAGS //////////////////////////////////////////////////////////////////////////////////////////
/**
* Used to add possible loot to treasure bags. As a reference, the weight of gold coins are 2000
* and a diamond is 50.
* The weights are the same for all loot bag types - the only difference is how many items the bag
* contains.
* @param item
* @param weight
* @param bagTypes array of which type of bag to add this loot to. Multiple types can be specified
* 0 = common, 1 = uncommon, 2 = rare
*/
public static void addLootBagItem(ItemStack item, int weight, int... bagTypes) {
if (bagTypes==null || bagTypes.length==0)
WeightedRandomLoot.lootBagCommon.add(new WeightedRandomLoot(item,weight));
else {
for (int rarity:bagTypes) {
switch(rarity) {
case 0: WeightedRandomLoot.lootBagCommon.add(new WeightedRandomLoot(item,weight)); break;
case 1: WeightedRandomLoot.lootBagUncommon.add(new WeightedRandomLoot(item,weight)); break;
case 2: WeightedRandomLoot.lootBagRare.add(new WeightedRandomLoot(item,weight)); break;
}
}
}
}
//CROPS //////////////////////////////////////////////////////////////////////////////////////////
/**
* To define mod crops you need to use FMLInterModComms in your @Mod.Init method.
* There are two 'types' of crops you can add. Standard crops and clickable crops.
*
* Standard crops work like normal vanilla crops - they grow until a certain metadata
* value is reached and you harvest them by destroying the block and collecting the blocks.
* You need to create and ItemStack that tells the golem what block id and metadata represents
* the crop when fully grown. Sending a metadata of [OreDictionary.WILDCARD_VALUE] will mean the metadata won't get
* checked.
* Example for vanilla wheat:
* FMLInterModComms.sendMessage("Thaumcraft", "harvestStandardCrop", new ItemStack(Block.crops,1,7));
*
* Clickable crops are crops that you right click to gather their bounty instead of destroying them.
* As for standard crops, you need to create and ItemStack that tells the golem what block id
* and metadata represents the crop when fully grown. The golem will trigger the blocks onBlockActivated method.
* Sending a metadata of [OreDictionary.WILDCARD_VALUE] will mean the metadata won't get checked.
* Example (this will technically do nothing since clicking wheat does nothing, but you get the idea):
* FMLInterModComms.sendMessage("Thaumcraft", "harvestClickableCrop", new ItemStack(Block.crops,1,7));
*
* Stacked crops (like reeds) are crops that you wish the bottom block should remain after harvesting.
* As for standard crops, you need to create and ItemStack that tells the golem what block id
* and metadata represents the crop when fully grown. Sending a metadata of [OreDictionary.WILDCARD_VALUE] will mean the actualy md won't get
* checked. If it has the order upgrade it will only harvest if the crop is more than one block high.
* Example:
* FMLInterModComms.sendMessage("Thaumcraft", "harvestStackedCrop", new ItemStack(Block.reed,1,7));
*/
//NATIVE CLUSTERS //////////////////////////////////////////////////////////////////////////////////
/**
* You can define certain ores that will have a chance to produce native clusters via FMLInterModComms
* in your @Mod.Init method using the "nativeCluster" string message.
* The format should be:
* "[ore item/block id],[ore item/block metadata],[cluster item/block id],[cluster item/block metadata],[chance modifier float]"
*
* NOTE: The chance modifier is a multiplier applied to the default chance for that cluster to be produced (default 27.5% for a pickaxe of the core)
*
* Example for vanilla iron ore to produce one of my own native iron clusters (assuming default id's) at double the default chance:
* FMLInterModComms.sendMessage("Thaumcraft", "nativeCluster","15,0,25016,16,2.0");
*/
//LAMP OF GROWTH BLACKLIST ///////////////////////////////////////////////////////////////////////////
/**
* You can blacklist crops that should not be effected by the Lamp of Growth via FMLInterModComms
* in your @Mod.Init method using the "lampBlacklist" itemstack message.
* Sending a metadata of [OreDictionary.WILDCARD_VALUE] will mean the metadata won't get checked.
* Example for vanilla wheat:
* FMLInterModComms.sendMessage("Thaumcraft", "lampBlacklist", new ItemStack(Block.crops,1,OreDictionary.WILDCARD_VALUE));
*/
//DIMENSION BLACKLIST ///////////////////////////////////////////////////////////////////////////
/**
* You can blacklist a dimension to not spawn certain thaumcraft features
* in your @Mod.Init method using the "dimensionBlacklist" string message in the format "[dimension]:[level]"
* The level values are as follows:
* [0] stop all tc spawning and generation
* [1] allow ore and node generation (and node special features)
* [2] allow mob spawning
* [3] allow ore and node gen + mob spawning (and node special features)
* Example:
* FMLInterModComms.sendMessage("Thaumcraft", "dimensionBlacklist", "15:1");
*/
//BIOME BLACKLIST ///////////////////////////////////////////////////////////////////////////
/**
* You can blacklist a biome to not spawn certain thaumcraft features
* in your @Mod.Init method using the "biomeBlacklist" string message in the format "[biome id]:[level]"
* The level values are as follows:
* [0] stop all tc spawning and generation
* [1] allow ore and node generation (and node special features)
* [2] allow mob spawning
* [3] allow ore and node gen + mob spawning (and node special features)
* Example:
* FMLInterModComms.sendMessage("Thaumcraft", "biomeBlacklist", "180:2");
*/
}
@@ -1,467 +0,0 @@
package thaumcraft.api;
import java.util.HashMap;
import java.util.Iterator;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
import thaumcraft.api.aspects.IEssentiaTransport;
public class ThaumcraftApiHelper {
public static AspectList cullTags(AspectList temp) {
AspectList temp2 = new AspectList();
for (Aspect tag:temp.getAspects()) {
if (tag!=null)
temp2.add(tag, temp.getAmount(tag));
}
while (temp2!=null && temp2.size()>6) {
Aspect lowest = null;
float low = Short.MAX_VALUE;
for (Aspect tag:temp2.getAspects()) {
if (tag==null) continue;
float ta=temp2.getAmount(tag);
if (tag.isPrimal()) {
ta *= .9f;
} else {
if (!tag.getComponents()[0].isPrimal()) {
ta *= 1.1f;
if (!tag.getComponents()[0].getComponents()[0].isPrimal()) {
ta *= 1.05f;
}
if (!tag.getComponents()[0].getComponents()[1].isPrimal()) {
ta *= 1.05f;
}
}
if (!tag.getComponents()[1].isPrimal()) {
ta *= 1.1f;
if (!tag.getComponents()[1].getComponents()[0].isPrimal()) {
ta *= 1.05f;
}
if (!tag.getComponents()[1].getComponents()[1].isPrimal()) {
ta *= 1.05f;
}
}
}
if (ta<low) {
low = ta;
lowest = tag;
}
}
temp2.aspects.remove(lowest);
}
return temp2;
}
public static boolean areItemsEqual(ItemStack s1,ItemStack s2)
{
if (s1.isItemStackDamageable() && s2.isItemStackDamageable())
{
return s1.getItem() == s2.getItem();
} else
return s1.getItem() == s2.getItem() && s1.getItemDamage() == s2.getItemDamage();
}
public static boolean isResearchComplete(String username, String researchkey) {
return ThaumcraftApi.internalMethods.isResearchComplete(username, researchkey);
}
public static boolean hasDiscoveredAspect(String username, Aspect aspect) {
return ThaumcraftApi.internalMethods.hasDiscoveredAspect(username, aspect);
}
public static AspectList getDiscoveredAspects(String username) {
return ThaumcraftApi.internalMethods.getDiscoveredAspects(username);
}
public static ItemStack getStackInRowAndColumn(Object instance, int row, int column) {
return ThaumcraftApi.internalMethods.getStackInRowAndColumn(instance, row, column);
}
public static AspectList getObjectAspects(ItemStack is) {
return ThaumcraftApi.internalMethods.getObjectAspects(is);
}
public static AspectList getBonusObjectTags(ItemStack is,AspectList ot) {
return ThaumcraftApi.internalMethods.getBonusObjectTags(is, ot);
}
public static AspectList generateTags(Item item, int meta) {
return ThaumcraftApi.internalMethods.generateTags(item, meta);
}
public static boolean containsMatch(boolean strict, ItemStack[] inputs, ItemStack... targets)
{
for (ItemStack input : inputs)
{
for (ItemStack target : targets)
{
if (itemMatches(target, input, strict))
{
return true;
}
}
}
return false;
}
public static boolean areItemStackTagsEqualForCrafting(ItemStack slotItem,ItemStack recipeItem)
{
if (recipeItem == null || slotItem == null) return false;
if (recipeItem.stackTagCompound!=null && slotItem.stackTagCompound==null ) return false;
if (recipeItem.stackTagCompound==null ) return true;
Iterator iterator = recipeItem.stackTagCompound.func_150296_c().iterator();
while (iterator.hasNext())
{
String s = (String)iterator.next();
if (slotItem.stackTagCompound.hasKey(s)) {
if (!slotItem.stackTagCompound.getTag(s).toString().equals(
recipeItem.stackTagCompound.getTag(s).toString())) {
return false;
}
} else {
return false;
}
}
return true;
}
public static boolean itemMatches(ItemStack target, ItemStack input, boolean strict)
{
if (input == null && target != null || input != null && target == null)
{
return false;
}
return (target.getItem() == input.getItem() &&
((target.getItemDamage() == OreDictionary.WILDCARD_VALUE && !strict) || target.getItemDamage() == input.getItemDamage()));
}
public static TileEntity getConnectableTile(World world, int x, int y, int z, ForgeDirection face) {
TileEntity te = world.getTileEntity(x+face.offsetX, y+face.offsetY, z+face.offsetZ);
if (te instanceof IEssentiaTransport && ((IEssentiaTransport)te).isConnectable(face.getOpposite()))
return te;
else
return null;
}
public static TileEntity getConnectableTile(IBlockAccess world, int x, int y, int z, ForgeDirection face) {
TileEntity te = world.getTileEntity(x+face.offsetX, y+face.offsetY, z+face.offsetZ);
if (te instanceof IEssentiaTransport && ((IEssentiaTransport)te).isConnectable(face.getOpposite()))
return te;
else
return null;
}
private static HashMap<Integer, AspectList> allAspects= new HashMap<Integer, AspectList>();
private static HashMap<Integer, AspectList> allCompoundAspects= new HashMap<Integer, AspectList>();
public static AspectList getAllAspects(int amount) {
if (allAspects.get(amount)==null) {
AspectList al = new AspectList();
for (Aspect aspect:Aspect.aspects.values()) {
al.add(aspect, amount);
}
allAspects.put(amount, al);
}
return allAspects.get(amount);
}
public static AspectList getAllCompoundAspects(int amount) {
if (allCompoundAspects.get(amount)==null) {
AspectList al = new AspectList();
for (Aspect aspect:Aspect.getCompoundAspects()) {
al.add(aspect, amount);
}
allCompoundAspects.put(amount, al);
}
return allCompoundAspects.get(amount);
}
/**
* Use to subtract vis from a wand for most operations
* Wands store vis differently so "real" vis costs need to be multiplied by 100 before calling this method
* @param wand the wand itemstack
* @param player the player using the wand
* @param cost the cost of the operation.
* @param doit actually subtract the vis from the wand if true - if false just simulate the result
* @param crafting is this a crafting operation or not - if
* false then things like frugal and potency will apply to the costs
* @return was the vis successfully subtracted
*/
public static boolean consumeVisFromWand(ItemStack wand, EntityPlayer player,
AspectList cost, boolean doit, boolean crafting) {
return ThaumcraftApi.internalMethods.consumeVisFromWand(wand, player, cost, doit, crafting);
}
/**
* Subtract vis for use by a crafting mechanic. Costs are calculated slightly
* differently and things like the frugal enchant is ignored
* Must NOT be multiplied by 100 - send the actual vis cost
* @param wand the wand itemstack
* @param player the player using the wand
* @param cost the cost of the operation.
* @param doit actually subtract the vis from the wand if true - if false just simulate the result
* @return was the vis successfully subtracted
*/
public static boolean consumeVisFromWandCrafting(ItemStack wand, EntityPlayer player,
AspectList cost, boolean doit) {
return ThaumcraftApi.internalMethods.consumeVisFromWandCrafting(wand, player, cost, doit);
}
/**
* Subtract vis from a wand the player is carrying. Works like consumeVisFromWand in that actual vis
* costs should be multiplied by 100. The costs are handled like crafting however and things like
* frugal don't effect them
* @param player the player using the wand
* @param cost the cost of the operation.
* @return was the vis successfully subtracted
*/
public static boolean consumeVisFromInventory(EntityPlayer player, AspectList cost) {
return ThaumcraftApi.internalMethods.consumeVisFromInventory(player, cost);
}
/**
* This adds permanents or temporary warp to a player. It will automatically be synced clientside
* @param player the player using the wand
* @param amount how much warp to add. Negative amounts are only valid for temporary warp
* @param temporary add temporary warp instead of permanent
*/
public static void addWarpToPlayer(EntityPlayer player, int amount, boolean temporary) {
ThaumcraftApi.internalMethods.addWarpToPlayer(player, amount, temporary);
}
/**
* This "sticky" warp to a player. Sticky warp is permanent warp that can be removed.
* It will automatically be synced clientside
* @param player the player using the wand
* @param amount how much warp to add. Can have negative amounts.
*/
public static void addStickyWarpToPlayer(EntityPlayer player, int amount) {
ThaumcraftApi.internalMethods.addStickyWarpToPlayer(player, amount);
}
public static MovingObjectPosition rayTraceIgnoringSource(World world, Vec3 v1, Vec3 v2,
boolean bool1, boolean bool2, boolean bool3)
{
if (!Double.isNaN(v1.xCoord) && !Double.isNaN(v1.yCoord) && !Double.isNaN(v1.zCoord))
{
if (!Double.isNaN(v2.xCoord) && !Double.isNaN(v2.yCoord) && !Double.isNaN(v2.zCoord))
{
int i = MathHelper.floor_double(v2.xCoord);
int j = MathHelper.floor_double(v2.yCoord);
int k = MathHelper.floor_double(v2.zCoord);
int l = MathHelper.floor_double(v1.xCoord);
int i1 = MathHelper.floor_double(v1.yCoord);
int j1 = MathHelper.floor_double(v1.zCoord);
Block block = world.getBlock(l, i1, j1);
int k1 = world.getBlockMetadata(l, i1, j1);
MovingObjectPosition movingobjectposition2 = null;
k1 = 200;
while (k1-- >= 0)
{
if (Double.isNaN(v1.xCoord) || Double.isNaN(v1.yCoord) || Double.isNaN(v1.zCoord))
{
return null;
}
if (l == i && i1 == j && j1 == k)
{
continue;
}
boolean flag6 = true;
boolean flag3 = true;
boolean flag4 = true;
double d0 = 999.0D;
double d1 = 999.0D;
double d2 = 999.0D;
if (i > l)
{
d0 = (double)l + 1.0D;
}
else if (i < l)
{
d0 = (double)l + 0.0D;
}
else
{
flag6 = false;
}
if (j > i1)
{
d1 = (double)i1 + 1.0D;
}
else if (j < i1)
{
d1 = (double)i1 + 0.0D;
}
else
{
flag3 = false;
}
if (k > j1)
{
d2 = (double)j1 + 1.0D;
}
else if (k < j1)
{
d2 = (double)j1 + 0.0D;
}
else
{
flag4 = false;
}
double d3 = 999.0D;
double d4 = 999.0D;
double d5 = 999.0D;
double d6 = v2.xCoord - v1.xCoord;
double d7 = v2.yCoord - v1.yCoord;
double d8 = v2.zCoord - v1.zCoord;
if (flag6)
{
d3 = (d0 - v1.xCoord) / d6;
}
if (flag3)
{
d4 = (d1 - v1.yCoord) / d7;
}
if (flag4)
{
d5 = (d2 - v1.zCoord) / d8;
}
boolean flag5 = false;
byte b0;
if (d3 < d4 && d3 < d5)
{
if (i > l)
{
b0 = 4;
}
else
{
b0 = 5;
}
v1.xCoord = d0;
v1.yCoord += d7 * d3;
v1.zCoord += d8 * d3;
}
else if (d4 < d5)
{
if (j > i1)
{
b0 = 0;
}
else
{
b0 = 1;
}
v1.xCoord += d6 * d4;
v1.yCoord = d1;
v1.zCoord += d8 * d4;
}
else
{
if (k > j1)
{
b0 = 2;
}
else
{
b0 = 3;
}
v1.xCoord += d6 * d5;
v1.yCoord += d7 * d5;
v1.zCoord = d2;
}
Vec3 vec32 = Vec3.createVectorHelper(v1.xCoord, v1.yCoord, v1.zCoord);
l = (int)(vec32.xCoord = (double)MathHelper.floor_double(v1.xCoord));
if (b0 == 5)
{
--l;
++vec32.xCoord;
}
i1 = (int)(vec32.yCoord = (double)MathHelper.floor_double(v1.yCoord));
if (b0 == 1)
{
--i1;
++vec32.yCoord;
}
j1 = (int)(vec32.zCoord = (double)MathHelper.floor_double(v1.zCoord));
if (b0 == 3)
{
--j1;
++vec32.zCoord;
}
Block block1 = world.getBlock(l, i1, j1);
int l1 = world.getBlockMetadata(l, i1, j1);
if (!bool2 || block1.getCollisionBoundingBoxFromPool(world, l, i1, j1) != null)
{
if (block1.canCollideCheck(l1, bool1))
{
MovingObjectPosition movingobjectposition1 = block1.collisionRayTrace(world, l, i1, j1, v1, v2);
if (movingobjectposition1 != null)
{
return movingobjectposition1;
}
}
else
{
movingobjectposition2 = new MovingObjectPosition(l, i1, j1, b0, v1, false);
}
}
}
return bool3 ? movingobjectposition2 : null;
}
else
{
return null;
}
}
else
{
return null;
}
}
}
@@ -1,63 +0,0 @@
package thaumcraft.api;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
/**
*
* @author azanor
*
* Custom tile entity class I use for most of my tile entities. Setup in such a way that only
* the nbt data within readCustomNBT / writeCustomNBT will be sent to the client when the tile
* updates. Apart from all the normal TE data that gets sent that is.
*
*/
public class TileThaumcraft extends TileEntity {
//NBT stuff
@Override
public void readFromNBT(NBTTagCompound nbttagcompound)
{
super.readFromNBT(nbttagcompound);
readCustomNBT(nbttagcompound);
}
public void readCustomNBT(NBTTagCompound nbttagcompound)
{
//TODO
}
@Override
public void writeToNBT(NBTTagCompound nbttagcompound)
{
super.writeToNBT(nbttagcompound);
writeCustomNBT(nbttagcompound);
}
public void writeCustomNBT(NBTTagCompound nbttagcompound)
{
//TODO
}
//Client Packet stuff
@Override
public Packet getDescriptionPacket() {
NBTTagCompound nbttagcompound = new NBTTagCompound();
this.writeCustomNBT(nbttagcompound);
return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, -999, nbttagcompound);
}
@Override
public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) {
super.onDataPacket(net, pkt);
this.readCustomNBT(pkt.func_148857_g());
}
}
@@ -1,117 +0,0 @@
package thaumcraft.api;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
public class WorldCoordinates implements Comparable
{
public int x;
/** the y coordinate */
public int y;
/** the z coordinate */
public int z;
public int dim;
public WorldCoordinates() {}
public WorldCoordinates(int par1, int par2, int par3, int d)
{
this.x = par1;
this.y = par2;
this.z = par3;
this.dim = d;
}
public WorldCoordinates(TileEntity tile)
{
this.x = tile.xCoord;
this.y = tile.yCoord;
this.z = tile.zCoord;
this.dim = tile.getWorldObj().provider.dimensionId;
}
public WorldCoordinates(WorldCoordinates par1ChunkCoordinates)
{
this.x = par1ChunkCoordinates.x;
this.y = par1ChunkCoordinates.y;
this.z = par1ChunkCoordinates.z;
this.dim = par1ChunkCoordinates.dim;
}
public boolean equals(Object par1Obj)
{
if (!(par1Obj instanceof WorldCoordinates))
{
return false;
}
else
{
WorldCoordinates coordinates = (WorldCoordinates)par1Obj;
return this.x == coordinates.x && this.y == coordinates.y && this.z == coordinates.z && this.dim == coordinates.dim ;
}
}
public int hashCode()
{
return this.x + this.y << 8 + this.z << 16 + this.dim << 24;
}
/**
* Compare the coordinate with another coordinate
*/
public int compareWorldCoordinate(WorldCoordinates par1)
{
return this.dim == par1.dim ? (
this.y == par1.y ? (this.z == par1.z ? this.x - par1.x : this.z - par1.z) : this.y - par1.y) : -1;
}
public void set(int par1, int par2, int par3, int d)
{
this.x = par1;
this.y = par2;
this.z = par3;
this.dim = d;
}
/**
* Returns the squared distance between this coordinates and the coordinates given as argument.
*/
public float getDistanceSquared(int par1, int par2, int par3)
{
float f = (float)(this.x - par1);
float f1 = (float)(this.y - par2);
float f2 = (float)(this.z - par3);
return f * f + f1 * f1 + f2 * f2;
}
/**
* Return the squared distance between this coordinates and the ChunkCoordinates given as argument.
*/
public float getDistanceSquaredToWorldCoordinates(WorldCoordinates par1ChunkCoordinates)
{
return this.getDistanceSquared(par1ChunkCoordinates.x, par1ChunkCoordinates.y, par1ChunkCoordinates.z);
}
public int compareTo(Object par1Obj)
{
return this.compareWorldCoordinate((WorldCoordinates)par1Obj);
}
public void readNBT(NBTTagCompound nbt) {
this.x = nbt.getInteger("w_x");
this.y = nbt.getInteger("w_y");
this.z = nbt.getInteger("w_z");
this.dim = nbt.getInteger("w_d");
}
public void writeNBT(NBTTagCompound nbt) {
nbt.setInteger("w_x",x);
nbt.setInteger("w_y",y);
nbt.setInteger("w_z",z);
nbt.setInteger("w_d",dim);
}
}
@@ -1,201 +0,0 @@
package thaumcraft.api.aspects;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import org.apache.commons.lang3.text.WordUtils;
public class Aspect {
String tag;
Aspect[] components;
int color;
private String chatcolor;
ResourceLocation image;
int blend;
/**
* Use this constructor to register your own aspects.
* @param tag the key that will be used to reference this aspect, as well as its latin display name
* @param color color to display the tag in
* @param components the aspects this one is formed from
* @param image ResourceLocation pointing to a 32x32 icon of the aspect
* @param blend GL11 blendmode (1 or 771). Used for rendering nodes. Default is 1
*/
public Aspect(String tag, int color, Aspect[] components, ResourceLocation image, int blend) {
if (aspects.containsKey(tag)) throw new IllegalArgumentException(tag+" already registered!");
this.tag = tag;
this.components = components;
this.color = color;
this.image = image;
this.blend = blend;
aspects.put(tag, this);
}
/**
* Shortcut constructor I use for the default aspects - you shouldn't be using this.
*/
public Aspect(String tag, int color, Aspect[] components) {
this(tag,color,components,new ResourceLocation("thaumcraft","textures/aspects/"+tag.toLowerCase()+".png"),1);
}
/**
* Shortcut constructor I use for the default aspects - you shouldn't be using this.
*/
public Aspect(String tag, int color, Aspect[] components, int blend) {
this(tag,color,components,new ResourceLocation("thaumcraft","textures/aspects/"+tag.toLowerCase()+".png"),blend);
}
/**
* Shortcut constructor I use for the primal aspects -
* you shouldn't use this as making your own primal aspects will break all the things.
*/
public Aspect(String tag, int color, String chatcolor, int blend) {
this(tag,color,(Aspect[])null, blend);
this.setChatcolor(chatcolor);
}
public int getColor() {
return color;
}
public String getName() {
return WordUtils.capitalizeFully(tag);
}
public String getLocalizedDescription() {
return StatCollector.translateToLocal("tc.aspect."+tag);
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public Aspect[] getComponents() {
return components;
}
public void setComponents(Aspect[] components) {
this.components = components;
}
public ResourceLocation getImage() {
return image;
}
public static Aspect getAspect(String tag) {
return aspects.get(tag);
}
public int getBlend() {
return blend;
}
public void setBlend(int blend) {
this.blend = blend;
}
public boolean isPrimal() {
return getComponents()==null || getComponents().length!=2;
}
///////////////////////////////
public static ArrayList<Aspect> getPrimalAspects() {
ArrayList<Aspect> primals = new ArrayList<Aspect>();
Collection<Aspect> pa = aspects.values();
for (Aspect aspect:pa) {
if (aspect.isPrimal()) primals.add(aspect);
}
return primals;
}
public static ArrayList<Aspect> getCompoundAspects() {
ArrayList<Aspect> compounds = new ArrayList<Aspect>();
Collection<Aspect> pa = aspects.values();
for (Aspect aspect:pa) {
if (!aspect.isPrimal()) compounds.add(aspect);
}
return compounds;
}
public String getChatcolor() {
return chatcolor;
}
public void setChatcolor(String chatcolor) {
this.chatcolor = chatcolor;
}
///////////////////////////////
public static LinkedHashMap<String,Aspect> aspects = new LinkedHashMap<String,Aspect>();
//PRIMAL
public static final Aspect AIR = new Aspect("aer",0xffff7e,"e",1);
public static final Aspect EARTH = new Aspect("terra",0x56c000,"2",1);
public static final Aspect FIRE = new Aspect("ignis",0xff5a01,"c",1);
public static final Aspect WATER = new Aspect("aqua",0x3cd4fc,"3",1);
public static final Aspect ORDER = new Aspect("ordo",0xd5d4ec,"7",1);
public static final Aspect ENTROPY = new Aspect("perditio",0x404040,"8",771);
//SECONDARY
public static final Aspect VOID = new Aspect("vacuos",0x888888, new Aspect[] {AIR, ENTROPY},771);
public static final Aspect LIGHT = new Aspect("lux",0xfff663, new Aspect[] {AIR, FIRE});
public static final Aspect WEATHER = new Aspect("tempestas",0xFFFFFF, new Aspect[] {AIR, WATER});
public static final Aspect MOTION = new Aspect("motus",0xcdccf4, new Aspect[] {AIR, ORDER});
public static final Aspect COLD = new Aspect("gelum",0xe1ffff, new Aspect[] {FIRE, ENTROPY});
public static final Aspect CRYSTAL = new Aspect("vitreus",0x80ffff, new Aspect[] {EARTH, ORDER});
public static final Aspect LIFE = new Aspect("victus",0xde0005, new Aspect[] {WATER, EARTH});
public static final Aspect POISON = new Aspect("venenum",0x89f000, new Aspect[] {WATER, ENTROPY});
public static final Aspect ENERGY = new Aspect("potentia",0xc0ffff, new Aspect[] {ORDER, FIRE});
public static final Aspect EXCHANGE = new Aspect("permutatio",0x578357, new Aspect[] {ENTROPY, ORDER});
// public static final Aspect ?? = new Aspect("??",0xcdccf4, new Aspect[] {AIR, EARTH});
// public static final Aspect ?? = new Aspect("??",0xcdccf4, new Aspect[] {FIRE, EARTH});
// public static final Aspect ?? = new Aspect("??",0xcdccf4, new Aspect[] {FIRE, WATER});
// public static final Aspect ?? = new Aspect("??",0xcdccf4, new Aspect[] {ORDER, WATER});
// public static final Aspect ?? = new Aspect("??",0xcdccf4, new Aspect[] {EARTH, ENTROPY});
//TERTIARY
public static final Aspect METAL = new Aspect("metallum",0xb5b5cd, new Aspect[] {EARTH, CRYSTAL});
public static final Aspect DEATH = new Aspect("mortuus",0x887788, new Aspect[] {LIFE, ENTROPY});
public static final Aspect FLIGHT = new Aspect("volatus",0xe7e7d7, new Aspect[] {AIR, MOTION});
public static final Aspect DARKNESS = new Aspect("tenebrae",0x222222, new Aspect[] {VOID, LIGHT});
public static final Aspect SOUL = new Aspect("spiritus",0xebebfb, new Aspect[] {LIFE, DEATH});
public static final Aspect HEAL = new Aspect("sano",0xff2f34, new Aspect[] {LIFE, ORDER});
public static final Aspect TRAVEL = new Aspect("iter",0xe0585b, new Aspect[] {MOTION, EARTH});
public static final Aspect ELDRITCH = new Aspect("alienis",0x805080, new Aspect[] {VOID, DARKNESS});
public static final Aspect MAGIC = new Aspect("praecantatio",0x9700c0, new Aspect[] {VOID, ENERGY});
public static final Aspect AURA = new Aspect("auram",0xffc0ff, new Aspect[] {MAGIC, AIR});
public static final Aspect TAINT = new Aspect("vitium",0x800080, new Aspect[] {MAGIC, ENTROPY});
public static final Aspect SLIME = new Aspect("limus",0x01f800, new Aspect[] {LIFE, WATER});
public static final Aspect PLANT = new Aspect("herba",0x01ac00, new Aspect[] {LIFE, EARTH});
public static final Aspect TREE = new Aspect("arbor",0x876531, new Aspect[] {AIR, PLANT});
public static final Aspect BEAST = new Aspect("bestia",0x9f6409, new Aspect[] {MOTION, LIFE});
public static final Aspect FLESH = new Aspect("corpus",0xee478d, new Aspect[] {DEATH, BEAST});
public static final Aspect UNDEAD = new Aspect("exanimis",0x3a4000, new Aspect[] {MOTION, DEATH});
public static final Aspect MIND = new Aspect("cognitio",0xffc2b3, new Aspect[] {FIRE, SOUL});
public static final Aspect SENSES = new Aspect("sensus",0x0fd9ff, new Aspect[] {AIR, SOUL});
public static final Aspect MAN = new Aspect("humanus",0xffd7c0, new Aspect[] {BEAST, MIND});
public static final Aspect CROP = new Aspect("messis",0xe1b371, new Aspect[] {PLANT, MAN});
public static final Aspect MINE = new Aspect("perfodio",0xdcd2d8, new Aspect[] {MAN, EARTH});
public static final Aspect TOOL = new Aspect("instrumentum",0x4040ee, new Aspect[] {MAN, ORDER});
public static final Aspect HARVEST = new Aspect("meto",0xeead82, new Aspect[] {CROP, TOOL});
public static final Aspect WEAPON = new Aspect("telum",0xc05050, new Aspect[] {TOOL, FIRE});
public static final Aspect ARMOR = new Aspect("tutamen",0x00c0c0, new Aspect[] {TOOL, EARTH});
public static final Aspect HUNGER = new Aspect("fames",0x9a0305, new Aspect[] {LIFE, VOID});
public static final Aspect GREED = new Aspect("lucrum",0xe6be44, new Aspect[] {MAN, HUNGER});
public static final Aspect CRAFT = new Aspect("fabrico",0x809d80, new Aspect[] {MAN, TOOL});
public static final Aspect CLOTH = new Aspect("pannus",0xeaeac2, new Aspect[] {TOOL, BEAST});
public static final Aspect MECHANISM = new Aspect("machina",0x8080a0, new Aspect[] {MOTION, TOOL});
public static final Aspect TRAP = new Aspect("vinculum",0x9a8080, new Aspect[] {MOTION, ENTROPY});
}
@@ -1,292 +0,0 @@
package thaumcraft.api.aspects;
import java.io.Serializable;
import java.util.LinkedHashMap;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import thaumcraft.api.ThaumcraftApiHelper;
public class AspectList implements Serializable {
public LinkedHashMap<Aspect,Integer> aspects = new LinkedHashMap<Aspect,Integer>();//aspects associated with this object
/**
* this creates a new aspect list with preloaded values based off the aspects of the given item.
* @param the itemstack of the given item
*/
public AspectList(ItemStack stack) {
try {
AspectList temp = ThaumcraftApiHelper.getObjectAspects(stack);
if (temp!=null)
for (Aspect tag:temp.getAspects()) {
add(tag,temp.getAmount(tag));
}
} catch (Exception e) {}
}
public AspectList() {
}
public AspectList copy() {
AspectList out = new AspectList();
for (Aspect a:this.getAspects())
out.add(a, this.getAmount(a));
return out;
}
/**
* @return the amount of different aspects in this collection
*/
public int size() {
return aspects.size();
}
/**
* @return the amount of total vis in this collection
*/
public int visSize() {
int q = 0;
for (Aspect as:aspects.keySet()) {
q+=this.getAmount(as);
}
return q;
}
/**
* @return an array of all the aspects in this collection
*/
public Aspect[] getAspects() {
Aspect[] q = new Aspect[1];
return aspects.keySet().toArray(q);
}
/**
* @return an array of all the aspects in this collection
*/
public Aspect[] getPrimalAspects() {
AspectList t = new AspectList();
for (Aspect as:aspects.keySet()) {
if (as.isPrimal()) {
t.add(as,1);
}
}
Aspect[] q = new Aspect[1];
return t.aspects.keySet().toArray(q);
}
/**
* @return an array of all the aspects in this collection sorted by name
*/
public Aspect[] getAspectsSorted() {
try {
Aspect[] out = aspects.keySet().toArray(new Aspect[]{});
boolean change=false;
do {
change=false;
for(int a=0;a<out.length-1;a++) {
Aspect e1 = out[a];
Aspect e2 = out[a+1];
if (e1!=null && e2!=null && e1.getTag().compareTo(e2.getTag())>0) {
out[a] = e2;
out[a+1] = e1;
change = true;
break;
}
}
} while (change==true);
return out;
} catch (Exception e) {
return this.getAspects();
}
}
/**
* @return an array of all the aspects in this collection sorted by amount
*/
public Aspect[] getAspectsSortedAmount() {
try {
Aspect[] out = aspects.keySet().toArray(new Aspect[1]);
boolean change=false;
do {
change=false;
for(int a=0;a<out.length-1;a++) {
int e1 = getAmount(out[a]);
int e2 = getAmount(out[a+1]);
if (e1>0 && e2>0 && e2>e1) {
Aspect ea = out[a];
Aspect eb = out[a+1];
out[a] = eb;
out[a+1] = ea;
change = true;
break;
}
}
} while (change==true);
return out;
} catch (Exception e) {
return this.getAspects();
}
}
/**
* @param key
* @return the amount associated with the given aspect in this collection
*/
public int getAmount(Aspect key) {
return aspects.get(key)==null?0:aspects.get(key);
}
/**
* Reduces the amount of an aspect in this collection by the given amount.
* @param key
* @param amount
* @return
*/
public boolean reduce(Aspect key, int amount) {
if (getAmount(key)>=amount) {
int am = getAmount(key)-amount;
aspects.put(key, am);
return true;
}
return false;
}
/**
* Reduces the amount of an aspect in this collection by the given amount.
* If reduced to 0 or less the aspect will be removed completely.
* @param key
* @param amount
* @return
*/
public AspectList remove(Aspect key, int amount) {
int am = getAmount(key)-amount;
if (am<=0) aspects.remove(key); else
this.aspects.put(key, am);
return this;
}
/**
* Simply removes the aspect from the list
* @param key
* @param amount
* @return
*/
public AspectList remove(Aspect key) {
aspects.remove(key);
return this;
}
/**
* Adds this aspect and amount to the collection.
* If the aspect exists then its value will be increased by the given amount.
* @param aspect
* @param amount
* @return
*/
public AspectList add(Aspect aspect, int amount) {
if (this.aspects.containsKey(aspect)) {
int oldamount = this.aspects.get(aspect);
amount+=oldamount;
}
this.aspects.put( aspect, amount );
return this;
}
/**
* Adds this aspect and amount to the collection.
* If the aspect exists then only the highest of the old or new amount will be used.
* @param aspect
* @param amount
* @return
*/
public AspectList merge(Aspect aspect, int amount) {
if (this.aspects.containsKey(aspect)) {
int oldamount = this.aspects.get(aspect);
if (amount<oldamount) amount=oldamount;
}
this.aspects.put( aspect, amount );
return this;
}
public AspectList add(AspectList in) {
for (Aspect a:in.getAspects())
this.add(a, in.getAmount(a));
return this;
}
public AspectList merge(AspectList in) {
for (Aspect a:in.getAspects())
this.merge(a, in.getAmount(a));
return this;
}
/**
* Reads the list of aspects from nbt
* @param nbttagcompound
* @return
*/
public void readFromNBT(NBTTagCompound nbttagcompound)
{
aspects.clear();
NBTTagList tlist = nbttagcompound.getTagList("Aspects",(byte)10);
for (int j = 0; j < tlist.tagCount(); j++) {
NBTTagCompound rs = (NBTTagCompound) tlist.getCompoundTagAt(j);
if (rs.hasKey("key")) {
add( Aspect.getAspect(rs.getString("key")),
rs.getInteger("amount"));
}
}
}
public void readFromNBT(NBTTagCompound nbttagcompound, String label)
{
aspects.clear();
NBTTagList tlist = nbttagcompound.getTagList(label,(byte)10);
for (int j = 0; j < tlist.tagCount(); j++) {
NBTTagCompound rs = (NBTTagCompound) tlist.getCompoundTagAt(j);
if (rs.hasKey("key")) {
add( Aspect.getAspect(rs.getString("key")),
rs.getInteger("amount"));
}
}
}
/**
* Writes the list of aspects to nbt
* @param nbttagcompound
* @return
*/
public void writeToNBT(NBTTagCompound nbttagcompound)
{
NBTTagList tlist = new NBTTagList();
nbttagcompound.setTag("Aspects", tlist);
for (Aspect aspect : getAspects())
if (aspect != null) {
NBTTagCompound f = new NBTTagCompound();
f.setString("key", aspect.getTag());
f.setInteger("amount", getAmount(aspect));
tlist.appendTag(f);
}
}
public void writeToNBT(NBTTagCompound nbttagcompound, String label)
{
NBTTagList tlist = new NBTTagList();
nbttagcompound.setTag(label, tlist);
for (Aspect aspect : getAspects())
if (aspect != null) {
NBTTagCompound f = new NBTTagCompound();
f.setString("key", aspect.getTag());
f.setInteger("amount", getAmount(aspect));
tlist.appendTag(f);
}
}
}
@@ -1,58 +0,0 @@
package thaumcraft.api.aspects;
import java.lang.reflect.Method;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import cpw.mods.fml.common.FMLLog;
public class AspectSourceHelper {
static Method drainEssentia;
static Method findEssentia;
/**
* This method is what is used to drain essentia from jars and other sources for things like
* infusion crafting or powering the arcane furnace. A record of possible sources are kept track of
* and refreshed as needed around the calling tile entity. This also renders the essentia trail particles.
* Only 1 essentia is drained at a time
* @param tile the tile entity that is draining the essentia
* @param aspect the aspect that you are looking for
* @param direction the direction from which you wish to drain. Forgedirection.Unknown simply seeks in all directions.
* @param range how many blocks you wish to search for essentia sources.
* @return boolean returns true if essentia was found and removed from a source.
*/
public static boolean drainEssentia(TileEntity tile, Aspect aspect, ForgeDirection direction, int range) {
try {
if(drainEssentia == null) {
Class fake = Class.forName("thaumcraft.common.lib.events.EssentiaHandler");
drainEssentia = fake.getMethod("drainEssentia", TileEntity.class, Aspect.class, ForgeDirection.class, int.class);
}
return (Boolean) drainEssentia.invoke(null, tile, aspect, direction, range);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.lib.events.EssentiaHandler method drainEssentia");
}
return false;
}
/**
* This method returns if there is any essentia of the passed type that can be drained. It in no way checks how
* much there is, only if an essentia container nearby contains at least 1 point worth.
* @param tile the tile entity that is checking the essentia
* @param aspect the aspect that you are looking for
* @param direction the direction from which you wish to drain. Forgedirection.Unknown simply seeks in all directions.
* @param range how many blocks you wish to search for essentia sources.
* @return boolean returns true if essentia was found and removed from a source.
*/
public static boolean findEssentia(TileEntity tile, Aspect aspect, ForgeDirection direction, int range) {
try {
if(findEssentia == null) {
Class fake = Class.forName("thaumcraft.common.lib.events.EssentiaHandler");
findEssentia = fake.getMethod("findEssentia", TileEntity.class, Aspect.class, ForgeDirection.class, int.class);
}
return (Boolean) findEssentia.invoke(null, tile, aspect, direction, range);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.lib.events.EssentiaHandler method findEssentia");
}
return false;
}
}
@@ -1,80 +0,0 @@
package thaumcraft.api.aspects;
/**
*
* @author azanor
*
* Used by blocks like the crucible and alembic to hold their aspects.
* Tiles extending this interface will have their aspects show up when viewed by goggles of revealing
*
*/
public interface IAspectContainer {
public AspectList getAspects();
public void setAspects(AspectList aspects);
/**
* This method is used to determine of a specific aspect can be added to this container.
* @param tag
* @return true or false
*/
public boolean doesContainerAccept(Aspect tag);
/**
* This method is used to add a certain amount of an aspect to the tile entity.
* @param tag
* @param amount
* @return the amount of aspect left over that could not be added.
*/
public int addToContainer(Aspect tag, int amount);
/**
* Removes a certain amount of a specific aspect from the tile entity
* @param tag
* @param amount
* @return true if that amount of aspect was available and was removed
*/
public boolean takeFromContainer(Aspect tag, int amount);
/**
* removes a bunch of different aspects and amounts from the tile entity.
* @param ot the ObjectTags object that contains the aspects and their amounts.
* @return true if all the aspects and their amounts were available and successfully removed
*
* Going away in the next major patch
*/
@Deprecated
public boolean takeFromContainer(AspectList ot);
/**
* Checks if the tile entity contains the listed amount (or more) of the aspect
* @param tag
* @param amount
* @return
*/
public boolean doesContainerContainAmount(Aspect tag,int amount);
/**
* Checks if the tile entity contains all the listed aspects and their amounts
* @param ot the ObjectTags object that contains the aspects and their amounts.
* @return
*
* Going away in the next major patch
*/
@Deprecated
public boolean doesContainerContain(AspectList ot);
/**
* Returns how much of the aspect this tile entity contains
* @param tag
* @return the amount of that aspect found
*/
public int containerContains(Aspect tag);
}
@@ -1,16 +0,0 @@
package thaumcraft.api.aspects;
/**
* @author Azanor
*
* This interface is implemented by tile entites (or possibly anything else) like jars
* so that they can act as an essentia source for blocks like the infusion altar.
*
*/
public interface IAspectSource extends IAspectContainer {
}
@@ -1,37 +0,0 @@
package thaumcraft.api.aspects;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
/**
*
* @author azanor
*
* Used by wispy essences and essentia phials to hold their aspects.
* Useful for similar item containers that store their aspect information in nbt form so TC
* automatically picks up the aspects they contain
*
*/
public interface IEssentiaContainerItem {
public AspectList getAspects(ItemStack itemstack);
public void setAspects(ItemStack itemstack, AspectList aspects);
}
//Example implementation
/*
@Override
public AspectList getAspects(ItemStack itemstack) {
if (itemstack.hasTagCompound()) {
AspectList aspects = new AspectList();
aspects.readFromNBT(itemstack.getTagCompound());
return aspects.size()>0?aspects:null;
}
return null;
}
@Override
public void setAspects(ItemStack itemstack, AspectList aspects) {
if (!itemstack.hasTagCompound()) itemstack.setTagCompound(new NBTTagCompound());
aspects.writeToNBT(itemstack.getTagCompound());
}
*/
@@ -1,100 +0,0 @@
package thaumcraft.api.aspects;
import net.minecraftforge.common.util.ForgeDirection;
/**
* @author Azanor
* This interface is used by tiles that use or transport vis.
* Only tiles that implement this interface will be able to connect to vis conduits or other thaumic devices
*/
public interface IEssentiaTransport {
/**
* Is this tile able to connect to other vis users/sources on the specified side?
* @param face
* @return
*/
public boolean isConnectable(ForgeDirection face);
/**
* Is this side used to input essentia?
* @param face
* @return
*/
boolean canInputFrom(ForgeDirection face);
/**
* Is this side used to output essentia?
* @param face
* @return
*/
boolean canOutputTo(ForgeDirection face);
/**
* Sets the amount of suction this block will apply
* @param suction
*/
public void setSuction(Aspect aspect, int amount);
/**
* Returns the type of suction this block is applying.
* @param loc
* the location from where the suction is being checked
* @return
* a return type of null indicates the suction is untyped and the first thing available will be drawn
*/
public Aspect getSuctionType(ForgeDirection face);
/**
* Returns the strength of suction this block is applying.
* @param loc
* the location from where the suction is being checked
* @return
*/
public int getSuctionAmount(ForgeDirection face);
/**
* remove the specified amount of essentia from this transport tile
* @return how much was actually taken
*/
public int takeEssentia(Aspect aspect, int amount, ForgeDirection face);
/**
* add the specified amount of essentia to this transport tile
* @return how much was actually added
*/
public int addEssentia(Aspect aspect, int amount, ForgeDirection face);
/**
* What type of essentia this contains
* @param face
* @return
*/
public Aspect getEssentiaType(ForgeDirection face);
/**
* How much essentia this block contains
* @param face
* @return
*/
public int getEssentiaAmount(ForgeDirection face);
/**
* Essentia will not be drawn from this container unless the suction exceeds this amount.
* @return the amount
*/
public int getMinimumSuction();
/**
* Return true if you want the conduit to extend a little further into the block.
* Used by jars and alembics that have smaller than normal hitboxes
* @return
*/
boolean renderExtendedTube();
}
@@ -1,91 +0,0 @@
package thaumcraft.api.crafting;
import java.util.ArrayList;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.ThaumcraftApiHelper;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
public class CrucibleRecipe {
private ItemStack recipeOutput;
public Object catalyst;
public AspectList aspects;
public String key;
public int hash;
public CrucibleRecipe(String researchKey, ItemStack result, Object cat, AspectList tags) {
recipeOutput = result;
this.aspects = tags;
this.key = researchKey;
this.catalyst = cat;
if (cat instanceof String) {
this.catalyst = OreDictionary.getOres((String) cat);
}
String hc = researchKey + result.toString();
for (Aspect tag:tags.getAspects()) {
hc += tag.getTag()+tags.getAmount(tag);
}
if (cat instanceof ItemStack) {
hc += ((ItemStack)cat).toString();
} else
if (cat instanceof ArrayList && ((ArrayList<ItemStack>)catalyst).size()>0) {
for (ItemStack is :(ArrayList<ItemStack>)catalyst) {
hc += is.toString();
}
}
hash = hc.hashCode();
}
public boolean matches(AspectList itags, ItemStack cat) {
if (catalyst instanceof ItemStack &&
!ThaumcraftApiHelper.itemMatches((ItemStack) catalyst,cat,false)) {
return false;
} else
if (catalyst instanceof ArrayList && ((ArrayList<ItemStack>)catalyst).size()>0) {
ItemStack[] ores = ((ArrayList<ItemStack>)catalyst).toArray(new ItemStack[]{});
if (!ThaumcraftApiHelper.containsMatch(false, new ItemStack[]{cat},ores)) return false;
}
if (itags==null) return false;
for (Aspect tag:aspects.getAspects()) {
if (itags.getAmount(tag)<aspects.getAmount(tag)) return false;
}
return true;
}
public boolean catalystMatches(ItemStack cat) {
if (catalyst instanceof ItemStack && ThaumcraftApiHelper.itemMatches((ItemStack) catalyst,cat,false)) {
return true;
} else
if (catalyst instanceof ArrayList && ((ArrayList<ItemStack>)catalyst).size()>0) {
ItemStack[] ores = ((ArrayList<ItemStack>)catalyst).toArray(new ItemStack[]{});
if (ThaumcraftApiHelper.containsMatch(false, new ItemStack[]{cat},ores)) return true;
}
return false;
}
public AspectList removeMatching(AspectList itags) {
AspectList temptags = new AspectList();
temptags.aspects.putAll(itags.aspects);
for (Aspect tag:aspects.getAspects()) {
temptags.remove(tag, aspects.getAmount(tag));
}
itags = temptags;
return itags;
}
public ItemStack getRecipeOutput() {
return recipeOutput;
}
}
@@ -1,35 +0,0 @@
package thaumcraft.api.crafting;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import thaumcraft.api.aspects.AspectList;
public interface IArcaneRecipe
{
/**
* Used to check if a recipe matches current crafting inventory
* @param player
*/
boolean matches(IInventory var1, World world, EntityPlayer player);
/**
* Returns an Item that is the result of this recipe
*/
ItemStack getCraftingResult(IInventory var1);
/**
* Returns the size of the recipe area
*/
int getRecipeSize();
ItemStack getRecipeOutput();
AspectList getAspects();
AspectList getAspects(IInventory var1);
String getResearch();
}
@@ -1,19 +0,0 @@
package thaumcraft.api.crafting;
import net.minecraft.world.World;
/**
*
* @author Azanor
*
* Blocks that implement this interface act as infusion crafting stabilisers like candles and skulls
*
*/
public interface IInfusionStabiliser {
/**
* returns true if the block can stabilise things
*/
public boolean canStabaliseInfusion(World world, int x, int y, int z);
}
@@ -1,154 +0,0 @@
package thaumcraft.api.crafting;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.ThaumcraftApiHelper;
import thaumcraft.api.aspects.AspectList;
public class InfusionEnchantmentRecipe
{
public AspectList aspects;
public String research;
public ItemStack[] components;
public Enchantment enchantment;
public int recipeXP;
public int instability;
public InfusionEnchantmentRecipe(String research, Enchantment input, int inst,
AspectList aspects2, ItemStack[] recipe) {
this.research = research;
this.enchantment = input;
this.aspects = aspects2;
this.components = recipe;
this.instability = inst;
this.recipeXP = Math.max(1, input.getMinEnchantability(1)/3);
}
/**
* Used to check if a recipe matches current crafting inventory
* @param player
*/
public boolean matches(ArrayList<ItemStack> input, ItemStack central, World world, EntityPlayer player) {
if (research.length()>0 && !ThaumcraftApiHelper.isResearchComplete(player.getCommandSenderName(), research)) {
return false;
}
if (!enchantment.canApply(central) || !central.getItem().isItemTool(central)) {
return false;
}
Map map1 = EnchantmentHelper.getEnchantments(central);
Iterator iterator = map1.keySet().iterator();
while (iterator.hasNext())
{
int j1 = ((Integer)iterator.next()).intValue();
Enchantment ench = Enchantment.enchantmentsList[j1];
if (j1 == enchantment.effectId &&
EnchantmentHelper.getEnchantmentLevel(j1, central)>=ench.getMaxLevel())
return false;
if (enchantment.effectId != ench.effectId &&
(!enchantment.canApplyTogether(ench) ||
!ench.canApplyTogether(enchantment))) {
return false;
}
}
ItemStack i2 = null;
ArrayList<ItemStack> ii = new ArrayList<ItemStack>();
for (ItemStack is:input) {
ii.add(is.copy());
}
for (ItemStack comp:components) {
boolean b=false;
for (int a=0;a<ii.size();a++) {
i2 = ii.get(a).copy();
if (comp.getItemDamage()==OreDictionary.WILDCARD_VALUE) {
i2.setItemDamage(OreDictionary.WILDCARD_VALUE);
}
if (areItemStacksEqual(i2, comp,true)) {
ii.remove(a);
b=true;
break;
}
}
if (!b) return false;
}
// System.out.println(ii.size());
return ii.size()==0?true:false;
}
protected boolean areItemStacksEqual(ItemStack stack0, ItemStack stack1, boolean fuzzy)
{
if (stack0==null && stack1!=null) return false;
if (stack0!=null && stack1==null) return false;
if (stack0==null && stack1==null) return true;
boolean t1=ThaumcraftApiHelper.areItemStackTagsEqualForCrafting(stack0, stack1);
if (!t1) return false;
if (fuzzy) {
int od = OreDictionary.getOreID(stack0);
if (od!=-1) {
ItemStack[] ores = OreDictionary.getOres(od).toArray(new ItemStack[]{});
if (ThaumcraftApiHelper.containsMatch(false, new ItemStack[]{stack1}, ores))
return true;
}
}
return stack0.getItem() != stack1.getItem() ? false : (stack0.getItemDamage() != stack1.getItemDamage() ? false : stack0.stackSize <= stack0.getMaxStackSize() );
}
public Enchantment getEnchantment() {
return enchantment;
}
public AspectList getAspects() {
return aspects;
}
public String getResearch() {
return research;
}
public int calcInstability(ItemStack recipeInput) {
int i = 0;
Map map1 = EnchantmentHelper.getEnchantments(recipeInput);
Iterator iterator = map1.keySet().iterator();
while (iterator.hasNext())
{
int j1 = ((Integer)iterator.next()).intValue();
i += EnchantmentHelper.getEnchantmentLevel(j1, recipeInput);
}
return (i/2) + instability;
}
public int calcXP(ItemStack recipeInput) {
return recipeXP * (1+EnchantmentHelper.getEnchantmentLevel(enchantment.effectId, recipeInput));
}
public float getEssentiaMod(ItemStack recipeInput) {
float mod = EnchantmentHelper.getEnchantmentLevel(enchantment.effectId, recipeInput);
Map map1 = EnchantmentHelper.getEnchantments(recipeInput);
Iterator iterator = map1.keySet().iterator();
while (iterator.hasNext())
{
int j1 = ((Integer)iterator.next()).intValue();
if (j1 != enchantment.effectId)
mod += EnchantmentHelper.getEnchantmentLevel(j1, recipeInput) * .1f;
}
return mod;
}
}
@@ -1,133 +0,0 @@
package thaumcraft.api.crafting;
import java.util.ArrayList;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.ThaumcraftApiHelper;
import thaumcraft.api.aspects.AspectList;
public class InfusionRecipe
{
protected AspectList aspects;
protected String research;
private ItemStack[] components;
private ItemStack recipeInput;
protected Object recipeOutput;
protected int instability;
public InfusionRecipe(String research, Object output, int inst,
AspectList aspects2, ItemStack input, ItemStack[] recipe) {
this.research = research;
this.recipeOutput = output;
this.recipeInput = input;
this.aspects = aspects2;
this.components = recipe;
this.instability = inst;
}
/**
* Used to check if a recipe matches current crafting inventory
* @param player
*/
public boolean matches(ArrayList<ItemStack> input, ItemStack central, World world, EntityPlayer player) {
if (getRecipeInput()==null) return false;
if (research.length()>0 && !ThaumcraftApiHelper.isResearchComplete(player.getCommandSenderName(), research)) {
return false;
}
ItemStack i2 = central.copy();
if (getRecipeInput().getItemDamage()==OreDictionary.WILDCARD_VALUE) {
i2.setItemDamage(OreDictionary.WILDCARD_VALUE);
}
if (!areItemStacksEqual(i2, getRecipeInput(), true)) return false;
ArrayList<ItemStack> ii = new ArrayList<ItemStack>();
for (ItemStack is:input) {
ii.add(is.copy());
}
for (ItemStack comp:getComponents()) {
boolean b=false;
for (int a=0;a<ii.size();a++) {
i2 = ii.get(a).copy();
if (comp.getItemDamage()==OreDictionary.WILDCARD_VALUE) {
i2.setItemDamage(OreDictionary.WILDCARD_VALUE);
}
if (areItemStacksEqual(i2, comp,true)) {
ii.remove(a);
b=true;
break;
}
}
if (!b) return false;
}
return ii.size()==0?true:false;
}
public static boolean areItemStacksEqual(ItemStack stack0, ItemStack stack1, boolean fuzzy)
{
if (stack0==null && stack1!=null) return false;
if (stack0!=null && stack1==null) return false;
if (stack0==null && stack1==null) return true;
//nbt
boolean t1=ThaumcraftApiHelper.areItemStackTagsEqualForCrafting(stack0, stack1);
if (!t1) return false;
if (fuzzy) {
int od = OreDictionary.getOreID(stack0);
if (od!=-1) {
ItemStack[] ores = OreDictionary.getOres(od).toArray(new ItemStack[]{});
if (ThaumcraftApiHelper.containsMatch(false, new ItemStack[]{stack1}, ores))
return true;
}
}
//damage
boolean damage = stack0.getItemDamage() == stack1.getItemDamage() ||
stack1.getItemDamage() == OreDictionary.WILDCARD_VALUE;
return stack0.getItem() != stack1.getItem() ? false : (!damage ? false : stack0.stackSize <= stack0.getMaxStackSize() );
}
public Object getRecipeOutput() {
return getRecipeOutput(this.getRecipeInput());
}
public AspectList getAspects() {
return getAspects(this.getRecipeInput());
}
public int getInstability() {
return getInstability(this.getRecipeInput());
}
public String getResearch() {
return research;
}
public ItemStack getRecipeInput() {
return recipeInput;
}
public ItemStack[] getComponents() {
return components;
}
public Object getRecipeOutput(ItemStack input) {
return recipeOutput;
}
public AspectList getAspects(ItemStack input) {
return aspects;
}
public int getInstability(ItemStack input) {
return instability;
}
}
@@ -1,261 +0,0 @@
package thaumcraft.api.crafting;
import java.util.ArrayList;
import java.util.HashMap;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.ThaumcraftApiHelper;
import thaumcraft.api.aspects.AspectList;
public class ShapedArcaneRecipe implements IArcaneRecipe
{
//Added in for future ease of change, but hard coded for now.
private static final int MAX_CRAFT_GRID_WIDTH = 3;
private static final int MAX_CRAFT_GRID_HEIGHT = 3;
public ItemStack output = null;
public Object[] input = null;
public AspectList aspects = null;
public String research;
public int width = 0;
public int height = 0;
private boolean mirrored = true;
public ShapedArcaneRecipe(String research, Block result, AspectList aspects, Object... recipe){ this(research, new ItemStack(result), aspects, recipe); }
public ShapedArcaneRecipe(String research, Item result, AspectList aspects, Object... recipe){ this(research, new ItemStack(result), aspects, recipe); }
public ShapedArcaneRecipe(String research, ItemStack result, AspectList aspects, Object... recipe)
{
output = result.copy();
this.research = research;
this.aspects = aspects;
String shape = "";
int idx = 0;
if (recipe[idx] instanceof Boolean)
{
mirrored = (Boolean)recipe[idx];
if (recipe[idx+1] instanceof Object[])
{
recipe = (Object[])recipe[idx+1];
}
else
{
idx = 1;
}
}
if (recipe[idx] instanceof String[])
{
String[] parts = ((String[])recipe[idx++]);
for (String s : parts)
{
width = s.length();
shape += s;
}
height = parts.length;
}
else
{
while (recipe[idx] instanceof String)
{
String s = (String)recipe[idx++];
shape += s;
width = s.length();
height++;
}
}
if (width * height != shape.length())
{
String ret = "Invalid shaped ore recipe: ";
for (Object tmp : recipe)
{
ret += tmp + ", ";
}
ret += output;
throw new RuntimeException(ret);
}
HashMap<Character, Object> itemMap = new HashMap<Character, Object>();
for (; idx < recipe.length; idx += 2)
{
Character chr = (Character)recipe[idx];
Object in = recipe[idx + 1];
if (in instanceof ItemStack)
{
itemMap.put(chr, ((ItemStack)in).copy());
}
else if (in instanceof Item)
{
itemMap.put(chr, new ItemStack((Item)in));
}
else if (in instanceof Block)
{
itemMap.put(chr, new ItemStack((Block)in, 1, OreDictionary.WILDCARD_VALUE));
}
else if (in instanceof String)
{
itemMap.put(chr, OreDictionary.getOres((String)in));
}
else
{
String ret = "Invalid shaped ore recipe: ";
for (Object tmp : recipe)
{
ret += tmp + ", ";
}
ret += output;
throw new RuntimeException(ret);
}
}
input = new Object[width * height];
int x = 0;
for (char chr : shape.toCharArray())
{
input[x++] = itemMap.get(chr);
}
}
@Override
public ItemStack getCraftingResult(IInventory var1){ return output.copy(); }
@Override
public int getRecipeSize(){ return input.length; }
@Override
public ItemStack getRecipeOutput(){ return output; }
@Override
public boolean matches(IInventory inv, World world, EntityPlayer player)
{
if (research.length()>0 && !ThaumcraftApiHelper.isResearchComplete(player.getCommandSenderName(), research)) {
return false;
}
for (int x = 0; x <= MAX_CRAFT_GRID_WIDTH - width; x++)
{
for (int y = 0; y <= MAX_CRAFT_GRID_HEIGHT - height; ++y)
{
if (checkMatch(inv, x, y, false))
{
return true;
}
if (mirrored && checkMatch(inv, x, y, true))
{
return true;
}
}
}
return false;
}
private boolean checkMatch(IInventory inv, int startX, int startY, boolean mirror)
{
for (int x = 0; x < MAX_CRAFT_GRID_WIDTH; x++)
{
for (int y = 0; y < MAX_CRAFT_GRID_HEIGHT; y++)
{
int subX = x - startX;
int subY = y - startY;
Object target = null;
if (subX >= 0 && subY >= 0 && subX < width && subY < height)
{
if (mirror)
{
target = input[width - subX - 1 + subY * width];
}
else
{
target = input[subX + subY * width];
}
}
ItemStack slot = ThaumcraftApiHelper.getStackInRowAndColumn(inv, x, y);
if (target instanceof ItemStack)
{
if (!checkItemEquals((ItemStack)target, slot))
{
return false;
}
}
else if (target instanceof ArrayList)
{
boolean matched = false;
for (ItemStack item : (ArrayList<ItemStack>)target)
{
matched = matched || checkItemEquals(item, slot);
}
if (!matched)
{
return false;
}
}
else if (target == null && slot != null)
{
return false;
}
}
}
return true;
}
private boolean checkItemEquals(ItemStack target, ItemStack input)
{
if (input == null && target != null || input != null && target == null)
{
return false;
}
return (target.getItem() == input.getItem() &&
(!target.hasTagCompound() || ThaumcraftApiHelper.areItemStackTagsEqualForCrafting(input,target)) &&
(target.getItemDamage() == OreDictionary.WILDCARD_VALUE|| target.getItemDamage() == input.getItemDamage()));
}
public ShapedArcaneRecipe setMirrored(boolean mirror)
{
mirrored = mirror;
return this;
}
/**
* Returns the input for this recipe, any mod accessing this value should never
* manipulate the values in this array as it will effect the recipe itself.
* @return The recipes input vales.
*/
public Object[] getInput()
{
return this.input;
}
@Override
public AspectList getAspects() {
return aspects;
}
@Override
public AspectList getAspects(IInventory inv) {
return aspects;
}
@Override
public String getResearch() {
return research;
}
}
@@ -1,161 +0,0 @@
package thaumcraft.api.crafting;
import java.util.ArrayList;
import java.util.Iterator;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.ThaumcraftApiHelper;
import thaumcraft.api.aspects.AspectList;
public class ShapelessArcaneRecipe implements IArcaneRecipe
{
private ItemStack output = null;
private ArrayList input = new ArrayList();
public AspectList aspects = null;
public String research;
public ShapelessArcaneRecipe(String research, Block result, AspectList aspects, Object... recipe){ this(research,new ItemStack(result),aspects, recipe); }
public ShapelessArcaneRecipe(String research, Item result, AspectList aspects, Object... recipe){ this(research,new ItemStack(result),aspects, recipe); }
public ShapelessArcaneRecipe(String research, ItemStack result, AspectList aspects, Object... recipe)
{
output = result.copy();
this.research = research;
this.aspects = aspects;
for (Object in : recipe)
{
if (in instanceof ItemStack)
{
input.add(((ItemStack)in).copy());
}
else if (in instanceof Item)
{
input.add(new ItemStack((Item)in));
}
else if (in instanceof Block)
{
input.add(new ItemStack((Block)in));
}
else if (in instanceof String)
{
input.add(OreDictionary.getOres((String)in));
}
else
{
String ret = "Invalid shapeless ore recipe: ";
for (Object tmp : recipe)
{
ret += tmp + ", ";
}
ret += output;
throw new RuntimeException(ret);
}
}
}
@Override
public int getRecipeSize(){ return input.size(); }
@Override
public ItemStack getRecipeOutput(){ return output; }
@Override
public ItemStack getCraftingResult(IInventory var1){ return output.copy(); }
@Override
public boolean matches(IInventory var1, World world, EntityPlayer player)
{
if (research.length()>0 && !ThaumcraftApiHelper.isResearchComplete(player.getCommandSenderName(), research)) {
return false;
}
ArrayList required = new ArrayList(input);
for (int x = 0; x < 9; x++)
{
ItemStack slot = var1.getStackInSlot(x);
if (slot != null)
{
boolean inRecipe = false;
Iterator req = required.iterator();
while (req.hasNext())
{
boolean match = false;
Object next = req.next();
if (next instanceof ItemStack)
{
match = checkItemEquals((ItemStack)next, slot);
}
else if (next instanceof ArrayList)
{
for (ItemStack item : (ArrayList<ItemStack>)next)
{
match = match || checkItemEquals(item, slot);
}
}
if (match)
{
inRecipe = true;
required.remove(next);
break;
}
}
if (!inRecipe)
{
return false;
}
}
}
return required.isEmpty();
}
private boolean checkItemEquals(ItemStack target, ItemStack input)
{
if (input == null && target != null || input != null && target == null)
{
return false;
}
return (target.getItem() == input.getItem() &&
(!target.hasTagCompound() || ThaumcraftApiHelper.areItemStackTagsEqualForCrafting(input,target)) &&
(target.getItemDamage() == OreDictionary.WILDCARD_VALUE|| target.getItemDamage() == input.getItemDamage()));
}
/**
* Returns the input for this recipe, any mod accessing this value should never
* manipulate the values in this array as it will effect the recipe itself.
* @return The recipes input vales.
*/
public ArrayList getInput()
{
return this.input;
}
@Override
public AspectList getAspects() {
return aspects;
}
@Override
public AspectList getAspects(IInventory inv) {
return aspects;
}
@Override
public String getResearch() {
return research;
}
}
@@ -1,32 +0,0 @@
package thaumcraft.api.damagesource;
import net.minecraft.entity.Entity;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EntityDamageSourceIndirect;
public class DamageSourceIndirectThaumcraftEntity extends EntityDamageSourceIndirect {
private boolean fireDamage;
private float hungerDamage;
private boolean isUnblockable;
public DamageSourceIndirectThaumcraftEntity(String par1Str,
Entity par2Entity, Entity par3Entity) {
super(par1Str, par2Entity, par3Entity);
}
public DamageSource setFireDamage()
{
this.fireDamage = true;
return this;
}
public DamageSource setDamageBypassesArmor()
{
this.isUnblockable = true;
this.hungerDamage = 0.0F;
return this;
}
}
@@ -1,47 +0,0 @@
package thaumcraft.api.damagesource;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EntityDamageSource;
public class DamageSourceThaumcraft extends DamageSource
{
public static DamageSource taint = new DamageSourceThaumcraft("taint").setDamageBypassesArmor().setMagicDamage();
public static DamageSource tentacle = new DamageSourceThaumcraft("tentacle");
public static DamageSource swarm = new DamageSourceThaumcraft("swarm");
public static DamageSource dissolve = new DamageSourceThaumcraft("dissolve").setDamageBypassesArmor();
protected DamageSourceThaumcraft(String par1Str) {
super(par1Str);
}
/** This kind of damage can be blocked or not. */
private boolean isUnblockable = false;
private boolean isDamageAllowedInCreativeMode = false;
private float hungerDamage = 0.3F;
/** This kind of damage is based on fire or not. */
private boolean fireDamage;
/** This kind of damage is based on a projectile or not. */
private boolean projectile;
/**
* Whether this damage source will have its damage amount scaled based on the current difficulty.
*/
private boolean difficultyScaled;
private boolean magicDamage = false;
private boolean explosion = false;
public static DamageSource causeSwarmDamage(EntityLivingBase par0EntityLiving)
{
return new EntityDamageSource("swarm", par0EntityLiving);
}
public static DamageSource causeTentacleDamage(EntityLivingBase par0EntityLiving)
{
return new EntityDamageSource("tentacle", par0EntityLiving);
}
}
@@ -1,5 +0,0 @@
package thaumcraft.api.entities;
public interface IEldritchMob {
}
@@ -1,5 +0,0 @@
package thaumcraft.api.entities;
public interface ITaintedMob {
}
@@ -1,78 +0,0 @@
package thaumcraft.api.internal;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
public class DummyInternalMethodHandler implements IInternalMethodHandler {
@Override
public void generateVisEffect(int dim, int x, int y, int z, int x2, int y2, int z2, int color) {
}
@Override
public boolean isResearchComplete(String username, String researchkey) {
return false;
}
@Override
public boolean hasDiscoveredAspect(String username, Aspect aspect) {
return false;
}
@Override
public AspectList getDiscoveredAspects(String username) {
return null;
}
@Override
public ItemStack getStackInRowAndColumn(Object instance, int row, int column) {
return null;
}
@Override
public AspectList getObjectAspects(ItemStack is) {
return null;
}
@Override
public AspectList getBonusObjectTags(ItemStack is, AspectList ot) {
return null;
}
@Override
public AspectList generateTags(Item item, int meta) {
return null;
}
@Override
public boolean consumeVisFromWand(ItemStack wand, EntityPlayer player,
AspectList cost, boolean doit, boolean crafting) {
return false;
}
@Override
public boolean consumeVisFromWandCrafting(ItemStack wand,
EntityPlayer player, AspectList cost, boolean doit) {
return false;
}
@Override
public boolean consumeVisFromInventory(EntityPlayer player, AspectList cost) {
return false;
}
@Override
public void addWarpToPlayer(EntityPlayer player, int amount, boolean temporary) {
}
@Override
public void addStickyWarpToPlayer(EntityPlayer player, int amount) {
}
}
@@ -1,25 +0,0 @@
package thaumcraft.api.internal;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
public interface IInternalMethodHandler {
public void generateVisEffect(int dim, int x, int y, int z, int x2, int y2, int z2, int color);
public boolean isResearchComplete(String username, String researchkey);
public ItemStack getStackInRowAndColumn(Object instance, int row, int column);
public AspectList getObjectAspects(ItemStack is);
public AspectList getBonusObjectTags(ItemStack is,AspectList ot);
public AspectList generateTags(Item item, int meta);
public boolean consumeVisFromWand(ItemStack wand, EntityPlayer player, AspectList cost, boolean doit, boolean crafting);
public boolean consumeVisFromWandCrafting(ItemStack wand,EntityPlayer player, AspectList cost, boolean doit);
public boolean consumeVisFromInventory(EntityPlayer player, AspectList cost);
public void addWarpToPlayer(EntityPlayer player, int amount,boolean temporary);
public void addStickyWarpToPlayer(EntityPlayer player, int amount);
public boolean hasDiscoveredAspect(String username, Aspect aspect);
public AspectList getDiscoveredAspects(String username);
}
@@ -1,24 +0,0 @@
package thaumcraft.api.internal;
import java.util.ArrayList;
import net.minecraft.item.ItemStack;
import net.minecraft.util.WeightedRandom;
public class WeightedRandomLoot extends WeightedRandom.Item {
/** The Item/Block ID to generate in the bag. */
public ItemStack item;
public WeightedRandomLoot(ItemStack stack, int weight)
{
super(weight);
this.item = stack;
}
public static ArrayList<WeightedRandomLoot> lootBagCommon = new ArrayList<WeightedRandomLoot>();
public static ArrayList<WeightedRandomLoot> lootBagUncommon = new ArrayList<WeightedRandomLoot>();
public static ArrayList<WeightedRandomLoot> lootBagRare = new ArrayList<WeightedRandomLoot>();
}
@@ -1,53 +0,0 @@
package thaumcraft.api.nodes;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
import thaumcraft.api.aspects.IAspectContainer;
public interface INode extends IAspectContainer {
/**
* Unique identifier to distinguish nodes. Normal node id's are based on world id and coordinates
* @return
*/
public String getId();
public AspectList getAspectsBase();
/**
* Return the type of node
* @return
*/
public NodeType getNodeType();
/**
* Set the type of node
* @return
*/
public void setNodeType(NodeType nodeType);
/**
* Return the node modifier
* @return
*/
public void setNodeModifier(NodeModifier nodeModifier);
/**
* Set the node modifier
* @return
*/
public NodeModifier getNodeModifier();
/**
* Return the maximum capacity of each aspect the node can hold
* @return
*/
public int getNodeVisBase(Aspect aspect);
/**
* Set the maximum capacity of each aspect the node can hold
* @return
*/
public void setNodeVisBase(Aspect aspect, short nodeVisBase);
}
@@ -1,22 +0,0 @@
package thaumcraft.api.nodes;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
/**
*
* @author Azanor
*
* Equipped head slot items that extend this class will make nodes visible in world.
*
*/
public interface IRevealer {
/*
* If this method returns true the nodes will be visible.
*/
public boolean showNodes(ItemStack itemstack, EntityLivingBase player);
}
@@ -1,6 +0,0 @@
package thaumcraft.api.nodes;
public enum NodeModifier
{
BRIGHT, PALE, FADING
}
@@ -1,6 +0,0 @@
package thaumcraft.api.nodes;
public enum NodeType
{
NORMAL, UNSTABLE, DARK, TAINTED, HUNGRY, PURE
}
@@ -1,4 +0,0 @@
@API(owner = "Thaumcraft", apiVersion = "4.2.2.0", provides = "Thaumcraft|API")
package thaumcraft.api;
import cpw.mods.fml.common.API;
@@ -1,67 +0,0 @@
package thaumcraft.api.potions;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.potion.Potion;
import net.minecraft.util.ResourceLocation;
import thaumcraft.api.damagesource.DamageSourceThaumcraft;
import thaumcraft.api.entities.ITaintedMob;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class PotionFluxTaint extends Potion
{
public static PotionFluxTaint instance = null; // will be instantiated at runtime
private int statusIconIndex = -1;
public PotionFluxTaint(int par1, boolean par2, int par3)
{
super(par1,par2,par3);
setIconIndex(0, 0);
}
public static void init()
{
instance.setPotionName("potion.fluxtaint");
instance.setIconIndex(3, 1);
instance.setEffectiveness(0.25D);
}
@Override
public boolean isBadEffect() {
return true;
}
@Override
@SideOnly(Side.CLIENT)
public int getStatusIconIndex() {
Minecraft.getMinecraft().renderEngine.bindTexture(rl);
return super.getStatusIconIndex();
}
static final ResourceLocation rl = new ResourceLocation("thaumcraft","textures/misc/potions.png");
@Override
public void performEffect(EntityLivingBase target, int par2) {
if (target instanceof ITaintedMob) {
target.heal(1);
} else
if (!target.isEntityUndead() && !(target instanceof EntityPlayer))
{
target.attackEntityFrom(DamageSourceThaumcraft.taint, 1);
}
else
if (!target.isEntityUndead() && (target.getMaxHealth() > 1 || (target instanceof EntityPlayer)))
{
target.attackEntityFrom(DamageSourceThaumcraft.taint, 1);
}
}
public boolean isReady(int par1, int par2)
{
int k = 40 >> par2;
return k > 0 ? par1 % k == 0 : true;
}
}
@@ -1,48 +0,0 @@
package thaumcraft.api.potions;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.potion.Potion;
import net.minecraft.util.ResourceLocation;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class PotionVisExhaust extends Potion
{
public static PotionVisExhaust instance = null; // will be instantiated at runtime
private int statusIconIndex = -1;
public PotionVisExhaust(int par1, boolean par2, int par3)
{
super(par1,par2,par3);
setIconIndex(0, 0);
}
public static void init()
{
instance.setPotionName("potion.visexhaust");
instance.setIconIndex(5, 1);
instance.setEffectiveness(0.25D);
}
@Override
public boolean isBadEffect() {
return true;
}
@Override
@SideOnly(Side.CLIENT)
public int getStatusIconIndex() {
Minecraft.getMinecraft().renderEngine.bindTexture(rl);
return super.getStatusIconIndex();
}
static final ResourceLocation rl = new ResourceLocation("thaumcraft","textures/misc/potions.png");
@Override
public void performEffect(EntityLivingBase target, int par2) {
}
}
@@ -1,9 +0,0 @@
package thaumcraft.api.research;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
public interface IScanEventHandler {
ScanResult scanPhenomena(ItemStack stack, World world, EntityPlayer player);
}
@@ -1,101 +0,0 @@
package thaumcraft.api.research;
import java.util.Collection;
import java.util.LinkedHashMap;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import org.apache.logging.log4j.Level;
import cpw.mods.fml.common.FMLLog;
public class ResearchCategories {
//Research
public static LinkedHashMap <String, ResearchCategoryList> researchCategories = new LinkedHashMap <String,ResearchCategoryList>();
/**
* @param key
* @return the research item linked to this key
*/
public static ResearchCategoryList getResearchList(String key) {
return researchCategories.get(key);
}
/**
* @param key
* @return the name of the research category linked to this key.
* Must be stored as localization information in the LanguageRegistry.
*/
public static String getCategoryName(String key) {
return StatCollector.translateToLocal("tc.research_category."+key);
}
/**
* @param key the research key
* @return the ResearchItem object.
*/
public static ResearchItem getResearch(String key) {
Collection rc = researchCategories.values();
for (Object cat:rc) {
Collection rl = ((ResearchCategoryList)cat).research.values();
for (Object ri:rl) {
if ((((ResearchItem)ri).key).equals(key)) return (ResearchItem)ri;
}
}
return null;
}
/**
* This should only be done at the PostInit stage
* @param key the key used for this category
* @param icon the icon to be used for the research category tab
* @param background the resource location of the background image to use for this category
* @return the name of the research linked to this key
*/
public static void registerCategory(String key, ResourceLocation icon, ResourceLocation background) {
if (getResearchList(key)==null) {
ResearchCategoryList rl = new ResearchCategoryList(icon, background);
researchCategories.put(key, rl);
}
}
public static void addResearch(ResearchItem ri) {
ResearchCategoryList rl = getResearchList(ri.category);
if (rl!=null && !rl.research.containsKey(ri.key)) {
if (!ri.isVirtual()) {
for (ResearchItem rr:rl.research.values()) {
if (rr.displayColumn == ri.displayColumn && rr.displayRow == ri.displayRow) {
FMLLog.log(Level.FATAL, "[Thaumcraft] Research ["+ri.getName()+"] not added as it overlaps with existing research ["+rr.getName()+"]");
return;
}
}
}
rl.research.put(ri.key, ri);
if (ri.displayColumn < rl.minDisplayColumn)
{
rl.minDisplayColumn = ri.displayColumn;
}
if (ri.displayRow < rl.minDisplayRow)
{
rl.minDisplayRow = ri.displayRow;
}
if (ri.displayColumn > rl.maxDisplayColumn)
{
rl.maxDisplayColumn = ri.displayColumn;
}
if (ri.displayRow > rl.maxDisplayRow)
{
rl.maxDisplayRow = ri.displayRow;
}
}
}
}
@@ -1,37 +0,0 @@
package thaumcraft.api.research;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.util.ResourceLocation;
public class ResearchCategoryList {
/** Is the smallest column used on the GUI. */
public int minDisplayColumn;
/** Is the smallest row used on the GUI. */
public int minDisplayRow;
/** Is the biggest column used on the GUI. */
public int maxDisplayColumn;
/** Is the biggest row used on the GUI. */
public int maxDisplayRow;
/** display variables **/
public ResourceLocation icon;
public ResourceLocation background;
public ResearchCategoryList(ResourceLocation icon, ResourceLocation background) {
this.icon = icon;
this.background = background;
}
//Research
public Map<String, ResearchItem> research = new HashMap<String,ResearchItem>();
}
@@ -1,369 +0,0 @@
package thaumcraft.api.research;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
public class ResearchItem
{
/**
* A short string used as a key for this research. Must be unique
*/
public final String key;
/**
* A short string used as a reference to the research category to which this must be added.
*/
public final String category;
/**
* The aspect tags and their values required to complete this research
*/
public final AspectList tags;
/**
* This links to any research that needs to be completed before this research can be discovered or learnt.
*/
public String[] parents = null;
/**
* Like parent above, but a line will not be displayed in the thaumonomicon linking them. Just used to prevent clutter.
*/
public String[] parentsHidden = null;
/**
* any research linked to this that will be unlocked automatically when this research is complete
*/
public String[] siblings = null;
/**
* the horizontal position of the research icon
*/
public final int displayColumn;
/**
* the vertical position of the research icon
*/
public final int displayRow;
/**
* the icon to be used for this research
*/
public final ItemStack icon_item;
/**
* the icon to be used for this research
*/
public final ResourceLocation icon_resource;
/**
* How large the research grid is. Valid values are 1 to 3.
*/
private int complexity;
/**
* Special research has a spiky border. Used for important research milestones.
*/
private boolean isSpecial;
/**
* Research that can be directly purchased with RP in normal research difficulty.
*/
private boolean isSecondary;
/**
* This indicates if the research should use a circular icon border. Usually used for "passive" research
* that doesn't have recipes and grants passive effects, or that unlock automatically.
*/
private boolean isRound;
/**
* Stub research cannot be discovered by normal means, but can be unlocked via the sibling system.
*/
private boolean isStub;
/**
* This indicated that the research is completely hidden and cannot be discovered by any
* player-controlled means. The recipes will never show up in the thaumonomicon.
* Usually used to unlock "hidden" recipes via sibling unlocking, like
* the various cap and rod combos for wands.
*/
private boolean isVirtual;
/**
* Concealed research does not display in the thaumonomicon until parent researches are discovered.
*/
private boolean isConcealed;
/**
* Hidden research can only be discovered via scanning or knowledge fragments
*/
private boolean isHidden;
/**
* This is the same as isHidden, except it cannot be discovered with knowledge fragments, only scanning.
*/
private boolean isLost;
/**
* These research items will automatically unlock for all players on game start
*/
private boolean isAutoUnlock;
/**
* Scanning these items will have a chance of revealing hidden knowledge in the thaumonomicon
*/
private ItemStack[] itemTriggers;
/**
* Scanning these entities will have a chance of revealing hidden knowledge in the thaumonomicon
*/
private String[] entityTriggers;
/**
* Scanning things with these aspects will have a chance of revealing hidden knowledge in the thaumonomicon
*/
private Aspect[] aspectTriggers;
private ResearchPage[] pages = null;
public ResearchItem(String key, String category)
{
this.key = key;
this.category = category;
this.tags = new AspectList();
this.icon_resource = null;
this.icon_item = null;
this.displayColumn = 0;
this.displayRow = 0;
this.setVirtual();
}
public ResearchItem(String key, String category, AspectList tags, int col, int row, int complex, ResourceLocation icon)
{
this.key = key;
this.category = category;
this.tags = tags;
this.icon_resource = icon;
this.icon_item = null;
this.displayColumn = col;
this.displayRow = row;
this.complexity = complex;
if (complexity < 1) this.complexity = 1;
if (complexity > 3) this.complexity = 3;
}
public ResearchItem(String key, String category, AspectList tags, int col, int row, int complex, ItemStack icon)
{
this.key = key;
this.category = category;
this.tags = tags;
this.icon_item = icon;
this.icon_resource = null;
this.displayColumn = col;
this.displayRow = row;
this.complexity = complex;
if (complexity < 1) this.complexity = 1;
if (complexity > 3) this.complexity = 3;
}
public ResearchItem setSpecial()
{
this.isSpecial = true;
return this;
}
public ResearchItem setStub()
{
this.isStub = true;
return this;
}
public ResearchItem setLost()
{
this.isLost = true;
return this;
}
public ResearchItem setConcealed()
{
this.isConcealed = true;
return this;
}
public ResearchItem setHidden()
{
this.isHidden = true;
return this;
}
public ResearchItem setVirtual()
{
this.isVirtual = true;
return this;
}
public ResearchItem setParents(String... par)
{
this.parents = par;
return this;
}
public ResearchItem setParentsHidden(String... par)
{
this.parentsHidden = par;
return this;
}
public ResearchItem setSiblings(String... sib)
{
this.siblings = sib;
return this;
}
public ResearchItem setPages(ResearchPage... par)
{
this.pages = par;
return this;
}
public ResearchPage[] getPages() {
return pages;
}
public ResearchItem setItemTriggers(ItemStack... par)
{
this.itemTriggers = par;
return this;
}
public ResearchItem setEntityTriggers(String... par)
{
this.entityTriggers = par;
return this;
}
public ResearchItem setAspectTriggers(Aspect... par)
{
this.aspectTriggers = par;
return this;
}
public ItemStack[] getItemTriggers() {
return itemTriggers;
}
public String[] getEntityTriggers() {
return entityTriggers;
}
public Aspect[] getAspectTriggers() {
return aspectTriggers;
}
public ResearchItem registerResearchItem()
{
ResearchCategories.addResearch(this);
return this;
}
public String getName()
{
return StatCollector.translateToLocal("tc.research_name."+key);
}
public String getText()
{
return StatCollector.translateToLocal("tc.research_text."+key);
}
public boolean isSpecial()
{
return this.isSpecial;
}
public boolean isStub()
{
return this.isStub;
}
public boolean isLost()
{
return this.isLost;
}
public boolean isConcealed()
{
return this.isConcealed;
}
public boolean isHidden()
{
return this.isHidden;
}
public boolean isVirtual()
{
return this.isVirtual;
}
public boolean isAutoUnlock() {
return isAutoUnlock;
}
public ResearchItem setAutoUnlock()
{
this.isAutoUnlock = true;
return this;
}
public boolean isRound() {
return isRound;
}
public ResearchItem setRound() {
this.isRound = true;
return this;
}
public boolean isSecondary() {
return isSecondary;
}
public ResearchItem setSecondary() {
this.isSecondary = true;
return this;
}
public int getComplexity() {
return complexity;
}
public ResearchItem setComplexity(int complexity) {
this.complexity = complexity;
return this;
}
/**
* @return the aspect aspects ordinal with the highest value. Used to determine scroll color and similar things
*/
public Aspect getResearchPrimaryTag() {
Aspect aspect=null;
int highest=0;
if (tags!=null)
for (Aspect tag:tags.getAspects()) {
if (tags.getAmount(tag)>highest) {
aspect=tag;
highest=tags.getAmount(tag);
};
}
return aspect;
}
}
@@ -1,193 +0,0 @@
package thaumcraft.api.research;
import java.util.List;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import thaumcraft.api.aspects.AspectList;
import thaumcraft.api.crafting.CrucibleRecipe;
import thaumcraft.api.crafting.IArcaneRecipe;
import thaumcraft.api.crafting.InfusionEnchantmentRecipe;
import thaumcraft.api.crafting.InfusionRecipe;
public class ResearchPage {
public static enum PageType
{
TEXT,
TEXT_CONCEALED,
IMAGE,
CRUCIBLE_CRAFTING,
ARCANE_CRAFTING,
ASPECTS,
NORMAL_CRAFTING,
INFUSION_CRAFTING,
COMPOUND_CRAFTING,
INFUSION_ENCHANTMENT,
SMELTING
}
public PageType type = PageType.TEXT;
public String text=null;
public String research=null;
public ResourceLocation image=null;
public AspectList aspects=null;
public Object recipe=null;
public ItemStack recipeOutput=null;
/**
* @param text this can (but does not have to) be a reference to a localization variable, not the actual text.
*/
public ResearchPage(String text) {
this.type = PageType.TEXT;
this.text = text;
}
/**
* @param research this page will only be displayed if the player has discovered this research
* @param text this can (but does not have to) be a reference to a localization variable, not the actual text.
*/
public ResearchPage(String research, String text) {
this.type = PageType.TEXT_CONCEALED;
this.research = research;
this.text = text;
}
/**
* @param recipe a vanilla crafting recipe.
*/
public ResearchPage(IRecipe recipe) {
this.type = PageType.NORMAL_CRAFTING;
this.recipe = recipe;
this.recipeOutput = recipe.getRecipeOutput();
}
/**
* @param recipe a collection of vanilla crafting recipes.
*/
public ResearchPage(IRecipe[] recipe) {
this.type = PageType.NORMAL_CRAFTING;
this.recipe = recipe;
}
/**
* @param recipe a collection of arcane crafting recipes.
*/
public ResearchPage(IArcaneRecipe[] recipe) {
this.type = PageType.ARCANE_CRAFTING;
this.recipe = recipe;
}
/**
* @param recipe a collection of arcane crafting recipes.
*/
public ResearchPage(CrucibleRecipe[] recipe) {
this.type = PageType.CRUCIBLE_CRAFTING;
this.recipe = recipe;
}
/**
* @param recipe a collection of infusion crafting recipes.
*/
public ResearchPage(InfusionRecipe[] recipe) {
this.type = PageType.INFUSION_CRAFTING;
this.recipe = recipe;
}
/**
* @param recipe a compound crafting recipe.
*/
public ResearchPage(List recipe) {
this.type = PageType.COMPOUND_CRAFTING;
this.recipe = recipe;
}
/**
* @param recipe an arcane worktable crafting recipe.
*/
public ResearchPage(IArcaneRecipe recipe) {
this.type = PageType.ARCANE_CRAFTING;
this.recipe = recipe;
this.recipeOutput = recipe.getRecipeOutput();
}
/**
* @param recipe an alchemy crafting recipe.
*/
public ResearchPage(CrucibleRecipe recipe) {
this.type = PageType.CRUCIBLE_CRAFTING;
this.recipe = recipe;
this.recipeOutput = recipe.getRecipeOutput();
}
/**
* @param recipe a furnace smelting crafting recipe.
*/
public ResearchPage(ItemStack input) {
this.type = PageType.SMELTING;
this.recipe = input;
this.recipeOutput = FurnaceRecipes.smelting().getSmeltingResult(input);
}
/**
* @param recipe an infusion crafting recipe.
*/
public ResearchPage(InfusionRecipe recipe) {
this.type = PageType.INFUSION_CRAFTING;
this.recipe = recipe;
if (recipe.getRecipeOutput() instanceof ItemStack) {
this.recipeOutput = (ItemStack) recipe.getRecipeOutput();
} else {
this.recipeOutput = recipe.getRecipeInput();
}
}
/**
* @param recipe an infusion crafting recipe.
*/
public ResearchPage(InfusionEnchantmentRecipe recipe) {
this.type = PageType.INFUSION_ENCHANTMENT;
this.recipe = recipe;
// if (recipe.recipeOutput instanceof ItemStack) {
// this.recipeOutput = (ItemStack) recipe.recipeOutput;
// } else {
// this.recipeOutput = recipe.recipeInput;
// }
}
/**
* @param image
* @param caption this can (but does not have to) be a reference to a localization variable, not the actual text.
*/
public ResearchPage(ResourceLocation image, String caption) {
this.type = PageType.IMAGE;
this.image = image;
this.text = caption;
}
/**
* This function should really not be called directly - used internally
*/
public ResearchPage(AspectList as) {
this.type = PageType.ASPECTS;
this.aspects = as;
}
/**
* returns a localized text of the text field (if one exists). Returns the text field itself otherwise.
* @return
*/
public String getTranslatedText() {
String ret="";
if (text != null) {
ret = StatCollector.translateToLocal(text);
if (ret.isEmpty()) ret = text;
}
return ret;
}
}
@@ -1,39 +0,0 @@
package thaumcraft.api.research;
import net.minecraft.entity.Entity;
public class ScanResult {
public byte type = 0; //1=blocks,2=entities,3=phenomena
public int id;
public int meta;
public Entity entity;
public String phenomena;
public ScanResult(byte type, int blockId, int blockMeta, Entity entity,
String phenomena) {
super();
this.type = type;
this.id = blockId;
this.meta = blockMeta;
this.entity = entity;
this.phenomena = phenomena;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ScanResult) {
ScanResult sr = (ScanResult) obj;
if (type != sr.type)
return false;
if (type == 1
&& (id != sr.id || meta != sr.meta))
return false;
if (type == 2 && entity.getEntityId() != sr.entity.getEntityId())
return false;
if (type == 3 && !phenomena.equals(sr.phenomena))
return false;
}
return true;
}
}
@@ -1,188 +0,0 @@
package thaumcraft.api.visnet;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import thaumcraft.api.TileThaumcraft;
import thaumcraft.api.WorldCoordinates;
import thaumcraft.api.aspects.Aspect;
/**
* @author Azanor
*
* The tile entity used by nodes in the vis energy network. A node is either a source (like an aura node),
* a transport relay or vis receiver (like the infernal furnace).
*
*/
public abstract class TileVisNode extends TileThaumcraft {
WeakReference<TileVisNode> parent = null;
ArrayList<WeakReference<TileVisNode>> children = new ArrayList<WeakReference<TileVisNode>>();
/**
* @return the WorldCoordinates location of where this node is located
*/
public WorldCoordinates getLocation() {
return new WorldCoordinates(this);
}
/**
* @return the number of blocks away this node will check for parent nodes to connect to.
*/
public abstract int getRange();
/**
* @return true if this is the source or root node of the vis network.
*/
public abstract boolean isSource();
/**
* This method should never be called directly. Use VisNetHandler.drainVis() instead
* @param aspect what aspect to drain
* @param vis how much to drain
* @return how much was actually drained
*/
public int consumeVis(Aspect aspect, int vis) {
if (VisNetHandler.isNodeValid(getParent())) {
int out = getParent().get().consumeVis(aspect, vis);
if (out>0) {
triggerConsumeEffect(aspect);
}
return out;
}
return 0;
}
public void removeThisNode() {
for (WeakReference<TileVisNode> n:getChildren()) {
if (n!=null && n.get()!=null) {
n.get().removeThisNode();
}
}
children = new ArrayList<WeakReference<TileVisNode>>();
if (VisNetHandler.isNodeValid(this.getParent())) {
this.getParent().get().nodeRefresh=true;
}
this.setParent(null);
this.parentChanged();
if (this.isSource()) {
HashMap<WorldCoordinates, WeakReference<TileVisNode>> sourcelist = VisNetHandler.sources.get(worldObj.provider.dimensionId);
if (sourcelist==null) {
sourcelist = new HashMap<WorldCoordinates, WeakReference<TileVisNode>>();
}
sourcelist.remove(getLocation());
VisNetHandler.sources.put( worldObj.provider.dimensionId, sourcelist );
}
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
@Override
public void invalidate() {
removeThisNode();
super.invalidate();
}
public void triggerConsumeEffect(Aspect aspect) { }
/**
* @return
*/
public WeakReference<TileVisNode> getParent() {
return parent;
}
/**
* @return
*/
public WeakReference<TileVisNode> getRootSource() {
return VisNetHandler.isNodeValid(getParent()) ?
getParent().get().getRootSource() : this.isSource() ?
new WeakReference(this) : null;
}
/**
* @param parent
*/
public void setParent(WeakReference<TileVisNode> parent) {
this.parent = parent;
}
/**
* @return
*/
public ArrayList<WeakReference<TileVisNode>> getChildren() {
return children;
}
@Override
public boolean canUpdate() {
return true;
}
protected int nodeCounter = 0;
private boolean nodeRegged = false;
public boolean nodeRefresh = false;
@Override
public void updateEntity() {
if (!worldObj.isRemote && ((nodeCounter++) % 40==0 || nodeRefresh)) {
//check for changes
if (!nodeRefresh && children.size()>0) {
for (WeakReference<TileVisNode> n:children) {
if (n==null || n.get()==null || !VisNetHandler.canNodeBeSeen(this, n.get())) {
nodeRefresh=true;
break;
}
}
}
//refresh linked nodes
if (nodeRefresh) {
for (WeakReference<TileVisNode> n:children) {
if (n.get()!=null) {
n.get().nodeRefresh=true;
}
}
children.clear();
parent=null;
}
//redo stuff
if (isSource() && !nodeRegged) {
VisNetHandler.addSource(getWorldObj(), this);
nodeRegged = true;
} else
if (!isSource() && !VisNetHandler.isNodeValid(getParent())) {
setParent(VisNetHandler.addNode(getWorldObj(), this));
nodeRefresh=true;
}
if (nodeRefresh) {
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
parentChanged();
}
nodeRefresh=false;
}
}
public void parentChanged() { }
/**
* @return the type of shard this is attuned to:
* none -1, air 0, fire 1, water 2, earth 3, order 4, entropy 5
* Should return -1 for most implementations
*/
public byte getAttunement() {
return -1;
}
}
@@ -1,275 +0,0 @@
package thaumcraft.api.visnet;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.MovingObjectPosition.MovingObjectType;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import thaumcraft.api.ThaumcraftApi;
import thaumcraft.api.ThaumcraftApiHelper;
import thaumcraft.api.WorldCoordinates;
import thaumcraft.api.aspects.Aspect;
public class VisNetHandler {
// / NODE DRAINING
/**
* This method drains vis from a relay or source near the passed in
* location. The amount received can be less than the amount requested so
* take that into account.
*
* @param world
* @param x the x position of the draining block or entity
* @param y the y position of the draining block or entity
* @param z the z position of the draining block or entity
* @param aspect what aspect to drain
* @param amount how much to drain
* @return how much was actually drained
*/
public static int drainVis(World world, int x, int y, int z, Aspect aspect, int amount) {
int drainedAmount = 0;
WorldCoordinates drainer = new WorldCoordinates(x, y, z,
world.provider.dimensionId);
if (!nearbyNodes.containsKey(drainer)) {
calculateNearbyNodes(world, x, y, z);
}
ArrayList<WeakReference<TileVisNode>> nodes = nearbyNodes.get(drainer);
if (nodes!=null && nodes.size()>0)
for (WeakReference<TileVisNode> noderef : nodes) {
TileVisNode node = noderef.get();
if (node == null) continue;
int a = node.consumeVis(aspect, amount);
drainedAmount += a;
amount -= a;
if (a>0) {
int color = Aspect.getPrimalAspects().indexOf(aspect);
generateVisEffect(world.provider.dimensionId, x, y, z, node.xCoord, node.yCoord, node.zCoord, color);
}
if (amount <= 0) {
break;
}
}
return drainedAmount;
}
public static void generateVisEffect(int dim, int x, int y, int z, int x2, int y2, int z2, int color) {
ThaumcraftApi.internalMethods.generateVisEffect(dim, x, y, z, x2, y2, z2, color);
}
public static HashMap<Integer, HashMap<WorldCoordinates, WeakReference<TileVisNode>>> sources = new HashMap<Integer, HashMap<WorldCoordinates, WeakReference<TileVisNode>>>();
public static void addSource(World world, TileVisNode vs) {
HashMap<WorldCoordinates, WeakReference<TileVisNode>> sourcelist = sources
.get(world.provider.dimensionId);
if (sourcelist == null) {
sourcelist = new HashMap<WorldCoordinates, WeakReference<TileVisNode>>();
}
sourcelist.put(vs.getLocation(), new WeakReference(vs));
sources.put(world.provider.dimensionId, sourcelist);
nearbyNodes.clear();
}
public static boolean isNodeValid(WeakReference<TileVisNode> node) {
if (node == null || node.get() == null || node.get().isInvalid())
return false;
return true;
}
public static WeakReference<TileVisNode> addNode(World world, TileVisNode vn) {
WeakReference ref = new WeakReference(vn);
HashMap<WorldCoordinates, WeakReference<TileVisNode>> sourcelist = sources
.get(world.provider.dimensionId);
if (sourcelist == null) {
sourcelist = new HashMap<WorldCoordinates, WeakReference<TileVisNode>>();
return null;
}
ArrayList<Object[]> nearby = new ArrayList<Object[]>();
for (WeakReference<TileVisNode> root : sourcelist.values()) {
if (!isNodeValid(root))
continue;
TileVisNode source = root.get();
float r = inRange(world, vn.getLocation(), source.getLocation(),
vn.getRange());
if (r > 0) {
nearby.add(new Object[] { source, r - vn.getRange() * 2 });
}
nearby = findClosestNodes(vn, source, nearby);
cache.clear();
}
float dist = Float.MAX_VALUE;
TileVisNode closest = null;
if (nearby.size() > 0) {
for (Object[] o : nearby) {
if ((Float) o[1] < dist &&
(vn.getAttunement() == -1 || ((TileVisNode) o[0]).getAttunement() == -1 ||
vn.getAttunement() == ((TileVisNode) o[0]).getAttunement())//) {
&& canNodeBeSeen(vn,(TileVisNode)o[0])) {
dist = (Float) o[1];
closest = (TileVisNode) o[0];
}
}
}
if (closest != null) {
closest.getChildren().add(ref);
nearbyNodes.clear();
return new WeakReference(closest);
}
return null;
}
static ArrayList<WorldCoordinates> cache = new ArrayList<WorldCoordinates>();
public static ArrayList<Object[]> findClosestNodes(TileVisNode target,
TileVisNode parent, ArrayList<Object[]> in) {
if (cache.size() > 512 || cache.contains(new WorldCoordinates(parent))) return in;
cache.add(new WorldCoordinates(parent));
for (WeakReference<TileVisNode> childWR : parent.getChildren()) {
TileVisNode child = childWR.get();
if (child != null && !child.equals(target) && !child.equals(parent)) {
float r2 = inRange(child.getWorldObj(), child.getLocation(),
target.getLocation(), target.getRange());
if (r2 > 0) {
in.add(new Object[] { child, r2 });
}
in = findClosestNodes(target, child, in);
}
}
return in;
}
private static float inRange(World world, WorldCoordinates cc1,
WorldCoordinates cc2, int range) {
float distance = cc1.getDistanceSquaredToWorldCoordinates(cc2);
return distance > range * range ? -1 : distance;
}
private static HashMap<WorldCoordinates, ArrayList<WeakReference<TileVisNode>>> nearbyNodes = new HashMap<WorldCoordinates, ArrayList<WeakReference<TileVisNode>>>();
private static void calculateNearbyNodes(World world, int x, int y, int z) {
HashMap<WorldCoordinates, WeakReference<TileVisNode>> sourcelist = sources
.get(world.provider.dimensionId);
if (sourcelist == null) {
sourcelist = new HashMap<WorldCoordinates, WeakReference<TileVisNode>>();
return;
}
ArrayList<WeakReference<TileVisNode>> cn = new ArrayList<WeakReference<TileVisNode>>();
WorldCoordinates drainer = new WorldCoordinates(x, y, z,
world.provider.dimensionId);
ArrayList<Object[]> nearby = new ArrayList<Object[]>();
for (WeakReference<TileVisNode> root : sourcelist.values()) {
if (!isNodeValid(root))
continue;
TileVisNode source = root.get();
TileVisNode closest = null;
float range = Float.MAX_VALUE;
float r = inRange(world, drainer, source.getLocation(),
source.getRange());
if (r > 0) {
range = r;
closest = source;
}
ArrayList<WeakReference<TileVisNode>> children = new ArrayList<WeakReference<TileVisNode>>();
children = getAllChildren(source,children);
for (WeakReference<TileVisNode> child : children) {
TileVisNode n = child.get();
if (n != null && !n.equals(root)) {
float r2 = inRange(n.getWorldObj(), n.getLocation(),
drainer, n.getRange());
if (r2 > 0 && r2 < range) {
range = r2;
closest = n;
}
}
}
if (closest != null) {
cn.add(new WeakReference(closest));
}
}
nearbyNodes.put(drainer, cn);
}
private static ArrayList<WeakReference<TileVisNode>> getAllChildren(TileVisNode source, ArrayList<WeakReference<TileVisNode>> list) {
for (WeakReference<TileVisNode> child : source.getChildren()) {
TileVisNode n = child.get();
if (n != null) {
list.add(child);
list = getAllChildren(n,list);
}
}
return list;
}
public static boolean canNodeBeSeen(TileVisNode source,TileVisNode target)
{
MovingObjectPosition mop = ThaumcraftApiHelper.rayTraceIgnoringSource(source.getWorldObj(),
Vec3.createVectorHelper(source.xCoord+.5, source.yCoord+.5,source.zCoord+.5),
Vec3.createVectorHelper(target.xCoord+.5, target.yCoord+.5,target.zCoord+.5),
false, true, false);
return mop == null || (mop.typeOfHit==MovingObjectType.BLOCK &&
mop.blockX==target.xCoord && mop.blockY==target.yCoord && mop.blockZ==target.zCoord);
}
// public static HashMap<WorldCoordinates,WeakReference<TileVisNode>>
// noderef = new HashMap<WorldCoordinates,WeakReference<TileVisNode>>();
//
// public static TileVisNode getClosestNodeWithinRadius(World world, int x,
// int y, int z, int radius) {
// TileVisNode out = null;
// WorldCoordinates wc = null;
// float cd = Float.MAX_VALUE;
// for (int sx = x - radius; sx <= x + radius; sx++) {
// for (int sy = y - radius; sy <= y + radius; sy++) {
// for (int sz = z - radius; sz <= z + radius; sz++) {
// wc = new WorldCoordinates(sx,sy,sz,world.provider.dimensionId);
// if (noderef.containsKey(wc)) {
// float d = wc.getDistanceSquared(x, y, z);
// if (d<radius*radius && noderef.get(wc).get()!=null &&
// !noderef.get(wc).get().isReceiver() &&
// isNodeValid(noderef.get(wc).get().getParent())
// ) {
// out = noderef.get(wc).get();
// cd = d;
// }
// }
// }
// }
// }
// return out;
// }
}
@@ -1,114 +0,0 @@
package thaumcraft.api.wands;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import org.apache.logging.log4j.LogManager;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
public class FocusUpgradeType {
public static FocusUpgradeType[] types = new FocusUpgradeType[20];
public short id;
public ResourceLocation icon;
public String name;
public String text;
/**
* What aspects are used to calculate the cost of this upgrade. The amounts given is ignored, just the type is used for the calculation.
*/
public AspectList aspects;
public FocusUpgradeType(int id, ResourceLocation icon, String name, String text, AspectList aspects) {
this.id = (short) id;
this.icon = icon;
this.name = name;
this.text = text;
this.aspects = aspects;
if (id<types.length && types[id]!=null) {
LogManager.getLogger("THAUMCRAFT").fatal("Focus Upgrade id "+id+" already occupied. Ignoring.");
return;
}
// allocate space
if (id>=types.length) {
FocusUpgradeType[] temp = new FocusUpgradeType[id+1];
System.arraycopy(types, 0, temp, 0, id);
types = temp;
}
types[id] = this;
}
public String getLocalizedName() {
return StatCollector.translateToLocal(name);
}
public String getLocalizedText() {
return StatCollector.translateToLocal(text);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof FocusUpgradeType) {
return this.id == ((FocusUpgradeType)obj).id;
} else return false;
}
// basic upgrade types
public static FocusUpgradeType potency = new FocusUpgradeType( 0,
new ResourceLocation("thaumcraft", "textures/foci/potency.png"),
"focus.upgrade.potency.name","focus.upgrade.potency.text",
new AspectList().add(Aspect.WEAPON,1));
public static FocusUpgradeType frugal = new FocusUpgradeType( 1,
new ResourceLocation("thaumcraft", "textures/foci/frugal.png"),
"focus.upgrade.frugal.name","focus.upgrade.frugal.text",
new AspectList().add(Aspect.HUNGER,1));
public static FocusUpgradeType treasure = new FocusUpgradeType( 2,
new ResourceLocation("thaumcraft", "textures/foci/treasure.png"),
"focus.upgrade.treasure.name","focus.upgrade.treasure.text",
new AspectList().add(Aspect.GREED,1));
public static FocusUpgradeType enlarge = new FocusUpgradeType( 3,
new ResourceLocation("thaumcraft", "textures/foci/enlarge.png"),
"focus.upgrade.enlarge.name","focus.upgrade.enlarge.text",
new AspectList().add(Aspect.TRAVEL,1));
public static FocusUpgradeType alchemistsfire = new FocusUpgradeType( 4,
new ResourceLocation("thaumcraft", "textures/foci/alchemistsfire.png"),
"focus.upgrade.alchemistsfire.name","focus.upgrade.alchemistsfire.text",
new AspectList().add(Aspect.ENERGY,1).add(Aspect.SLIME,1));
public static FocusUpgradeType alchemistsfrost = new FocusUpgradeType( 5,
new ResourceLocation("thaumcraft", "textures/foci/alchemistsfrost.png"),
"focus.upgrade.alchemistsfrost.name","focus.upgrade.alchemistsfrost.text",
new AspectList().add(Aspect.COLD,1).add(Aspect.TRAP,1));
public static FocusUpgradeType architect = new FocusUpgradeType( 6,
new ResourceLocation("thaumcraft", "textures/foci/architect.png"),
"focus.upgrade.architect.name","focus.upgrade.architect.text",
new AspectList().add(Aspect.CRAFT,1));
public static FocusUpgradeType extend = new FocusUpgradeType( 7,
new ResourceLocation("thaumcraft", "textures/foci/extend.png"),
"focus.upgrade.extend.name","focus.upgrade.extend.text",
new AspectList().add(Aspect.EXCHANGE,1));
public static FocusUpgradeType silktouch = new FocusUpgradeType( 8,
new ResourceLocation("thaumcraft", "textures/foci/silktouch.png"),
"focus.upgrade.silktouch.name","focus.upgrade.silktouch.text",
new AspectList().add(Aspect.GREED,1));
}
@@ -1,16 +0,0 @@
package thaumcraft.api.wands;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
*
* @author azanor
*
* Implemented by a class that you wish to be called whenever a wand with this rod performs its
* update tick.
*
*/
public interface IWandRodOnUpdate {
void onUpdate(ItemStack itemstack, EntityPlayer player);
}
@@ -1,15 +0,0 @@
package thaumcraft.api.wands;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
public interface IWandTriggerManager {
/**
* This class will be called by wands with the proper parameters. It is up to you to decide what to do with them.
*/
public boolean performTrigger(World world, ItemStack wand, EntityPlayer player,
int x, int y, int z, int side, int event);
}
@@ -1,25 +0,0 @@
package thaumcraft.api.wands;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
/**
*
* @author azanor
*
* Add this to a tile entity that you wish wands to interact with in some way.
*
*/
public interface IWandable {
public int onWandRightClick(World world, ItemStack wandstack, EntityPlayer player, int x, int y, int z, int side, int md);
public ItemStack onWandRightClick(World world, ItemStack wandstack, EntityPlayer player);
public void onUsingWandTick(ItemStack wandstack, EntityPlayer player, int count);
public void onWandStoppedUsing(ItemStack wandstack, World world, EntityPlayer player, int count);
}
@@ -1,259 +0,0 @@
package thaumcraft.api.wands;
import java.text.DecimalFormat;
import java.util.LinkedHashMap;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumRarity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IIcon;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public abstract class ItemFocusBasic extends Item {
public ItemFocusBasic ()
{
super();
maxStackSize = 1;
canRepair=false;
this.setMaxDamage(0);
}
public IIcon icon;
@SideOnly(Side.CLIENT)
@Override
public IIcon getIconFromDamage(int par1) {
return icon;
}
@Override
public boolean isDamageable() {
return false;
}
@Override
public void addInformation(ItemStack stack,EntityPlayer player, List list, boolean par4) {
AspectList al = this.getVisCost(stack);
if (al!=null && al.size()>0) {
list.add(StatCollector.translateToLocal(isVisCostPerTick(stack)?"item.Focus.cost2":"item.Focus.cost1"));
for (Aspect aspect:al.getAspectsSorted()) {
DecimalFormat myFormatter = new DecimalFormat("#####.##");
String amount = myFormatter.format(al.getAmount(aspect)/100f);
list.add(" \u00A7"+aspect.getChatcolor()+aspect.getName()+"\u00A7r x "+ amount);
}
}
addFocusInformation(stack,player,list,par4);
}
public void addFocusInformation(ItemStack focusstack,EntityPlayer player, List list, boolean par4) {
LinkedHashMap<Short, Integer> map = new LinkedHashMap<Short, Integer>();
for (short id:this.getAppliedUpgrades(focusstack)) {
if (id>=0) {
int amt = 1;
if (map.containsKey(id)) {
amt = map.get(id) + 1;
}
map.put(id, amt);
}
}
for (Short id:map.keySet()) {
list.add(EnumChatFormatting.DARK_PURPLE +FocusUpgradeType.types[id].getLocalizedName()+
(map.get(id)>1?" "+StatCollector.translateToLocal("enchantment.level." + map.get(id)):""));
}
}
/**
* Purely for display on the focus tooltip (see addInformation method above)
*/
public boolean isVisCostPerTick(ItemStack focusstack) {
return false;
}
@Override
public EnumRarity getRarity(ItemStack focusstack)
{
return EnumRarity.rare;
}
/**
* What color will the focus orb be rendered on the held wand
*/
public abstract int getFocusColor(ItemStack focusstack);
/**
* Does the focus have ornamentation like the focus of the nine hells. Ornamentation is a standard icon rendered in a cross around the focus
*/
public IIcon getOrnament(ItemStack focusstack) {
// TODO Auto-generated method stub
return null;
}
/**
* An icon to be rendered inside the focus itself
*/
public IIcon getFocusDepthLayerIcon(ItemStack focusstack) {
// TODO Auto-generated method stub
return null;
}
public enum WandFocusAnimation {
WAVE, CHARGE;
}
public WandFocusAnimation getAnimation(ItemStack focusstack) {
return WandFocusAnimation.WAVE;
}
/**
* Just insert two alphanumeric characters before this string in your focus item class
*/
public String getSortingHelper(ItemStack focusstack) {
String out="";
for (short id:this.getAppliedUpgrades(focusstack)) {
out = out + id;
}
return out;
}
/**
* How much vis does this focus consume per activation.
*/
public abstract AspectList getVisCost(ItemStack focusstack);
/**
* This returns how many milliseconds must pass before the focus can be activated again.
*/
public int getActivationCooldown(ItemStack focusstack) {
return 0;
}
/**
* Used by foci like equal trade to determine their area in artchitect mode
*/
public int getMaxAreaSize(ItemStack focusstack) {
return 1;
}
/**
* What upgrades can be applied to this focus for ranks 1 to 5
*/
public abstract FocusUpgradeType[] getPossibleUpgradesByRank(ItemStack focusstack, int rank);
/**
* What upgrades does the focus currently have
*/
public short[] getAppliedUpgrades(ItemStack focusstack) {
short[] l = new short[] {-1,-1,-1,-1,-1};
NBTTagList nbttaglist = getFocusUpgradeTagList(focusstack);
if (nbttaglist == null)
{
return l;
}
else
{
for (int j = 0; j < nbttaglist.tagCount(); ++j)
{
if (j>=5) break;
l[j] = nbttaglist.getCompoundTagAt(j).getShort("id");
}
return l;
}
}
public boolean applyUpgrade(ItemStack focusstack, FocusUpgradeType type, int rank) {
short[] upgrades = getAppliedUpgrades(focusstack);
if (upgrades[rank-1]!=-1 || rank<1 || rank>5) {
return false;
}
upgrades[rank-1] = type.id;
setFocusUpgradeTagList(focusstack, upgrades);
return true;
}
/**
* Use this method to define custom logic about which upgrades can be applied. This can be used to set up upgrade "trees"
* that make certain upgrades available only when others are unlocked first, when certain research is completed, or similar logic.
*
*/
public boolean canApplyUpgrade(ItemStack focusstack, EntityPlayer player, FocusUpgradeType type, int rank) {
return true;
}
/**
* Does this focus have the passed upgrade type
*/
public boolean isUpgradedWith(ItemStack focusstack, FocusUpgradeType focusUpgradetype) {
return getUpgradeLevel(focusstack,focusUpgradetype)>0;
}
/**
* What level is the passed upgrade type on the focus. If it is not present it returns 0
*/
public int getUpgradeLevel(ItemStack focusstack, FocusUpgradeType focusUpgradetype) {
short[] list = getAppliedUpgrades(focusstack);
int level=0;
for (short id:list) {
if (id == focusUpgradetype.id)
{
level++;
}
}
return level;
}
public ItemStack onFocusRightClick(ItemStack wandstack, World world,EntityPlayer player, MovingObjectPosition movingobjectposition) {
// TODO Auto-generated method stub
return null;
}
public void onUsingFocusTick(ItemStack wandstack, EntityPlayer player,int count) {
// TODO Auto-generated method stub
}
public void onPlayerStoppedUsingFocus(ItemStack wandstack, World world, EntityPlayer player, int count) {
// TODO Auto-generated method stub
}
public boolean onFocusBlockStartBreak(ItemStack wandstack, int x, int y,int z, EntityPlayer player) {
// TODO Auto-generated method stub
return false;
}
/**
* Internal helper methods
*/
private NBTTagList getFocusUpgradeTagList(ItemStack focusstack)
{
return focusstack.stackTagCompound == null ? null : focusstack.stackTagCompound.getTagList("upgrade", 10);
}
private void setFocusUpgradeTagList(ItemStack focusstack, short[] upgrades) {
if (!focusstack.hasTagCompound())
focusstack.setTagCompound(new NBTTagCompound());
NBTTagCompound nbttagcompound = focusstack.getTagCompound();
NBTTagList tlist = new NBTTagList();
nbttagcompound.setTag("upgrade", tlist);
for (short id : upgrades) {
NBTTagCompound f = new NBTTagCompound();
f.setShort("id", id);
tlist.appendTag(f);
}
}
}
@@ -1,48 +0,0 @@
package thaumcraft.api.wands;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
/**
*
* @author Azanor
*
* This class is used to keep the material information for the various rods.
* It is also used to generate the wand recipes ingame.
*
*/
public class StaffRod extends WandRod {
boolean runes=false;
public StaffRod(String tag, int capacity, ItemStack item, int craftCost) {
super(tag+"_staff", capacity, item, craftCost);
this.texture = new ResourceLocation("thaumcraft","textures/models/wand_rod_"+tag+".png");
}
public StaffRod(String tag, int capacity, ItemStack item, int craftCost,
IWandRodOnUpdate onUpdate, ResourceLocation texture) {
super(tag+"_staff", capacity, item, craftCost, onUpdate, texture);
}
public StaffRod(String tag, int capacity, ItemStack item, int craftCost,
IWandRodOnUpdate onUpdate) {
super(tag+"_staff", capacity, item, craftCost, onUpdate);
this.texture = new ResourceLocation("thaumcraft","textures/models/wand_rod_"+tag+".png");
}
public StaffRod(String tag, int capacity, ItemStack item, int craftCost,
ResourceLocation texture) {
super(tag+"_staff", capacity, item, craftCost, texture);
}
public boolean hasRunes() {
return runes;
}
public void setRunes(boolean hasRunes) {
this.runes = hasRunes;
}
}
@@ -1,129 +0,0 @@
package thaumcraft.api.wands;
import java.util.LinkedHashMap;
import java.util.List;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import thaumcraft.api.aspects.Aspect;
/**
* This class is used to keep the material information for the various caps.
* It is also used to generate the wand recipes ingame.
* @author Azanor
*
*/
public class WandCap {
private String tag;
/**
* Cost to craft this wand. Combined with the rod cost.
*/
private int craftCost;
/**
* the amount by which all aspect costs are multiplied
*/
float baseCostModifier;
/**
* specifies a list of primal aspects that use the special discount figure instead of the normal discount.
*/
List<Aspect> specialCostModifierAspects;
/**
* the amount by which the specified aspect costs are multiplied
*/
float specialCostModifier;
/**
* The texture that will be used for the ingame wand cap
*/
ResourceLocation texture;
/**
* the actual item that makes up this cap and will be used to generate the wand recipes
*/
ItemStack item;
public static LinkedHashMap<String,WandCap> caps = new LinkedHashMap<String,WandCap>();
public WandCap (String tag, float discount, ItemStack item, int craftCost) {
this.setTag(tag);
this.baseCostModifier = discount;
this.specialCostModifierAspects = null;
texture = new ResourceLocation("thaumcraft","textures/models/wand_cap_"+getTag()+".png");
this.item=item;
this.setCraftCost(craftCost);
caps.put(tag, this);
}
public WandCap (String tag, float discount, List<Aspect> specialAspects, float discountSpecial, ItemStack item, int craftCost) {
this.setTag(tag);
this.baseCostModifier = discount;
this.specialCostModifierAspects = specialAspects;
this.specialCostModifier = discountSpecial;
texture = new ResourceLocation("thaumcraft","textures/models/wand_cap_"+getTag()+".png");
this.item=item;
this.setCraftCost(craftCost);
caps.put(tag, this);
}
public float getBaseCostModifier() {
return baseCostModifier;
}
public List<Aspect> getSpecialCostModifierAspects() {
return specialCostModifierAspects;
}
public float getSpecialCostModifier() {
return specialCostModifier;
}
public ResourceLocation getTexture() {
return texture;
}
public void setTexture(ResourceLocation texture) {
this.texture = texture;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public ItemStack getItem() {
return item;
}
public void setItem(ItemStack item) {
this.item = item;
}
public int getCraftCost() {
return craftCost;
}
public void setCraftCost(int craftCost) {
this.craftCost = craftCost;
}
/**
* The research a player needs to have finished to be able to craft a wand with this cap.
*/
public String getResearch() {
return "CAP_"+getTag();
}
// Some examples:
// WandCap WAND_CAP_IRON = new WandCap("iron", 1.1f, Arrays.asList(Aspect.ORDER),1, new ItemStack(ConfigItems.itemWandCap,1,0),1);
// WandCap WAND_CAP_GOLD = new WandCap("gold", 1f, new ItemStack(ConfigItems.itemWandCap,1,1),3);
}
@@ -1,158 +0,0 @@
package thaumcraft.api.wands;
import java.util.LinkedHashMap;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
/**
*
* @author Azanor
*
* This class is used to keep the material information for the various rods.
* It is also used to generate the wand recipes ingame.
*
*/
public class WandRod {
private String tag;
/**
* Cost to craft this wand. Combined with the rod cost.
*/
private int craftCost;
/**
* The amount of vis that can be stored - this number is actually multiplied
* by 100 for use by the wands internals
*/
int capacity;
/**
* The texture that will be used for the ingame wand rod
*/
protected ResourceLocation texture;
/**
* the actual item that makes up this rod and will be used to generate the wand recipes
*/
ItemStack item;
/**
* A class that will be called whenever the wand onUpdate tick is run
*/
IWandRodOnUpdate onUpdate;
/**
* Does the rod glow in the dark?
*/
boolean glow;
public static LinkedHashMap<String,WandRod> rods = new LinkedHashMap<String,WandRod>();
public WandRod (String tag, int capacity, ItemStack item, int craftCost, ResourceLocation texture) {
this.setTag(tag);
this.capacity = capacity;
this.texture = texture;
this.item=item;
this.setCraftCost(craftCost);
rods.put(tag, this);
}
public WandRod (String tag, int capacity, ItemStack item, int craftCost, IWandRodOnUpdate onUpdate, ResourceLocation texture) {
this.setTag(tag);
this.capacity = capacity;
this.texture = texture;
this.item=item;
this.setCraftCost(craftCost);
rods.put(tag, this);
this.onUpdate = onUpdate;
}
public WandRod (String tag, int capacity, ItemStack item, int craftCost) {
this.setTag(tag);
this.capacity = capacity;
this.texture = new ResourceLocation("thaumcraft","textures/models/wand_rod_"+getTag()+".png");
this.item=item;
this.setCraftCost(craftCost);
rods.put(tag, this);
}
public WandRod (String tag, int capacity, ItemStack item, int craftCost, IWandRodOnUpdate onUpdate) {
this.setTag(tag);
this.capacity = capacity;
this.texture = new ResourceLocation("thaumcraft","textures/models/wand_rod_"+getTag()+".png");
this.item=item;
this.setCraftCost(craftCost);
rods.put(tag, this);
this.onUpdate = onUpdate;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public int getCapacity() {
return capacity;
}
public void setCapacity(int capacity) {
this.capacity = capacity;
}
public ResourceLocation getTexture() {
return texture;
}
public void setTexture(ResourceLocation texture) {
this.texture = texture;
}
public ItemStack getItem() {
return item;
}
public void setItem(ItemStack item) {
this.item = item;
}
public int getCraftCost() {
return craftCost;
}
public void setCraftCost(int craftCost) {
this.craftCost = craftCost;
}
public IWandRodOnUpdate getOnUpdate() {
return onUpdate;
}
public void setOnUpdate(IWandRodOnUpdate onUpdate) {
this.onUpdate = onUpdate;
}
public boolean isGlowing() {
return glow;
}
public void setGlowing(boolean hasGlow) {
this.glow = hasGlow;
}
/**
* The research a player needs to have finished to be able to craft a wand with this rod.
*/
public String getResearch() {
return "ROD_"+getTag();
}
// Some examples:
// WandRod WAND_ROD_WOOD = new WandRod("wood",25,new ItemStack(Item.stick),1);
// WandRod WAND_ROD_BLAZE = new WandRod("blaze",100,new ItemStack(Item.blazeRod),7,new WandRodBlazeOnUpdate());
}
@@ -1,126 +0,0 @@
package thaumcraft.api.wands;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
/**
* This class serves a similar function to IWandable in that it allows wands to interact
* with object in the world. In this case it is most useful for adding interaction with non-mod
* blocks where you can't control what happens in their code.
* Example where it is used is in crafting the thaumonomicon from a bookshelf and the
* crucible from a cauldron
*
* @author azanor
*
*/
public class WandTriggerRegistry {
private static HashMap<String,HashMap<List,List>> triggers = new HashMap<String,HashMap<List,List>>();
private static final String DEFAULT = "default";
/**
* Registers an action to perform when a casting wand right clicks on a specific block.
* A manager class needs to be created that implements IWandTriggerManager.
* @param manager
* @param event a logical number that you can use to differentiate different events or actions
* @param block
* @param meta send -1 as a wildcard value for all possible meta values
* @param modid a unique identifier. It is best to register your own triggers using your mod id to avoid conflicts with mods that register triggers for the same block
*/
public static void registerWandBlockTrigger(IWandTriggerManager manager, int event, Block block, int meta, String modid) {
if (!triggers.containsKey(modid)) {
triggers.put(modid, new HashMap<List,List>());
}
HashMap<List,List> temp = triggers.get(modid);
temp.put(Arrays.asList(block,meta),Arrays.asList(manager,event));
triggers.put(modid, temp);
}
/**
* for legacy support
*/
public static void registerWandBlockTrigger(IWandTriggerManager manager, int event, Block block, int meta) {
registerWandBlockTrigger(manager, event, block, meta, DEFAULT);
}
/**
* Checks all trigger registries if one exists for the given block and meta
* @param block
* @param meta
* @return
*/
public static boolean hasTrigger(Block block, int meta) {
for (String modid:triggers.keySet()) {
HashMap<List,List> temp = triggers.get(modid);
if (temp.containsKey(Arrays.asList(block,meta)) ||
temp.containsKey(Arrays.asList(block,-1))) return true;
}
return false;
}
/**
* modid sensitive version
*/
public static boolean hasTrigger(Block block, int meta, String modid) {
if (!triggers.containsKey(modid)) return false;
HashMap<List,List> temp = triggers.get(modid);
if (temp.containsKey(Arrays.asList(block,meta)) ||
temp.containsKey(Arrays.asList(block,-1))) return true;
return false;
}
/**
* This is called by the onItemUseFirst function in wands.
* Parameters and return value functions like you would expect for that function.
* @param world
* @param wand
* @param player
* @param x
* @param y
* @param z
* @param side
* @param block
* @param meta
* @return
*/
public static boolean performTrigger(World world, ItemStack wand, EntityPlayer player,
int x, int y, int z, int side, Block block, int meta) {
for (String modid:triggers.keySet()) {
HashMap<List,List> temp = triggers.get(modid);
List l = temp.get(Arrays.asList(block,meta));
if (l==null) l = temp.get(Arrays.asList(block,-1));
if (l==null) continue;
IWandTriggerManager manager = (IWandTriggerManager) l.get(0);
int event = (Integer) l.get(1);
boolean result = manager.performTrigger(world, wand, player, x, y, z, side, event);
if (result) return true;
}
return false;
}
/**
* modid sensitive version
*/
public static boolean performTrigger(World world, ItemStack wand, EntityPlayer player,
int x, int y, int z, int side, Block block, int meta, String modid) {
if (!triggers.containsKey(modid)) return false;
HashMap<List,List> temp = triggers.get(modid);
List l = temp.get(Arrays.asList(block,meta));
if (l==null) l = temp.get(Arrays.asList(block,-1));
if (l==null) return false;
IWandTriggerManager manager = (IWandTriggerManager) l.get(0);
int event = (Integer) l.get(1);
return manager.performTrigger(world, wand, player, x, y, z, side, event);
}
}
-122
View File
@@ -1,122 +0,0 @@
package truetyper;
/**
* TrueTyper: Open Source TTF implementation for Minecraft.
* Copyright (C) 2013 - Mr_okushama
* Modified by Kihira
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScaledResolution;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Matrix4f;
import java.nio.FloatBuffer;
import java.util.regex.Pattern;
public class FontHelper {
private static final String formatEscape = "\u00A7";
private static final Pattern formattingCodePattern = Pattern.compile("(?i)" + String.valueOf('\u00a7') + "[0-9A-FK-OR]");
public static void drawString(String s, float x, float y, TrueTypeFont font, float scaleX, float scaleY, float... rgba){
drawString(s,x,y,font,scaleX,scaleY,0,rgba);
}
public static void drawCenteredString(String s, float x, float y, TrueTypeFont font, float scaleX, float scaleY, float ... rgba) {
drawString(s, x - (font.getWidth(s.replaceAll(formattingCodePattern.toString(), "")) / (4F / scaleX)), y, font, scaleX, scaleY, rgba);
}
public static void drawString(String s, float x, float y, TrueTypeFont font, float scaleX, float scaleY, float rotationZ, float... rgba){
Minecraft mc = Minecraft.getMinecraft();
ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
if(mc.gameSettings.hideGUI){
return;
}
float amt = 2F / sr.getScaleFactor();
if(sr.getScaleFactor() == 1){
amt = 2;
}
FloatBuffer matrixData = BufferUtils.createFloatBuffer(16);
GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, matrixData);
FontHelper.set2DMode(matrixData);
GL11.glPushMatrix();
y = mc.displayHeight-(y*sr.getScaleFactor())-(((font.getLineHeight()/amt)));
float tx = (x*sr.getScaleFactor())+(font.getWidth(s)/2);
float tranx = tx+2;
float trany = y+(font.getLineHeight()/2);
GL11.glTranslatef(tranx,trany,0);
GL11.glRotatef(rotationZ, 0f, 0f, 1f);
GL11.glTranslatef(-tranx,-trany,0);
GL11.glEnable(GL11.GL_BLEND);
if(s.contains(formatEscape)){
String[] pars = s.split(formatEscape);
float totalOffset = 0;
for(int i = 0; i < pars.length; i++){
String par = pars[i];
float[] c = rgba;
if(i > 0){
c = Formatter.getFormatted(par.charAt(0));
par = par.substring(1, par.length());
}
font.drawString((x*sr.getScaleFactor()+totalOffset), y, par, scaleX/amt, scaleY/amt, c);
totalOffset += font.getWidth(par);
}
}else{
font.drawString((x*sr.getScaleFactor()), y, s, scaleX/amt, scaleY/amt, rgba);
}
GL11.glPopMatrix();
GL11.glDisable(GL11.GL_BLEND);
FontHelper.set3DMode();
}
private static void set2DMode(FloatBuffer matrixData) {
Minecraft mc = Minecraft.getMinecraft();
ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
mc.entityRenderer.setupOverlayRendering();
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPushMatrix();
//GL11.glLoadMatrix(matrixData);
GL11.glLoadIdentity();
GL11.glOrtho(0, mc.displayWidth, 0, mc.displayHeight, -1, 1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glPushMatrix();
GL11.glLoadIdentity();
Matrix4f matrix = new Matrix4f();
matrix.load(matrixData);
GL11.glTranslatef(matrix.m30*sr.getScaleFactor(),-matrix.m31*sr.getScaleFactor(), 0f);
}
private static void set3DMode() {
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPopMatrix();
Minecraft mc = Minecraft.getMinecraft();
mc.entityRenderer.setupOverlayRendering();
}
}
-63
View File
@@ -1,63 +0,0 @@
package truetyper;
/**
* TrueTyper: Open Source TTF implementation for Minecraft.
* Copyright (C) 2013 - Mr_okushama
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import net.minecraft.client.Minecraft;
import net.minecraft.util.ResourceLocation;
import java.awt.*;
public class FontLoader{
public static TrueTypeFont loadSystemFont(String name, float defSize, boolean antialias){
return loadSystemFont(name, defSize, antialias, Font.TRUETYPE_FONT);
}
public static TrueTypeFont loadSystemFont(String name, float defSize, boolean antialias, int type){
Font font;
TrueTypeFont out = null;
try {
font = new Font(name, type, (int)defSize);
font = font.deriveFont(defSize);
out = new TrueTypeFont(font, antialias);
} catch (Exception e) {
e.printStackTrace();
}
return out;
}
public static TrueTypeFont createFont(ResourceLocation res, float defSize, boolean antialias){
return createFont(res, defSize, antialias, Font.TRUETYPE_FONT);
}
public static TrueTypeFont createFont(ResourceLocation res, float defSize, boolean antialias, int type){
Font font;
TrueTypeFont out = null;
try {
font = Font.createFont(type, Minecraft.getMinecraft().getResourceManager().getResource(res).getInputStream());
font = font.deriveFont(defSize);
out = new TrueTypeFont(font, antialias);
} catch (Exception e) {
e.printStackTrace();
}
return out;
}
}
-86
View File
@@ -1,86 +0,0 @@
package truetyper;
/**
* TrueTyper: Open Source TTF implementation for Minecraft.
* Copyright (C) 2013 - Mr_okushama
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
public class Formatter {
public static float[] getFormatted(char c){
int[] outrgba = null;
float[] outfloat;
switch(c){
case '0':
outrgba = new int[]{0,0,0,0,255};
break;
case '1':
outrgba = new int[]{0,0,170,255};
break;
case '2':
outrgba = new int[]{0,170,0,255};
break;
case '3':
outrgba = new int[]{0,170,170,255};
break;
case '4':
outrgba = new int[]{170,0,0,255};
break;
case '5':
outrgba = new int[]{170,0,170,255};
break;
case '6':
outrgba = new int[]{255,170,0,255};
break;
case '7':
outrgba = new int[]{170,170,170,255};
break;
case '8':
outrgba = new int[]{85,85,85,255};
break;
case '9':
outrgba = new int[]{85,85,255,255};
break;
case 'a':
outrgba = new int[]{85,255,85,255};
break;
case 'b':
outrgba = new int[]{85,255,255,255};
break;
case 'c':
outrgba = new int[]{255,85,85,255};
break;
case 'd':
outrgba = new int[]{85,255,255,255};
break;
case 'e':
outrgba = new int[]{255,255,85,255};
break;
case 'f':
outrgba = new int[]{255,255,255,255};
break;
default:
outrgba = new int[]{255,255,255,255};
break;
}
outfloat = new float[outrgba.length];
for(int i = 0; i < outrgba.length ; i++){
outfloat[i] = outrgba[i] > 0 ? outrgba[i]/255 : 0;
}
return outfloat;
}
}
-674
View File
@@ -1,674 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
-51
View File
@@ -1,51 +0,0 @@
An open TrueType Font renderer for Minecraft
USAGE GUIDE!
Create a TrueTypeFont object variable using either a resource location to a .ttf or
name of a system font, choose base size and whether or not you want anti aliasing like so:
testFont = FontLoader.createFont(new ResourceLocation("modid", "testfont.ttf"), 24f, false);
testFont2 = FontLoader.loadSystemFont("Arial", 16f, false);
Once the font has been created, to render to screen, simply use the static call:
FontHelper.drawString(String name, float x, float y, TrueTypeFont font, float scaleX, float scaleY, float... rgba)
eg,
FontHelper.drawString(windowTitle, posX, posY, testFont, 1f, 1f);
Thanks to ProfMobius for tweaking the matrix ( http://www.twitter.com/ProfMobius )
----
CHANGELOG:
10/11/2013 - Added support for minecraft's colour code formatting ( § / \u00A7) - I personally use net.minecraft.util.EnumChatFormatting in my strings
----
TrueTyper in part, is modified from Slick2d, full details on their licensing can be found here:
http://slick.ninjacave.com/license/
----
TrueTyper: Open Source TTF implementation for Minecraft.
Copyright (C) 2013 - Mr_okushama ( http://www.twitter.com/Mr_okushama )
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-496
View File
@@ -1,496 +0,0 @@
package truetyper;
import net.minecraft.client.renderer.Tessellator;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Map;
/**
* TrueTyper: Open Source TTF implementation for Minecraft.
* Modified from Slick2D - under BSD Licensing - http://slick.ninjacave.com/license/
*
* Copyright (c) 2013 - Slick2D
*
* All rights reserved.
*/
public class TrueTypeFont {
public final static int
ALIGN_LEFT = 0,
ALIGN_RIGHT = 1,
ALIGN_CENTER = 2;
/** Array that holds necessary information about the font characters */
private FloatObject[] charArray = new FloatObject[256];
/** Map of user defined font characters (Character <-> IntObject) */
private Map customChars = new HashMap();
/** Boolean flag on whether AntiAliasing is enabled or not */
protected boolean antiAlias;
/** Font's size */
private float fontSize = 0;
/** Font's height */
private float fontHeight = 0;
/** Texture used to cache the font 0-255 characters */
private int fontTextureID;
/** Default font texture width */
private int textureWidth = 1024;
/** Default font texture height */
private int textureHeight = 1024;
/** A reference to Java's AWT Font that we create our font texture from */
protected Font font;
/** The font metrics for our Java AWT font */
private FontMetrics fontMetrics;
private int correctL = 9, correctR = 8;
private class FloatObject {
/** Character's width */
public float width;
/** Character's height */
public float height;
/** Character's stored x position */
public float storedX;
/** Character's stored y position */
public float storedY;
}
public TrueTypeFont(Font font, boolean antiAlias, char[] additionalChars) {
this.font = font;
this.fontSize = font.getSize()+3;
this.antiAlias = antiAlias;
createSet( additionalChars );
System.out.println("TrueTypeFont loaded: "+font+" - AntiAlias = "+antiAlias);
fontHeight -= 1;
if (fontHeight <= 0) fontHeight = 1;
}
public TrueTypeFont(Font font, boolean antiAlias) {
this( font, antiAlias, null );
}
public void setCorrection(boolean on) {
if (on) {
correctL = 2;
correctR = 1;
} else {
correctL = 0;
correctR = 0;
}
}
private BufferedImage getFontImage(char ch) {
// Create a temporary image to extract the character's size
BufferedImage tempfontImage = new BufferedImage(1, 1,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) tempfontImage.getGraphics();
if (antiAlias == true) {
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
g.setFont(font);
fontMetrics = g.getFontMetrics();
float charwidth = fontMetrics.charWidth(ch)+8;
if (charwidth <= 0) {
charwidth = 7;
}
float charheight = fontMetrics.getHeight()+3;
if (charheight <= 0) {
charheight = fontSize;
}
// Create another image holding the character we are creating
BufferedImage fontImage;
fontImage = new BufferedImage((int)charwidth,(int)charheight,
BufferedImage.TYPE_INT_ARGB);
Graphics2D gt = (Graphics2D) fontImage.getGraphics();
if (antiAlias == true) {
gt.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
gt.setFont(font);
gt.setColor(Color.WHITE);
int charx = 3;
int chary = 1;
gt.drawString(String.valueOf(ch), (charx), (chary)
+ fontMetrics.getAscent());
return fontImage;
}
private void createSet( char[] customCharsArray ) {
// If there are custom chars then I expand the font texture twice
if (customCharsArray != null && customCharsArray.length > 0) {
textureWidth *= 2;
}
// In any case this should be done in other way. Texture with size 512x512
// can maintain only 256 characters with resolution of 32x32. The texture
// size should be calculated dynamicaly by looking at character sizes.
try {
BufferedImage imgTemp = new BufferedImage(textureWidth, textureHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) imgTemp.getGraphics();
g.setColor(new Color(0,0,0,1));
g.fillRect(0,0,textureWidth,textureHeight);
float rowHeight = 0;
float positionX = 0;
float positionY = 0;
int customCharsLength = ( customCharsArray != null ) ? customCharsArray.length : 0;
for (int i = 0; i < 256 + customCharsLength; i++) {
// get 0-255 characters and then custom characters
char ch = ( i < 256 ) ? (char) i : customCharsArray[i-256];
BufferedImage fontImage = getFontImage(ch);
FloatObject newIntObject = new FloatObject();
newIntObject.width = fontImage.getWidth();
newIntObject.height = fontImage.getHeight();
if (positionX + newIntObject.width >= textureWidth) {
positionX = 0;
positionY += rowHeight;
rowHeight = 0;
}
newIntObject.storedX = positionX;
newIntObject.storedY = positionY;
if (newIntObject.height > fontHeight) {
fontHeight = newIntObject.height;
}
if (newIntObject.height > rowHeight) {
rowHeight = newIntObject.height;
}
// Draw it here
g.drawImage(fontImage, (int)positionX, (int)positionY, null);
positionX += newIntObject.width;
if( i < 256 ) { // standard characters
charArray[i] = newIntObject;
} else { // custom characters
customChars.put( new Character( ch ), newIntObject );
}
fontImage = null;
}
fontTextureID = loadImage(imgTemp);
//.getTexture(font.toString(), imgTemp);
} catch (Exception e) {
System.err.println("Failed to create font.");
e.printStackTrace();
}
}
private void drawQuad(float drawX, float drawY, float drawX2, float drawY2,
float srcX, float srcY, float srcX2, float srcY2) {
float DrawWidth = drawX2 - drawX;
float DrawHeight = drawY2 - drawY;
float TextureSrcX= srcX / textureWidth;
float TextureSrcY = srcY / textureHeight;
float SrcWidth = srcX2 - srcX;
float SrcHeight = srcY2 - srcY;
float RenderWidth = (SrcWidth / textureWidth);
float RenderHeight = (SrcHeight / textureHeight);
Tessellator t = Tessellator.instance;
//t.setColorRGBA_F(0f, 0f, 0f, 1f);
t.addVertexWithUV(drawX, drawY, 0, TextureSrcX, TextureSrcY);
//GL11.glTexCoord2f(TextureSrcX, TextureSrcY);
//GL11.glVertex2f(drawX, drawY);
t.addVertexWithUV(drawX, drawY + DrawHeight, 0, TextureSrcX, TextureSrcY + RenderHeight);
//GL11.glTexCoord2f(TextureSrcX, TextureSrcY + RenderHeight);
//GL11.glVertex2f(drawX, drawY + DrawHeight);
t.addVertexWithUV(drawX + DrawWidth, drawY + DrawHeight, 0, TextureSrcX + RenderWidth, TextureSrcY + RenderHeight);
//GL11.glTexCoord2f(TextureSrcX + RenderWidth, TextureSrcY + RenderHeight);
//GL11.glVertex2f(drawX + DrawWidth, drawY + DrawHeight);
t.addVertexWithUV(drawX + DrawWidth, drawY, 0, TextureSrcX + RenderWidth, TextureSrcY);
//GL11.glTexCoord2f(TextureSrcX + RenderWidth, TextureSrcY);
//GL11.glVertex2f(drawX + DrawWidth, drawY);
}
public float getWidth(String whatchars) {
float totalwidth = 0;
FloatObject floatObject = null;
int currentChar = 0;
float lastWidth = -10f;
for (int i = 0; i < whatchars.length(); i++) {
currentChar = whatchars.charAt(i);
if (currentChar < 256) {
floatObject = charArray[currentChar];
} else {
floatObject = (FloatObject)customChars.get( new Character( (char) currentChar ) );
}
if( floatObject != null ){
totalwidth += floatObject.width/2;
lastWidth = floatObject.width;
}
}
//System.out.println("Size: "+totalwidth);
return this.fontMetrics.stringWidth(whatchars);
//return (totalwidth);
}
public float getHeight() {
return fontHeight;
}
public float getHeight(String HeightString) {
return fontHeight;
}
public float getLineHeight() {
return fontHeight;
}
public void drawString(float x, float y, String whatchars, float scaleX, float scaleY, float... rgba) {
if(rgba.length == 0) rgba = new float[]{1f,1f,1f,1f};
drawString(x,y,whatchars, 0, whatchars.length()-1, scaleX, scaleY, ALIGN_LEFT, rgba);
}
public void drawString(float x, float y, String whatchars, float scaleX, float scaleY, int format, float... rgba) {
if(rgba.length == 0) rgba = new float[]{1f,1f,1f,1f};
drawString(x,y,whatchars, 0, whatchars.length()-1, scaleX, scaleY, format, rgba);
}
public void drawString(float x, float y, String whatchars, int startIndex, int endIndex, float scaleX, float scaleY, int format, float... rgba) {
if(rgba.length == 0) rgba = new float[]{1f,1f,1f,1f};
GL11.glPushMatrix();
GL11.glScalef (scaleX, scaleY, 1.0f);
FloatObject floatObject = null;
int charCurrent;
float totalwidth = 0;
int i = startIndex, d, c;
float startY = 0;
switch (format) {
case ALIGN_RIGHT: {
d = -1;
c = correctR;
while (i < endIndex) {
if (whatchars.charAt(i) == '\n') startY -= fontHeight;
i++;
}
break;
}
case ALIGN_CENTER: {
for (int l = startIndex; l <= endIndex; l++) {
charCurrent = whatchars.charAt(l);
if (charCurrent == '\n') break;
if (charCurrent < 256) {
floatObject = charArray[charCurrent];
} else {
floatObject = (FloatObject)customChars.get( new Character( (char) charCurrent ) );
}
totalwidth += floatObject.width-correctL;
}
totalwidth /= -2;
}
case ALIGN_LEFT:
default: {
d = 1;
c = correctL;
break;
}
}
GL11.glBindTexture(GL11.GL_TEXTURE_2D, fontTextureID);
Tessellator t = Tessellator.instance;
t.startDrawingQuads();
// GL11.glBegin(GL11.GL_QUADS);
if(rgba.length == 4) t.setColorRGBA_F(rgba[0], rgba[1], rgba[2], rgba[3]);
while (i >= startIndex && i <= endIndex) {
charCurrent = whatchars.charAt(i);
if (charCurrent < 256) {
floatObject = charArray[charCurrent];
} else {
floatObject = (FloatObject)customChars.get( new Character( (char) charCurrent ) );
}
if( floatObject != null ) {
if (d < 0) totalwidth += (floatObject.width-c) * d;
if (charCurrent == '\n') {
startY -= fontHeight * d;
totalwidth = 0;
if (format == ALIGN_CENTER) {
for (int l = i+1; l <= endIndex; l++) {
charCurrent = whatchars.charAt(l);
if (charCurrent == '\n') break;
if (charCurrent < 256) {
floatObject = charArray[charCurrent];
} else {
floatObject = (FloatObject)customChars.get( new Character( (char) charCurrent ) );
}
totalwidth += floatObject.width-correctL;
}
totalwidth /= -2;
}
//if center get next lines total width/2;
}
else {
drawQuad((totalwidth + floatObject.width) + x/scaleX,
startY + y/scaleY,
totalwidth + x/scaleX,
(startY + floatObject.height) + y/scaleY,
floatObject.storedX + floatObject.width,
floatObject.storedY + floatObject.height,
floatObject.storedX,
floatObject.storedY);
if (d > 0) totalwidth += (floatObject.width-c) * d ;
}
i += d;
}
}
t.draw();
// GL11.glEnd();
GL11.glPopMatrix();
}
public static int loadImage(BufferedImage bufferedImage) {
try {
short width = (short)bufferedImage.getWidth();
short height = (short)bufferedImage.getHeight();
//textureLoader.bpp = bufferedImage.getColorModel().hasAlpha() ? (byte)32 : (byte)24;
int bpp = (byte)bufferedImage.getColorModel().getPixelSize();
ByteBuffer byteBuffer;
DataBuffer db = bufferedImage.getData().getDataBuffer();
if (db instanceof DataBufferInt) {
int intI[] = ((DataBufferInt)(bufferedImage.getData().getDataBuffer())).getData();
byte newI[] = new byte[intI.length * 4];
for (int i = 0; i < intI.length; i++) {
byte b[] = intToByteArray(intI[i]);
int newIndex = i*4;
newI[newIndex] = b[1];
newI[newIndex+1] = b[2];
newI[newIndex+2] = b[3];
newI[newIndex+3] = b[0];
}
byteBuffer = ByteBuffer.allocateDirect(
width*height*(bpp/8))
.order(ByteOrder.nativeOrder())
.put(newI);
} else {
byteBuffer = ByteBuffer.allocateDirect(
width*height*(bpp/8))
.order(ByteOrder.nativeOrder())
.put(((DataBufferByte)(bufferedImage.getData().getDataBuffer())).getData());
}
byteBuffer.flip();
int internalFormat = GL11.GL_RGBA8,
format = GL11.GL_RGBA;
IntBuffer textureId = BufferUtils.createIntBuffer(1);;
GL11.glGenTextures(textureId);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId.get(0));
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
//GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
//GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_NEAREST);
//GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
//GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST_MIPMAP_LINEAR);
//GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST_MIPMAP_NEAREST);
GL11.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE);
GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D, internalFormat, width, height, format, GL11.GL_UNSIGNED_BYTE, byteBuffer);
return textureId.get(0);
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
return -1;
}
public static boolean isSupported(String fontname) {
Font font[] = getFonts();
for (int i = font.length-1; i >= 0; i--) {
if (font[i].getName().equalsIgnoreCase(fontname))
return true;
}
return false;
}
public static Font[] getFonts() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
}
public static byte[] intToByteArray(int value) {
return new byte[] {
(byte)(value >>> 24),
(byte)(value >>> 16),
(byte)(value >>> 8),
(byte)value};
}
public void destroy() {
IntBuffer scratch = BufferUtils.createIntBuffer(1);
scratch.put(0, fontTextureID);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
GL11.glDeleteTextures(scratch);
}
}
@@ -1,676 +0,0 @@
/**
* This class was created by <Vazkii>. It's distributed as
* part of the Botania Mod. Get the Source Code in github:
* https://github.com/Vazkii/Botania
*
* Botania is Open Source and distributed under the
* Botania License: http://botaniamod.net/license.php
*
* File Created @ [Jan 14, 2014, 6:15:28 PM (GMT)]
*/
package vazkii.botania.api;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.EnumRarity;
import net.minecraft.item.Item;
import net.minecraft.item.Item.ToolMaterial;
import net.minecraft.item.ItemArmor.ArmorMaterial;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.common.util.EnumHelper;
import net.minecraftforge.oredict.OreDictionary;
import vazkii.botania.api.brew.Brew;
import vazkii.botania.api.internal.DummyMethodHandler;
import vazkii.botania.api.internal.DummySubTile;
import vazkii.botania.api.internal.IInternalMethodHandler;
import vazkii.botania.api.lexicon.KnowledgeType;
import vazkii.botania.api.lexicon.LexiconCategory;
import vazkii.botania.api.lexicon.LexiconEntry;
import vazkii.botania.api.recipe.RecipeBrew;
import vazkii.botania.api.recipe.RecipeElvenTrade;
import vazkii.botania.api.recipe.RecipeManaInfusion;
import vazkii.botania.api.recipe.RecipeMiniFlower;
import vazkii.botania.api.recipe.RecipePetals;
import vazkii.botania.api.recipe.RecipePureDaisy;
import vazkii.botania.api.recipe.RecipeRuneAltar;
import vazkii.botania.api.subtile.SubTileEntity;
import vazkii.botania.api.subtile.signature.BasicSignature;
import vazkii.botania.api.subtile.signature.SubTileSignature;
import vazkii.botania.api.wiki.IWikiProvider;
import vazkii.botania.api.wiki.SimpleWikiProvider;
import vazkii.botania.api.wiki.WikiHooks;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import cpw.mods.fml.common.Loader;
public final class BotaniaAPI {
private static List<LexiconCategory> categories = new ArrayList<LexiconCategory>();
private static List<LexiconEntry> allEntries = new ArrayList<LexiconEntry>();
public static Map<String, KnowledgeType> knowledgeTypes = new HashMap<String, KnowledgeType>();
public static Map<String, Brew> brewMap = new LinkedHashMap<String, Brew>();
public static List<String> disposableBlocks = new ArrayList<String>();
public static List<String> semiDisposableBlocks = new ArrayList<String>();
public static List<RecipePetals> petalRecipes = new ArrayList<RecipePetals>();
public static List<RecipePureDaisy> pureDaisyRecipes = new ArrayList<RecipePureDaisy>();
public static List<RecipeManaInfusion> manaInfusionRecipes = new ArrayList<RecipeManaInfusion>();
public static List<RecipeRuneAltar> runeAltarRecipes = new ArrayList<RecipeRuneAltar>();
public static List<RecipeElvenTrade> elvenTradeRecipes = new ArrayList<RecipeElvenTrade>();
public static List<RecipeBrew> brewRecipes = new ArrayList<RecipeBrew>();
public static List<RecipeManaInfusion> miniFlowerRecipes = new ArrayList<RecipeManaInfusion>();
private static BiMap<String, Class<? extends SubTileEntity>> subTiles = HashBiMap.<String, Class<? extends SubTileEntity>> create();
private static Map<Class<? extends SubTileEntity>, SubTileSignature> subTileSignatures = new HashMap<Class<? extends SubTileEntity>, SubTileSignature>();
public static Set<String> subtilesForCreativeMenu = new LinkedHashSet();
public static Map<String, String> subTileMods = new HashMap<String, String>();
public static BiMap<String, String> miniFlowers = HashBiMap.<String, String> create();
public static Map<String, Integer> oreWeights = new HashMap<String, Integer>();
public static Map<String, Integer> oreWeightsNether = new HashMap<String, Integer>();
public static Map<Item, Block> seeds = new HashMap();
public static Set<Item> looniumBlacklist = new LinkedHashSet<Item>();
public static Set<Block> paintableBlocks = new LinkedHashSet<Block>();
public static Set<String> magnetBlacklist = new LinkedHashSet<String>();
public static Set<Class<? extends Entity>> gravityRodBlacklist = new LinkedHashSet<Class<? extends Entity>>();
public static ArmorMaterial manasteelArmorMaterial = EnumHelper.addArmorMaterial("MANASTEEL", 16, new int[] { 2, 6, 5, 2 }, 18);
public static ToolMaterial manasteelToolMaterial = EnumHelper.addToolMaterial("MANASTEEL", 3, 300, 6.2F, 2F, 20);
public static ArmorMaterial elementiumArmorMaterial = EnumHelper.addArmorMaterial("B_ELEMENTIUM", 18, new int[] { 2, 6, 5, 2 }, 18);
public static ToolMaterial elementiumToolMaterial = EnumHelper.addToolMaterial("B_ELEMENTIUM", 3, 720, 6.2F, 2F, 20);
public static ArmorMaterial terrasteelArmorMaterial = EnumHelper.addArmorMaterial("TERRASTEEL", 34, new int[] {3, 8, 6, 3}, 26);
public static ToolMaterial terrasteelToolMaterial = EnumHelper.addToolMaterial("TERRASTEEL", 4, 2300, 9F, 3F, 26);
public static ArmorMaterial manaweaveArmorMaterial = EnumHelper.addArmorMaterial("MANAWEAVE", 5, new int[] { 1, 2, 2, 1 }, 18);
public static EnumRarity rarityRelic = EnumHelper.addRarity("RELIC", EnumChatFormatting.GOLD, "Relic");
public static KnowledgeType basicKnowledge;
public static KnowledgeType elvenKnowledge;
// This is here for completeness sake, but you shouldn't use it
public static KnowledgeType relicKnowledge;
// All of these categories are initialized during botania's PreInit stage.
public static LexiconCategory categoryBasics;
public static LexiconCategory categoryMana;
public static LexiconCategory categoryFunctionalFlowers;
public static LexiconCategory categoryGenerationFlowers;
public static LexiconCategory categoryDevices;
public static LexiconCategory categoryTools;
public static LexiconCategory categoryBaubles;
public static LexiconCategory categoryEnder;
public static LexiconCategory categoryAlfhomancy;
public static LexiconCategory categoryMisc;
public static Brew fallbackBrew = new Brew("fallback", "botania.brew.fallback", 0, 0);
static {
registerSubTile("", DummySubTile.class);
basicKnowledge = registerKnowledgeType("minecraft", EnumChatFormatting.RESET, true);
elvenKnowledge = registerKnowledgeType("alfheim", EnumChatFormatting.DARK_GREEN, false);
relicKnowledge = registerKnowledgeType("relic", EnumChatFormatting.DARK_PURPLE, false);
addOreWeight("oreAluminum", 3940); // Tinkers' Construct
addOreWeight("oreAmber", 2075); // Thaumcraft
addOreWeight("oreApatite", 1595); // Forestry
addOreWeight("oreBlueTopaz", 3195); // Ars Magica
addOreWeight("oreCertusQuartz", 3975); // Applied Energistics
addOreWeight("oreChimerite", 3970); // Ars Magica
addOreWeight("oreCinnabar", 2585); // Thaumcraft
addOreWeight("oreCoal", 46525); // Vanilla
addOreWeight("oreCopper", 8325); // IC2, Thermal Expansion, Tinkers' Construct, etc.
addOreWeight("oreDark", 1350); // EvilCraft
addOreWeight("oreDarkIron", 1700); // Factorization (older versions)
addOreWeight("oreFzDarkIron", 1700); // Factorization (newer versions)
addOreWeight("oreDiamond", 1265); // Vanilla
addOreWeight("oreEmerald", 780); // Vanilla
addOreWeight("oreGalena", 1000); // Factorization
addOreWeight("oreGold", 2970); // Vanilla
addOreWeight("oreInfusedAir", 925); // Thaumcraft
addOreWeight("oreInfusedEarth", 925); // Thaumcraft
addOreWeight("oreInfusedEntropy", 925); // Thaumcraft
addOreWeight("oreInfusedFire", 925); // Thaumcraft
addOreWeight("oreInfusedOrder", 925); // Thaumcraft
addOreWeight("oreInfusedWater", 925); // Thaumcraft
addOreWeight("oreIron", 20665); // Vanilla
addOreWeight("oreLapis", 1285); // Vanilla
addOreWeight("oreLead", 7985); // IC2, Thermal Expansion, Factorization, etc.
addOreWeight("oreMCropsEssence", 3085); // Magical Crops
addOreWeight("oreMithril", 8); // Thermal Expansion
addOreWeight("oreNickel", 2275); // Thermal Expansion
addOreWeight("oreOlivine", 1100); // Project RED
addOreWeight("orePlatinum", 365); // Thermal Expansion
addOreWeight("oreRedstone", 6885); // Vanilla
addOreWeight("oreRuby", 1100); // Project RED
addOreWeight("oreSapphire", 1100); // Project RED
addOreWeight("oreSilver", 6300); // Thermal Expansion, Factorization, etc.
addOreWeight("oreSulfur", 1105); // Railcraft
addOreWeight("oreTin", 9450); // IC2, Thermal Expansion, etc.
addOreWeight("oreUranium", 1337); // IC2
addOreWeight("oreVinteum", 5925); // Ars Magica
addOreWeight("oreYellorite", 3520); // Big Reactors
addOreWeight("oreZinc", 6485); // Flaxbeard's Steam Power
addOreWeight("oreMythril", 6485); // Simple Ores2
addOreWeight("oreAdamantium", 2275); // Simple Ores2
addOreWeight("oreTungsten", 3520); // Simple Tungsten
addOreWeightNether("oreQuartz", 19600); // Vanilla
addOreWeightNether("oreCobalt", 500); // Tinker's Construct
addOreWeightNether("oreArdite", 500); // Tinker's Construct
addOreWeightNether("oreFirestone", 5); // Railcraft
addOreWeightNether("oreNetherCoal", 17000); // Nether Ores
addOreWeightNether("oreNetherCopper", 4700); // Nether Ores
addOreWeightNether("oreNetherDiamond", 175); // Nether Ores
addOreWeightNether("oreNetherEssence", 2460); // Magical Crops
addOreWeightNether("oreNetherGold", 3635); // Nether Ores
addOreWeightNether("oreNetherIron", 5790); // Nether Ores
addOreWeightNether("oreNetherLapis", 3250); // Nether Ores
addOreWeightNether("oreNetherLead", 2790); // Nether Ores
addOreWeightNether("oreNetherNickel", 1790); // Nether Ores
addOreWeightNether("oreNetherPlatinum", 170); // Nether Ores
addOreWeightNether("oreNetherRedstone", 5600); // Nether Ores
addOreWeightNether("oreNetherSilver", 1550); // Nether Ores
addOreWeightNether("oreNetherSteel", 1690); // Nether Ores
addOreWeightNether("oreNetherTin", 3750); // Nether Ores
addOreWeightNether("oreFyrite", 1000); // Netherrocks
addOreWeightNether("oreAshstone", 1000); // Netherrocks
addOreWeightNether("oreDragonstone", 175); // Netherrocks
addOreWeightNether("oreArgonite", 1000); // Netherrocks
addOreWeightNether("oreOnyx", 500); // SimpleOres 2
addOreWeightNether("oreHaditeCoal", 500); // Hadite
addSeed(Items.wheat_seeds, Blocks.wheat);
addSeed(Items.potato, Blocks.potatoes);
addSeed(Items.carrot, Blocks.carrots);
addSeed(Items.nether_wart, Blocks.nether_wart);
addSeed(Items.pumpkin_seeds, Blocks.pumpkin_stem);
addSeed(Items.melon_seeds, Blocks.melon_stem);
registerModWiki("Minecraft", new SimpleWikiProvider("Minecraft Wiki", "http://minecraft.gamepedia.com/%s"));
IWikiProvider technicWiki = new SimpleWikiProvider("Technic Wiki", "http://wiki.technicpack.net/%s");
IWikiProvider mekanismWiki = new SimpleWikiProvider("Mekanism Wiki", "http://wiki.aidancbrady.com/wiki/%s");
IWikiProvider buildcraftWiki = new SimpleWikiProvider("BuildCraft Wiki", "http://www.mod-buildcraft.com/wiki/doku.php?id=%s");
registerModWiki("Mekanism", mekanismWiki);
registerModWiki("MekanismGenerators", mekanismWiki);
registerModWiki("MekanismTools", mekanismWiki);
registerModWiki("EnderIO", new SimpleWikiProvider("EnderIO Wiki", "http://wiki.enderio.com/%s"));
registerModWiki("TropiCraft", new SimpleWikiProvider("Tropicraft Wiki", "http://wiki.tropicraft.net/wiki/%s"));
registerModWiki("RandomThings", new SimpleWikiProvider("Random Things Wiki", "http://randomthingsminecraftmod.wikispaces.com/%s"));
registerModWiki("Witchery", new SimpleWikiProvider("Witchery Wiki", "https://sites.google.com/site/witcherymod/%s", "-", true));
registerModWiki("AppliedEnergistics2", new SimpleWikiProvider("AE2 Wiki", "http://ae-mod.info/%s"));
registerModWiki("BigReactors", technicWiki);
registerModWiki("BuildCraft|Core", buildcraftWiki);
registerModWiki("BuildCraft|Builders", buildcraftWiki);
registerModWiki("BuildCraft|Energy", buildcraftWiki);
registerModWiki("BuildCraft|Factory", buildcraftWiki);
registerModWiki("BuildCraft|Silicon", buildcraftWiki);
registerModWiki("BuildCraft|Transport", buildcraftWiki);
registerModWiki("ArsMagica2", new SimpleWikiProvider("ArsMagica2 Wiki", "http://wiki.arsmagicamod.com/wiki/%s"));
registerModWiki("PneumaticCraft", new SimpleWikiProvider("PneumaticCraft Wiki", "http://www.minemaarten.com/wikis/pneumaticcraft-wiki/pneumaticcraft-wiki-%s"));
registerModWiki("StevesCarts2", new SimpleWikiProvider("Steve's Carts Wiki", "http://stevescarts2.wikispaces.com/%s"));
registerModWiki("GanysSurface", new SimpleWikiProvider("Gany's Surface Wiki", "http://ganys-surface.wikia.com/wiki/%s"));
registerModWiki("GanysNether", new SimpleWikiProvider("Gany's Nether Wiki", "http://ganys-nether.wikia.com/wiki/%s"));
registerModWiki("GanysEnd", new SimpleWikiProvider("Gany's End Wiki", "http://ganys-end.wikia.com/wiki/%s"));
registerPaintableBlock(Blocks.stained_glass);
registerPaintableBlock(Blocks.stained_glass_pane);
registerPaintableBlock(Blocks.stained_hardened_clay);
registerPaintableBlock(Blocks.wool);
registerPaintableBlock(Blocks.carpet);
registerDisposableBlock("dirt"); // Vanilla
registerDisposableBlock("sand"); // Vanilla
registerDisposableBlock("gravel"); // Vanilla
registerDisposableBlock("cobblestone"); // Vanilla
registerDisposableBlock("netherrack"); // Vanilla
registerSemiDisposableBlock("stoneAndesite"); // Botania
registerSemiDisposableBlock("stoneBasalt"); // Botania
registerSemiDisposableBlock("stoneDiorite"); // Botania
registerSemiDisposableBlock("stoneGranite"); // Botania
}
/**
* The internal method handler in use.
* <b>DO NOT OVERWRITE THIS OR YOU'RE GOING TO FEEL MY WRATH WHEN I UPDATE THE API.</b>
* The fact I have to write that means some moron already tried, don't be that moron.
* @see IInternalMethodHandler
*/
public static IInternalMethodHandler internalHandler = new DummyMethodHandler();
/**
* Registers a new Knowledge Type.
* @param id The ID for this knowledge type.
* @param color The color to display this knowledge type as.
*/
public static KnowledgeType registerKnowledgeType(String id, EnumChatFormatting color, boolean autoUnlock) {
KnowledgeType type = new KnowledgeType(id, color, autoUnlock);
knowledgeTypes.put(id, type);
return type;
}
/**
* Registers a Brew and returns it.
*/
public static Brew registerBrew(Brew brew) {
brewMap.put(brew.getKey(), brew);
return brew;
}
/**
* Gets a brew from the key passed in, returns the fallback if
* it's not in the map.
*/
public static Brew getBrewFromKey(String key) {
if(brewMap.containsKey(key))
return brewMap.get(key);
return fallbackBrew;
}
/*
* Registers a Block as disposable using its Ore Dictionary Name.
*/
public static void registerDisposableBlock(String oreDictName) {
disposableBlocks.add(oreDictName);
}
/*
* Registers a Block as semi disposable using its Ore Dictionary Name.
* This means it will not be trashed when sneaking.
*/
public static void registerSemiDisposableBlock(String oreDictName) {
semiDisposableBlocks.add(oreDictName);
}
/**
* Registers a paintableBlock and returns it.
*/
public static Block registerPaintableBlock(Block paintable){
paintableBlocks.add(paintable);
return paintable;
}
/*
* Blacklists an Entity from being affected by the Rod of the Shaded Mesa.
* Pass in the class for the Entity, e.g. EntityCow.class
*/
public static void blacklistEntityFromGravityRod(Class entity) {
gravityRodBlacklist.add(entity);
}
/*
* Checks if the provided Entity is contained in the Blacklist.
* Pass in the class for the Entity, e.g. entity.getClass()
*/
public static boolean isEntityBlacklistedFromGravityRod(Class entity) {
return gravityRodBlacklist.contains(entity);
}
/**
* Blacklists an item from being pulled by the Ring of Magnetization.
* Short.MAX_VALUE can be used as the stack's damage for a wildcard.
*/
public static void blacklistItemFromMagnet(ItemStack stack) {
String key = getMagnetKey(stack);
magnetBlacklist.add(key);
}
/**
* Blacklists a block from having items on top of it being pulled by the Ring of Magnetization.
* Short.MAX_VALUE can be used as meta for a wildcard.
*/
public static void blacklistBlockFromMagnet(Block block, int meta) {
String key = getMagnetKey(block, meta);
magnetBlacklist.add(key);
}
public static boolean isItemBlacklistedFromMagnet(ItemStack stack) {
return isItemBlacklistedFromMagnet(stack, 0);
}
public static boolean isItemBlacklistedFromMagnet(ItemStack stack, int recursion) {
if(recursion > 5)
return false;
if(stack.getItemDamage() != Short.MAX_VALUE) {
ItemStack copy = new ItemStack(stack.getItem(), 0, Short.MAX_VALUE);
boolean general = isItemBlacklistedFromMagnet(copy, recursion + 1);
if(general)
return true;
}
String key = getMagnetKey(stack);
return magnetBlacklist.contains(key);
}
public static boolean isBlockBlacklistedFromMagnet(Block block, int meta) {
return isBlockBlacklistedFromMagnet(block, meta, 0);
}
public static boolean isBlockBlacklistedFromMagnet(Block block, int meta, int recursion) {
if(recursion >= 5)
return false;
if(meta != Short.MAX_VALUE) {
boolean general = isBlockBlacklistedFromMagnet(block, Short.MAX_VALUE, recursion + 1);
if(general)
return true;
}
String key = getMagnetKey(block, meta);
return magnetBlacklist.contains(key);
}
/**
* Registers a Petal Recipe.
* @param output The ItemStack to craft.
* @param inputs The objects for crafting. Can be ItemStack, MappableStackWrapper
* or String (case for Ore Dictionary). The array can't be larger than 16.
* @return The recipe created.
*/
public static RecipePetals registerPetalRecipe(ItemStack output, Object... inputs) {
RecipePetals recipe = new RecipePetals(output, inputs);
petalRecipes.add(recipe);
return recipe;
}
/**
* Registers a Pure Daisy Recipe.
* @param input The block that works as an input for the recipe. Can be a Block or an oredict String.
* @param output The block to be placed upon recipe completion.
* @param outputMeta The metadata to be placed upon recipe completion.
* @return The recipe created.
*/
public static RecipePureDaisy registerPureDaisyRecipe(Object input, Block output, int outputMeta) {
RecipePureDaisy recipe = new RecipePureDaisy(input, output, outputMeta);
pureDaisyRecipes.add(recipe);
return recipe;
}
/**
* Registers a Rune Altar Recipe.
* @param output The ItemStack to craft.
* @param mana The amount of mana required. Don't go over 100000!
* @param inputs The objects for crafting. Can be ItemStack, MappableStackWrapper
* or String (case for Ore Dictionary). The array can't be larger than 16.
* @return The recipe created.
*/
public static RecipeRuneAltar registerRuneAltarRecipe(ItemStack output, int mana, Object... inputs) {
RecipeRuneAltar recipe = new RecipeRuneAltar(output, mana, inputs);
runeAltarRecipes.add(recipe);
return recipe;
}
/**
* Registers a Mana Infusion Recipe (throw an item in a mana pool)
* @param output The ItemStack to craft
* @param input The input item, be it an ItemStack or an ore dictionary entry String.
* @param mana The amount of mana required. Don't go over 100000!
* @return The recipe created.
*/
public static RecipeManaInfusion registerManaInfusionRecipe(ItemStack output, Object input, int mana) {
RecipeManaInfusion recipe = new RecipeManaInfusion(output, input, mana);
manaInfusionRecipes.add(recipe);
return recipe;
}
/**
* Register a Mana Infusion Recipe and flags it as an Alchemy recipe (requires an
* Alchemy Catalyst below the pool).
* @see BotaniaAPI#registerManaInfusionRecipe
*/
public static RecipeManaInfusion registerManaAlchemyRecipe(ItemStack output, Object input, int mana) {
RecipeManaInfusion recipe = registerManaInfusionRecipe(output, input, mana);
recipe.setAlchemy(true);
return recipe;
}
/**
* Register a Mana Infusion Recipe and flags it as an Conjuration recipe (requires a
* Conjuration Catalyst below the pool).
* @see BotaniaAPI#registerManaInfusionRecipe
*/
public static RecipeManaInfusion registerManaConjurationRecipe(ItemStack output, Object input, int mana) {
RecipeManaInfusion recipe = registerManaInfusionRecipe(output, input, mana);
recipe.setConjuration(true);
return recipe;
}
/**
* Registers a Elven Trade recipe (throw an item in an Alfheim Portal).
* @param output The ItemStack to return.
* @param inputs The items required, can be ItemStack or ore dictionary entry string.
* @return The recipe created.
*/
public static RecipeElvenTrade registerElvenTradeRecipe(ItemStack output, Object... inputs) {
RecipeElvenTrade recipe = new RecipeElvenTrade(output, inputs);
elvenTradeRecipes.add(recipe);
return recipe;
}
/**
* Registers a Brew Recipe (for the Botanical Brewery).
* @param brew The brew in to be set in this recipe.
* @inputs The items used in the recipe, no more than 6.
*/
public static RecipeBrew registerBrewRecipe(Brew brew, Object... inputs) {
RecipeBrew recipe = new RecipeBrew(brew, inputs);
brewRecipes.add(recipe);
return recipe;
}
/**
* Registers a SubTileEntity, a new special flower. Look in the subtile package of the API.
* If you call this after PostInit you're a failiure and we are very disappointed in you.
*/
public static void registerSubTile(String key, Class<? extends SubTileEntity> subtileClass) {
subTiles.put(key, subtileClass);
subTileMods.put(key, Loader.instance().activeModContainer().getModId());
}
/**
* Register a SubTileEntity and makes it a mini flower. Also adds the recipe and returns it.
* @see BotaniaAPI#registerSubTile
*/
public static RecipeManaInfusion registerMiniSubTile(String key, Class<? extends SubTileEntity> subtileClass, String original) {
registerSubTile(key, subtileClass);
miniFlowers.put(original, key);
RecipeMiniFlower recipe = new RecipeMiniFlower(key, original, 2500);
manaInfusionRecipes.add(recipe);
miniFlowerRecipes.add(recipe);
return recipe;
}
/**
* Registers a SubTileEntity's signature.
* @see SubTileSignature
*/
public static void registerSubTileSignature(Class<? extends SubTileEntity> subtileClass, SubTileSignature signature) {
subTileSignatures.put(subtileClass, signature);
}
/**
* Gets the singleton signature for a SubTileEntity class. Registers a fallback if one wasn't registered
* before the call.
*/
public static SubTileSignature getSignatureForClass(Class<? extends SubTileEntity> subtileClass) {
if(!subTileSignatures.containsKey(subtileClass))
registerSubTileSignature(subtileClass, new BasicSignature(subTiles.inverse().get(subtileClass)));
return subTileSignatures.get(subtileClass);
}
/**
* Gets the singleton signature for a SubTileEntity's name. Registers a fallback if one wasn't registered
* before the call.
*/
public static SubTileSignature getSignatureForName(String name) {
Class<? extends SubTileEntity> subtileClass = subTiles.get(name);
return getSignatureForClass(subtileClass);
}
/**
* Adds the key for a SubTileEntity into the creative menu. This goes into the
* subtilesForCreativeMenu Set. This does not need to be called for mini flowers,
* those will just use the mini flower map to add themselves next to the source.
*/
public static void addSubTileToCreativeMenu(String key) {
subtilesForCreativeMenu.add(key);
}
/**
* Adds a category to the list of registered categories to appear in the Lexicon.
*/
public static void addCategory(LexiconCategory category) {
categories.add(category);
}
/**
* Gets all registered categories.
*/
public static List<LexiconCategory> getAllCategories() {
return categories;
}
/**
* Gets all registered entries.
*/
public static List<LexiconEntry> getAllEntries() {
return allEntries;
}
/**
* Registers a Lexicon Entry and adds it to the category passed in.
*/
public static void addEntry(LexiconEntry entry, LexiconCategory category) {
allEntries.add(entry);
category.entries.add(entry);
}
/**
* Maps an ore (ore dictionary key) to it's weight on the world generation. This
* is used for the Orechid flower. Check the static block in the BotaniaAPI class
* to get the weights for the vanilla blocks.<br>
* Alternatively get the values with the OreDetector mod:<br>
* https://gist.github.com/Vazkii/9493322
*/
public static void addOreWeight(String ore, int weight) {
oreWeights.put(ore, weight);
}
/**
* Maps an ore (ore dictionary key) to it's weight on the nether world generation. This
* is used for the Orechid Ignem flower. Check the static block in the BotaniaAPI class
* to get the weights for the vanilla blocks.<br>
* Alternatively get the values with the OreDetector mod:<br>
* https://gist.github.com/Vazkii/9493322
*/
public static void addOreWeightNether(String ore, int weight) {
if(ore.contains("Nether") && OreDictionary.getOres(ore.replace("Nether", "")).size() == 0)
return;
oreWeightsNether.put(ore, weight);
}
public static int getOreWeight(String ore) {
return oreWeights.get(ore);
}
public static int getOreWeightNether(String ore) {
return oreWeightsNether.get(ore);
}
/**
* Allows an item to be counted as a seed. Any item in this list can be
* dispensed by a dispenser, the block is the block to be placed.
*/
public static void addSeed(Item item, Block block) {
seeds.put(item, block);
}
/**
* Blacklists an item from the Loonium drop table.
*/
public static void blackListItemFromLoonium(Item item) {
looniumBlacklist.add(item);
}
/**
* Gets the last recipe to have been added to the recipe list.
*/
public static IRecipe getLatestAddedRecipe() {
List<IRecipe> list = CraftingManager.getInstance().getRecipeList();
return list.get(list.size() - 1);
}
/**
* Gets the last x recipes added to the recipe list.
*/
public static List<IRecipe> getLatestAddedRecipes(int x) {
List<IRecipe> list = CraftingManager.getInstance().getRecipeList();
List<IRecipe> newList = new ArrayList();
for(int i = x - 1; i >= 0; i--)
newList.add(list.get(list.size() - 1 - i));
return newList;
}
/**
* Registers a Wiki provider for a mod so it uses that instead of the fallback
* FTB wiki. Make sure to call this on PostInit only!
*/
public static void registerModWiki(String mod, IWikiProvider provider) {
WikiHooks.registerModWiki(mod, provider);
}
public static Class<? extends SubTileEntity> getSubTileMapping(String key) {
if(!subTiles.containsKey(key))
key = "";
return subTiles.get(key);
}
public static String getSubTileStringMapping(Class<? extends SubTileEntity> clazz) {
return subTiles.inverse().get(clazz);
}
public static Set<String> getAllSubTiles() {
return subTiles.keySet();
}
private static String getMagnetKey(ItemStack stack) {
if(stack == null)
return "";
return "i_" + stack.getItem().getUnlocalizedName() + "@" + stack.getItemDamage();
}
private static String getMagnetKey(Block block, int meta) {
return "bm_" + block.getUnlocalizedName() + "@" + meta;
}
}
Loaded 100 of 233 files, more files were not shown because too many files have changed in this diff. Show more