diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..e7920da8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+/bin
+/out
+/build
+/run
+/.idea/workspace.xml
+/.idea/dictionaries
+/eclipse
+/.gradle
+/*.iml
+/*.ipr
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..926a8ae6
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "bdlib"]
+ path = bdlib
+ url = D:\\dropbox\\mcmods\\bdlib.git
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 00000000..eac6c590
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+gendustry
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 00000000..f6e673ad
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
new file mode 100644
index 00000000..5e9478bd
--- /dev/null
+++ b/.idea/codeStyleSettings.xml
@@ -0,0 +1,230 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GETTERS_AND_SETTERS
+ KEEP
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 00000000..217af471
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/MMPL__gendustry_.xml b/.idea/copyright/MMPL__gendustry_.xml
new file mode 100644
index 00000000..b490696a
--- /dev/null
+++ b/.idea/copyright/MMPL__gendustry_.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/copyright/MMPL__lib_.xml b/.idea/copyright/MMPL__lib_.xml
new file mode 100644
index 00000000..fa6252cc
--- /dev/null
+++ b/.idea/copyright/MMPL__lib_.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 00000000..d1d7b7d2
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 00000000..e206d70d
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/highlighting.xml b/.idea/highlighting.xml
new file mode 100644
index 00000000..f33b64d9
--- /dev/null
+++ b/.idea/highlighting.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 00000000..20bcff66
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 00000000..3b312839
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 00000000..0cae957f
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 00000000..511dc350
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scala_settings.xml b/.idea/scala_settings.xml
new file mode 100644
index 00000000..f350c240
--- /dev/null
+++ b/.idea/scala_settings.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/lib.xml b/.idea/scopes/lib.xml
new file mode 100644
index 00000000..9ef6479d
--- /dev/null
+++ b/.idea/scopes/lib.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/.idea/scopes/main.xml b/.idea/scopes/main.xml
new file mode 100644
index 00000000..6397915a
--- /dev/null
+++ b/.idea/scopes/main.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/.idea/scopes/my_files.xml b/.idea/scopes/my_files.xml
new file mode 100644
index 00000000..af16f14b
--- /dev/null
+++ b/.idea/scopes/my_files.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 00000000..922003b8
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 00000000..3b000203
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000..275077f8
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/MMPL-1.0.txt b/MMPL-1.0.txt
new file mode 100644
index 00000000..a445a6fb
--- /dev/null
+++ b/MMPL-1.0.txt
@@ -0,0 +1,87 @@
+Minecraft Mod Public License
+============================
+
+Version 1.0.1
+
+0. Definitions
+--------------
+
+Minecraft: Denotes a copy of the Minecraft game licensed by Mojang AB
+
+User: Anybody that interacts with the software in one of the following ways:
+ - play
+ - decompile
+ - recompile or compile
+ - modify
+ - distribute
+
+Mod: The mod code designated by the present license, in source form, binary
+form, as obtained standalone, as part of a wider distribution or resulting from
+the compilation of the original or modified sources.
+
+Dependency: Code required for the mod to work properly. This includes
+dependencies required to compile the code as well as any file or modification
+that is explicitely or implicitely required for the mod to be working.
+
+1. Scope
+--------
+
+The present license is granted to any user of the mod. As a prerequisite,
+a user must own a legally acquired copy of Minecraft
+
+2. Liability
+------------
+
+This mod is provided 'as is' with no warranties, implied or otherwise. The owner
+of this mod takes no responsibility for any damages incurred from the use of
+this mod. This mod alters fundamental parts of the Minecraft game, parts of
+Minecraft may not work with this mod installed. All damages caused from the use
+or misuse of this mad fall on the user.
+
+3. Play rights
+--------------
+
+The user is allowed to install this mod on a client or a server and to play
+without restriction.
+
+4. Modification rights
+----------------------
+
+The user has the right to decompile the source code, look at either the
+decompiled version or the original source code, and to modify it.
+
+5. Derivation rights
+--------------------
+
+The user has the rights to derive code from this mod, that is to say to
+write code that extends or instanciate the mod classes or interfaces, refer to
+its objects, or calls its functions. This code is known as "derived" code, and
+can be licensed under a license different from this mod.
+
+6. Distribution of original or modified copy rights
+---------------------------------------------------
+
+Is subject to distribution rights this entire mod in its various forms. This
+include:
+ - original binary or source forms of this mod files
+ - modified versions of these binaries or source files, as well as binaries
+ resulting from source modifications
+ - patch to its source or binary files
+ - any copy of a portion of its binary source files
+
+The user is allowed to redistribute this mod partially, in totality, or
+included in a distribution.
+
+When distributing binary files, the user must provide means to obtain its
+entire set of sources or modified sources at no costs.
+
+All distributions of this mod must remain licensed under the MMPL.
+
+All dependencies that this mod have on other mods or classes must be licensed
+under conditions comparable to this version of MMPL, with the exception of the
+Minecraft code and the mod loading framework (e.g. ModLoader, ModLoaderMP or
+Bukkit).
+
+Modified version of binaries and sources, as well as files containing sections
+copied from this mod, should be distributed under the terms of the present
+license.
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 00000000..5539695e
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,135 @@
+buildscript {
+ configurations.all {
+ resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
+ }
+ repositories {
+ mavenCentral()
+ maven {
+ name = "bdew"
+ url = "http://jenkins.bdew.net/maven"
+ }
+ maven {
+ name = "forge"
+ url = "http://files.minecraftforge.net/maven"
+ }
+ }
+ dependencies {
+ classpath 'net.minecraftforge.gradle:ForgeGradle:1.0-SNAPSHOT'
+ }
+}
+
+apply plugin: 'forge'
+apply plugin: 'scala'
+
+version = "0.9.0"
+ext.bdlibver = "0.9.0.2"
+
+if (project.hasProperty('buildnum')) {
+ project.version = project.version + '.' + project.buildnum
+} else {
+ project.version = "0-SNAPSHOT"
+ ext.bdlibver = "0-SNAPSHOT"
+ repositories.mavenLocal()
+}
+
+group = "net.bdew"
+archivesBaseName = "gendustry"
+
+minecraft {
+ version = "1.6.4-9.11.1.964"
+}
+
+
+repositories {
+ mavenCentral()
+ maven {
+ name = "bdew"
+ url = "http://jenkins.bdew.net/maven"
+ }
+}
+
+dependencies {
+ compile "net.bdew:bdlib:" + bdlibver
+ compile "net.bdew.gendustry:gendustry-deps:1.0.0.+"
+}
+
+import org.apache.tools.ant.filters.ReplaceTokens
+
+sourceSets {
+ main {
+ scala {
+ srcDir 'src'
+ }
+ resources {
+ srcDir 'resources'
+ }
+ }
+ processed {
+ scala {
+ srcDir 'build/stage'
+ }
+ }
+}
+
+def myTokens = [GendustryVer: project.version, BdLibVer: project.bdlibver]
+
+task stage(type: Sync) {
+ from sourceSets.main.scala
+ into 'build/stage'
+ inputs.property "tokens", myTokens
+ stage.filter(ReplaceTokens, tokens: myTokens)
+}
+
+processResources {
+ inputs.property "tokens", myTokens
+ from(sourceSets.main.resources.srcDirs) {
+ include 'mcmod.info'
+ filter(ReplaceTokens, tokens: myTokens)
+ }
+
+ from(sourceSets.main.resources.srcDirs) {
+ exclude 'mcmod.info'
+ }
+}
+
+
+compileScala {
+ source = sourceSets.processed.scala
+ dependsOn stage
+}
+
+task sourceJar(type: Jar) {
+ from sourceSets.main.allSource
+}
+
+task deobfJar(type: Jar) {
+ from sourceSets.main.output
+}
+
+jar {
+ appendix = 'universal'
+}
+
+artifacts {
+ archives sourceJar
+ archives deobfJar
+}
+
+apply plugin: 'maven-publish'
+
+publishing {
+ publications {
+ maven(MavenPublication) {
+ artifact deobfJar
+
+ artifact sourceJar {
+ classifier "sources"
+ }
+ }
+ }
+ repositories {
+ maven {
+ url "file://var/www/maven"
+ }
+ }
+}
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..d5c591c9
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..2b644501
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Nov 28 11:30:59 IST 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.9-bin.zip
diff --git a/gradlew b/gradlew
new file mode 100644
index 00000000..91a7e269
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# 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"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+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
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ 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=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 00000000..8a0b282a
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@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 Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz 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.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+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
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/resources/assets/gendustry/gendustry-recipes.cfg b/resources/assets/gendustry/gendustry-recipes.cfg
new file mode 100644
index 00000000..3ead4369
--- /dev/null
+++ b/resources/assets/gendustry/gendustry-recipes.cfg
@@ -0,0 +1,203 @@
+// This file is loaded in init, recipes should go here
+
+// === RECIPES ===
+
+B = OD:ingotBronze
+T = OD:ingotTin
+C = OD:ingotCopper
+A = OD:gearBronze
+S = B:pistonBase
+R = I:redstone
+G = I:ingotGold
+I = I:ingotIron
+g = I:goldNugget
+D = I:diamond
+
+Y = buildcraft.BuildCraftSilicon[redstoneChipset] @ 4 // BC has no proper item interface?
+
+def forestryB = forestry.api.core.BlockInterface.getBlock
+def forestryI = forestry.api.core.ItemInterface.getItem
+
+// === Crafting items ===
+
+P = B:thinGlass
+
+TPT
+TPT => gendustry:MutagenTank
+TPT
+
+Z = B:weightedPlate_light
+
+BBB
+BPB => gendustry:BeeReceptacle
+RZR
+
+AGA
+SRS => gendustry:PowerModule
+AGA
+
+Q = I:netherquartz
+
+DQD
+QYQ => gendustry:GeneticsProcessor
+DQD
+
+// alternative recipe, cheaper but takes a lot of power
+assembly: D*2, Y, Q*2, 100000 mj => gendustry:GeneticsProcessor
+
+TgT
+R_R => gendustry:UpgradeFrame
+TgT
+
+BRB
+BAB => gendustry:ClimateModule
+BRB
+
+P_P
+P_P => gendustry:Labware * 16
+_D_
+
+// === Templates ===
+
+s = gendustry:GeneSample
+t = gendustry:GeneTemplate
+
+_T_
+TRT => gendustry:GeneSampleBlank
+_T_
+
+RTR
+TDT => gendustry:GeneTemplate
+RTR
+
+smelt: $s => gendustry:GeneSampleBlank,0
+smelt: $t => $t, 0
+
+// === Machines ===
+
+O = $forestryI(sturdyCasing)
+
+M = gendustry:MutagenTank
+T = gendustry:BeeReceptacle
+P = gendustry:PowerModule
+Z = gendustry:GeneticsProcessor
+
+H = B:hopper
+L = B:glass
+
+BHB
+POP => gendustry:MutagenProducer
+AMA
+
+TZB
+POT => gendustry:Mutatron
+TMB
+
+AZA
+TOT => gendustry:Imprinter
+APA
+
+AZA
+TOD => gendustry:Sampler
+APA
+
+LTL
+LOL => gendustry:IndustrialApiary
+ASA
+
+// === Upgrades ===
+
+X = gendustry:UpgradeFrame
+
+_A_
+RXR => gendustry:"upgrade.auto"
+_S_
+
+r = OD:dyeRed
+g = OD:dyeGreen
+b = OD:dyeBlue
+y = OD:dyeYellow
+L = B:glass
+
+rbg
+yXy => gendustry:"upgrade.flowering"
+LLL
+
+bbb
+LXL => gendustry:"upgrade.sky"
+LLL
+
+W = $forestryI(craftingMaterial) @ 2 // silk wasp
+
+WWW
+WXW => gendustry:"upgrade.sieve"
+WAW
+
+W = $forestryI(beeswax)
+
+WLW
+LXL => gendustry:"upgrade.sealing"
+WLW
+
+W = I:yellowDust
+
+WLW
+LXL => gendustry:"upgrade.light"
+WLW
+
+J = $forestryI(royalJelly)
+S = I:sugar
+
+BJB
+SXS => gendustry:"upgrade.prod"
+BAB
+
+Z = I:blazePowder
+
+AZA
+QXQ => gendustry:"upgrade.hell"
+AZA
+
+F = I:fermentedSpiderEye
+
+FLF
+LXL => gendustry:"upgrade.life"
+___
+
+I_I
+_X_ => gendustry:"upgrade.territory"
+I_I
+
+L = gendustry:ClimateModule
+R = B:reeds
+S = B:sand
+N = B:hellrock
+O = I:snowball
+
+SSS
+BXB => gendustry:"upgrade.dryer"
+BLB
+
+RRR
+BXB => gendustry:"upgrade.humidifier"
+BLB
+
+NNN
+BXB => gendustry:"upgrade.heater"
+BLB
+
+OOO
+BXB => gendustry:"upgrade.cooler"
+BLB
+
+mutagen: I:redstone -> 100
+mutagen: I:yellowDust -> 200
+mutagen: B:lightgem -> 800
+mutagen: B:blockRedstone -> 900
+
+ifMod IC2 {
+ mutagen: ic2.core.Ic2Items[uraniumBlock] -> 4500
+ mutagen: ic2.core.Ic2Items[Uran235] -> 9000
+ mutagen: ic2.core.Ic2Items[smallUran235] -> 1000
+ mutagen: ic2.core.Ic2Items[Uran238] -> 500
+}
\ No newline at end of file
diff --git a/resources/assets/gendustry/gendustry-tuning.cfg b/resources/assets/gendustry/gendustry-tuning.cfg
new file mode 100644
index 00000000..30fa51f3
--- /dev/null
+++ b/resources/assets/gendustry/gendustry-tuning.cfg
@@ -0,0 +1,237 @@
+// This file is loaded early in preInit and should contain all the configuration
+// Recipes shouldn't go here as items aren't registered yet
+
+// Power config values, those are used for all machines
+// ----------------------------------------------------
+//
+// MinReceivedEnergy:
+// Min energy received into buffer in a single pulse
+// Should be reasonably high to prevent small update spam
+//
+// MaxReceivedEnergy:
+// Max energy received into buffer in a single pulse
+// Should be high if direct connections form BC engines are expected as they output once in up to 100 ticks
+// 500 is a good value for a combustion engines
+//
+// ActivationEnergy:
+// Machine will until that much energy is available before it does anything
+// Should be reasonably high to prevent small update spam
+//
+// MaxStoredEnergy:
+// Size of internal buffer, for some machines this affects speed, see below
+//
+// PowerLoss, PowerLossInterval:
+// Power loss from internal buffer, will loose on average PowerLoss/PowerLossInterval MJ/tick
+// Cannot be set below 0.01, this is enforced by BC API
+//
+// MjPerItem:
+// Cost of a single operation in MJ, for most machines this means processing 1 item
+//
+// PowerUseRate:
+// Sets the max speed of machines with variable speed
+//
+// Most machines use a variable speed system, while MjPerItem is constant, the actual energy used per tick is variable
+// The upper bound is MaxStoredEnergy * PowerUseRate and the lower bound is ActivationEnergy
+//
+// For example, with the following config:
+//
+// MaxStoredEnergy = 10000
+// MjPerItem = 10000
+// PowerUseRate = 0.005
+// ActivationEnergy = 5
+//
+// If a machine recieves 10 MJ/t it will stabilize at ~2000 energy stored and use 10 MJ/t to run, completing a cycle in 1000 ticks
+// If the same machine recieves 50 MJ/t it will stabilize at ~10000 energy stored and use 50 MJ/t to run, completing a cycle in 200 ticks
+// While if it would recieve 2 MJ/t it will only run once in 2.5 ticks on average, will consume 5 MJ/t every time it activates and will take 5000 ticks to finish, no energy will be stored
+
+cfg Machines {
+ cfg MutagenProducer {
+ MinReceivedEnergy = 50
+ MaxReceivedEnergy = 500
+ PowerLoss = 1
+ PowerLossInterval = 100
+
+ PowerUseRate = 0.0005
+ MjPerItem = 100000
+ MaxStoredEnergy = 500000
+ ActivationEnergy = 25
+
+ TankSize = 10000 // Output tank size in milibuckets
+ }
+
+ cfg Mutatron {
+ MinReceivedEnergy = 50
+ MaxReceivedEnergy = 500
+ PowerLoss = 1
+ PowerLossInterval = 100
+
+ PowerUseRate = 0.001
+ MjPerItem = 20000
+ MaxStoredEnergy = 100000
+ ActivationEnergy = 10
+
+ TankSize = 10000 // Output tank size in milibuckets
+ MutagenPerItem = 1000 // Mutagen use per run, in milibuckets
+ LabwareConsumeChance = 100 // Chance that the Genetic Labware will be consumed, 0-100
+ DegradeChanceNatural = 0 // Chance of natural princesses to become artificial when mutating, 0-100
+ DeathChanceArtificial = 10 // Chance of artificial princesses to be killed when mutating, 0-100
+ }
+
+ cfg Sampler {
+ MinReceivedEnergy = 50
+ MaxReceivedEnergy = 500
+ PowerLoss = 1
+ PowerLossInterval = 100
+
+ PowerUseRate = 0.001
+ MjPerItem = 20000
+ MaxStoredEnergy = 100000
+ ActivationEnergy = 10
+
+ LabwareConsumeChance = 100 // Chance that the Genetic Labware will be consumed, 0-100
+ }
+
+ cfg Imprinter {
+ MinReceivedEnergy = 50
+ MaxReceivedEnergy = 500
+ PowerLoss = 1
+ PowerLossInterval = 100
+
+ PowerUseRate = 0.0005
+ MjPerItem = 80000
+ MaxStoredEnergy = 400000
+ ActivationEnergy = 20
+
+ LabwareConsumeChance = 100 // Chance that the Genetic Labware will be consumed, 0-100
+ DeathChanceNatural = 0 // Chance of natural princesses or queen to be killed when imprinting, 0-100
+ DeathChanceArtificial = 10 // Chance of artificial princesses or queen to be killed when imprinting, 0-100
+ }
+
+ cfg IndustrialApiary {
+ MinReceivedEnergy = 10
+ MaxReceivedEnergy = 100
+ MaxStoredEnergy = 10000
+ PowerLoss = 1
+ PowerLossInterval = 100
+ ActivationEnergy = 0
+
+ BaseMjPerTick = 2 // Base run cost in MJ/t, before any modifiers
+ }
+}
+
+cfg Items {
+ cfg IndustrialGrafter {
+ Charges = 200
+ RfPerCharge = 5000 // This is in RF not MJ!
+ }
+}
+
+// === INDUSTRIAL APIARY UPGRADES ===
+
+cfg Upgrades {
+
+ // section names are used in localization and texture names
+ // id is used in saves, changing it will brake any upgrades that already exist
+ // max is the maximum number installed in a single apiary
+ // valid modifiers:
+ // * Boolean: sealed, selfLighted, sunlightSimulated, hellish, automated, collectingPollen
+ // * Numeric: lifespan, territory, mutation, production, flowering, geneticDecay, energy, temperature, humidity
+
+ cfg prod {
+ id = 0
+ max = 8
+ production *= 1.2
+ energy *= 1.2
+ }
+
+ cfg life {
+ id = 1
+ max = 4
+ energy *= 1.05
+ lifespan /= 1.5
+ }
+
+ cfg flowering {
+ id = 2
+ max = 8
+ energy *= 1.1
+ flowering *= 1.2
+ }
+
+ cfg territory {
+ id = 3
+ max = 4
+ energy *= 1.05
+ territory *= 1.5
+ }
+
+ cfg humidifier {
+ id = 4
+ max = 8
+ energy *= 1.05
+ humidity += 0.25
+ }
+
+ cfg dryer {
+ id = 5
+ max = 8
+ energy *= 1.05
+ humidity -= 0.25
+ }
+
+ cfg heater {
+ id = 6
+ max = 8
+ energy *= 1.05
+ temperature += 0.25
+ }
+
+ cfg cooler {
+ id = 7
+ max = 8
+ energy *= 1.05
+ temperature -= 0.25
+ }
+
+ cfg sealing {
+ id = 10
+ max = 1
+ energy *= 1.05
+ sealed = Y
+ }
+
+ cfg light {
+ id = 11
+ max = 1
+ energy *= 1.05
+ selfLighted = Y
+ }
+
+ cfg sky {
+ id = 12
+ max = 1
+ energy *= 1.05
+ sunlightSimulated = Y
+ }
+
+ cfg hell {
+ id = 13
+ max = 1
+ energy *= 1.5
+ hellish = Y
+ }
+
+ cfg auto {
+ id = 14
+ max = 1
+ energy *= 1.1
+ automated = Y
+ }
+
+ cfg sieve {
+ id = 15
+ max = 1
+ energy *= 1.25
+ collectingPollen = Y
+ }
+}
\ No newline at end of file
diff --git a/resources/assets/gendustry/lang/en_US.lang b/resources/assets/gendustry/lang/en_US.lang
new file mode 100644
index 00000000..2c65deea
--- /dev/null
+++ b/resources/assets/gendustry/lang/en_US.lang
@@ -0,0 +1,109 @@
+tile.gendustry.mutagen.name=Mutagen
+tile.gendustry.mutagen.producer.name=Mutagen Producer
+tile.gendustry.mutatron.name=Mutatron
+tile.gendustry.apiary.name=Industrial Apiary
+tile.gendustry.imprinter.name=Genetic Imprinter
+tile.gendustry.sampler.name=Genetic Sampler
+
+item.gendustry.mutagen.bucket.name=Mutagen Bucket
+item.gendustry.mutagen.can.name=Mutagen Can
+
+item.gendustry.MutagenTank.name=Mutagen Tank
+item.gendustry.BeeReceptacle.name=Bee Receptacle
+item.gendustry.PowerModule.name=Power Module
+item.gendustry.GeneticsProcessor.name=Genetics Processor
+item.gendustry.UpgradeFrame.name=Upgrade Frame
+item.gendustry.ClimateModule.name=Climate Control Module
+item.gendustry.Labware.name=Genetics Labware
+item.gendustry.GeneSample.name=Gene Sample
+item.gendustry.GeneTemplate.name=Genetic Template
+item.gendustry.GeneSampleBlank.name=Blank Gene Sample
+item.gendustry.Waste.name=Genetic Waste
+item.gendustry.grafter.name=Industrial Grafter
+
+gendustry.upgrades.prod.name=Production Upgrade
+gendustry.upgrades.life.name=Lifespan Upgrade
+gendustry.upgrades.flowering.name=Flowering Upgrade
+gendustry.upgrades.territory.name=Territory Upgrade
+gendustry.upgrades.sealing.name=Seal Upgrade
+gendustry.upgrades.light.name=Light Upgrade
+gendustry.upgrades.sky.name=Open Sky Upgrade
+gendustry.upgrades.hell.name=Hell Upgrade
+gendustry.upgrades.auto.name=Automation Upgrade
+gendustry.upgrades.humidifier.name=Humidifier Upgrade
+gendustry.upgrades.dryer.name=Dryer Upgrade
+gendustry.upgrades.heater.name=Heater Upgrade
+gendustry.upgrades.sieve.name=Sieve Upgrade
+gendustry.upgrades.cooler.name=Cooler Upgrade
+
+fluid.gendustry.mutagen=Mutagen
+
+gendustry.label.charges=Charges: %s
+
+gendustry.label.empty=Empty
+gendustry.label.breeding=Breeding
+gendustry.label.working=Working
+gendustry.label.maxinstall=Maximum Installed:
+gendustry.label.temperature=Temperature: %s
+gendustry.label.humidity=Humidity: %s
+gendustry.label.energy=Energy Required: %s MJ/t
+gendustry.label.lifespan=Lifespan Modifier: %s
+gendustry.label.flowering=Flowering Chance: %s
+gendustry.label.production=Production Modifier: %s
+gendustry.label.territory=Territory: %s
+
+gendustry.label.mod.automated=* Automation
+gendustry.label.mod.hellish=* Hell Environment Simulation
+gendustry.label.mod.sealed=* Rain Protection
+gendustry.label.mod.selflighted=* Internal Lighting
+gendustry.label.mod.sky=* Open Sky Simulation
+gendustry.label.mod.energy=* Energy Consumption
+gendustry.label.mod.lifespan=* Lifespan
+gendustry.label.mod.flowering=* Flowering and Pollination
+gendustry.label.mod.geneticDecay=* Genetic Decay
+gendustry.label.mod.mutation=* Mutation Chance
+gendustry.label.mod.production=* Production
+gendustry.label.mod.territory=* Territory
+gendustry.label.mod.sieve=* Pollen Collection
+gendustry.label.mod.temperature=* Temperature
+gendustry.label.mod.humidity=* Humidity
+
+gendustry.error.power=Not enough power
+
+gendustry.label.sample.rootBees=Taken from a Bee
+gendustry.label.sample.rootTrees=Taken from a Sapling
+gendustry.label.sample.rootButterflies=Taken from a Butterfly
+
+gendustry.label.template.rootBees=Can be applied to a Bee
+gendustry.label.template.rootTrees=Can be applied to a Sapling
+gendustry.label.template.rootButterflies=Can be applied to a Butterfly
+gendustry.label.template.blank=Gene Samples can be added
+
+gendustry.chromosome.FLOWER_PROVIDER=Flowers
+gendustry.chromosome.GIRTH=Girth
+gendustry.chromosome.SPEED=Speed
+gendustry.chromosome.YIELD=Yield
+gendustry.chromosome.HEIGHT=Height
+gendustry.chromosome.GROWTH=Growth
+gendustry.chromosome.FLOWERING=Flowering
+gendustry.chromosome.METABOLISM=Metabolism
+gendustry.chromosome.LIFESPAN=Lifespan
+gendustry.chromosome.TERRITORY=Territory
+gendustry.chromosome.FERTILITY=Fertility
+gendustry.chromosome.SIZE=Size
+gendustry.chromosome.HUMIDITY=Humidity
+gendustry.chromosome.SPECIES=Species
+gendustry.chromosome.FIRE_RESIST=Fire resist
+gendustry.chromosome.TEMPERATURE_TOLERANCE=Temperature tolerance
+gendustry.chromosome.HUMIDITY_TOLERANCE=Humidity tolerance
+gendustry.chromosome.PLANT=Plant
+gendustry.chromosome.EFFECT=Effect
+gendustry.chromosome.CAVE_DWELLING=Cave dwelling
+gendustry.chromosome.MATURATION=Maturation
+gendustry.chromosome.NOCTURNAL=Nocturnal
+gendustry.chromosome.TOLERANT_FLYER=Tolerant flyer
+gendustry.chromosome.FRUITS=Fruits
+gendustry.chromosome.SAPPINESS=Sappiness
+
+gendustry.allele.false=False
+gendustry.allele.true=True
\ No newline at end of file
diff --git a/resources/assets/gendustry/textures/blocks/apiary/apiary.psd b/resources/assets/gendustry/textures/blocks/apiary/apiary.psd
new file mode 100644
index 00000000..b7c2e514
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/apiary/apiary.psd differ
diff --git a/resources/assets/gendustry/textures/blocks/apiary/side.png b/resources/assets/gendustry/textures/blocks/apiary/side.png
new file mode 100644
index 00000000..9b3436b6
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/apiary/side.png differ
diff --git a/resources/assets/gendustry/textures/blocks/apiary/top.png b/resources/assets/gendustry/textures/blocks/apiary/top.png
new file mode 100644
index 00000000..e14d0ce1
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/apiary/top.png differ
diff --git a/resources/assets/gendustry/textures/blocks/imprinter/bottom.png b/resources/assets/gendustry/textures/blocks/imprinter/bottom.png
new file mode 100644
index 00000000..00d239bf
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/imprinter/bottom.png differ
diff --git a/resources/assets/gendustry/textures/blocks/imprinter/imprinter.psd b/resources/assets/gendustry/textures/blocks/imprinter/imprinter.psd
new file mode 100644
index 00000000..ca019bf8
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/imprinter/imprinter.psd differ
diff --git a/resources/assets/gendustry/textures/blocks/imprinter/side.png b/resources/assets/gendustry/textures/blocks/imprinter/side.png
new file mode 100644
index 00000000..080325a6
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/imprinter/side.png differ
diff --git a/resources/assets/gendustry/textures/blocks/imprinter/top.png b/resources/assets/gendustry/textures/blocks/imprinter/top.png
new file mode 100644
index 00000000..ced1db3f
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/imprinter/top.png differ
diff --git a/resources/assets/gendustry/textures/blocks/mutagen/flowing.png b/resources/assets/gendustry/textures/blocks/mutagen/flowing.png
new file mode 100644
index 00000000..20976a30
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/mutagen/flowing.png differ
diff --git a/resources/assets/gendustry/textures/blocks/mutagen/flowing.png.mcmeta b/resources/assets/gendustry/textures/blocks/mutagen/flowing.png.mcmeta
new file mode 100644
index 00000000..4f0718ac
--- /dev/null
+++ b/resources/assets/gendustry/textures/blocks/mutagen/flowing.png.mcmeta
@@ -0,0 +1,3 @@
+{
+ "animation": {}
+}
\ No newline at end of file
diff --git a/resources/assets/gendustry/textures/blocks/mutagen/flowing.psd b/resources/assets/gendustry/textures/blocks/mutagen/flowing.psd
new file mode 100644
index 00000000..e3ab4f96
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/mutagen/flowing.psd differ
diff --git a/resources/assets/gendustry/textures/blocks/mutagen/sample.psd b/resources/assets/gendustry/textures/blocks/mutagen/sample.psd
new file mode 100644
index 00000000..6d1e6c2b
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/mutagen/sample.psd differ
diff --git a/resources/assets/gendustry/textures/blocks/mutagen/still.png b/resources/assets/gendustry/textures/blocks/mutagen/still.png
new file mode 100644
index 00000000..ff604208
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/mutagen/still.png differ
diff --git a/resources/assets/gendustry/textures/blocks/mutagen/still.png.mcmeta b/resources/assets/gendustry/textures/blocks/mutagen/still.png.mcmeta
new file mode 100644
index 00000000..0645f48c
--- /dev/null
+++ b/resources/assets/gendustry/textures/blocks/mutagen/still.png.mcmeta
@@ -0,0 +1,5 @@
+{
+ "animation": {
+ "frametime": 2
+ }
+}
diff --git a/resources/assets/gendustry/textures/blocks/mutagen/still.psd b/resources/assets/gendustry/textures/blocks/mutagen/still.psd
new file mode 100644
index 00000000..9c084428
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/mutagen/still.psd differ
diff --git a/resources/assets/gendustry/textures/blocks/mutagenproducer/bottom.png b/resources/assets/gendustry/textures/blocks/mutagenproducer/bottom.png
new file mode 100644
index 00000000..00d239bf
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/mutagenproducer/bottom.png differ
diff --git a/resources/assets/gendustry/textures/blocks/mutagenproducer/mutagenproducer.psd b/resources/assets/gendustry/textures/blocks/mutagenproducer/mutagenproducer.psd
new file mode 100644
index 00000000..3addb3a6
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/mutagenproducer/mutagenproducer.psd differ
diff --git a/resources/assets/gendustry/textures/blocks/mutagenproducer/side.png b/resources/assets/gendustry/textures/blocks/mutagenproducer/side.png
new file mode 100644
index 00000000..d68477ba
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/mutagenproducer/side.png differ
diff --git a/resources/assets/gendustry/textures/blocks/mutagenproducer/top.png b/resources/assets/gendustry/textures/blocks/mutagenproducer/top.png
new file mode 100644
index 00000000..2ef69547
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/mutagenproducer/top.png differ
diff --git a/resources/assets/gendustry/textures/blocks/mutatron/bottom.png b/resources/assets/gendustry/textures/blocks/mutatron/bottom.png
new file mode 100644
index 00000000..00d239bf
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/mutatron/bottom.png differ
diff --git a/resources/assets/gendustry/textures/blocks/mutatron/mutatron.psd b/resources/assets/gendustry/textures/blocks/mutatron/mutatron.psd
new file mode 100644
index 00000000..72b60043
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/mutatron/mutatron.psd differ
diff --git a/resources/assets/gendustry/textures/blocks/mutatron/side.png b/resources/assets/gendustry/textures/blocks/mutatron/side.png
new file mode 100644
index 00000000..475179d8
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/mutatron/side.png differ
diff --git a/resources/assets/gendustry/textures/blocks/mutatron/top.png b/resources/assets/gendustry/textures/blocks/mutatron/top.png
new file mode 100644
index 00000000..507f2473
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/mutatron/top.png differ
diff --git a/resources/assets/gendustry/textures/blocks/sampler/bottom.png b/resources/assets/gendustry/textures/blocks/sampler/bottom.png
new file mode 100644
index 00000000..00d239bf
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/sampler/bottom.png differ
diff --git a/resources/assets/gendustry/textures/blocks/sampler/sampler.psd b/resources/assets/gendustry/textures/blocks/sampler/sampler.psd
new file mode 100644
index 00000000..5a32cd6e
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/sampler/sampler.psd differ
diff --git a/resources/assets/gendustry/textures/blocks/sampler/side.png b/resources/assets/gendustry/textures/blocks/sampler/side.png
new file mode 100644
index 00000000..336dc5a6
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/sampler/side.png differ
diff --git a/resources/assets/gendustry/textures/blocks/sampler/top.png b/resources/assets/gendustry/textures/blocks/sampler/top.png
new file mode 100644
index 00000000..ced1db3f
Binary files /dev/null and b/resources/assets/gendustry/textures/blocks/sampler/top.png differ
diff --git a/resources/assets/gendustry/textures/gui/apiary.png b/resources/assets/gendustry/textures/gui/apiary.png
new file mode 100644
index 00000000..501906a1
Binary files /dev/null and b/resources/assets/gendustry/textures/gui/apiary.png differ
diff --git a/resources/assets/gendustry/textures/gui/apiary.psd b/resources/assets/gendustry/textures/gui/apiary.psd
new file mode 100644
index 00000000..f5fe4259
Binary files /dev/null and b/resources/assets/gendustry/textures/gui/apiary.psd differ
diff --git a/resources/assets/gendustry/textures/gui/imprinter.png b/resources/assets/gendustry/textures/gui/imprinter.png
new file mode 100644
index 00000000..8997acec
Binary files /dev/null and b/resources/assets/gendustry/textures/gui/imprinter.png differ
diff --git a/resources/assets/gendustry/textures/gui/imprinter_templater.psd b/resources/assets/gendustry/textures/gui/imprinter_templater.psd
new file mode 100644
index 00000000..00aa8cd6
Binary files /dev/null and b/resources/assets/gendustry/textures/gui/imprinter_templater.psd differ
diff --git a/resources/assets/gendustry/textures/gui/mutagenproducer.png b/resources/assets/gendustry/textures/gui/mutagenproducer.png
new file mode 100644
index 00000000..0952f9a8
Binary files /dev/null and b/resources/assets/gendustry/textures/gui/mutagenproducer.png differ
diff --git a/resources/assets/gendustry/textures/gui/mutagenproducer.psd b/resources/assets/gendustry/textures/gui/mutagenproducer.psd
new file mode 100644
index 00000000..4eb84329
Binary files /dev/null and b/resources/assets/gendustry/textures/gui/mutagenproducer.psd differ
diff --git a/resources/assets/gendustry/textures/gui/mutatron.png b/resources/assets/gendustry/textures/gui/mutatron.png
new file mode 100644
index 00000000..0e9830e6
Binary files /dev/null and b/resources/assets/gendustry/textures/gui/mutatron.png differ
diff --git a/resources/assets/gendustry/textures/gui/mutatron.psd b/resources/assets/gendustry/textures/gui/mutatron.psd
new file mode 100644
index 00000000..c44580b3
Binary files /dev/null and b/resources/assets/gendustry/textures/gui/mutatron.psd differ
diff --git a/resources/assets/gendustry/textures/gui/sampler.png b/resources/assets/gendustry/textures/gui/sampler.png
new file mode 100644
index 00000000..ded731da
Binary files /dev/null and b/resources/assets/gendustry/textures/gui/sampler.png differ
diff --git a/resources/assets/gendustry/textures/gui/widgets.png b/resources/assets/gendustry/textures/gui/widgets.png
new file mode 100644
index 00000000..8b7ffaa1
Binary files /dev/null and b/resources/assets/gendustry/textures/gui/widgets.png differ
diff --git a/resources/assets/gendustry/textures/gui/widgets.psd b/resources/assets/gendustry/textures/gui/widgets.psd
new file mode 100644
index 00000000..3a4f4046
Binary files /dev/null and b/resources/assets/gendustry/textures/gui/widgets.psd differ
diff --git a/resources/assets/gendustry/textures/items/beereceptacle.png b/resources/assets/gendustry/textures/items/beereceptacle.png
new file mode 100644
index 00000000..0f246396
Binary files /dev/null and b/resources/assets/gendustry/textures/items/beereceptacle.png differ
diff --git a/resources/assets/gendustry/textures/items/beereceptacle.psd b/resources/assets/gendustry/textures/items/beereceptacle.psd
new file mode 100644
index 00000000..6b6ef472
Binary files /dev/null and b/resources/assets/gendustry/textures/items/beereceptacle.psd differ
diff --git a/resources/assets/gendustry/textures/items/climatemodule.png b/resources/assets/gendustry/textures/items/climatemodule.png
new file mode 100644
index 00000000..445fe19f
Binary files /dev/null and b/resources/assets/gendustry/textures/items/climatemodule.png differ
diff --git a/resources/assets/gendustry/textures/items/climatemodule.psd b/resources/assets/gendustry/textures/items/climatemodule.psd
new file mode 100644
index 00000000..7478e5c1
Binary files /dev/null and b/resources/assets/gendustry/textures/items/climatemodule.psd differ
diff --git a/resources/assets/gendustry/textures/items/genesample.png b/resources/assets/gendustry/textures/items/genesample.png
new file mode 100644
index 00000000..4589aed1
Binary files /dev/null and b/resources/assets/gendustry/textures/items/genesample.png differ
diff --git a/resources/assets/gendustry/textures/items/genesampleblank.png b/resources/assets/gendustry/textures/items/genesampleblank.png
new file mode 100644
index 00000000..d4de1281
Binary files /dev/null and b/resources/assets/gendustry/textures/items/genesampleblank.png differ
diff --git a/resources/assets/gendustry/textures/items/genetemplate.png b/resources/assets/gendustry/textures/items/genetemplate.png
new file mode 100644
index 00000000..b2cd1187
Binary files /dev/null and b/resources/assets/gendustry/textures/items/genetemplate.png differ
diff --git a/resources/assets/gendustry/textures/items/geneticsprocessor.png b/resources/assets/gendustry/textures/items/geneticsprocessor.png
new file mode 100644
index 00000000..8bc6e2c1
Binary files /dev/null and b/resources/assets/gendustry/textures/items/geneticsprocessor.png differ
diff --git a/resources/assets/gendustry/textures/items/geneticsprocessor.psd b/resources/assets/gendustry/textures/items/geneticsprocessor.psd
new file mode 100644
index 00000000..ae4412e7
Binary files /dev/null and b/resources/assets/gendustry/textures/items/geneticsprocessor.psd differ
diff --git a/resources/assets/gendustry/textures/items/labware.png b/resources/assets/gendustry/textures/items/labware.png
new file mode 100644
index 00000000..ae025eb9
Binary files /dev/null and b/resources/assets/gendustry/textures/items/labware.png differ
diff --git a/resources/assets/gendustry/textures/items/labware.psd b/resources/assets/gendustry/textures/items/labware.psd
new file mode 100644
index 00000000..b25e0c5d
Binary files /dev/null and b/resources/assets/gendustry/textures/items/labware.psd differ
diff --git a/resources/assets/gendustry/textures/items/mutagen/bucket.png b/resources/assets/gendustry/textures/items/mutagen/bucket.png
new file mode 100644
index 00000000..c0c8ed2f
Binary files /dev/null and b/resources/assets/gendustry/textures/items/mutagen/bucket.png differ
diff --git a/resources/assets/gendustry/textures/items/mutagen/bucket.psd b/resources/assets/gendustry/textures/items/mutagen/bucket.psd
new file mode 100644
index 00000000..e29a1e7e
Binary files /dev/null and b/resources/assets/gendustry/textures/items/mutagen/bucket.psd differ
diff --git a/resources/assets/gendustry/textures/items/mutagen/can.png b/resources/assets/gendustry/textures/items/mutagen/can.png
new file mode 100644
index 00000000..315bdd40
Binary files /dev/null and b/resources/assets/gendustry/textures/items/mutagen/can.png differ
diff --git a/resources/assets/gendustry/textures/items/mutagen/can.psd b/resources/assets/gendustry/textures/items/mutagen/can.psd
new file mode 100644
index 00000000..0285f058
Binary files /dev/null and b/resources/assets/gendustry/textures/items/mutagen/can.psd differ
diff --git a/resources/assets/gendustry/textures/items/mutagentank.png b/resources/assets/gendustry/textures/items/mutagentank.png
new file mode 100644
index 00000000..bd474256
Binary files /dev/null and b/resources/assets/gendustry/textures/items/mutagentank.png differ
diff --git a/resources/assets/gendustry/textures/items/mutagentank.psd b/resources/assets/gendustry/textures/items/mutagentank.psd
new file mode 100644
index 00000000..20c17403
Binary files /dev/null and b/resources/assets/gendustry/textures/items/mutagentank.psd differ
diff --git a/resources/assets/gendustry/textures/items/powermodule.png b/resources/assets/gendustry/textures/items/powermodule.png
new file mode 100644
index 00000000..866c9e19
Binary files /dev/null and b/resources/assets/gendustry/textures/items/powermodule.png differ
diff --git a/resources/assets/gendustry/textures/items/powermodule.psd b/resources/assets/gendustry/textures/items/powermodule.psd
new file mode 100644
index 00000000..d228a4ed
Binary files /dev/null and b/resources/assets/gendustry/textures/items/powermodule.psd differ
diff --git a/resources/assets/gendustry/textures/items/sample.psd b/resources/assets/gendustry/textures/items/sample.psd
new file mode 100644
index 00000000..e66070e8
Binary files /dev/null and b/resources/assets/gendustry/textures/items/sample.psd differ
diff --git a/resources/assets/gendustry/textures/items/template.psd b/resources/assets/gendustry/textures/items/template.psd
new file mode 100644
index 00000000..d32f04a6
Binary files /dev/null and b/resources/assets/gendustry/textures/items/template.psd differ
diff --git a/resources/assets/gendustry/textures/items/upgradeframe.png b/resources/assets/gendustry/textures/items/upgradeframe.png
new file mode 100644
index 00000000..0391c345
Binary files /dev/null and b/resources/assets/gendustry/textures/items/upgradeframe.png differ
diff --git a/resources/assets/gendustry/textures/items/upgrades/auto.png b/resources/assets/gendustry/textures/items/upgrades/auto.png
new file mode 100644
index 00000000..638bbbc1
Binary files /dev/null and b/resources/assets/gendustry/textures/items/upgrades/auto.png differ
diff --git a/resources/assets/gendustry/textures/items/upgrades/cooler.png b/resources/assets/gendustry/textures/items/upgrades/cooler.png
new file mode 100644
index 00000000..3c06ed2a
Binary files /dev/null and b/resources/assets/gendustry/textures/items/upgrades/cooler.png differ
diff --git a/resources/assets/gendustry/textures/items/upgrades/dryer.png b/resources/assets/gendustry/textures/items/upgrades/dryer.png
new file mode 100644
index 00000000..2e0d34aa
Binary files /dev/null and b/resources/assets/gendustry/textures/items/upgrades/dryer.png differ
diff --git a/resources/assets/gendustry/textures/items/upgrades/flowering.png b/resources/assets/gendustry/textures/items/upgrades/flowering.png
new file mode 100644
index 00000000..e9040ab8
Binary files /dev/null and b/resources/assets/gendustry/textures/items/upgrades/flowering.png differ
diff --git a/resources/assets/gendustry/textures/items/upgrades/heater.png b/resources/assets/gendustry/textures/items/upgrades/heater.png
new file mode 100644
index 00000000..6152af7a
Binary files /dev/null and b/resources/assets/gendustry/textures/items/upgrades/heater.png differ
diff --git a/resources/assets/gendustry/textures/items/upgrades/hell.png b/resources/assets/gendustry/textures/items/upgrades/hell.png
new file mode 100644
index 00000000..00a5b46a
Binary files /dev/null and b/resources/assets/gendustry/textures/items/upgrades/hell.png differ
diff --git a/resources/assets/gendustry/textures/items/upgrades/humidifier.png b/resources/assets/gendustry/textures/items/upgrades/humidifier.png
new file mode 100644
index 00000000..7de729ca
Binary files /dev/null and b/resources/assets/gendustry/textures/items/upgrades/humidifier.png differ
diff --git a/resources/assets/gendustry/textures/items/upgrades/life.png b/resources/assets/gendustry/textures/items/upgrades/life.png
new file mode 100644
index 00000000..557674d0
Binary files /dev/null and b/resources/assets/gendustry/textures/items/upgrades/life.png differ
diff --git a/resources/assets/gendustry/textures/items/upgrades/light.png b/resources/assets/gendustry/textures/items/upgrades/light.png
new file mode 100644
index 00000000..ac01b486
Binary files /dev/null and b/resources/assets/gendustry/textures/items/upgrades/light.png differ
diff --git a/resources/assets/gendustry/textures/items/upgrades/prod.png b/resources/assets/gendustry/textures/items/upgrades/prod.png
new file mode 100644
index 00000000..1ab4df0d
Binary files /dev/null and b/resources/assets/gendustry/textures/items/upgrades/prod.png differ
diff --git a/resources/assets/gendustry/textures/items/upgrades/sealing.png b/resources/assets/gendustry/textures/items/upgrades/sealing.png
new file mode 100644
index 00000000..b6095b03
Binary files /dev/null and b/resources/assets/gendustry/textures/items/upgrades/sealing.png differ
diff --git a/resources/assets/gendustry/textures/items/upgrades/sieve.png b/resources/assets/gendustry/textures/items/upgrades/sieve.png
new file mode 100644
index 00000000..a111ade4
Binary files /dev/null and b/resources/assets/gendustry/textures/items/upgrades/sieve.png differ
diff --git a/resources/assets/gendustry/textures/items/upgrades/sky.png b/resources/assets/gendustry/textures/items/upgrades/sky.png
new file mode 100644
index 00000000..ccf04c32
Binary files /dev/null and b/resources/assets/gendustry/textures/items/upgrades/sky.png differ
diff --git a/resources/assets/gendustry/textures/items/upgrades/territory.png b/resources/assets/gendustry/textures/items/upgrades/territory.png
new file mode 100644
index 00000000..697c8de4
Binary files /dev/null and b/resources/assets/gendustry/textures/items/upgrades/territory.png differ
diff --git a/resources/assets/gendustry/textures/items/upgrades/upgrades.psd b/resources/assets/gendustry/textures/items/upgrades/upgrades.psd
new file mode 100644
index 00000000..c113085b
Binary files /dev/null and b/resources/assets/gendustry/textures/items/upgrades/upgrades.psd differ
diff --git a/resources/assets/gendustry/textures/items/waste.png b/resources/assets/gendustry/textures/items/waste.png
new file mode 100644
index 00000000..da100ced
Binary files /dev/null and b/resources/assets/gendustry/textures/items/waste.png differ
diff --git a/resources/assets/gendustry/textures/items/waste.psd b/resources/assets/gendustry/textures/items/waste.psd
new file mode 100644
index 00000000..0d2d6526
Binary files /dev/null and b/resources/assets/gendustry/textures/items/waste.psd differ
diff --git a/resources/mcmod.info b/resources/mcmod.info
new file mode 100644
index 00000000..7250099e
--- /dev/null
+++ b/resources/mcmod.info
@@ -0,0 +1,20 @@
+[
+{
+ "modid": "gendustry",
+ "name": "GenDustry",
+ "description": "",
+ "version": "@GendustryVer@",
+ "url": "bdew.net/mods/",
+ "updateUrl": "",
+ "authorList": [
+ "bdew"
+ ],
+ "credits": "",
+ "logoFile": "",
+ "screenshots": [
+ ],
+ "parent":"",
+ "dependencies": [
+ ]
+}
+]
\ No newline at end of file
diff --git a/src/cofh/api/energy/IEnergyContainerItem.java b/src/cofh/api/energy/IEnergyContainerItem.java
new file mode 100644
index 00000000..0db36758
--- /dev/null
+++ b/src/cofh/api/energy/IEnergyContainerItem.java
@@ -0,0 +1,59 @@
+/*
+ * This file belongs to CoFHLib and is here temporarily, untill i implement full TE support
+ * It's licensed under LGPLv3
+ *
+ * https://github.com/KingLemming/CoFHLib
+ */
+
+package cofh.api.energy;
+
+import net.minecraft.item.ItemStack;
+
+/**
+ * Implement this interface on Item classes that support external manipulation of their internal energy storages.
+ *
+ * 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);
+
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/Gendustry.scala b/src/net/bdew/gendustry/Gendustry.scala
new file mode 100644
index 00000000..40db1539
--- /dev/null
+++ b/src/net/bdew/gendustry/Gendustry.scala
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry
+
+import java.util.logging.Logger
+import net.bdew.gendustry.config._
+import net.minecraftforge.common.Configuration
+import cpw.mods.fml.common.Mod
+import cpw.mods.fml.common.Mod.EventHandler
+import cpw.mods.fml.common.event.FMLInitializationEvent
+import cpw.mods.fml.common.event.FMLPostInitializationEvent
+import cpw.mods.fml.common.event.FMLPreInitializationEvent
+import cpw.mods.fml.common.network.NetworkMod
+import cpw.mods.fml.common.network.NetworkRegistry
+import net.bdew.gendustry.gui.GuiHandler
+import java.io.File
+import net.bdew.gendustry.machines.apiary.upgrades.Upgrades
+
+@Mod(modid = Gendustry.modId, version = "@GendustryVer@", name = "Gendustry", dependencies = "required-after:Forestry;required-after:BuildCraft|Core;required-after:bdlib@[@BdLibVer@,)", modLanguage = "scala")
+@NetworkMod(clientSideRequired = true, serverSideRequired = false)
+object Gendustry {
+ var log: Logger = null
+ var instance = this
+
+ final val modId = "gendustry"
+ final val channel = "bdew.gendustry"
+
+ var configDir: File = null
+
+ def logInfo(msg: String, args: Any*) = log.info(msg.format(args: _*))
+ def logWarn(msg: String, args: Any*) = log.warning(msg.format(args: _*))
+
+ @EventHandler
+ def preInit(event: FMLPreInitializationEvent) {
+ log = event.getModLog
+ configDir = event.getModConfigurationDirectory
+ TuningLoader.load("tuning")
+ val config: Configuration = Config.load(event.getSuggestedConfigurationFile)
+ try {
+ Ids.init(config)
+ Blocks.load(config)
+ Machines.load(config)
+ Items.load(config)
+ } finally {
+ config.save()
+ }
+ }
+
+ @EventHandler
+ def init(event: FMLInitializationEvent) {
+ NetworkRegistry.instance.registerGuiHandler(this, GuiHandler)
+ Upgrades.init()
+ TuningLoader.load("recipes")
+ }
+
+ @EventHandler
+ def postInit(event: FMLPostInitializationEvent) {
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/api/ApiaryModifiers.java b/src/net/bdew/gendustry/api/ApiaryModifiers.java
new file mode 100644
index 00000000..c1dbab21
--- /dev/null
+++ b/src/net/bdew/gendustry/api/ApiaryModifiers.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.api;
+
+public class ApiaryModifiers {
+ public float territory = 1;
+
+ //max safe = 10 (degenerating - offspring become unnatural)
+ public float mutation = 1;
+
+ //increases lifespan
+ public float lifespan = 1;
+
+ //increases chance to get products each cycle, max safe = 16 (overworked - becomes unnatural)
+ public float production = 1;
+
+ public float flowering = 1;
+
+ // set to 0 to reduce decay from fatigue
+ public float geneticDecay = 1;
+
+ public boolean isSealed = false;
+ public boolean isSelfLighted = false;
+ public boolean isSunlightSimulated = false;
+ public boolean isHellish = false;
+ public boolean isAutomated = false;
+ public boolean isCollectingPollen = false;
+
+ public float energy = 1;
+
+ public float temperature = 0;
+ public float humidity = 0;
+}
diff --git a/src/net/bdew/gendustry/api/IApiaryUpgrade.java b/src/net/bdew/gendustry/api/IApiaryUpgrade.java
new file mode 100644
index 00000000..ec4251d2
--- /dev/null
+++ b/src/net/bdew/gendustry/api/IApiaryUpgrade.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.api;
+
+import net.minecraft.item.ItemStack;
+
+public interface IApiaryUpgrade {
+ void applyModifiers(ApiaryModifiers mods, ItemStack stack);
+
+ long getStackingId(ItemStack stack);
+
+ int getMaxNumber(ItemStack stack);
+}
diff --git a/src/net/bdew/gendustry/config/Blocks.scala b/src/net/bdew/gendustry/config/Blocks.scala
new file mode 100644
index 00000000..1ce611b8
--- /dev/null
+++ b/src/net/bdew/gendustry/config/Blocks.scala
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.config
+
+import cpw.mods.fml.common.registry.GameRegistry
+import net.bdew.gendustry.machines.mproducer.BlockMutagenProducer
+import net.bdew.gendustry.machines.mutatron.BlockMutatron
+import net.bdew.gendustry.mutagen.BlockMutagen
+import net.bdew.gendustry.mutagen.FluidMutagen
+import net.bdew.gendustry.test.PowerEmitterBlock
+import net.bdew.gendustry.test.PowerEmitterTile
+import net.minecraftforge.common.Configuration
+
+object Blocks {
+ var mutagenFluid: FluidMutagen = null
+ var mutagen: BlockMutagen = null
+ var mutagenProducer: BlockMutagenProducer = null
+ var mutatron: BlockMutatron = null
+ var testPowerEmitter: PowerEmitterBlock = null
+
+ def load(cfg: Configuration) {
+ mutagenFluid = new FluidMutagen
+
+ mutagen = new BlockMutagen(cfg.getBlock("Mutagen", Ids.blockIds.next()).getInt)
+ GameRegistry.registerBlock(mutagen, "Mutagen")
+
+ testPowerEmitter = new PowerEmitterBlock(cfg.getBlock("Test Power Emitter", Ids.blockIds.next()).getInt)
+ GameRegistry.registerBlock(testPowerEmitter, "PowerEmitterBlock")
+ GameRegistry.registerTileEntity(classOf[PowerEmitterTile], "PowerEmitterBlock")
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/config/Config.scala b/src/net/bdew/gendustry/config/Config.scala
new file mode 100644
index 00000000..ab5cc206
--- /dev/null
+++ b/src/net/bdew/gendustry/config/Config.scala
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.config
+
+import net.minecraftforge.common.Configuration
+import java.io.File
+
+object Config {
+ var neiAddSamples = false
+
+ def load(cfg: File): Configuration = {
+ val c = new Configuration(cfg)
+ c.load()
+ c.addCustomCategoryComment("machines enabled", "Disabling a machine will remove it's block registration, loading any world will remove the blocks permanently")
+
+ neiAddSamples = c.get("NEI", "Add samples", true).getBoolean(false)
+
+ return c
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/config/Ids.scala b/src/net/bdew/gendustry/config/Ids.scala
new file mode 100644
index 00000000..186db7fd
--- /dev/null
+++ b/src/net/bdew/gendustry/config/Ids.scala
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.config
+
+import net.minecraft.block.Block
+import net.minecraft.item.Item
+import net.minecraftforge.common.Configuration
+
+object Ids {
+
+ class MyIter(start: Int, check: Array[_], offset: Int = 0) {
+ var now = start
+ def next(): Int = {
+ while (check(now + offset) != null) now += 1
+ return now
+ }
+ }
+
+ val blockIds = new MyIter(3500, Block.blocksList)
+ val itemIds = new MyIter(15000, Item.itemsList, 256)
+
+ def init(cfg: Configuration) {
+ // figure out what's the max id we already use, because forge is stupid
+ // ignore ids in the top slots as they were probably assigned to resolve conflicts
+ import scala.collection.JavaConverters._
+
+ val maxBlock = (cfg.getCategory(Configuration.CATEGORY_BLOCK).values().asScala.map(_.getInt).filter(_ < Block.blocksList.length - 100) ++ Seq(0)).max + 1
+ val maxItem = (cfg.getCategory(Configuration.CATEGORY_ITEM).values().asScala.map(_.getInt).filter(_ < Item.itemsList.length - 1000) ++ Seq(0)).max + 1
+
+ if (maxBlock > blockIds.now) blockIds.now = maxBlock
+ if (maxItem > itemIds.now) itemIds.now = maxItem
+ }
+}
diff --git a/src/net/bdew/gendustry/config/Items.scala b/src/net/bdew/gendustry/config/Items.scala
new file mode 100644
index 00000000..211b12d6
--- /dev/null
+++ b/src/net/bdew/gendustry/config/Items.scala
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.config
+
+import cpw.mods.fml.common.registry.GameRegistry
+import forestry.api.core.ItemInterface
+import net.bdew.gendustry.mutagen.ItemMutagenBucket
+import net.bdew.gendustry.mutagen.ItemMutagenCan
+import net.minecraft.item.Item
+import net.minecraft.item.ItemStack
+import net.minecraftforge.common.Configuration
+import net.minecraftforge.fluids.FluidContainerRegistry
+import net.bdew.gendustry.items.{IndustrialGrafter, GeneTemplate, GeneSample, SimpleItem}
+import net.bdew.gendustry.machines.apiary.upgrades.ItemApiaryUpgrade
+
+object Items {
+ var mutagenBucket: ItemMutagenBucket = null
+ var mutagenCan: ItemMutagenCan = null
+ var labware: SimpleItem = null
+ var waste: SimpleItem = null
+ var geneSample: GeneSample = null
+ var geneSampleBlank: SimpleItem = null
+ var geneTemplate: GeneTemplate = null
+ var upgradeItem: ItemApiaryUpgrade = null
+ var grafter: IndustrialGrafter = null
+
+ def regSimpleItem(cfg: Configuration, name: String): SimpleItem =
+ regItem(new SimpleItem(cfg.getItem(name, Ids.itemIds.next()).getInt, name), name)
+
+ def regItem[T <: SimpleItem](item: T): T = regItem(item, item.name)
+
+ def regItem[T <: Item](item: T, name: String): T = {
+ GameRegistry.registerItem(item, name)
+ GameRegistry.registerCustomItemStack(name, new ItemStack(item))
+ return item
+ }
+
+ def load(cfg: Configuration) {
+ mutagenBucket = regItem(new ItemMutagenBucket(cfg.getItem("MutagenBucket", Ids.itemIds.next()).getInt),"MutagenBucket")
+ mutagenCan = regItem(new ItemMutagenCan(cfg.getItem("MutagenCan", Ids.itemIds.next()).getInt), "MutagenCan")
+
+ FluidContainerRegistry.registerFluidContainer(Blocks.mutagenFluid, new ItemStack(mutagenBucket), new ItemStack(Item.bucketEmpty))
+ FluidContainerRegistry.registerFluidContainer(Blocks.mutagenFluid, new ItemStack(mutagenCan), ItemInterface.getItem("canEmpty"))
+
+ geneSample = regItem(new GeneSample(cfg.getItem("GeneSample", Ids.itemIds.next()).getInt))
+ geneTemplate = regItem(new GeneTemplate(cfg.getItem("GeneTemplate", Ids.itemIds.next()).getInt))
+
+ upgradeItem = regItem(new ItemApiaryUpgrade(cfg.getItem("ApiaryUpgrade", Ids.itemIds.next()).getInt), "ApiaryUpgrade")
+
+ grafter = regItem(new IndustrialGrafter(cfg.getItem("IndustrialGrafter", Ids.itemIds.next()).getInt), "IndustrialGrafter")
+
+ regSimpleItem(cfg, "MutagenTank")
+ regSimpleItem(cfg, "BeeReceptacle")
+ regSimpleItem(cfg, "PowerModule")
+ regSimpleItem(cfg, "GeneticsProcessor")
+ regSimpleItem(cfg, "UpgradeFrame")
+ regSimpleItem(cfg, "ClimateModule")
+
+ labware = regSimpleItem(cfg, "Labware")
+ waste = regSimpleItem(cfg, "Waste")
+ geneSampleBlank = regSimpleItem(cfg, "GeneSampleBlank")
+
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/config/Machines.scala b/src/net/bdew/gendustry/config/Machines.scala
new file mode 100644
index 00000000..8779c527
--- /dev/null
+++ b/src/net/bdew/gendustry/config/Machines.scala
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.config
+
+import net.minecraftforge.common.Configuration
+import net.bdew.gendustry.machines.mproducer.MachineMutagenProducer
+import net.bdew.gendustry.machines.mutatron.MachineMutatron
+import net.bdew.gendustry.machines.apiary.MachineApiary
+import net.bdew.gendustry.machines.imprinter.MachineImprinter
+import net.bdew.gendustry.machines.sampler.MachineSampler
+
+object Machines {
+ var mutagenProducer: MachineMutagenProducer = null
+ var mutatron: MachineMutatron = null
+ var apiary: MachineApiary = null
+ var imprinter: MachineImprinter = null
+ var sampler: MachineSampler = null
+
+ def load(cfg: Configuration) {
+ mutagenProducer = new MachineMutagenProducer(cfg)
+ mutatron = new MachineMutatron(cfg)
+ apiary = new MachineApiary(cfg)
+ imprinter = new MachineImprinter(cfg)
+ sampler = new MachineSampler(cfg)
+ }
+}
diff --git a/src/net/bdew/gendustry/config/Tuning.scala b/src/net/bdew/gendustry/config/Tuning.scala
new file mode 100644
index 00000000..5ce37447
--- /dev/null
+++ b/src/net/bdew/gendustry/config/Tuning.scala
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.config
+
+import net.bdew.lib.recipes.gencfg._
+import net.bdew.lib.recipes.{RecipeLoader, RecipeParser, Statement, StackRef}
+import net.bdew.gendustry.mutagen.MutagenRegistry
+import net.minecraftforge.oredict.OreDictionary
+import buildcraft.api.recipes.AssemblyRecipe
+import java.io.{InputStreamReader, FileReader, File}
+import net.bdew.gendustry.Gendustry
+
+object Tuning extends ConfigSection
+
+object TuningLoader {
+
+ abstract class EntryModifier extends CfgEntry
+
+ case class EntryModifierAdd(v: Float) extends EntryModifier
+
+ case class EntryModifierSub(v: Float) extends EntryModifier
+
+ case class EntryModifierMul(v: Float) extends EntryModifier
+
+ case class EntryModifierDiv(v: Float) extends EntryModifier
+
+ case class StMutagen(st: StackRef, mb: Int) extends Statement
+
+ case class StAssembly(rec: List[(Char, Int)], power: Int, out: StackRef, cnt: Int) extends Statement
+
+ class Parser extends RecipeParser with GenericConfigParser {
+ override def statement = mutagen | assembly | super.statement
+ def mutagen = "mutagen" ~> ":" ~> spec ~ ("->" ~> int) ^^ {
+ case sp ~ n => StMutagen(sp, n)
+ }
+
+ def charWithCount = recipeChar ~ ("*" ~> int).? ^^ {
+ case ch ~ cnt => (ch, cnt.getOrElse(1))
+ }
+
+ def assembly = "assembly" ~> ":" ~> (charWithCount <~ ",").+ ~ (int <~ "mj") ~ ("=>" ~> specWithCount) ^^ {
+ case r ~ p ~ (s ~ n) => StAssembly(r, p, s, n.getOrElse(1))
+ }
+
+ override def cfgStatement = cfgAdd | cfgMul | cfgSub | cfgDiv | super.cfgStatement
+
+ def cfgAdd = ident ~ ("+" ~> "=" ~> decimalNumber) ^^ { case id ~ n => CfgVal(id, EntryModifierAdd(n.toFloat)) }
+ def cfgMul = ident ~ ("*" ~> "=" ~> decimalNumber) ^^ { case id ~ n => CfgVal(id, EntryModifierMul(n.toFloat)) }
+ def cfgSub = ident ~ ("-" ~> "=" ~> decimalNumber) ^^ { case id ~ n => CfgVal(id, EntryModifierSub(n.toFloat)) }
+ def cfgDiv = ident ~ ("/" ~> "=" ~> decimalNumber) ^^ { case id ~ n => CfgVal(id, EntryModifierDiv(n.toFloat)) }
+ }
+
+ class Loader extends RecipeLoader with GenericConfigLoader {
+ val cfgStore = Tuning
+
+ override def newParser(): RecipeParser = new Parser()
+
+ override def processStatement(s: Statement): Unit = s match {
+ case StMutagen(st, mb) =>
+ val in = getConcreteStack(st)
+ MutagenRegistry.register(in, mb)
+ log.info("Added mutagen source %s -> %d mb".format(in, mb))
+
+ case StAssembly(rec, power, out, cnt) =>
+ log.info("Adding assembly recipe: %s + %d mj => %s * %d".format(rec, power, out, cnt))
+ val outStack = getConcreteStack(out, cnt)
+ val stacks = rec.map {
+ case (c, n) =>
+ val s = getConcreteStack(currCharMap(c), n)
+ if (s.getItemDamage == OreDictionary.WILDCARD_VALUE) {
+ s.setItemDamage(0)
+ log.warning("%s added with wildcard metadata which is unsupported, assuming 0".format(s))
+ }
+ log.info("%s -> %s".format(c, s))
+ s
+ }
+ log.info("Output: %s".format(outStack))
+ AssemblyRecipe.assemblyRecipes.add(new AssemblyRecipe(stacks.toArray, power, outStack))
+ log.info("Done")
+ case _ => super.processStatement(s)
+ }
+ }
+
+ def load(part: String) {
+ val f = new File(Gendustry.configDir, "%s-%s.cfg".format(Gendustry.modId, part))
+ val r = if (f.exists() && f.canRead) {
+ new FileReader(f)
+ } else {
+ new InputStreamReader(this.getClass.getResourceAsStream("/assets/%s/%s-%s.cfg".format(Gendustry.modId, Gendustry.modId, part)))
+ }
+ try {
+ new Loader().load(r)
+ } finally {
+ r.close()
+ }
+ }
+}
+
diff --git a/src/net/bdew/gendustry/data/DataSlotPower.scala b/src/net/bdew/gendustry/data/DataSlotPower.scala
new file mode 100644
index 00000000..0ac9f338
--- /dev/null
+++ b/src/net/bdew/gendustry/data/DataSlotPower.scala
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.data
+
+import net.minecraft.nbt.NBTTagCompound
+import buildcraft.api.power.{IPowerReceptor, PowerHandler}
+import net.bdew.lib.data.base.{TileDataSlots, UpdateKind, DataSlot}
+import net.bdew.gendustry.machines.PoweredMachine
+
+case class DataSlotPower(name: String, parent: TileDataSlots, kind: PowerHandler.Type) extends DataSlot {
+ updateKind = Set(UpdateKind.GUI, UpdateKind.SAVE)
+ var oldVal = 0F
+
+ require(parent.isInstanceOf[IPowerReceptor])
+ val handler = new PowerHandler(parent.asInstanceOf[IPowerReceptor], kind)
+
+ def configure(cfg: PoweredMachine): DataSlotPower = {
+ handler.configure(cfg.minReceivedEnergy, cfg.maxReceivedEnergy, cfg.activationEnergy, cfg.maxStoredEnergy)
+ handler.configurePowerPerdition(cfg.powerLoss, cfg.powerLossInterval)
+ return this
+ }
+
+ parent.serverTick.listen(checkUpdate)
+
+ updateKind = Set(UpdateKind.GUI, UpdateKind.SAVE)
+
+ def checkUpdate() {
+ handler.update()
+ if (getEnergyStored != oldVal) {
+ oldVal = getEnergyStored
+ parent.dataSlotChanged(this)
+ }
+ }
+
+ def useEnergy(min: Float, max: Float, doUse: Boolean): Float = handler.useEnergy(min, max, doUse)
+ def getMinEnergyReceived: Float = handler.getMinEnergyReceived
+ def getMaxEnergyReceived: Float = handler.getMaxEnergyReceived
+ def getMaxEnergyStored: Float = handler.getMaxEnergyStored
+ def getActivationEnergy: Float = handler.getActivationEnergy
+ def getEnergyStored: Float = handler.getEnergyStored
+
+ def save(t: NBTTagCompound, kind: UpdateKind.Value) {
+ handler.writeToNBT(t, name)
+ if (kind == UpdateKind.GUI)
+ t.getCompoundTag(name).setFloat("maxStored", getMaxEnergyStored)
+ }
+
+ def load(t: NBTTagCompound, kind: UpdateKind.Value) {
+ handler.readFromNBT(t, name)
+ if (kind == UpdateKind.GUI)
+ handler.configure(getMaxEnergyReceived, getMaxEnergyReceived, getActivationEnergy, t.getCompoundTag(name).getFloat("maxStored"))
+ }
+}
+
+
diff --git a/src/net/bdew/gendustry/data/ExposePower.scala b/src/net/bdew/gendustry/data/ExposePower.scala
new file mode 100644
index 00000000..a23d1cde
--- /dev/null
+++ b/src/net/bdew/gendustry/data/ExposePower.scala
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.data
+
+import buildcraft.api.power.{PowerHandler, IPowerReceptor}
+import net.minecraft.world.World
+import net.minecraftforge.common.ForgeDirection
+import net.bdew.lib.tile.TileExtended
+
+trait ExposePower extends TileExtended with IPowerReceptor {
+ def getPowerDataslot(from: ForgeDirection): DataSlotPower
+ def doWork(workProvider: PowerHandler) {}
+ def getPowerReceiver(side: ForgeDirection) = getPowerDataslot(side).handler.getPowerReceiver
+ def getWorld: World = worldObj
+}
diff --git a/src/net/bdew/gendustry/forestry/GeneRecipe.scala b/src/net/bdew/gendustry/forestry/GeneRecipe.scala
new file mode 100644
index 00000000..d5b396a5
--- /dev/null
+++ b/src/net/bdew/gendustry/forestry/GeneRecipe.scala
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.forestry
+
+import net.minecraft.item.crafting.IRecipe
+import net.minecraft.item.ItemStack
+import net.minecraft.inventory.InventoryCrafting
+import net.minecraft.world.World
+import net.bdew.gendustry.items.{GeneTemplate, GeneSample}
+import net.bdew.gendustry.config.Items
+
+class GeneRecipe extends IRecipe {
+ def matches(inv: InventoryCrafting, world: World): Boolean = getCraftingResult(inv) != null
+ def getCraftingResult(inv: InventoryCrafting): ItemStack = {
+ var template: ItemStack = null
+ var samples = Seq.empty[GeneSampleInfo]
+ for (i <- 0 until 3; j <- 0 until 3) {
+ val itm = inv.getStackInRowAndColumn(i, j)
+ if (itm != null && itm.getItem.isInstanceOf[GeneSample])
+ samples :+= Items.geneSample.getInfo(itm)
+ else if (itm != null && itm.getItem.isInstanceOf[GeneTemplate] && template == null)
+ template = itm
+ else if (itm != null)
+ return null
+ }
+ if (samples.isEmpty || template == null) return null
+ val out = template.copy()
+ for (s <- samples) {
+ if (!Items.geneTemplate.addSample(out, s)) return null
+ }
+ return out
+ }
+ def getRecipeSize: Int = 9
+ def getRecipeOutput: ItemStack = null
+}
diff --git a/src/net/bdew/gendustry/forestry/GeneSampleInfo.scala b/src/net/bdew/gendustry/forestry/GeneSampleInfo.scala
new file mode 100644
index 00000000..8b616729
--- /dev/null
+++ b/src/net/bdew/gendustry/forestry/GeneSampleInfo.scala
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.forestry
+
+import forestry.api.genetics._
+import net.minecraft.nbt.NBTTagCompound
+import forestry.api.apiculture.{EnumBeeChromosome, IBeeRoot}
+import forestry.api.arboriculture.{IAlleleGrowth, IAlleleFruit, EnumTreeChromosome, ITreeRoot}
+import forestry.api.lepidopterology.{EnumButterflyChromosome, IButterflyRoot}
+import net.bdew.lib.Misc
+
+case class GeneSampleInfo(root: ISpeciesRoot, chromosome: Int, allele: IAllele) {
+ def writeToNBT(t: NBTTagCompound) {
+ t.setString("species", root.getUID)
+ t.setInteger("chromosome", chromosome)
+ t.setString("allele", allele.getUID)
+ }
+
+ def getText: String = {
+ import scala.collection.JavaConverters._
+ val chr = root match {
+ case x: IBeeRoot => EnumBeeChromosome.values()(chromosome).toString
+ case x: ITreeRoot => EnumTreeChromosome.values()(chromosome).toString
+ case x: IButterflyRoot => EnumButterflyChromosome.values()(chromosome).toString
+ case _ => "Invalid"
+ }
+ val alstr = allele match {
+ case i: IAlleleInteger => chr match {
+ case "GIRTH" => "%d x %d".format(i.getValue, i.getValue)
+ case "FERTILITY" if !root.isInstanceOf[ITreeRoot] => i.getValue.toString
+ case "METABOLISM" => i.getValue.toString
+ case _ => i.getName
+ }
+ case f: IAlleleFruit => StringUtil.localize(f.getProvider.getDescription)
+ case p: IAllelePlantType => if (p.getPlantTypes.isEmpty) "-" else p.getPlantTypes.asScala.mkString(", ")
+ case b: IAlleleBoolean => if (b.getValue) Misc.toLocal("gendustry.allele.true") else Misc.toLocal("gendustry.allele.false")
+ case g: IAlleleGrowth => g.getProvider.getDescription
+ case x => x.getName
+ }
+ return "%s: %s".format(Misc.toLocal("gendustry.chromosome." + chr), alstr)
+ }
+}
+
+object GeneSampleInfo {
+ def fromNBT(t: NBTTagCompound): GeneSampleInfo = {
+ val species = AlleleManager.alleleRegistry.getSpeciesRoot(t.getString("species"))
+ val allele = AlleleManager.alleleRegistry.getAllele(t.getString("allele"))
+ return GeneSampleInfo(species, t.getInteger("chromosome"), allele)
+ }
+}
diff --git a/src/net/bdew/gendustry/forestry/StringUtil.scala b/src/net/bdew/gendustry/forestry/StringUtil.scala
new file mode 100644
index 00000000..0b1f7c9f
--- /dev/null
+++ b/src/net/bdew/gendustry/forestry/StringUtil.scala
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.forestry
+
+object StringUtil {
+ val cl = Class.forName("forestry.core.utils.StringUtil")
+ val mLocalize = cl.getMethod("localize", classOf[String])
+
+ def localize(s: String) = mLocalize.invoke(null, s).asInstanceOf[String]
+}
diff --git a/src/net/bdew/gendustry/gui/BlockGuiWrenchable.scala b/src/net/bdew/gendustry/gui/BlockGuiWrenchable.scala
new file mode 100644
index 00000000..e452c7b9
--- /dev/null
+++ b/src/net/bdew/gendustry/gui/BlockGuiWrenchable.scala
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.gui
+
+import net.minecraft.world.World
+import net.minecraft.entity.player.EntityPlayer
+import buildcraft.api.tools.IToolWrench
+import net.bdew.gendustry.Gendustry
+import net.minecraft.block.Block
+
+trait BlockGuiWrenchable extends Block {
+ val guiId: Int
+ override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer, meta: Int, xoffs: Float, yoffs: Float, zoffs: Float): Boolean = {
+ if (player.isSneaking) {
+ val equipped = if (player.getCurrentEquippedItem != null) player.getCurrentEquippedItem.getItem else null
+ if (equipped.isInstanceOf[IToolWrench] && equipped.asInstanceOf[IToolWrench].canWrench(player, x, y, z)) {
+ if (!world.isRemote) world.destroyBlock(x, y, z, true)
+ return true
+ }
+ return false
+ } else {
+ if (!world.isRemote) player.openGui(Gendustry.instance, guiId, world, x, y, z)
+ return true
+ }
+ }
+}
diff --git a/src/net/bdew/gendustry/gui/GuiHandler.scala b/src/net/bdew/gendustry/gui/GuiHandler.scala
new file mode 100644
index 00000000..9408b223
--- /dev/null
+++ b/src/net/bdew/gendustry/gui/GuiHandler.scala
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.gui
+
+import cpw.mods.fml.common.network.IGuiHandler
+import scala.collection.mutable
+import net.minecraft.entity.player.EntityPlayer
+import net.minecraft.world.World
+
+object GuiHandler extends IGuiHandler {
+ val guis = mutable.Map.empty[Int, GuiProvider]
+
+ def register(p: GuiProvider) = {
+ if (guis.isDefinedAt(p.guiId))
+ sys.error("GUI ID Collision - %d was registered for %s and attemted to register by %s".format(p.guiId, guis(p.guiId), p))
+ guis += (p.guiId -> p)
+ }
+
+ def getServerGuiElement(ID: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): AnyRef =
+ guis(ID).getContainer(world.getBlockTileEntity(x, y, z), player)
+
+ def getClientGuiElement(ID: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): AnyRef =
+ guis(ID).getGui(world.getBlockTileEntity(x, y, z), player)
+}
diff --git a/src/net/bdew/gendustry/gui/GuiProvider.scala b/src/net/bdew/gendustry/gui/GuiProvider.scala
new file mode 100644
index 00000000..26cebd6e
--- /dev/null
+++ b/src/net/bdew/gendustry/gui/GuiProvider.scala
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.gui
+
+import net.minecraft.tileentity.TileEntity
+import net.minecraft.entity.player.EntityPlayer
+import net.minecraft.client.gui.inventory.GuiContainer
+import net.minecraft.inventory.Container
+import cpw.mods.fml.relauncher.{Side, SideOnly}
+
+trait GuiProvider {
+ GuiHandler.register(this)
+ def guiId: Int
+
+ @SideOnly(Side.CLIENT)
+ def getGui(te: TileEntity, player: EntityPlayer): GuiContainer
+ def getContainer(te: TileEntity, player: EntityPlayer): Container
+}
diff --git a/src/net/bdew/gendustry/gui/Textures.scala b/src/net/bdew/gendustry/gui/Textures.scala
new file mode 100644
index 00000000..377c44a5
--- /dev/null
+++ b/src/net/bdew/gendustry/gui/Textures.scala
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.gui
+
+import net.bdew.lib.gui.TextureLocation
+import net.minecraft.util.ResourceLocation
+import net.bdew.gendustry.Gendustry
+
+object Textures {
+ val texture = new ResourceLocation(Gendustry.modId + ":textures/gui/widgets.png")
+ val tankOverlay = new TextureLocation(texture, 16, 0)
+ val powerFill = new TextureLocation(texture, 0, 0)
+ val texturePowerError = new TextureLocation(texture, 32, 0)
+ def greenProgress(width: Int) = new TextureLocation(texture, 136 - width, 58)
+ def whiteProgress(width: Int) = new TextureLocation(texture, 136 - width, 73)
+}
diff --git a/src/net/bdew/gendustry/gui/WidgetMJGauge.scala b/src/net/bdew/gendustry/gui/WidgetMJGauge.scala
new file mode 100644
index 00000000..d289a6a2
--- /dev/null
+++ b/src/net/bdew/gendustry/gui/WidgetMJGauge.scala
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.gui
+
+import net.bdew.lib.gui.{Point, TextureLocation, Rect}
+import scala.collection.mutable
+import java.text.DecimalFormat
+import net.bdew.gendustry.data.DataSlotPower
+import net.minecraft.client.Minecraft
+import net.bdew.lib.gui.widgets.Widget
+
+class WidgetMJGauge(val rect: Rect, texture: TextureLocation, dslot: DataSlotPower) extends Widget {
+ val formater = new DecimalFormat("#,###")
+
+ override def draw() {
+ Minecraft.getMinecraft.renderEngine.bindTexture(texture.resource)
+ val fill = (dslot.getEnergyStored / dslot.getMaxEnergyStored * rect.h).round
+ parent.drawTexturedModalRect(rect.x, rect.y + rect.h - fill, texture.x, texture.y + rect.h - fill, rect.w, fill)
+ }
+
+ override def handleTooltip(p: Point, tip: mutable.MutableList[String]) = tip += formater.format(dslot.getEnergyStored) + "/" + formater.format(dslot.getMaxEnergyStored) + " MJ"
+}
diff --git a/src/net/bdew/gendustry/items/GeneSample.scala b/src/net/bdew/gendustry/items/GeneSample.scala
new file mode 100644
index 00000000..46f339b9
--- /dev/null
+++ b/src/net/bdew/gendustry/items/GeneSample.scala
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.items
+
+import net.minecraft.item.ItemStack
+import net.minecraft.nbt.NBTTagCompound
+import net.minecraft.entity.player.EntityPlayer
+import java.util
+import net.bdew.lib.Misc
+import net.bdew.gendustry.forestry.GeneSampleInfo
+import net.bdew.gendustry.config.Items
+
+class GeneSample(id: Int) extends SimpleItem(id, "GeneSample") {
+
+ setMaxStackSize(1)
+ setContainerItem(Items.geneSampleBlank)
+
+ def newStack(info: GeneSampleInfo): ItemStack = {
+ val stack = new ItemStack(this)
+ val tag = new NBTTagCompound()
+ info.writeToNBT(tag)
+ stack.setTagCompound(tag)
+ return stack
+ }
+
+ def getInfo(stack: ItemStack): GeneSampleInfo = GeneSampleInfo.fromNBT(stack.getTagCompound)
+
+ override def addInformation(stack: ItemStack, player: EntityPlayer, l: util.List[_], par4: Boolean) = {
+ import scala.collection.JavaConverters._
+ if (stack.hasTagCompound) {
+ val tip = l.asInstanceOf[util.List[String]].asScala
+ val info = getInfo(stack)
+ tip += Misc.toLocal("gendustry.label.sample." + info.root.getUID)
+ tip += info.getText
+ }
+ }
+}
diff --git a/src/net/bdew/gendustry/items/GeneTemplate.scala b/src/net/bdew/gendustry/items/GeneTemplate.scala
new file mode 100644
index 00000000..6e2c5f02
--- /dev/null
+++ b/src/net/bdew/gendustry/items/GeneTemplate.scala
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.items
+
+import net.minecraft.item.ItemStack
+import net.bdew.gendustry.forestry.{GeneRecipe, GeneSampleInfo}
+import net.bdew.lib.Misc
+import net.minecraft.nbt.{NBTTagList, NBTTagCompound}
+import net.minecraft.entity.player.EntityPlayer
+import java.util
+import cpw.mods.fml.common.registry.GameRegistry
+import forestry.api.genetics.{ISpeciesRoot, AlleleManager}
+
+class GeneTemplate(id: Int) extends SimpleItem(id, "GeneTemplate") {
+ setMaxStackSize(1)
+
+ GameRegistry.addRecipe(new GeneRecipe)
+
+ override def getUnlocalizedName: String = super.getUnlocalizedName
+ override def getUnlocalizedName(par1ItemStack: ItemStack): String = super.getUnlocalizedName
+
+ def getSpecies(stack: ItemStack): ISpeciesRoot =
+ if (stack.hasTagCompound) AlleleManager.alleleRegistry.getSpeciesRoot(stack.getTagCompound.getString("species")) else null
+
+ def getSamples(stack: ItemStack): Iterable[GeneSampleInfo] = {
+ val tag = stack.getTagCompound
+ if (tag != null)
+ return Misc.iterNbtList[NBTTagCompound](tag.getTagList("samples")).map(x => GeneSampleInfo.fromNBT(x))
+ else
+ return Seq.empty[GeneSampleInfo]
+ }
+
+ def addSample(stack: ItemStack, sample: GeneSampleInfo): Boolean = {
+ val tag = if (stack.hasTagCompound) {
+ stack.getTagCompound
+ } else {
+ val newTag = new NBTTagCompound()
+ newTag.setString("species", sample.root.getUID)
+ newTag.setTag("samples", new NBTTagList())
+ stack.setTagCompound(newTag)
+ newTag
+ }
+ if (tag.getString("species") != sample.root.getUID) return false
+ val samples = new NBTTagList()
+ for (s <- getSamples(stack) if s.chromosome != sample.chromosome) {
+ val t = new NBTTagCompound()
+ s.writeToNBT(t)
+ samples.appendTag(t)
+ }
+ val stag = new NBTTagCompound()
+ sample.writeToNBT(stag)
+ samples.appendTag(stag)
+ tag.setTag("samples", samples)
+ return true
+ }
+
+ override def addInformation(stack: ItemStack, player: EntityPlayer, l: util.List[_], par4: Boolean) = {
+ import scala.collection.JavaConverters._
+ val tip = l.asInstanceOf[util.List[String]].asScala
+ val tag = stack.getTagCompound
+ if (tag != null && tag.hasKey("species")) {
+ try {
+ tip += Misc.toLocal("gendustry.label.template." + tag.getString("species"))
+ tip ++= getSamples(stack).map(_.getText)
+ } catch {
+ case e: Throwable =>
+ e.printStackTrace()
+ tip += "Error"
+ }
+ } else {
+ tip += Misc.toLocal("gendustry.label.template.blank")
+ }
+ }
+}
diff --git a/src/net/bdew/gendustry/items/IndustrialGrafter.scala b/src/net/bdew/gendustry/items/IndustrialGrafter.scala
new file mode 100644
index 00000000..357b7877
--- /dev/null
+++ b/src/net/bdew/gendustry/items/IndustrialGrafter.scala
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.items
+
+import cofh.api.energy.IEnergyContainerItem
+import net.minecraft.item.{ItemStack, EnumToolMaterial, ItemTool}
+import forestry.api.arboriculture.IToolGrafter
+import net.minecraft.world.World
+import net.minecraft.entity.player.EntityPlayer
+import net.bdew.gendustry.Gendustry
+import net.bdew.gendustry.config.Tuning
+import net.minecraft.nbt.NBTTagCompound
+import net.bdew.lib.Misc
+import net.minecraft.block.Block
+import net.minecraft.block.material.Material
+import net.minecraft.entity.EntityLivingBase
+import java.util
+import net.minecraft.creativetab.CreativeTabs
+
+class IndustrialGrafter(id: Int) extends ItemTool(id, 0, EnumToolMaterial.IRON, Array.empty[Block]) with IEnergyContainerItem with IToolGrafter {
+ val cfg = Tuning.getSection("Items").getSection("IndustrialGrafter")
+ val rfPerCharge = cfg.getInt("RfPerCharge")
+ val maxCharge = cfg.getInt("Charges") * rfPerCharge
+
+ setUnlocalizedName(Gendustry.modId + ".grafter")
+ setMaxStackSize(1)
+ setMaxDamage(101)
+
+ efficiencyOnProperMaterial = 32
+
+ def getCharge(stack: ItemStack): Int = {
+ if (!stack.hasTagCompound) setCharge(stack, 0)
+ return Misc.clamp(stack.getTagCompound.getInteger("charge"), 0, maxCharge)
+ }
+
+ def useCharge(stack: ItemStack, uses: Int = 1) {
+ setCharge(stack, Misc.clamp(getCharge(stack) - uses * rfPerCharge, 0, maxCharge))
+ }
+
+ def setCharge(stack: ItemStack, charge: Int) {
+ if (!stack.hasTagCompound) stack.setTagCompound(new NBTTagCompound())
+ stack.getTagCompound.setInteger("charge", charge)
+ updateDamage(stack)
+ }
+
+ def updateDamage(stack: ItemStack) {
+ setDamage(stack, Misc.clamp((100 * (1 - getCharge(stack).toFloat / maxCharge)).round.toInt, 1, 100))
+ }
+
+ def stackWithCharge(charge: Int): ItemStack = {
+ val n = new ItemStack(this)
+ setCharge(n, charge)
+ return n
+ }
+
+ override def setDamage(stack: ItemStack, damage: Int) = super.setDamage(stack, Misc.clamp(damage, 1, 100))
+
+ override def getStrVsBlock(stack: ItemStack, block: Block, meta: Int): Float = getStrVsBlock(stack, block)
+ override def getStrVsBlock(stack: ItemStack, block: Block): Float = {
+ if (getCharge(stack) < rfPerCharge) return 0.1F
+ if (block.blockMaterial == Material.leaves) return efficiencyOnProperMaterial
+ return 0.1F
+ }
+
+ override def onBlockDestroyed(stack: ItemStack, world: World, blockId: Int, x: Int, y: Int, z: Int, player: EntityLivingBase): Boolean = {
+ if (Block.blocksList(blockId).blockMaterial == Material.leaves) {
+ val aoe = 2
+ if (!world.isRemote && player.isInstanceOf[EntityPlayer]) {
+ for (dx <- -1 * aoe to aoe;
+ dy <- -1 * aoe to aoe;
+ dz <- -1 * aoe to aoe
+ if dy + y > 0 && dy + y < world.getHeight) {
+ val bl = Block.blocksList(world.getBlockId(x + dx, y + dy, z + dz))
+ if (bl != null && bl.blockMaterial == Material.leaves && getCharge(stack) > rfPerCharge) {
+ bl.removeBlockByPlayer(world, player.asInstanceOf[EntityPlayer], x + dx, y + dy, z + dz)
+ useCharge(stack)
+ }
+ }
+ }
+ useCharge(stack)
+ return true
+ }
+ return false
+ }
+
+ override def addInformation(stack: ItemStack, player: EntityPlayer, l: util.List[_], par4: Boolean) = {
+ import scala.collection.JavaConverters._
+ val tip = l.asInstanceOf[util.List[String]].asScala
+
+ tip += Misc.toLocalF("gendustry.label.charges", getCharge(stack) / rfPerCharge)
+ }
+
+ override def getSubItems(par1: Int, tabs: CreativeTabs, l: util.List[_]) {
+ import scala.collection.JavaConverters._
+ val items = l.asInstanceOf[util.List[ItemStack]].asScala
+ items += new ItemStack(this)
+ items += stackWithCharge(maxCharge)
+ }
+
+ override def getItemEnchantability: Int = 0
+ override def getIsRepairable(par1ItemStack: ItemStack, par2ItemStack: ItemStack): Boolean = false
+ override def isBookEnchantable(itemstack1: ItemStack, itemstack2: ItemStack): Boolean = false
+
+ def receiveEnergy(container: ItemStack, maxReceive: Int, simulate: Boolean): Int = {
+ val charge = getCharge(container)
+ val canCharge = Misc.clamp(maxCharge - charge, 0, maxReceive)
+ if (!simulate) setCharge(container, charge + canCharge)
+ return canCharge
+ }
+
+ def extractEnergy(container: ItemStack, maxExtract: Int, simulate: Boolean): Int = 0
+ def getEnergyStored(container: ItemStack): Int = getCharge(container)
+ def getMaxEnergyStored(container: ItemStack): Int = maxCharge
+
+ def getSaplingModifier(stack: ItemStack, world: World, player: EntityPlayer, x: Int, y: Int, z: Int): Float = if (getCharge(stack) > rfPerCharge) 100 else 0
+}
diff --git a/src/net/bdew/gendustry/items/SimpleItem.scala b/src/net/bdew/gendustry/items/SimpleItem.scala
new file mode 100644
index 00000000..c812f584
--- /dev/null
+++ b/src/net/bdew/gendustry/items/SimpleItem.scala
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.items
+
+import net.minecraft.item.Item
+import net.bdew.gendustry.Gendustry
+import net.minecraft.client.renderer.texture.IconRegister
+import cpw.mods.fml.relauncher.{Side, SideOnly}
+
+class SimpleItem(id: Int, val name: String) extends Item(id) {
+ setUnlocalizedName(Gendustry.modId + "." + name)
+
+ @SideOnly(Side.CLIENT)
+ override def registerIcons(reg: IconRegister) {
+ itemIcon = reg.registerIcon(Gendustry.modId + ":" + name.toLowerCase)
+ }
+}
diff --git a/src/net/bdew/gendustry/machines/Machine.scala b/src/net/bdew/gendustry/machines/Machine.scala
new file mode 100644
index 00000000..d4905520
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/Machine.scala
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines
+
+import net.minecraft.tileentity.TileEntity
+import cpw.mods.fml.common.registry.GameRegistry
+import net.bdew.gendustry.Gendustry
+import net.minecraft.block.Block
+import net.minecraftforge.common.Configuration
+import net.bdew.lib.block.HasTE
+import net.bdew.gendustry.config.{Tuning, Ids}
+import net.minecraft.item.ItemStack
+
+abstract class Machine(cfg: Configuration, val name: String) {
+ lazy val tuning = Tuning.getSection("Machines").getSection(name)
+
+ def registerBlock(block: Block) {
+ GameRegistry.registerBlock(block, name)
+ GameRegistry.registerCustomItemStack(name, new ItemStack(block))
+ if (block.isInstanceOf[HasTE[_]]) {
+ registerTE(block.asInstanceOf[HasTE[_]].TEClass)
+ }
+ }
+
+ def registerTE(teClass: Class[_ <: TileEntity]) {
+ GameRegistry.registerTileEntity(teClass, "%s.%s".format(Gendustry.modId, name))
+ }
+
+ def getBlockId = cfg.getBlock(name, Ids.blockIds.next()).getInt
+}
diff --git a/src/net/bdew/gendustry/machines/PoweredMachine.scala b/src/net/bdew/gendustry/machines/PoweredMachine.scala
new file mode 100644
index 00000000..3001034b
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/PoweredMachine.scala
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines
+
+import net.minecraftforge.common.Configuration
+
+abstract class PoweredMachine(cfg: Configuration, name: String) extends Machine(cfg, name) {
+ lazy val minReceivedEnergy = tuning.getFloat("MinReceivedEnergy")
+ lazy val maxReceivedEnergy = tuning.getFloat("MaxReceivedEnergy")
+ lazy val activationEnergy = tuning.getFloat("ActivationEnergy")
+ lazy val maxStoredEnergy = tuning.getFloat("MaxStoredEnergy")
+ lazy val powerLoss = tuning.getInt("PowerLoss")
+ lazy val powerLossInterval = tuning.getInt("PowerLossInterval")
+}
diff --git a/src/net/bdew/gendustry/machines/ProcessorMachine.scala b/src/net/bdew/gendustry/machines/ProcessorMachine.scala
new file mode 100644
index 00000000..7d17e2f3
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/ProcessorMachine.scala
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines
+
+import net.minecraftforge.common.Configuration
+
+abstract class ProcessorMachine(cfg: Configuration, name: String) extends PoweredMachine(cfg, name) {
+ lazy val mjPerItem = tuning.getFloat("MjPerItem")
+ lazy val powerUseRate = tuning.getFloat("PowerUseRate")
+}
diff --git a/src/net/bdew/gendustry/machines/TileBaseProcessor.scala b/src/net/bdew/gendustry/machines/TileBaseProcessor.scala
new file mode 100644
index 00000000..69cf53fc
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/TileBaseProcessor.scala
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines
+
+import net.bdew.lib.tile.TileExtended
+import net.bdew.lib.data.base.{UpdateKind, TileDataSlots}
+import net.bdew.lib.tile.inventory.{BreakableInventoryTile, SidedInventory, PersistentInventoryTile}
+import net.bdew.gendustry.data.{DataSlotPower, ExposePower}
+import buildcraft.api.power.PowerHandler.Type
+import net.bdew.lib.data.DataSlotFloat
+import net.minecraftforge.common.ForgeDirection
+
+abstract class TileBaseProcessor extends TileExtended
+with TileDataSlots
+with PersistentInventoryTile
+with BreakableInventoryTile
+with SidedInventory
+with ExposePower {
+ def cfg: ProcessorMachine
+ val power = DataSlotPower("power", this, Type.MACHINE).configure(cfg)
+ val progress = DataSlotFloat("progress", this).setUpdate(UpdateKind.SAVE, UpdateKind.GUI)
+
+ def getPowerDataslot(from: ForgeDirection): DataSlotPower = power
+
+ override def tickServer() {
+ if (power.getEnergyStored > cfg.activationEnergy) {
+
+ if (!isWorking)
+ if (tryStart())
+ progress := 0
+
+ if (isWorking) {
+
+ if ((progress < 1) && (power.getEnergyStored > cfg.activationEnergy)) {
+ val maxConsume = Math.min(Math.max(cfg.powerUseRate * power.getEnergyStored, cfg.activationEnergy), cfg.mjPerItem * (1 - progress))
+ val consumed = power.useEnergy(0, maxConsume, true)
+ progress += consumed / cfg.mjPerItem
+ }
+
+ if (progress >= 1) {
+ if (tryFinish())
+ progress := 0
+ }
+ }
+ }
+ }
+
+ /**
+ * Return true when an operation is in progress
+ */
+ def isWorking: Boolean
+
+ /**
+ * Try starting a new operation, return true if succesful
+ */
+ def tryStart(): Boolean
+
+ /**
+ * Perform output when operation is done, return true if succesful
+ */
+ def tryFinish(): Boolean
+}
diff --git a/src/net/bdew/gendustry/machines/TileItemProcessor.scala b/src/net/bdew/gendustry/machines/TileItemProcessor.scala
new file mode 100644
index 00000000..131b92d1
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/TileItemProcessor.scala
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines
+
+import net.bdew.lib.data.DataSlotItemStack
+import net.bdew.lib.data.base.UpdateKind
+import net.bdew.lib.items.ItemUtils
+
+abstract class TileItemProcessor extends TileBaseProcessor {
+ val output = DataSlotItemStack("output", this).setUpdate(UpdateKind.SAVE)
+ val outputSlots: Seq[Int]
+
+ def isWorking = output :!= null
+
+ def tryFinish(): Boolean = {
+ output := ItemUtils.addStackToSlots(output, this, outputSlots, false)
+ return output :== null
+ }
+}
diff --git a/src/net/bdew/gendustry/machines/apiary/BlockApiary.scala b/src/net/bdew/gendustry/machines/apiary/BlockApiary.scala
new file mode 100644
index 00000000..2b2d9e00
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/apiary/BlockApiary.scala
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.apiary
+
+import net.bdew.gendustry.Gendustry
+import net.minecraft.block.Block
+import net.minecraft.block.material.Material
+import net.minecraft.client.renderer.texture.IconRegister
+import net.minecraft.entity.player.EntityPlayerMP
+import net.minecraft.util.Icon
+import net.minecraft.world.{IBlockAccess, World}
+import cpw.mods.fml.relauncher.Side
+import cpw.mods.fml.relauncher.SideOnly
+import net.bdew.lib.block.HasTE
+import net.bdew.lib.tile.inventory.BreakableInventoryBlock
+import net.bdew.gendustry.config.Machines
+import net.minecraft.entity.EntityLivingBase
+import net.minecraft.item.ItemStack
+import net.bdew.gendustry.gui.BlockGuiWrenchable
+
+class BlockApiary(id: Int) extends Block(id, Material.rock) with HasTE[TileApiary] with BlockGuiWrenchable with BreakableInventoryBlock {
+ private var icons: Array[Icon] = null
+ val TEClass = classOf[TileApiary]
+ lazy val guiId: Int = Machines.apiary.guiId
+
+ setUnlocalizedName(Gendustry.modId + ".apiary")
+ setHardness(5)
+
+ override def getIcon(side: Int, meta: Int): Icon = if (side < 2) icons(0) else icons(1)
+
+ @SideOnly(Side.CLIENT)
+ override def registerIcons(reg: IconRegister) {
+ icons = new Array[Icon](2)
+ icons(0) = reg.registerIcon(Gendustry.modId + ":apiary/top")
+ icons(1) = reg.registerIcon(Gendustry.modId + ":apiary/side")
+ }
+
+ override def getLightValue(world: IBlockAccess, x: Int, y: Int, z: Int): Int = {
+ val block: Block = Block.blocksList(world.getBlockId(x, y, z))
+ if (block != null && block != this)
+ return block.getLightValue(world, x, y, z)
+ else if (world.getBlockTileEntity(x, y, z) != null && getTE(world, x, y, z).hasLight)
+ return 15
+ else
+ return 0
+ }
+
+ override def onBlockPlacedBy(world: World, x: Int, y: Int, z: Int, player: EntityLivingBase, stack: ItemStack) {
+ if (player.isInstanceOf[EntityPlayerMP])
+ getTE(world, x, y, z).owner := player.asInstanceOf[EntityPlayerMP].username
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/apiary/ContainerApiary.scala b/src/net/bdew/gendustry/machines/apiary/ContainerApiary.scala
new file mode 100644
index 00000000..70355d9f
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/apiary/ContainerApiary.scala
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.apiary
+
+import net.minecraft.entity.player.EntityPlayer
+import net.bdew.lib.gui.{BaseContainer, SlotValidating}
+import net.minecraft.item.ItemStack
+import net.minecraft.inventory.{IInventory, Slot}
+import net.bdew.lib.items.ItemUtils
+import net.bdew.lib.data.base.ContainerDataSlots
+import net.bdew.lib.Misc
+
+class ContainerApiary(val te: TileApiary, player: EntityPlayer) extends BaseContainer(te) with ContainerDataSlots {
+ lazy val dataSource = te
+
+ addSlotToContainer(new SlotValidating(te, 0, 39, 29))
+ addSlotToContainer(new SlotValidating(te, 1, 39, 52))
+
+ class SlotUpgrade(inv: IInventory, slot: Int, x: Int, y: Int) extends SlotValidating(inv, slot, x, y) {
+ // Fixes glitch in nei mouse scroll support
+ override def isItemValid(stack: ItemStack): Boolean = stack == this.getStack || super.isItemValid(stack)
+ }
+
+ for (i <- 0 to 1; j <- 0 to 1)
+ addSlotToContainer(new SlotUpgrade(te, 2 + j + i * 2, 70 + j * 18, 43 + i * 18))
+
+ for (i <- 0 to 2; j <- 0 to 2)
+ addSlotToContainer(new SlotValidating(te, 6 + j + i * 3, 116 + j * 18, 25 + i * 18))
+
+ bindPlayerInventory(player.inventory, 8, 84, 142)
+
+
+
+ override def transferStackInSlot(player: EntityPlayer, slot: Int): ItemStack = {
+ val stack = getSlot(slot).getStack
+ if (getSlot(slot).inventory == player.inventory && te.isUpgrade(stack)) {
+ val canAdd = Misc.min(te.getMaxAdditionalUpgrades(stack), stack.stackSize)
+ if (canAdd > 0) {
+ ItemUtils.addStackToSlots(stack.splitStack(canAdd), te, te.slotsUpgrades, true)
+ }
+ getSlot(slot).putStack(if (stack.stackSize > 0) stack else null)
+ return null
+ }
+ return super.transferStackInSlot(player, slot)
+ }
+
+ override def slotClick(slot: Int, button: Int, modifiers: Int, player: EntityPlayer): ItemStack = {
+ var pstack = player.inventory.getItemStack
+ if (te.slotsUpgrades.contains(slot) && te.isUpgrade(pstack)) {
+ val idx = inventorySlots.get(slot).asInstanceOf[Slot].getSlotIndex
+ if (te.slotsUpgrades.contains(idx) && modifiers == 0 && button <= 1) {
+ if (te.getStackInSlot(idx) == null || ItemUtils.isSameItem(pstack, te.getStackInSlot(idx))) {
+ var canAdd = te.getMaxAdditionalUpgrades(pstack)
+ if (canAdd > 0) {
+ if (button == 1) canAdd = 1
+ var nstack: ItemStack = null
+ if (canAdd >= pstack.stackSize) {
+ nstack = pstack
+ pstack = null
+ } else {
+ nstack = pstack.splitStack(canAdd)
+ }
+ player.inventory.setItemStack(nstack)
+ val res = super.slotClick(slot, button, modifiers, player)
+ player.inventory.setItemStack(pstack)
+ return res
+ }
+ }
+ }
+ }
+ return super.slotClick(slot, button, modifiers, player)
+ }
+
+ def canInteractWith(entityplayer: EntityPlayer): Boolean = te.isUseableByPlayer(entityplayer)
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/apiary/ErrorCodes.scala b/src/net/bdew/gendustry/machines/apiary/ErrorCodes.scala
new file mode 100644
index 00000000..02e206ec
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/apiary/ErrorCodes.scala
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.apiary
+
+import net.minecraft.util.Icon
+
+object ErrorCodes {
+
+ import scala.language.existentials
+
+ private val cEnumErrorCode = Class.forName("forestry.core.EnumErrorCode")
+ private val mGetIcon = cEnumErrorCode.getMethod("getIcon")
+ private val mGetDescription = cEnumErrorCode.getMethod("getDescription")
+ private val mGetHelp = cEnumErrorCode.getMethod("getHelp")
+ private val cLocalization = Class.forName("forestry.core.utils.Localization")
+ private lazy val iLocalization = cLocalization.getField("instance").get(null)
+ private val mGet = cLocalization.getMethod("get", classOf[String])
+
+ val values = cEnumErrorCode.getEnumConstants
+
+ def isValid(i: Int) = values.isDefinedAt(i)
+
+ def getIcon(i: Int) = mGetIcon.invoke(values(i)).asInstanceOf[Icon]
+ def getDescription(i: Int) = mGet.invoke(iLocalization, mGetDescription.invoke(values(i)).asInstanceOf[String]).asInstanceOf[String]
+ def getHelp(i: Int) = mGet.invoke(iLocalization, mGetHelp.invoke(values(i)).asInstanceOf[String]).asInstanceOf[String]
+}
diff --git a/src/net/bdew/gendustry/machines/apiary/GuiApiary.scala b/src/net/bdew/gendustry/machines/apiary/GuiApiary.scala
new file mode 100644
index 00000000..ff27f0db
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/apiary/GuiApiary.scala
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.apiary
+
+import net.bdew.gendustry.Gendustry
+import net.minecraft.entity.player.EntityPlayer
+import net.minecraft.util.ResourceLocation
+import net.bdew.lib.gui.{Rect, BaseScreen}
+import net.bdew.lib.gui.widgets.WidgetLabel
+import net.bdew.gendustry.gui.{WidgetMJGauge, Textures}
+import net.bdew.lib.Misc
+
+class GuiApiary(val te: TileApiary, player: EntityPlayer) extends BaseScreen(new ContainerApiary(te, player), 176, 166) {
+ val texture = new ResourceLocation(Gendustry.modId + ":textures/gui/apiary.png")
+ override def initGui() {
+ super.initGui()
+ addWidget(new WidgetError(155, 5, te))
+ addWidget(new WidgetMJGauge(new Rect(8, 19, 16, 58), Textures.powerFill, te.power))
+ addWidget(new WidgetApiaryProgress(new Rect(69, 22, 36, 15), te.guiBreeding, te.guiProgress))
+ addWidget(new WidgetLabel(Misc.toLocal("tile.gendustry.apiary.name"), 8, 6, 4210752))
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/apiary/MachineApiary.scala b/src/net/bdew/gendustry/machines/apiary/MachineApiary.scala
new file mode 100644
index 00000000..385fd7f7
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/apiary/MachineApiary.scala
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.apiary
+
+import net.bdew.gendustry.machines.PoweredMachine
+import net.minecraft.tileentity.TileEntity
+import net.minecraft.entity.player.EntityPlayer
+import net.minecraft.inventory.Container
+import net.minecraft.client.gui.inventory.GuiContainer
+import net.minecraftforge.common.Configuration
+import net.bdew.gendustry.gui.GuiProvider
+import net.bdew.gendustry.machines.apiary.upgrades.ItemApiaryUpgrade
+import net.bdew.gendustry.config.Ids
+import cpw.mods.fml.common.registry.GameRegistry
+import cpw.mods.fml.relauncher.{Side, SideOnly}
+
+class MachineApiary(cfg: Configuration) extends PoweredMachine(cfg, "IndustrialApiary") with GuiProvider {
+ var block: BlockApiary = null
+ lazy val guiId = 3
+
+ lazy val baseMjPerTick = tuning.getInt("BaseMjPerTick")
+
+ if (cfg.get("Machines Enabled", name, true).getBoolean(true)) {
+ block = new BlockApiary(getBlockId)
+ registerBlock(block)
+ }
+
+ @SideOnly(Side.CLIENT)
+ def getGui(te: TileEntity, player: EntityPlayer): GuiContainer = new GuiApiary(te.asInstanceOf[TileApiary], player)
+ def getContainer(te: TileEntity, player: EntityPlayer): Container = new ContainerApiary(te.asInstanceOf[TileApiary], player)
+}
diff --git a/src/net/bdew/gendustry/machines/apiary/TileApiary.scala b/src/net/bdew/gendustry/machines/apiary/TileApiary.scala
new file mode 100644
index 00000000..3199a5f3
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/apiary/TileApiary.scala
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.apiary
+
+import net.bdew.lib.data._
+import net.bdew.lib.tile.inventory.{BreakableInventoryTile, SidedInventory, PersistentInventoryTile}
+import net.bdew.gendustry.data.ExposePower
+import forestry.api.apiculture._
+import net.minecraftforge.common.ForgeDirection
+import forestry.api.genetics.{AlleleManager, IIndividual}
+import net.minecraft.item.ItemStack
+import forestry.api.core.{EnumHumidity, EnumTemperature}
+import net.bdew.lib.Misc
+import forestry.api.arboriculture.EnumGermlingType
+import net.bdew.lib.tile.TileExtended
+import buildcraft.api.power.PowerHandler.Type
+import net.bdew.gendustry.config.Machines
+import net.bdew.lib.items.ItemUtils
+import net.bdew.gendustry.api.{ApiaryModifiers, IApiaryUpgrade}
+import scala.collection.mutable
+import net.minecraft.world.biome.BiomeGenBase
+import net.bdew.lib.data.base.{UpdateKind, TileDataSlots}
+import net.bdew.lib.data.DataSlotFloat
+import net.bdew.lib.data.DataSlotInt
+import net.bdew.lib.data.DataSlotString
+import net.bdew.lib.data.DataSlotBoolean
+import net.bdew.gendustry.data.DataSlotPower
+
+class TileApiary extends TileExtended
+with TileDataSlots
+with PersistentInventoryTile
+with SidedInventory
+with BreakableInventoryTile
+with ExposePower
+with IBeeHousing {
+ val slotsBees = 0 to 1
+ val slotsUpgrades = 2 to 5
+ val slotsOutput = 6 to 14
+
+ var mods = new ApiaryModifiers
+ var movePrincess = false
+
+ val beeRoot = AlleleManager.alleleRegistry.getSpeciesRoot("rootBees").asInstanceOf[IBeeRoot]
+ val logic = beeRoot.createBeekeepingLogic(this)
+ lazy val cfg = Machines.apiary
+
+ val power = DataSlotPower("power", this, Type.MACHINE).configure(cfg)
+ val errorState = DataSlotInt("error", this).setUpdate(UpdateKind.GUI, UpdateKind.SAVE, UpdateKind.WORLD)
+ val owner = DataSlotString("owner", this, "").setUpdate(UpdateKind.SAVE)
+ val guiProgress = DataSlotFloat("progress", this)
+ val guiBreeding = DataSlotFloat("breeding", this)
+
+ // for client rendering and fx
+ val hasLight = DataSlotBoolean("haslight", this).setUpdate(UpdateKind.WORLD)
+ val queen = DataSlotItemStack("queen", this).setUpdate(UpdateKind.WORLD)
+
+ persistLoad.listen(x => {
+ updateModifiers()
+ queen := getStackInSlot(0)
+ })
+
+ def updateModifiers() {
+ mods = new ApiaryModifiers
+ for (upgrade <- Misc.iterSome(inv, slotsUpgrades).filter(isUpgrade))
+ getUpgrade(upgrade).applyModifiers(mods, upgrade)
+ hasLight := mods.isSelfLighted
+ }
+
+ override def setInventorySlotContents(slot: Int, stack: ItemStack) = {
+ if (slot == 0) queen := stack
+ super.setInventorySlotContents(slot, stack)
+ }
+
+ override def onInventoryChanged() {
+ updateModifiers()
+ super.onInventoryChanged()
+ }
+
+ def doMovePrincess() {
+ for ((slot, stack) <- Misc.iterSomeEnum(inv, slotsOutput) if stack != null && beeRoot.isMember(stack, EnumBeeType.PRINCESS.ordinal())) {
+ setInventorySlotContents(0, stack)
+ setInventorySlotContents(slot, null)
+ return
+ }
+ }
+
+ clientTick.listen(() =>
+ if (beeRoot.isMated(queen) && (errorState :== 1)) {
+ beeRoot.getMember(queen).doFX(logic.getEffectData, this)
+ }
+ )
+
+ serverTick.listen(() => {
+ movePrincess = false
+
+ if (power.getEnergyStored >= cfg.baseMjPerTick * mods.energy) {
+ logic.update()
+ if ((logic.getQueen != null || logic.getBreedingTime > 0) && (errorState :== 1))
+ power.useEnergy(cfg.baseMjPerTick, cfg.baseMjPerTick * mods.energy, true)
+ } else {
+ setErrorState(-1)
+ }
+
+ if (movePrincess && getStackInSlot(0) == null)
+ doMovePrincess()
+
+ if (logic.getQueen != null)
+ guiProgress := 1 - (logic.getQueen.getHealth.toFloat / logic.getQueen.getMaxHealth)
+ else
+ guiProgress := -1
+
+ guiBreeding := logic.getBreedingTime.toFloat / logic.getTotalBreedingTime
+ })
+
+ def getUpgrade(stack: ItemStack) = stack.getItem.asInstanceOf[IApiaryUpgrade]
+ def isUpgrade(stack: ItemStack) = stack != null && stack.getItem != null && stack.getItem.isInstanceOf[IApiaryUpgrade]
+
+ def getMaxAdditionalUpgrades(stack: ItemStack): Int = {
+ if (!isUpgrade(stack)) return 0
+ var existing = 0
+ val thisId = getUpgrade(stack).getStackingId(stack)
+ for (upgrade <- Misc.iterSome(inv, slotsUpgrades).filter(isUpgrade)) {
+ if (getUpgrade(upgrade).getStackingId(upgrade) == thisId)
+ existing += upgrade.stackSize
+ }
+ return getUpgrade(stack).getMaxNumber(stack) - existing
+ }
+
+ override def isItemValidForSlot(slot: Int, stack: ItemStack): Boolean = {
+ if (stack == null || stack.getItem == null) return false
+ if (slotsUpgrades.contains(slot)) {
+ return getMaxAdditionalUpgrades(stack) >= stack.stackSize
+ } else if (slot == 0) {
+ return beeRoot.isMember(stack, EnumBeeType.QUEEN.ordinal()) || beeRoot.isMember(stack, EnumBeeType.PRINCESS.ordinal())
+ } else if (slot == 1) {
+ return beeRoot.isMember(stack, EnumBeeType.DRONE.ordinal())
+ } else
+ return false
+ }
+
+ def addStats(l: mutable.MutableList[String]) {
+ l += Misc.toLocalF("gendustry.label.energy", "%.1f".format(cfg.baseMjPerTick * mods.energy))
+ l += Misc.toLocalF("gendustry.label.temperature", Misc.toLocal(getTemperature.getName))
+ l += Misc.toLocalF("gendustry.label.humidity", Misc.toLocal(getHumidity.getName))
+
+ if (getQueen != null) {
+ val bee = beeRoot.getMember(getQueen)
+ if (bee != null && bee.isAnalyzed) {
+ val genome = bee.getGenome
+ l += Misc.toLocalF("gendustry.label.production", "%.0f%%".format(100F * mods.production * genome.getSpeed))
+ l += Misc.toLocalF("gendustry.label.flowering", "%.0f%%".format(mods.flowering * genome.getFlowering))
+ l += Misc.toLocalF("gendustry.label.lifespan", "%.0f%%".format(mods.lifespan * genome.getLifespan))
+ val t = genome.getTerritory.toSeq.map(mods.territory * _)
+ l += Misc.toLocalF("gendustry.label.territory", "%.0f x %.0f x %.0f".format(t: _*))
+ }
+ }
+ }
+
+ // Misc
+ lazy val getBiome = worldObj.getBiomeGenForCoordsBody(xCoord, zCoord)
+ def getPowerDataslot(from: ForgeDirection) = power
+ def getSizeInventory = 15
+
+ override def canInsertItem(slot: Int, stack: ItemStack, side: Int) = slotsBees.contains(slot) && isItemValidForSlot(slot, stack)
+ override def canExtractItem(slot: Int, stack: ItemStack, side: Int) = slotsOutput.contains(slot)
+
+ // IBeeListener
+ def onPostQueenDeath(queen: IBee) {
+ if (mods.isAutomated) movePrincess = true
+ }
+
+ def onQueenDeath(queen: IBee) {}
+ def wearOutEquipment(amount: Int) {}
+ def onQueenChange(stack: ItemStack) {}
+ def onEggLaid(queen: IBee) = false
+ def onPollenRetrieved(queen: IBee, pollen: IIndividual, isHandled: Boolean): Boolean = {
+ if (isHandled) return true
+ if (!mods.isCollectingPollen) return false
+ val sproot = pollen.getGenome.getSpeciesRoot
+ val stack = sproot.getMemberStack(pollen, EnumGermlingType.POLLEN.ordinal())
+ addProduct(stack, true)
+ return true
+ }
+
+ // IBeeModifier
+ def getTerritoryModifier(genome: IBeeGenome, currentModifier: Float) = Misc.min(mods.territory, 5)
+ def getMutationModifier(genome: IBeeGenome, mate: IBeeGenome, currentModifier: Float) = mods.mutation
+ def getLifespanModifier(genome: IBeeGenome, mate: IBeeGenome, currentModifier: Float) = mods.lifespan
+ def getProductionModifier(genome: IBeeGenome, currentModifier: Float) = mods.production
+ def getFloweringModifier(genome: IBeeGenome, currentModifier: Float) = mods.flowering
+ def getGeneticDecay(genome: IBeeGenome, currentModifier: Float) = mods.geneticDecay
+ def isSealed = mods.isSealed
+ def isSelfLighted = mods.isSelfLighted
+ def isSunlightSimulated = mods.isSunlightSimulated
+ def isHellish = mods.isHellish
+
+ // IBeeHousing
+ def setQueen(itemstack: ItemStack) = setInventorySlotContents(0, itemstack)
+ def setDrone(itemstack: ItemStack) = setInventorySlotContents(1, itemstack)
+ def getQueen = getStackInSlot(0)
+ def getDrone = getStackInSlot(1)
+ def canBreed = true
+
+ // IHousing
+ def setErrorState(state: Int) = errorState := state
+ def getOwnerName = owner
+ def getXCoord = xCoord
+ def getYCoord = yCoord
+ def getZCoord = zCoord
+ def getBiomeId = if (mods.isHellish) BiomeGenBase.hell.biomeID else getBiome.biomeID
+ def getTemperature: EnumTemperature = {
+ if (mods.isHellish || EnumTemperature.isBiomeHellish(getBiome.biomeID))
+ return EnumTemperature.HELLISH
+ return EnumTemperature.getFromValue(getBiome.temperature + mods.temperature)
+ }
+ def getHumidity = EnumHumidity.getFromValue(getBiome.rainfall + mods.humidity)
+ def getErrorOrdinal = errorState
+ def addProduct(product: ItemStack, all: Boolean): Boolean = {
+ var p = product
+ if (mods.isAutomated && beeRoot.isMember(product))
+ p = ItemUtils.addStackToSlots(p, this, slotsBees, false)
+ p = ItemUtils.addStackToSlots(p, this, slotsOutput, false)
+ return p == null
+ }
+}
diff --git a/src/net/bdew/gendustry/machines/apiary/WidgetApiaryProgress.scala b/src/net/bdew/gendustry/machines/apiary/WidgetApiaryProgress.scala
new file mode 100644
index 00000000..8499c9d0
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/apiary/WidgetApiaryProgress.scala
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.apiary
+
+import net.bdew.lib.gui.{Point, Rect}
+import net.bdew.lib.gui.widgets.Widget
+import net.bdew.lib.data.DataSlotFloat
+import net.bdew.gendustry.gui.Textures
+import scala.collection.mutable
+import net.bdew.lib.Misc
+import net.bdew.gendustry.Gendustry
+import net.minecraft.client.Minecraft
+
+class WidgetApiaryProgress(val rect: Rect, breeding: DataSlotFloat, progress: DataSlotFloat) extends Widget {
+ val texture = Textures.whiteProgress(rect.w)
+
+ override def handleTooltip(p: Point, tip: mutable.MutableList[String]) {
+ if (breeding.cval > 0) {
+ tip += "%s - %.0f%%".format(Misc.toLocal(Gendustry.modId + ".label.breeding"), breeding.cval * 100)
+ } else if (progress.cval > 0) {
+ tip += "%s - %.0f%%".format(Misc.toLocal(Gendustry.modId + ".label.working"), progress.cval * 100)
+ }
+ }
+
+ override def draw() {
+ Minecraft.getMinecraft.renderEngine.bindTexture(texture.resource)
+ if (breeding.cval > 0) {
+ parent.drawTexturedModalRect(rect.x, rect.y, texture.x, texture.y, (breeding.cval * rect.w).round, rect.h)
+ } else if (progress.cval > 0) {
+ parent.drawTexturedModalRect(rect.x, rect.y, texture.x, texture.y, (progress.cval * rect.w).round, rect.h)
+ }
+ }
+}
diff --git a/src/net/bdew/gendustry/machines/apiary/WidgetError.scala b/src/net/bdew/gendustry/machines/apiary/WidgetError.scala
new file mode 100644
index 00000000..08472c21
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/apiary/WidgetError.scala
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.apiary
+
+import net.bdew.lib.gui.widgets.Widget
+import net.bdew.lib.gui.{Point, Rect}
+import net.minecraft.client.renderer.texture.TextureMap
+import scala.collection.mutable
+import net.bdew.lib.Misc
+import net.bdew.gendustry.Gendustry
+import net.bdew.gendustry.gui.Textures
+
+class WidgetError(x: Int, y: Int, apiary: TileApiary) extends Widget {
+ val rect: Rect = new Rect(x, y, 16, 16)
+ override def draw() {
+ val err = apiary.errorState.cval
+ if (err == -1) {
+ bindTexture(Textures.texture)
+ parent.drawTexturedModalRect(rect.x, rect.y, Textures.texturePowerError.x, Textures.texturePowerError.y, rect.w, rect.h)
+ } else {
+ bindTexture(TextureMap.locationItemsTexture)
+ if (ErrorCodes.isValid(err)) {
+ parent.drawTexturedModelRectFromIcon(rect.x, rect.y, ErrorCodes.getIcon(err), 16, 16)
+ } else {
+ parent.drawTexturedModelRectFromIcon(rect.x, rect.y, ErrorCodes.getIcon(0), 16, 16)
+ }
+ }
+ }
+ override def handleTooltip(p: Point, tip: mutable.MutableList[String]) {
+ val err = apiary.errorState.cval
+ if (err == -1) {
+ tip += Misc.toLocal(Gendustry.modId + ".error.power")
+ } else if (ErrorCodes.isValid(err)) {
+ tip += ErrorCodes.getDescription(err)
+ } else {
+ tip += ErrorCodes.getDescription(0)
+ }
+ apiary.addStats(tip)
+ }
+}
diff --git a/src/net/bdew/gendustry/machines/apiary/upgrades/ItemApiaryUpgrade.scala b/src/net/bdew/gendustry/machines/apiary/upgrades/ItemApiaryUpgrade.scala
new file mode 100644
index 00000000..f067278e
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/apiary/upgrades/ItemApiaryUpgrade.scala
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.apiary.upgrades
+
+import net.minecraft.item.{ItemStack, Item}
+import net.bdew.gendustry.api.{ApiaryModifiers, IApiaryUpgrade}
+import net.minecraft.client.renderer.texture.IconRegister
+import net.bdew.gendustry.Gendustry
+import net.minecraft.util.Icon
+import cpw.mods.fml.relauncher.{Side, SideOnly}
+import net.minecraft.creativetab.CreativeTabs
+import java.util
+import net.minecraft.entity.player.EntityPlayer
+import net.bdew.lib.Misc
+import cpw.mods.fml.common.registry.GameRegistry
+
+class ItemApiaryUpgrade(id: Int) extends Item(id) with IApiaryUpgrade {
+ val icons = collection.mutable.Map.empty[Int, Icon]
+
+ setHasSubtypes(true)
+ setMaxDamage(-1)
+ setUnlocalizedName(Gendustry.modId + ".apiary.upgrade")
+
+ for ((id, upgrade) <- Upgrades.map)
+ GameRegistry.registerCustomItemStack("upgrade." + upgrade.name, new ItemStack(this, 1, id))
+
+ def formatModifier(f: Float, base: Float) = (if (f > base) "+" else "") + "%.0f".format((f - base) * 100) + "%"
+
+ override def addInformation(stack: ItemStack, player: EntityPlayer, list: util.List[_], par4: Boolean) {
+ if (!Upgrades.map.contains(stack.getItemDamage)) return
+ val upgrade = Upgrades.map(stack.getItemDamage)
+ val l = list.asInstanceOf[util.List[String]]
+ val mods = new ApiaryModifiers
+
+ upgrade.mod(mods, 1)
+
+ l.add(Misc.toLocal(Gendustry.modId + ".label.maxinstall") + " " + upgrade.maxNum.toString)
+
+ if (mods.isAutomated)
+ l.add(Misc.toLocal(Gendustry.modId + ".label.mod.automated"))
+ if (mods.isHellish)
+ l.add(Misc.toLocal(Gendustry.modId + ".label.mod.hellish"))
+ if (mods.isSealed)
+ l.add(Misc.toLocal(Gendustry.modId + ".label.mod.sealed"))
+ if (mods.isSelfLighted)
+ l.add(Misc.toLocal(Gendustry.modId + ".label.mod.selflighted"))
+ if (mods.isSunlightSimulated)
+ l.add(Misc.toLocal(Gendustry.modId + ".label.mod.sky"))
+ if (mods.isCollectingPollen)
+ l.add(Misc.toLocal(Gendustry.modId + ".label.mod.sieve"))
+
+ if (mods.lifespan != 1)
+ l.add(Misc.toLocal(Gendustry.modId + ".label.mod.lifespan") + " " + formatModifier(mods.lifespan, 1))
+ if (mods.flowering != 1)
+ l.add(Misc.toLocal(Gendustry.modId + ".label.mod.flowering") + " " + formatModifier(mods.flowering, 1))
+ if (mods.geneticDecay != 1)
+ l.add(Misc.toLocal(Gendustry.modId + ".label.mod.geneticDecay") + " " + formatModifier(mods.geneticDecay, 1))
+ if (mods.mutation != 1)
+ l.add(Misc.toLocal(Gendustry.modId + ".label.mod.mutation") + " " + formatModifier(mods.mutation, 1))
+ if (mods.production != 1)
+ l.add(Misc.toLocal(Gendustry.modId + ".label.mod.production") + " " + formatModifier(mods.production, 1))
+ if (mods.territory != 1)
+ l.add(Misc.toLocal(Gendustry.modId + ".label.mod.territory") + " " + formatModifier(mods.territory, 1))
+
+ if (mods.humidity != 0)
+ l.add(Misc.toLocal(Gendustry.modId + ".label.mod.humidity") + " " + formatModifier(mods.humidity, 0))
+ if (mods.temperature != 0)
+ l.add(Misc.toLocal(Gendustry.modId + ".label.mod.temperature") + " " + formatModifier(mods.temperature, 0))
+
+ if (mods.energy != 1)
+ l.add(Misc.toLocal(Gendustry.modId + ".label.mod.energy") + " " + formatModifier(mods.energy, 1))
+
+ }
+
+ def getStackingId(stack: ItemStack) = itemID * Int.MaxValue + stack.getItemDamage
+ def getMaxNumber(stack: ItemStack): Int = {
+ if (Upgrades.map.contains(stack.getItemDamage))
+ return Upgrades.map(stack.getItemDamage).maxNum
+ return 0
+ }
+
+ def applyModifiers(mods: ApiaryModifiers, stack: ItemStack) {
+ if (Upgrades.map.contains(stack.getItemDamage)) {
+ val upg = Upgrades.map(stack.getItemDamage)
+ upg.mod(mods, Misc.min(upg.maxNum, stack.stackSize))
+ }
+ }
+
+ override def getIconFromDamage(meta: Int): Icon = {
+ if (icons.contains(meta))
+ return icons(meta)
+ return null
+ }
+
+ override def getUnlocalizedName(stack: ItemStack): String = {
+ if (Upgrades.map.contains(stack.getItemDamage))
+ return "%s.upgrades.%s".format(Gendustry.modId, Upgrades.map(stack.getItemDamage).name)
+ return "invalid"
+ }
+
+ override def getSubItems(par1: Int, par2CreativeTabs: CreativeTabs, list: util.List[_]) {
+ val l = list.asInstanceOf[util.List[ItemStack]]
+ for ((id, name) <- Upgrades.map)
+ l.add(new ItemStack(this, 1, id))
+ }
+
+ @SideOnly(Side.CLIENT)
+ override def registerIcons(reg: IconRegister) {
+ for ((id, upgrade) <- Upgrades.map) {
+ icons += id -> reg.registerIcon("%s:upgrades/%s".format(Gendustry.modId, upgrade.name))
+ }
+ }
+}
diff --git a/src/net/bdew/gendustry/machines/apiary/upgrades/Upgrades.scala b/src/net/bdew/gendustry/machines/apiary/upgrades/Upgrades.scala
new file mode 100644
index 00000000..fe2a7a9b
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/apiary/upgrades/Upgrades.scala
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.apiary.upgrades
+
+import net.bdew.gendustry.api.ApiaryModifiers
+import net.bdew.gendustry.config.TuningLoader._
+import net.bdew.gendustry.config.{Items, Tuning}
+import net.bdew.lib.recipes.gencfg.{EntryStr, ConfigSection}
+import cpw.mods.fml.common.registry.GameRegistry
+import net.minecraft.item.ItemStack
+
+object Upgrades {
+ val map = collection.mutable.Map.empty[Int, Upgrade]
+ type ModFunc = (ApiaryModifiers, Int) => Unit
+
+ case class Upgrade(id: Int, name: String, maxNum: Int, mods: Seq[(ApiaryModifiers, Int) => Unit]) {
+ def mod(v: ApiaryModifiers, num: Int) {
+ val n = if (num > maxNum) maxNum else num
+ mods.foreach(_(v,n))
+ }
+ }
+
+ def makeMod(upg:String, n: String, e: EntryModifier): ModFunc = {
+ val calc: (Float, Int) => Float = e match {
+ case EntryModifierAdd(v) => (x, n) => x + v * n
+ case EntryModifierSub(v) => (x, n) => x - v * n
+ case EntryModifierMul(v) => (x, n) => x * math.pow(v, n).toFloat
+ case EntryModifierDiv(v) => (x, n) => x / math.pow(v, n).toFloat
+ }
+ n match {
+ case "lifespan" => (a, n) => a.lifespan = calc(a.lifespan, n)
+ case "territory" => (a, n) => a.territory = calc(a.territory, n)
+ case "mutation" => (a, n) => a.mutation = calc(a.mutation, n)
+ case "production" => (a, n) => a.production = calc(a.production, n)
+ case "flowering" => (a, n) => a.flowering = calc(a.flowering, n)
+ case "geneticDecay" => (a, n) => a.geneticDecay = calc(a.geneticDecay, n)
+ case "energy" => (a, n) => a.energy = calc(a.energy, n)
+ case "temperature" => (a, n) => a.temperature = calc(a.temperature, n)
+ case "humidity" => (a, n) => a.humidity = calc(a.humidity, n)
+ case x => sys.error("Unknown numeric upgrade modifier '%s' in upgrade '%s'".format(x, upg))
+ }
+ }
+
+ def makeBoolMod(upg:String, n: String, b: Boolean): ModFunc = n match {
+ case "sealed" => (a, n) => a.isSealed = b
+ case "selfLighted" => (a, n) => a.isSelfLighted = b
+ case "sunlightSimulated" => (a, n) => a.isSunlightSimulated = b
+ case "hellish" => (a, n) => a.isHellish = b
+ case "automated" => (a, n) => a.isAutomated = b
+ case "collectingPollen" => (a, n) => a.isCollectingPollen = b
+ case x => sys.error("Unknown boolean upgrade modifier '%s' in upgrade '%s'".format(x, upg))
+ }
+
+ def init() {
+ for ((name, sect) <- Tuning.getSection("Upgrades").filterType(classOf[ConfigSection])) {
+ val id = sect.getInt("id")
+ val max = sect.getInt("max")
+ val mods = sect.flatMap({
+ case (pname, EntryStr(_)) => Some(makeBoolMod(name, pname, sect.getBoolean(pname)))
+ case (pname, x: EntryModifier) => Some(makeMod(name, pname, x))
+ case ("id", _) | ("max", _) => None
+ case (pname, v) => sys.error("Unknown upgrade modifier '%s' - %s in upgrade '%s'".format(pname, v, name))
+ })
+ map += id -> Upgrade(id, name, max, mods.toSeq)
+ GameRegistry.registerCustomItemStack("upgrade."+name, new ItemStack(Items.upgradeItem, 1, id))
+ }
+ }
+}
diff --git a/src/net/bdew/gendustry/machines/imprinter/BlockImprinter.scala b/src/net/bdew/gendustry/machines/imprinter/BlockImprinter.scala
new file mode 100644
index 00000000..8fbc263f
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/imprinter/BlockImprinter.scala
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.imprinter
+
+import cpw.mods.fml.relauncher.Side
+import cpw.mods.fml.relauncher.SideOnly
+import net.bdew.gendustry.Gendustry
+import net.minecraft.block.Block
+import net.minecraft.block.material.Material
+import net.minecraft.client.renderer.texture.IconRegister
+import net.minecraft.util.Icon
+import net.bdew.lib.block.HasTE
+import net.bdew.lib.tile.inventory.BreakableInventoryBlock
+import net.bdew.gendustry.config.Machines
+import net.bdew.gendustry.gui.BlockGuiWrenchable
+
+class BlockImprinter(id: Int) extends Block(id, Material.rock) with HasTE[TileImprinter] with BreakableInventoryBlock with BlockGuiWrenchable {
+ val TEClass = classOf[TileImprinter]
+ private var icons: Array[Icon] = null
+ lazy val guiId: Int = Machines.imprinter.guiId
+
+ setUnlocalizedName(Gendustry.modId + ".imprinter")
+ setHardness(5)
+
+ override def getIcon(side: Int, meta: Int): Icon = {
+ side match {
+ case 0 =>
+ return icons(0)
+ case 1 =>
+ return icons(1)
+ case _ =>
+ return icons(2)
+ }
+ }
+
+ @SideOnly(Side.CLIENT)
+ override def registerIcons(reg: IconRegister) {
+ icons = new Array[Icon](3)
+ icons(0) = reg.registerIcon(Gendustry.modId + ":imprinter/bottom")
+ icons(1) = reg.registerIcon(Gendustry.modId + ":imprinter/top")
+ icons(2) = reg.registerIcon(Gendustry.modId + ":imprinter/side")
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/imprinter/ContainerImprinter.scala b/src/net/bdew/gendustry/machines/imprinter/ContainerImprinter.scala
new file mode 100644
index 00000000..c14f6878
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/imprinter/ContainerImprinter.scala
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.imprinter
+
+import net.bdew.lib.gui.{BaseContainer, SlotValidating}
+import net.minecraft.entity.player.EntityPlayer
+import net.bdew.lib.data.base.ContainerDataSlots
+
+class ContainerImprinter(val te: TileImprinter, player: EntityPlayer) extends BaseContainer(te) with ContainerDataSlots {
+ lazy val dataSource = te
+
+ addSlotToContainer(new SlotValidating(te, 0, 74, 28))
+ addSlotToContainer(new SlotValidating(te, 1, 98, 28))
+ addSlotToContainer(new SlotValidating(te, 2, 41, 49))
+ addSlotToContainer(new SlotValidating(te, 3, 137, 49))
+ bindPlayerInventory(player.inventory, 8, 84, 142)
+
+ def canInteractWith(entityplayer: EntityPlayer): Boolean = {
+ return te.isUseableByPlayer(entityplayer)
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/imprinter/GuiImprinter.scala b/src/net/bdew/gendustry/machines/imprinter/GuiImprinter.scala
new file mode 100644
index 00000000..e8924a68
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/imprinter/GuiImprinter.scala
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.imprinter
+
+import net.bdew.gendustry.Gendustry
+import net.bdew.gendustry.gui.{WidgetMJGauge, Textures}
+import net.minecraft.entity.player.EntityPlayer
+import net.minecraft.util.ResourceLocation
+import net.bdew.lib.gui.{Rect, BaseScreen}
+import net.bdew.lib.gui.widgets.{WidgetLabel, WidgetProgressBar}
+import net.bdew.lib.Misc
+
+class GuiImprinter(val te: TileImprinter, player: EntityPlayer) extends BaseScreen(new ContainerImprinter(te, player), 176, 166) {
+ val texture: ResourceLocation = new ResourceLocation(Gendustry.modId + ":textures/gui/imprinter.png")
+ override def initGui() {
+ super.initGui()
+ addWidget(new WidgetProgressBar(new Rect(63, 49, 66, 15), Textures.whiteProgress(66), te.progress))
+ addWidget(new WidgetMJGauge(new Rect(8, 19, 16, 58), Textures.powerFill, te.power))
+ addWidget(new WidgetLabel(Misc.toLocal("tile.gendustry.imprinter.name"), 8, 6, 4210752))
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/imprinter/MachineImprinter.scala b/src/net/bdew/gendustry/machines/imprinter/MachineImprinter.scala
new file mode 100644
index 00000000..d8710e2d
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/imprinter/MachineImprinter.scala
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.imprinter
+
+import net.bdew.gendustry.machines.ProcessorMachine
+import net.minecraft.tileentity.TileEntity
+import net.minecraft.entity.player.EntityPlayer
+import net.minecraft.inventory.Container
+import net.minecraft.client.gui.inventory.GuiContainer
+import net.minecraftforge.common.Configuration
+import net.bdew.gendustry.gui.GuiProvider
+import cpw.mods.fml.relauncher.{Side, SideOnly}
+
+class MachineImprinter(cfg: Configuration) extends ProcessorMachine(cfg, "Imprinter") with GuiProvider {
+ var block: BlockImprinter = null
+ lazy val guiId = 4
+
+ lazy val labwareConsumeChance = tuning.getInt("LabwareConsumeChance")
+ lazy val deathChanceNatural = tuning.getInt("DeathChanceNatural")
+ lazy val deathChanceArtificial = tuning.getInt("DeathChanceArtificial")
+
+ if (cfg.get("Machines Enabled", name, true).getBoolean(true)) {
+ block = new BlockImprinter(getBlockId)
+ registerBlock(block)
+ }
+
+ @SideOnly(Side.CLIENT)
+ def getGui(te: TileEntity, player: EntityPlayer): GuiContainer = new GuiImprinter(te.asInstanceOf[TileImprinter], player)
+ def getContainer(te: TileEntity, player: EntityPlayer): Container = new ContainerImprinter(te.asInstanceOf[TileImprinter], player)
+}
diff --git a/src/net/bdew/gendustry/machines/imprinter/TileImprinter.scala b/src/net/bdew/gendustry/machines/imprinter/TileImprinter.scala
new file mode 100644
index 00000000..376e8096
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/imprinter/TileImprinter.scala
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.imprinter
+
+import net.bdew.gendustry.config.{Items, Machines}
+import net.minecraft.item.ItemStack
+import forestry.api.genetics.AlleleManager
+import net.bdew.gendustry.machines.TileItemProcessor
+import net.minecraft.nbt.NBTTagCompound
+import forestry.api.apiculture.{EnumBeeType, IBeeRoot, IBee}
+import scala.util.Random
+
+class TileImprinter extends TileItemProcessor {
+ lazy val cfg = Machines.imprinter
+ val outputSlots = Seq(3)
+ def getSizeInventory = 4
+
+ def tryStart(): Boolean = {
+ if (getStackInSlot(0) != null && getStackInSlot(1) != null && getStackInSlot(2) != null) {
+
+ val individual = AlleleManager.alleleRegistry.getIndividual(getStackInSlot(2))
+ val genome = individual.getGenome.getChromosomes
+ val root = Items.geneTemplate.getSpecies(getStackInSlot(0))
+
+ if (root != individual.getGenome.getSpeciesRoot) return false
+
+ if (individual.isInstanceOf[IBee]) {
+ if (root.asInstanceOf[IBeeRoot].getType(getStackInSlot(2)) != EnumBeeType.DRONE) {
+ val random = new Random()
+ if (individual.asInstanceOf[IBee].isNatural) {
+ if (random.nextInt(100) < Machines.imprinter.deathChanceNatural) {
+ doStart(new ItemStack(Items.waste))
+ return true
+ }
+ } else {
+ if (random.nextInt(100) < Machines.imprinter.deathChanceArtificial) {
+ doStart(new ItemStack(Items.waste))
+ return true
+ }
+ }
+ }
+ }
+
+ val primary = genome.map(x => if (x == null) null else x.getPrimaryAllele)
+ val secondary = genome.map(x => if (x == null) null else x.getSecondaryAllele)
+
+ for (x <- Items.geneTemplate.getSamples(getStackInSlot(0))) {
+ primary(x.chromosome) = x.allele
+ secondary(x.chromosome) = x.allele
+ }
+
+ val newStack = getStackInSlot(2).copy()
+ newStack.stackSize = 1
+
+ val newTag = new NBTTagCompound()
+ root.templateAsGenome(primary, secondary).writeToNBT(newTag)
+ newStack.getTagCompound.setCompoundTag("Genome", newTag)
+
+ doStart(newStack)
+
+ return true
+
+ } else return false
+ }
+
+ def doStart(s: ItemStack) {
+ output := s
+ decrStackSize(2, 1)
+ if (worldObj.rand.nextInt(100) < cfg.labwareConsumeChance)
+ decrStackSize(1, 1)
+ }
+
+ override def isItemValidForSlot(slot: Int, stack: ItemStack): Boolean = {
+ if (stack == null || stack.getItem == null) return false
+ slot match {
+ case 0 =>
+ return (stack.getItem == Items.geneTemplate) &&
+ (inv(2) == null || Items.geneTemplate.getSpecies(stack) == AlleleManager.alleleRegistry.getSpeciesRoot(inv(2)))
+ case 1 =>
+ return stack.getItem == Items.labware
+ case 2 =>
+ return (AlleleManager.alleleRegistry.getIndividual(stack) != null) &&
+ (inv(0) == null || Items.geneTemplate.getSpecies(inv(0)) == AlleleManager.alleleRegistry.getSpeciesRoot(stack))
+ case _ =>
+ return false
+ }
+ }
+
+ allowSided = true
+
+ // can extract the template if input is empty and there's no operation in progress
+ override def canExtractItem(slot: Int, item: ItemStack, side: Int) = slot == 3 || (slot == 0 && inv(2) == null && (output :== null))
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/mproducer/BlockMutagenProducer.scala b/src/net/bdew/gendustry/machines/mproducer/BlockMutagenProducer.scala
new file mode 100644
index 00000000..531ae6eb
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/mproducer/BlockMutagenProducer.scala
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.mproducer
+
+import net.bdew.gendustry.Gendustry
+import net.minecraft.block.Block
+import net.minecraft.block.material.Material
+import net.minecraft.client.renderer.texture.IconRegister
+import net.minecraft.util.Icon
+import cpw.mods.fml.relauncher.Side
+import cpw.mods.fml.relauncher.SideOnly
+import net.bdew.lib.block.HasTE
+import net.bdew.lib.tile.inventory.BreakableInventoryBlock
+import net.bdew.gendustry.config.Machines
+import net.bdew.gendustry.gui.BlockGuiWrenchable
+
+class BlockMutagenProducer(id: Int) extends Block(id, Material.rock) with HasTE[TileMutagenProducer] with BreakableInventoryBlock with BlockGuiWrenchable {
+ private var icons: Array[Icon] = null
+ val TEClass = classOf[TileMutagenProducer]
+ lazy val guiId = Machines.mutagenProducer.guiId
+
+ setUnlocalizedName(Gendustry.modId + ".mutagen.producer")
+ setHardness(5)
+
+ override def getIcon(side: Int, meta: Int): Icon = {
+ side match {
+ case 0 =>
+ return icons(0)
+ case 1 =>
+ return icons(1)
+ case _ =>
+ return icons(2)
+ }
+ }
+
+ @SideOnly(Side.CLIENT)
+ override def registerIcons(reg: IconRegister) {
+ icons = new Array[Icon](3)
+ icons(0) = reg.registerIcon(Gendustry.modId + ":mutagenproducer/bottom")
+ icons(1) = reg.registerIcon(Gendustry.modId + ":mutagenproducer/top")
+ icons(2) = reg.registerIcon(Gendustry.modId + ":mutagenproducer/side")
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/mproducer/ContainerMutagenProducer.scala b/src/net/bdew/gendustry/machines/mproducer/ContainerMutagenProducer.scala
new file mode 100644
index 00000000..4d04b537
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/mproducer/ContainerMutagenProducer.scala
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.mproducer
+
+import net.minecraft.entity.player.EntityPlayer
+import net.bdew.lib.gui.{BaseContainer, SlotValidating}
+import net.bdew.lib.data.base.ContainerDataSlots
+
+class ContainerMutagenProducer(val te: TileMutagenProducer, player: EntityPlayer) extends BaseContainer(te) with ContainerDataSlots {
+ lazy val dataSource = te
+
+ addSlotToContainer(new SlotValidating(te, 0, 44, 41))
+ bindPlayerInventory(player.inventory, 8, 84, 142)
+
+ def canInteractWith(entityplayer: EntityPlayer): Boolean = te.isUseableByPlayer(entityplayer)
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/mproducer/GuiMutagenProducer.scala b/src/net/bdew/gendustry/machines/mproducer/GuiMutagenProducer.scala
new file mode 100644
index 00000000..a6121a6a
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/mproducer/GuiMutagenProducer.scala
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.mproducer
+
+import net.bdew.gendustry.Gendustry
+import net.minecraft.entity.player.EntityPlayer
+import net.minecraft.util.ResourceLocation
+import net.bdew.lib.gui.{Rect, BaseScreen}
+import net.bdew.lib.gui.widgets.{WidgetLabel, WidgetFluidGauge, WidgetProgressBar}
+import net.bdew.lib.Misc
+import net.bdew.gendustry.gui.{WidgetMJGauge, Textures}
+
+class GuiMutagenProducer(val te: TileMutagenProducer, player: EntityPlayer) extends BaseScreen(new ContainerMutagenProducer(te, player), 176, 166) {
+ val texture = new ResourceLocation(Gendustry.modId + ":textures/gui/mutagenproducer.png")
+ override def initGui() {
+ super.initGui()
+ addWidget(new WidgetProgressBar(new Rect(79, 41, 53, 15), Textures.greenProgress(53), te.progress))
+ addWidget(new WidgetMJGauge(new Rect(8, 19, 16, 58), Textures.powerFill, te.power))
+ addWidget(new WidgetFluidGauge(new Rect(152, 19, 16, 58), Textures.tankOverlay, te.tank))
+ addWidget(new WidgetLabel(Misc.toLocal("tile.gendustry.mutagen.producer.name"), 8, 6, 4210752))
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/mproducer/MachineMutagenProducer.scala b/src/net/bdew/gendustry/machines/mproducer/MachineMutagenProducer.scala
new file mode 100644
index 00000000..b2a4f2e9
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/mproducer/MachineMutagenProducer.scala
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.mproducer
+
+import net.bdew.gendustry.machines.ProcessorMachine
+import net.minecraft.tileentity.TileEntity
+import net.minecraft.entity.player.EntityPlayer
+import net.minecraft.inventory.Container
+import net.minecraft.client.gui.inventory.GuiContainer
+import net.minecraftforge.common.Configuration
+import net.bdew.gendustry.gui.GuiProvider
+import cpw.mods.fml.relauncher.{SideOnly, Side}
+
+class MachineMutagenProducer(cfg: Configuration) extends ProcessorMachine(cfg, "MutagenProducer") with GuiProvider {
+ var block: BlockMutagenProducer = null
+ lazy val guiId = 1
+
+ lazy val tankSize = tuning.getInt("TankSize")
+
+ if (cfg.get("Machines Enabled", name, true).getBoolean(true)) {
+ block = new BlockMutagenProducer(getBlockId)
+ registerBlock(block)
+ }
+
+ @SideOnly(Side.CLIENT)
+ def getGui(te: TileEntity, player: EntityPlayer): GuiContainer = new GuiMutagenProducer(te.asInstanceOf[TileMutagenProducer], player)
+ def getContainer(te: TileEntity, player: EntityPlayer): Container = new ContainerMutagenProducer(te.asInstanceOf[TileMutagenProducer], player)
+}
diff --git a/src/net/bdew/gendustry/machines/mproducer/TileMutagenProducer.scala b/src/net/bdew/gendustry/machines/mproducer/TileMutagenProducer.scala
new file mode 100644
index 00000000..92d6cf39
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/mproducer/TileMutagenProducer.scala
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.mproducer
+
+import net.bdew.gendustry.config.{Blocks, Machines}
+import net.bdew.gendustry.mutagen.MutagenRegistry
+import net.minecraft.item.ItemStack
+import net.minecraft.tileentity.TileEntity
+import net.minecraftforge.common.ForgeDirection
+import net.minecraftforge.fluids._
+import net.bdew.lib.data._
+import net.bdew.lib.tile.ExposeTank
+import net.bdew.lib.data.base.UpdateKind
+import net.bdew.gendustry.machines.TileBaseProcessor
+
+class TileMutagenProducer extends TileBaseProcessor with ExposeTank {
+ lazy val cfg = Machines.mutagenProducer
+
+ val tank = DataSlotTankRestricted("tank", this, cfg.tankSize, Blocks.mutagenFluid.getID).setUpdate(UpdateKind.GUI, UpdateKind.SAVE)
+ val output = DataSlotInt("output", this).setUpdate(UpdateKind.SAVE)
+
+ def getSizeInventory = 1
+
+ def getTankFromDirection(dir: ForgeDirection): IFluidTank = tank
+
+ def isWorking = output > 0
+ def tryStart(): Boolean = {
+ if (getStackInSlot(0) != null) {
+ output := MutagenRegistry.getValue(getStackInSlot(0))
+ decrStackSize(0, 1)
+ return true
+ } else return false
+ }
+
+ def tryFinish(): Boolean = {
+ if (tank.fill(output, false) == output.cval) {
+ tank.fill(output, true)
+ output := -1
+ return true
+ } else return false
+ }
+
+ def sendFluid() {
+ for (dir <- ForgeDirection.VALID_DIRECTIONS) {
+ val te: TileEntity = worldObj.getBlockTileEntity(xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ)
+ if (te != null && te.isInstanceOf[IFluidHandler]) {
+ val pumped = te.asInstanceOf[IFluidHandler].fill(dir.getOpposite, tank.getFluid, true)
+ if (pumped > 0) {
+ tank.drain(pumped, true)
+ if (tank.getFluidAmount <= 0) return
+ }
+ }
+ }
+ }
+
+ override def tickServer() {
+ super.tickServer()
+ if (tank.getFluidAmount > 0) sendFluid()
+ }
+
+ allowSided = true
+ override def isItemValidForSlot(slot: Int, itemstack: ItemStack): Boolean = MutagenRegistry.getValue(itemstack) > 0
+ override def canExtractItem(slot: Int, item: ItemStack, side: Int): Boolean = false
+
+ override def fill(from: ForgeDirection, resource: FluidStack, doFill: Boolean) = 0
+ override def canFill(from: ForgeDirection, fluid: Fluid) = false
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/mutatron/BlockMutatron.scala b/src/net/bdew/gendustry/machines/mutatron/BlockMutatron.scala
new file mode 100644
index 00000000..5552213f
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/mutatron/BlockMutatron.scala
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.mutatron
+
+import cpw.mods.fml.relauncher.Side
+import cpw.mods.fml.relauncher.SideOnly
+import net.bdew.gendustry.Gendustry
+import net.minecraft.block.Block
+import net.minecraft.block.material.Material
+import net.minecraft.client.renderer.texture.IconRegister
+import net.minecraft.util.Icon
+import net.bdew.lib.block.HasTE
+import net.bdew.lib.tile.inventory.BreakableInventoryBlock
+import net.bdew.gendustry.config.Machines
+import net.bdew.gendustry.gui.BlockGuiWrenchable
+
+class BlockMutatron(id: Int) extends Block(id, Material.rock) with HasTE[TileMutatron] with BreakableInventoryBlock with BlockGuiWrenchable {
+ val TEClass = classOf[TileMutatron]
+ private var icons: Array[Icon] = null
+ lazy val guiId: Int = Machines.mutatron.guiId
+
+ setUnlocalizedName(Gendustry.modId + ".mutatron")
+ setHardness(5)
+
+ override def getIcon(side: Int, meta: Int): Icon = {
+ side match {
+ case 0 =>
+ return icons(0)
+ case 1 =>
+ return icons(1)
+ case _ =>
+ return icons(2)
+ }
+ }
+
+ @SideOnly(Side.CLIENT)
+ override def registerIcons(reg: IconRegister) {
+ icons = new Array[Icon](3)
+ icons(0) = reg.registerIcon(Gendustry.modId + ":mutatron/bottom")
+ icons(1) = reg.registerIcon(Gendustry.modId + ":mutatron/top")
+ icons(2) = reg.registerIcon(Gendustry.modId + ":mutatron/side")
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/mutatron/ContainerMutatron.scala b/src/net/bdew/gendustry/machines/mutatron/ContainerMutatron.scala
new file mode 100644
index 00000000..3c8fa861
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/mutatron/ContainerMutatron.scala
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.mutatron
+
+import net.bdew.lib.gui.{BaseContainer, SlotValidating}
+import net.minecraft.entity.player.EntityPlayer
+import net.bdew.lib.data.base.ContainerDataSlots
+
+class ContainerMutatron(val te: TileMutatron, player: EntityPlayer) extends BaseContainer(te) with ContainerDataSlots {
+ lazy val dataSource = te
+
+ addSlotToContainer(new SlotValidating(te, 0, 60, 30))
+ addSlotToContainer(new SlotValidating(te, 1, 60, 53))
+ addSlotToContainer(new SlotValidating(te, 2, 142, 41))
+ addSlotToContainer(new SlotValidating(te, 3, 98, 17))
+ bindPlayerInventory(player.inventory, 8, 84, 142)
+
+ def canInteractWith(entityplayer: EntityPlayer): Boolean = {
+ return te.isUseableByPlayer(entityplayer)
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/mutatron/GeneticsHelper.scala b/src/net/bdew/gendustry/machines/mutatron/GeneticsHelper.scala
new file mode 100644
index 00000000..2870fdaf
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/mutatron/GeneticsHelper.scala
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.mutatron
+
+import forestry.api.apiculture.EnumBeeType
+import forestry.api.apiculture.IBee
+import forestry.api.apiculture.IBeeRoot
+import forestry.api.arboriculture.{EnumGermlingType, ITreeRoot}
+import forestry.api.genetics._
+import net.minecraft.item.ItemStack
+import java.util.Random
+import net.bdew.gendustry.config.{Items, Machines}
+
+object GeneticsHelper {
+ def checkIndividualType(root: ISpeciesRoot, stack: ItemStack, slot: Int): Boolean = {
+ (root, slot) match {
+ case (bees: IBeeRoot, 0) => bees.getType(stack) == EnumBeeType.PRINCESS
+ case (bees: IBeeRoot, 1) => bees.getType(stack) == EnumBeeType.DRONE
+ case (trees: ITreeRoot, 0) => trees.getType(stack) == EnumGermlingType.SAPLING
+ case (trees: ITreeRoot, 1) => trees.getType(stack) == EnumGermlingType.POLLEN
+ case _ => true
+ }
+ }
+
+ def isValidItemForSlot(stack: ItemStack, slot: Int): Boolean = {
+ val root = AlleleManager.alleleRegistry.getSpeciesRoot(stack)
+ if (root == null)
+ return false
+ return checkIndividualType(root, stack, slot)
+ }
+
+ def checkMutation(m: IMutation, s1: IAlleleSpecies, s2: IAlleleSpecies): Boolean = {
+ if (m.getAllele0 == s1 && m.getAllele1 == s2) return true
+ if (m.getAllele0 == s2 && m.getAllele1 == s1) return true
+ return false
+ }
+
+ def getValidMutations(fromStack: ItemStack, toStack: ItemStack): Seq[IMutation] = {
+ val emptyMutations = Seq.empty[IMutation]
+
+ if (fromStack == null || toStack == null) return emptyMutations
+
+ val root = AlleleManager.alleleRegistry.getSpeciesRoot(fromStack)
+ if (root == null || !root.isMember(toStack)) return emptyMutations
+ if (!checkIndividualType(root, fromStack, 0)) return emptyMutations
+ if (!checkIndividualType(root, toStack, 1)) return emptyMutations
+
+ val fromIndividual = root.getMember(fromStack)
+ val toIndividual = root.getMember(toStack)
+ if (fromIndividual == null || toIndividual == null) return emptyMutations
+
+ val fromSpecies = fromIndividual.getGenome.getPrimary
+ val toSpecies = toIndividual.getGenome.getPrimary
+ if (fromSpecies == null || toSpecies == null) return emptyMutations
+
+ import scala.collection.JavaConverters._
+
+ val mutations = root.getCombinations(fromSpecies).asScala
+
+ return mutations.filter(checkMutation(_, fromSpecies, toSpecies)).toSeq
+ }
+
+ def isPotentialMutationPair(fromStack: ItemStack, toStack: ItemStack): Boolean = {
+ if (fromStack == null && toStack == null) return false
+ if (toStack == null) return isValidItemForSlot(fromStack, 0)
+ if (fromStack == null) return isValidItemForSlot(toStack, 1)
+ return getValidMutations(fromStack, toStack).size > 0
+ }
+
+ def getMutationResult(fromStack: ItemStack, toStack: ItemStack): ItemStack = {
+ val valid = getValidMutations(fromStack, toStack)
+ val random = new Random
+ if (valid.size == 0) return null
+
+ val selected = valid(random.nextInt(valid.size))
+ val root = selected.getRoot
+ val individual = root.templateAsIndividual(selected.getTemplate)
+
+ root match {
+ case bees: IBeeRoot =>
+ individual.asInstanceOf[IBee].mate(individual)
+ val original = bees.getMember(fromStack)
+ if (original.isNatural) {
+ if (random.nextInt(100) < Machines.mutatron.degradeChanceNatural)
+ individual.asInstanceOf[IBee].setIsNatural(false)
+ } else {
+ if (random.nextInt(100) < Machines.mutatron.deathChanceArtificial)
+ return new ItemStack(Items.waste)
+ }
+ return root.getMemberStack(individual, EnumBeeType.QUEEN.ordinal)
+ case _: ITreeRoot =>
+ return root.getMemberStack(individual, EnumGermlingType.SAPLING.ordinal)
+ case _ =>
+ return root.getMemberStack(individual, 0)
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/mutatron/GuiMutatron.scala b/src/net/bdew/gendustry/machines/mutatron/GuiMutatron.scala
new file mode 100644
index 00000000..f989473d
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/mutatron/GuiMutatron.scala
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.mutatron
+
+import net.bdew.gendustry.Gendustry
+import net.bdew.gendustry.gui.{WidgetMJGauge, Textures}
+import net.minecraft.entity.player.EntityPlayer
+import net.minecraft.util.ResourceLocation
+import net.bdew.lib.gui.{Rect, BaseScreen}
+import net.bdew.lib.gui.widgets.{WidgetLabel, WidgetFluidGauge, WidgetProgressBar}
+import net.bdew.lib.Misc
+
+class GuiMutatron(val te: TileMutatron, player: EntityPlayer) extends BaseScreen(new ContainerMutatron(te, player), 176, 166) {
+ val texture: ResourceLocation = new ResourceLocation(Gendustry.modId + ":textures/gui/mutatron.png")
+ override def initGui() {
+ super.initGui()
+ addWidget(new WidgetProgressBar(new Rect(89, 41, 40, 15), Textures.greenProgress(40), te.progress))
+ addWidget(new WidgetMJGauge(new Rect(8, 19, 16, 58), Textures.powerFill, te.power))
+ addWidget(new WidgetFluidGauge(new Rect(32, 19, 16, 58), Textures.tankOverlay, te.tank))
+ addWidget(new WidgetLabel(Misc.toLocal("tile.gendustry.mutatron.name"), 8, 6, 4210752))
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/mutatron/MachineMutatron.scala b/src/net/bdew/gendustry/machines/mutatron/MachineMutatron.scala
new file mode 100644
index 00000000..f98dd97d
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/mutatron/MachineMutatron.scala
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.mutatron
+
+import net.bdew.gendustry.machines.ProcessorMachine
+import net.minecraft.tileentity.TileEntity
+import net.minecraft.entity.player.EntityPlayer
+import net.minecraft.inventory.Container
+import net.minecraft.client.gui.inventory.GuiContainer
+import net.minecraftforge.common.Configuration
+import net.bdew.gendustry.gui.GuiProvider
+import cpw.mods.fml.relauncher.{Side, SideOnly}
+
+class MachineMutatron(cfg: Configuration) extends ProcessorMachine(cfg, "Mutatron") with GuiProvider {
+ var block: BlockMutatron = null
+ lazy val guiId = 2
+
+ lazy val tankSize = tuning.getInt("TankSize")
+ lazy val mutagenPerItem = tuning.getInt("MutagenPerItem")
+ lazy val labwareConsumeChance = tuning.getFloat("LabwareConsumeChance")
+ lazy val degradeChanceNatural = tuning.getFloat("DegradeChanceNatural")
+ lazy val deathChanceArtificial = tuning.getFloat("DeathChanceArtificial")
+
+ if (cfg.get("Machines Enabled", name, true).getBoolean(true)) {
+ block = new BlockMutatron(getBlockId)
+ registerBlock(block)
+ }
+
+ @SideOnly(Side.CLIENT)
+ def getGui(te: TileEntity, player: EntityPlayer): GuiContainer = new GuiMutatron(te.asInstanceOf[TileMutatron], player)
+ def getContainer(te: TileEntity, player: EntityPlayer): Container = new ContainerMutatron(te.asInstanceOf[TileMutatron], player)
+}
diff --git a/src/net/bdew/gendustry/machines/mutatron/TileMutatron.scala b/src/net/bdew/gendustry/machines/mutatron/TileMutatron.scala
new file mode 100644
index 00000000..6fe69b53
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/mutatron/TileMutatron.scala
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.mutatron
+
+import net.bdew.gendustry.config.{Items, Machines, Blocks}
+import net.minecraft.item.ItemStack
+import net.minecraftforge.common.ForgeDirection
+import net.minecraftforge.fluids._
+import net.bdew.lib.data.DataSlotTankRestricted
+import net.bdew.lib.tile.ExposeTank
+import net.bdew.gendustry.machines.TileItemProcessor
+
+class TileMutatron extends TileItemProcessor with ExposeTank {
+ lazy val cfg = Machines.mutatron
+ val outputSlots = Seq(2)
+
+ val tank = DataSlotTankRestricted("tank", this, cfg.tankSize, Blocks.mutagenFluid.getID)
+
+ def getSizeInventory = 4
+
+ def getTankFromDirection(dir: ForgeDirection): IFluidTank = tank
+
+ def tryStart(): Boolean = {
+ if (getStackInSlot(0) != null && getStackInSlot(1) != null && getStackInSlot(3) != null && tank.getFluidAmount >= cfg.mutagenPerItem) {
+ output := GeneticsHelper.getMutationResult(getStackInSlot(0), getStackInSlot(1))
+ tank.drain(cfg.mutagenPerItem, true)
+ decrStackSize(0, 1)
+ decrStackSize(1, 1)
+ if (worldObj.rand.nextInt(100) < cfg.labwareConsumeChance)
+ decrStackSize(3, 1)
+ return true
+ } else return false
+ }
+
+ override def isItemValidForSlot(slot: Int, itemstack: ItemStack): Boolean = {
+ slot match {
+ case 0 =>
+ return GeneticsHelper.isPotentialMutationPair(itemstack, getStackInSlot(1))
+ case 1 =>
+ return GeneticsHelper.isPotentialMutationPair(getStackInSlot(0), itemstack)
+ case 3 =>
+ return itemstack.getItem == Items.labware
+ case _ =>
+ return false
+ }
+ }
+
+ allowSided = true
+ override def canExtractItem(slot: Int, item: ItemStack, side: Int) = slot == 2
+
+ override def canDrain(from: ForgeDirection, fluid: Fluid): Boolean = false
+ override def drain(from: ForgeDirection, resource: FluidStack, doDrain: Boolean): FluidStack = null
+ override def drain(from: ForgeDirection, maxDrain: Int, doDrain: Boolean): FluidStack = null
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/sampler/BlockSampler.scala b/src/net/bdew/gendustry/machines/sampler/BlockSampler.scala
new file mode 100644
index 00000000..26758b37
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/sampler/BlockSampler.scala
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.sampler
+
+import cpw.mods.fml.relauncher.Side
+import cpw.mods.fml.relauncher.SideOnly
+import net.bdew.gendustry.Gendustry
+import net.minecraft.block.Block
+import net.minecraft.block.material.Material
+import net.minecraft.client.renderer.texture.IconRegister
+import net.minecraft.util.Icon
+import net.bdew.lib.block.HasTE
+import net.bdew.lib.tile.inventory.BreakableInventoryBlock
+import net.bdew.gendustry.config.Machines
+import net.bdew.gendustry.gui.BlockGuiWrenchable
+
+class BlockSampler(id: Int) extends Block(id, Material.rock) with HasTE[TileSampler] with BreakableInventoryBlock with BlockGuiWrenchable {
+ val TEClass = classOf[TileSampler]
+ private var icons: Array[Icon] = null
+ lazy val guiId: Int = Machines.sampler.guiId
+
+ setUnlocalizedName(Gendustry.modId + ".sampler")
+ setHardness(5)
+
+ override def getIcon(side: Int, meta: Int): Icon = {
+ side match {
+ case 0 =>
+ return icons(0)
+ case 1 =>
+ return icons(1)
+ case _ =>
+ return icons(2)
+ }
+ }
+
+ @SideOnly(Side.CLIENT)
+ override def registerIcons(reg: IconRegister) {
+ icons = new Array[Icon](3)
+ icons(0) = reg.registerIcon(Gendustry.modId + ":sampler/bottom")
+ icons(1) = reg.registerIcon(Gendustry.modId + ":sampler/top")
+ icons(2) = reg.registerIcon(Gendustry.modId + ":sampler/side")
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/sampler/ContainerSampler.scala b/src/net/bdew/gendustry/machines/sampler/ContainerSampler.scala
new file mode 100644
index 00000000..ac949100
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/sampler/ContainerSampler.scala
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.sampler
+
+import net.bdew.lib.gui.{BaseContainer, SlotValidating}
+import net.minecraft.entity.player.EntityPlayer
+import net.bdew.lib.data.base.ContainerDataSlots
+
+class ContainerSampler(val te: TileSampler, player: EntityPlayer) extends BaseContainer(te) with ContainerDataSlots {
+ lazy val dataSource = te
+
+ addSlotToContainer(new SlotValidating(te, 0, 74, 28))
+ addSlotToContainer(new SlotValidating(te, 1, 98, 28))
+ addSlotToContainer(new SlotValidating(te, 2, 41, 49))
+ addSlotToContainer(new SlotValidating(te, 3, 137, 49))
+ bindPlayerInventory(player.inventory, 8, 84, 142)
+
+ def canInteractWith(entityplayer: EntityPlayer): Boolean = {
+ return te.isUseableByPlayer(entityplayer)
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/sampler/GuiSampler.scala b/src/net/bdew/gendustry/machines/sampler/GuiSampler.scala
new file mode 100644
index 00000000..4ecbfc6a
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/sampler/GuiSampler.scala
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.sampler
+
+import net.bdew.gendustry.Gendustry
+import net.bdew.gendustry.gui.{WidgetMJGauge, Textures}
+import net.minecraft.entity.player.EntityPlayer
+import net.minecraft.util.ResourceLocation
+import net.bdew.lib.gui.{Rect, BaseScreen}
+import net.bdew.lib.gui.widgets.{WidgetLabel, WidgetProgressBar}
+import net.bdew.lib.Misc
+
+class GuiSampler(val te: TileSampler, player: EntityPlayer) extends BaseScreen(new ContainerSampler(te, player), 176, 166) {
+ val texture: ResourceLocation = new ResourceLocation(Gendustry.modId + ":textures/gui/sampler.png")
+ override def initGui() {
+ super.initGui()
+ addWidget(new WidgetProgressBar(new Rect(63, 49, 66, 15), Textures.whiteProgress(66), te.progress))
+ addWidget(new WidgetMJGauge(new Rect(8, 19, 16, 58), Textures.powerFill, te.power))
+ addWidget(new WidgetLabel(Misc.toLocal("tile.gendustry.sampler.name"), 8, 6, 4210752))
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/machines/sampler/MachineSampler.scala b/src/net/bdew/gendustry/machines/sampler/MachineSampler.scala
new file mode 100644
index 00000000..f7bc28ce
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/sampler/MachineSampler.scala
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.sampler
+
+import net.bdew.gendustry.machines.ProcessorMachine
+import net.minecraft.tileentity.TileEntity
+import net.minecraft.entity.player.EntityPlayer
+import net.minecraft.inventory.Container
+import net.minecraft.client.gui.inventory.GuiContainer
+import net.minecraftforge.common.Configuration
+import net.bdew.gendustry.gui.GuiProvider
+import cpw.mods.fml.relauncher.{Side, SideOnly}
+
+class MachineSampler(cfg: Configuration) extends ProcessorMachine(cfg, "Sampler") with GuiProvider {
+ var block: BlockSampler = null
+ lazy val guiId = 5
+
+ lazy val labwareConsumeChance = tuning.getInt("LabwareConsumeChance")
+
+ if (cfg.get("Machines Enabled", name, true).getBoolean(true)) {
+ block = new BlockSampler(getBlockId)
+ registerBlock(block)
+ }
+
+ @SideOnly(Side.CLIENT)
+ def getGui(te: TileEntity, player: EntityPlayer): GuiContainer = new GuiSampler(te.asInstanceOf[TileSampler], player)
+ def getContainer(te: TileEntity, player: EntityPlayer): Container = new ContainerSampler(te.asInstanceOf[TileSampler], player)
+}
diff --git a/src/net/bdew/gendustry/machines/sampler/TileSampler.scala b/src/net/bdew/gendustry/machines/sampler/TileSampler.scala
new file mode 100644
index 00000000..d277d3d7
--- /dev/null
+++ b/src/net/bdew/gendustry/machines/sampler/TileSampler.scala
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.machines.sampler
+
+import buildcraft.api.power.PowerHandler.Type
+import net.bdew.gendustry.data.{DataSlotPower, ExposePower}
+import net.bdew.gendustry.config.{Items, Machines}
+import net.minecraft.item.ItemStack
+import net.minecraftforge.common.ForgeDirection
+import net.bdew.lib.data.{DataSlotItemStack, DataSlotFloat}
+import net.bdew.lib.tile.inventory.{BreakableInventoryTile, SidedInventory, PersistentInventoryTile}
+import net.bdew.lib.tile.TileExtended
+import net.bdew.lib.data.base.{UpdateKind, TileDataSlots}
+import forestry.api.genetics.AlleleManager
+import net.bdew.gendustry.machines.TileItemProcessor
+import scala.util.Random
+import net.bdew.gendustry.forestry.GeneSampleInfo
+
+class TileSampler extends TileItemProcessor {
+ lazy val cfg = Machines.imprinter
+ val outputSlots = Seq(3)
+
+ def getSizeInventory = 4
+
+ def selectRandomAllele(stack: ItemStack): ItemStack = {
+ val root = AlleleManager.alleleRegistry.getSpeciesRoot(stack)
+ if (root == null) return new ItemStack(Items.waste)
+ val member = root.getMember(stack)
+ val genome = member.getGenome
+ val chromosomes = genome.getChromosomes.zipWithIndex.filter(_._1!=null)
+ val alleles = chromosomes.map({
+ case (x,n)=>Seq(n -> x.getPrimaryAllele, n-> x.getSecondaryAllele)
+ }).flatten
+
+ val rand = new Random()
+ val (chr,allele) = alleles(rand.nextInt(alleles.length))
+ return Items.geneSample.newStack(GeneSampleInfo(root, chr, allele))
+ }
+
+ def tryStart(): Boolean = {
+ if (getStackInSlot(0) != null && getStackInSlot(1) != null && getStackInSlot(2) != null) {
+
+ output := selectRandomAllele(getStackInSlot(2))
+
+ decrStackSize(0, 1)
+ decrStackSize(2, 1)
+ if (worldObj.rand.nextInt(100) < cfg.labwareConsumeChance)
+ decrStackSize(1, 1)
+
+ return true
+ } else return false
+ }
+
+
+ override def isItemValidForSlot(slot: Int, itemstack: ItemStack): Boolean = {
+ if (itemstack == null || itemstack.getItem == null) return false
+ slot match {
+ case 0 =>
+ return itemstack.getItem == Items.geneSampleBlank
+ case 1 =>
+ return itemstack.getItem == Items.labware
+ case 2 =>
+ return AlleleManager.alleleRegistry.getIndividual(itemstack) != null
+ case _ =>
+ return false
+ }
+ }
+
+ allowSided = true
+ override def canExtractItem(slot: Int, item: ItemStack, side: Int) = slot == 3
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/mutagen/BlockMutagen.scala b/src/net/bdew/gendustry/mutagen/BlockMutagen.scala
new file mode 100644
index 00000000..81bb6817
--- /dev/null
+++ b/src/net/bdew/gendustry/mutagen/BlockMutagen.scala
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.mutagen
+
+import cpw.mods.fml.relauncher.Side
+import cpw.mods.fml.relauncher.SideOnly
+import net.bdew.gendustry.Gendustry
+import net.bdew.gendustry.config.Blocks
+import net.bdew.gendustry.config.Items
+import net.minecraft.block.material.Material
+import net.minecraft.client.renderer.texture.IconRegister
+import net.minecraft.item.ItemStack
+import net.minecraft.util.Icon
+import net.minecraft.world.IBlockAccess
+import net.minecraft.world.World
+import net.minecraftforge.common.MinecraftForge
+import net.minecraftforge.event.Event.Result
+import net.minecraftforge.event.ForgeSubscribe
+import net.minecraftforge.event.entity.player.FillBucketEvent
+import net.minecraftforge.fluids.BlockFluidClassic
+
+class BlockMutagen(id: Int) extends BlockFluidClassic(id, Blocks.mutagenFluid, Material.water) {
+ protected var stillIcon: Icon = null
+ protected var flowingIcon: Icon = null
+
+ Blocks.mutagenFluid.setBlockID(id)
+ setUnlocalizedName(Gendustry.modId + ".mutagen")
+ MinecraftForge.EVENT_BUS.register(this)
+
+ override def colorMultiplier(iblockaccess: IBlockAccess, x: Int, y: Int, z: Int): Int = 0x66FF00
+
+ override def canDisplace(world: IBlockAccess, x: Int, y: Int, z: Int): Boolean = {
+ if (world.getBlockMaterial(x, y, z).isLiquid) return false
+ return super.canDisplace(world, x, y, z)
+ }
+
+ override def displaceIfPossible(world: World, x: Int, y: Int, z: Int): Boolean = {
+ if (world.getBlockMaterial(x, y, z).isLiquid) return false
+ return super.displaceIfPossible(world, x, y, z)
+ }
+
+ @ForgeSubscribe
+ def onBucketFill(event: FillBucketEvent) {
+ if (event.world.getBlockMetadata(event.target.blockX, event.target.blockY, event.target.blockZ) != 0) return
+ if (event.world.getBlockId(event.target.blockX, event.target.blockY, event.target.blockZ) != blockID) return
+ event.world.setBlockToAir(event.target.blockX, event.target.blockY, event.target.blockZ)
+ event.result = new ItemStack(Items.mutagenBucket)
+ event.setResult(Result.ALLOW)
+ }
+
+ @SideOnly(Side.CLIENT)
+ override def getIcon(side: Int, meta: Int): Icon = if (side == 0 || side == 1) stillIcon else flowingIcon
+
+ @SideOnly(Side.CLIENT)
+ override def registerIcons(register: IconRegister) {
+ stillIcon = register.registerIcon(Gendustry.modId + ":mutagen/still")
+ flowingIcon = register.registerIcon(Gendustry.modId + ":mutagen/flowing")
+ Blocks.mutagenFluid.setIcons(stillIcon, flowingIcon)
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/mutagen/FluidMutagen.scala b/src/net/bdew/gendustry/mutagen/FluidMutagen.scala
new file mode 100644
index 00000000..ddf3ecbb
--- /dev/null
+++ b/src/net/bdew/gendustry/mutagen/FluidMutagen.scala
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.mutagen
+
+import net.minecraftforge.fluids.Fluid
+import net.minecraftforge.fluids.FluidRegistry
+
+class FluidMutagen extends Fluid("Mutagen") {
+ setDensity(1000)
+ setViscosity(1000)
+ setUnlocalizedName("gendustry.mutagen")
+ FluidRegistry.registerFluid(this)
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/mutagen/ItemMutagenBucket.scala b/src/net/bdew/gendustry/mutagen/ItemMutagenBucket.scala
new file mode 100644
index 00000000..c0f31918
--- /dev/null
+++ b/src/net/bdew/gendustry/mutagen/ItemMutagenBucket.scala
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.mutagen
+
+import cpw.mods.fml.relauncher.Side
+import cpw.mods.fml.relauncher.SideOnly
+import net.bdew.gendustry.Gendustry
+import net.bdew.gendustry.config.Blocks
+import net.minecraft.client.renderer.texture.IconRegister
+import net.minecraft.item.ItemBucket
+
+class ItemMutagenBucket(id: Int) extends ItemBucket(id, Blocks.mutagen.blockID) {
+ setUnlocalizedName(Gendustry.modId + ".mutagen.bucket")
+
+ @SideOnly(Side.CLIENT)
+ override def registerIcons(reg: IconRegister) {
+ itemIcon = reg.registerIcon(Gendustry.modId + ":mutagen/bucket")
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/mutagen/ItemMutagenCan.scala b/src/net/bdew/gendustry/mutagen/ItemMutagenCan.scala
new file mode 100644
index 00000000..ee36f660
--- /dev/null
+++ b/src/net/bdew/gendustry/mutagen/ItemMutagenCan.scala
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.mutagen
+
+import cpw.mods.fml.relauncher.Side
+import cpw.mods.fml.relauncher.SideOnly
+import net.bdew.gendustry.Gendustry
+import net.minecraft.client.renderer.texture.IconRegister
+import net.minecraft.item.Item
+
+class ItemMutagenCan(id: Int) extends Item(id) {
+ setUnlocalizedName(Gendustry.modId + ".mutagen.can")
+
+ @SideOnly(Side.CLIENT)
+ override def registerIcons(reg: IconRegister) {
+ itemIcon = reg.registerIcon(Gendustry.modId + ":mutagen/can")
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/mutagen/MutagenRegistry.scala b/src/net/bdew/gendustry/mutagen/MutagenRegistry.scala
new file mode 100644
index 00000000..f33cf0eb
--- /dev/null
+++ b/src/net/bdew/gendustry/mutagen/MutagenRegistry.scala
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.mutagen
+
+import net.minecraft.block.Block
+import net.minecraft.item.Item
+import net.minecraft.item.ItemStack
+import scala.collection.mutable
+import net.minecraftforge.oredict.OreDictionary
+
+object MutagenRegistry {
+ val values = mutable.Map.empty[Int, mutable.Map[Int, Int]]
+
+ def register(block: Block, value: Integer): Unit = register(block.blockID, OreDictionary.WILDCARD_VALUE, value)
+ def register(item: Item, value: Integer): Unit = register(item.itemID, OreDictionary.WILDCARD_VALUE, value)
+ def register(item: ItemStack, value: Integer): Unit = register(item.itemID, item.getItemDamage, value)
+
+ def register(id: Int, damage: Int, value: Int) {
+ if (values.contains(id)) {
+ values(id) += (damage -> value)
+ } else {
+ val sub = mutable.Map.empty[Int, Int]
+ sub += (damage -> value)
+ values.put(id, sub)
+ }
+ }
+
+ def getValue(item: ItemStack): Int = {
+ if (!values.contains(item.itemID)) return 0
+ val sub = values(item.itemID)
+ if (sub.contains(item.getItemDamage)) {
+ return sub(item.getItemDamage)
+ } else if (sub.contains(OreDictionary.WILDCARD_VALUE)) {
+ return sub(OreDictionary.WILDCARD_VALUE)
+ } else {
+ return 0
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/net/bdew/gendustry/nei/NEIGendustryConfig.scala b/src/net/bdew/gendustry/nei/NEIGendustryConfig.scala
new file mode 100644
index 00000000..5d950148
--- /dev/null
+++ b/src/net/bdew/gendustry/nei/NEIGendustryConfig.scala
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.nei
+
+import codechicken.nei.api.{API, IConfigureNEI}
+import forestry.api.genetics.{IAlleleSpecies, AlleleManager}
+import net.bdew.gendustry.config.{Config, Items}
+import net.bdew.gendustry.forestry.GeneSampleInfo
+
+class NEIGendustryConfig extends IConfigureNEI {
+ def getName: String = "Gendustry"
+ def getVersion: String = "@@VERSION@@"
+
+ def addSamples() {
+ import scala.collection.JavaConverters._
+ val species = AlleleManager.alleleRegistry.getRegisteredAlleles.asScala.values.filter(_.isInstanceOf[IAlleleSpecies])
+ val combos = species.map({
+ case x: IAlleleSpecies =>
+ val root = x.getRoot
+ val tpl = root.getTemplate(x.getUID)
+ tpl.toIterable.zipWithIndex.filter(x => x._1 != null && !AlleleManager.alleleRegistry.isBlacklisted(x._1.getUID)).map(x => GeneSampleInfo(root, x._2, x._1))
+ }).flatten.toSet
+ combos.foreach(x => API.addNBTItem(Items.geneSample.newStack(x)))
+ }
+
+ def loadConfig() = {
+ if (Config.neiAddSamples) addSamples()
+ }
+}
diff --git a/src/net/bdew/gendustry/test/PowerEmitterBlock.scala b/src/net/bdew/gendustry/test/PowerEmitterBlock.scala
new file mode 100644
index 00000000..5cce4491
--- /dev/null
+++ b/src/net/bdew/gendustry/test/PowerEmitterBlock.scala
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.test
+
+import net.minecraft.block.Block
+import net.minecraft.block.material.Material
+import net.bdew.lib.block.HasTE
+
+class PowerEmitterBlock(id: Int) extends Block(id, Material.iron) with HasTE[PowerEmitterTile] {
+ val TEClass = classOf[PowerEmitterTile]
+ setUnlocalizedName("test.power.emitter")
+ setHardness(1)
+}
diff --git a/src/net/bdew/gendustry/test/PowerEmitterTile.scala b/src/net/bdew/gendustry/test/PowerEmitterTile.scala
new file mode 100644
index 00000000..f3fcba17
--- /dev/null
+++ b/src/net/bdew/gendustry/test/PowerEmitterTile.scala
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) bdew, 2013
+ * https://github.com/bdew/gendustry
+ *
+ * This mod is distributed under the terms of the Minecraft Mod Public
+ * License 1.0, or MMPL. Please check the contents of the license located in
+ * https://raw.github.com/bdew/gendustry/master/MMPL-1.0.txt
+ */
+
+package net.bdew.gendustry.test
+
+import net.minecraft.tileentity.TileEntity
+import net.minecraftforge.common.ForgeDirection
+import buildcraft.api.power.PowerHandler.Type
+import buildcraft.api.power.{IPowerEmitter, IPowerReceptor}
+
+class PowerEmitterTile extends TileEntity with IPowerEmitter {
+ def canEmitPowerFrom(side: ForgeDirection): Boolean = true
+ override def updateEntity() {
+ if (worldObj.isRemote) return
+ for (dir <- ForgeDirection.VALID_DIRECTIONS) {
+ val te = worldObj.getBlockTileEntity(xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ)
+ if (te != null && te.isInstanceOf[IPowerReceptor]) {
+ val pr = te.asInstanceOf[IPowerReceptor].getPowerReceiver(dir.getOpposite)
+ if (pr != null) {
+ val power = pr.getMaxEnergyReceived
+ if (power > 0)
+ pr.receiveEnergy(Type.ENGINE, power, dir.getOpposite)
+ }
+ }
+ }
+ }
+}