mirror of
https://github.com/GTNewHorizons/bdlib.git
synced 2026-10-25 20:22:25 +00:00
Preparing for public release
This commit is contained in:
commit
9156249843
60 files changed
+2825
No files matched your search
@@ -0,0 +1,9 @@
|
|||||||
|
/.gradle
|
||||||
|
/build
|
||||||
|
/deps
|
||||||
|
/eclipse
|
||||||
|
/out
|
||||||
|
|
||||||
|
*.ipr
|
||||||
|
*.iml
|
||||||
|
*.iws
|
||||||
@@ -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.
|
||||||
+112
@@ -0,0 +1,112 @@
|
|||||||
|
buildscript {
|
||||||
|
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"
|
||||||
|
|
||||||
|
if (project.hasProperty('buildnum')) {
|
||||||
|
project.version = project.version + '.' + project.buildnum
|
||||||
|
} else {
|
||||||
|
project.version = project.version + '-dev'
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "net.bdew"
|
||||||
|
archivesBaseName = "bdlib"
|
||||||
|
|
||||||
|
minecraft {
|
||||||
|
version = "1.6.4-9.11.1.964"
|
||||||
|
}
|
||||||
|
|
||||||
|
import org.apache.tools.ant.filters.ReplaceTokens
|
||||||
|
|
||||||
|
def myTokens = [BdLibVer: project.version]
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
scala {
|
||||||
|
srcDir 'src'
|
||||||
|
}
|
||||||
|
resources {
|
||||||
|
srcDir 'resources'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
processed {
|
||||||
|
scala {
|
||||||
|
srcDir 'build/stage'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task stage(type: Sync) {
|
||||||
|
from sourceSets.main.scala
|
||||||
|
into 'build/stage'
|
||||||
|
filter(ReplaceTokens, tokens: myTokens)
|
||||||
|
}
|
||||||
|
|
||||||
|
compileScala {
|
||||||
|
source = sourceSets.processed.scala
|
||||||
|
dependsOn stage
|
||||||
|
}
|
||||||
|
|
||||||
|
processResources {
|
||||||
|
from(sourceSets.main.resources.srcDirs) {
|
||||||
|
include 'mcmod.info'
|
||||||
|
filter(ReplaceTokens, tokens: myTokens)
|
||||||
|
}
|
||||||
|
|
||||||
|
from(sourceSets.main.resources.srcDirs) {
|
||||||
|
exclude 'mcmod.info'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
BIN
Binary file not shown.
+6
@@ -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
|
||||||
@@ -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 "$@"
|
||||||
Vendored
+90
@@ -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
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"modid": "bdlib",
|
||||||
|
"name": "BD Lib",
|
||||||
|
"description": "",
|
||||||
|
"version": "@BdLibVer@",
|
||||||
|
"url": "bdew.net/mods/",
|
||||||
|
"updateUrl": "",
|
||||||
|
"authorList": [
|
||||||
|
"bdew"
|
||||||
|
],
|
||||||
|
"credits": "",
|
||||||
|
"logoFile": "",
|
||||||
|
"screenshots": [
|
||||||
|
],
|
||||||
|
"parent":"",
|
||||||
|
"dependencies": [
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package net.bdew.lib
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.Mod
|
||||||
|
import cpw.mods.fml.common.event.FMLPreInitializationEvent
|
||||||
|
|
||||||
|
@Mod(modid = "bdlib", version = "@BdLibVer@", modLanguage = "scala")
|
||||||
|
object BdLib {
|
||||||
|
def preInit(ev: FMLPreInitializationEvent) {
|
||||||
|
ev.getModLog.info("bdlib @BdLibVer@ loaded")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib
|
||||||
|
|
||||||
|
class EventBase[T] extends {
|
||||||
|
var listeners = Seq.empty[T]
|
||||||
|
def listen(x: T) = listeners :+= x
|
||||||
|
def hasListeners = listeners.size > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
class Event0 extends EventBase[() => Unit] {
|
||||||
|
def trigger() = for (x <- listeners) x()
|
||||||
|
}
|
||||||
|
|
||||||
|
class Event1[T] extends EventBase[(T) => Unit] {
|
||||||
|
def trigger(p1: T) = for (x <- listeners) x(p1)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Event2[T, R] extends EventBase[(T, R) => Unit] {
|
||||||
|
def trigger(p1: T, p2: R) = for (x <- listeners) x(p1, p2)
|
||||||
|
}
|
||||||
|
|
||||||
|
object Event {
|
||||||
|
def apply(t: Unit) = new Event0
|
||||||
|
def apply[T] = new Event1[T]
|
||||||
|
def apply[T, R] = new Event2[T, R]
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.registry.GameRegistry
|
||||||
|
import net.minecraft.nbt.{NBTTagCompound, NBTTagList}
|
||||||
|
import net.minecraft.util.StatCollector
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import cpw.mods.fml.common.versioning.{ArtifactVersion, VersionParser}
|
||||||
|
import cpw.mods.fml.common.Loader
|
||||||
|
import net.minecraftforge.oredict.ShapedOreRecipe
|
||||||
|
|
||||||
|
object Misc {
|
||||||
|
def iterNbtList[X](list: NBTTagList) =
|
||||||
|
for (i <- 0 until list.tagCount()) yield list.tagAt(i).asInstanceOf[X]
|
||||||
|
|
||||||
|
def toLocal(s: String) = StatCollector.translateToLocal(s)
|
||||||
|
def toLocalF(s: String, params: Any*) = StatCollector.translateToLocal(s).format(params: _*)
|
||||||
|
|
||||||
|
def flattenRecipe(pattern: Seq[String], items: Map[Char, AnyRef]) =
|
||||||
|
pattern ++ items.map {
|
||||||
|
case (k, v) => Seq(new Character(k), v)
|
||||||
|
}.flatten
|
||||||
|
|
||||||
|
def wrapTag(n: String, f: (NBTTagCompound) => Any)(t: NBTTagCompound) {
|
||||||
|
val p = t.getCompoundTag(n)
|
||||||
|
f(p)
|
||||||
|
t.setCompoundTag(n, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
def addRecipe(result: ItemStack, pattern: Seq[String], items: Map[Char, AnyRef]) =
|
||||||
|
GameRegistry.addRecipe(result, flattenRecipe(pattern, items): _*)
|
||||||
|
|
||||||
|
def addRecipeOD(result: ItemStack, pattern: Seq[String], items: Map[Char, AnyRef]) =
|
||||||
|
GameRegistry.addRecipe(new ShapedOreRecipe(result, flattenRecipe(pattern, items): _*))
|
||||||
|
|
||||||
|
def min[T](vals: T*)(implicit o: Ordering[T]): T = vals.min(o)
|
||||||
|
def max[T](vals: T*)(implicit o: Ordering[T]): T = vals.max(o)
|
||||||
|
|
||||||
|
def clamp[T](value: T, min: T, max: T)(implicit o: Ordering[T]): T = if (o.gt(value,max)) max else if (o.lt(value,min)) min else value
|
||||||
|
|
||||||
|
def iterSome[T](list: Seq[T], indexes: Iterable[Int]): Iterable[T] = for (i <- indexes) yield list(i)
|
||||||
|
def iterSomeEnum[T](list: Seq[T], indexes: Iterable[Int]): Iterable[(Int, T)] = for (i <- indexes) yield i -> list(i)
|
||||||
|
|
||||||
|
def filterType[T](from: Iterable[_], cls: Class[T]) = from.filter(cls.isInstance).asInstanceOf[Iterable[T]]
|
||||||
|
|
||||||
|
def haveModVersion(spec: String): Boolean = {
|
||||||
|
val req = VersionParser.parseVersionReference(spec)
|
||||||
|
val modid = req.getLabel
|
||||||
|
|
||||||
|
if (!Loader.instance.getIndexedModList.containsKey(modid)) return false
|
||||||
|
|
||||||
|
val found: ArtifactVersion = Loader.instance.getIndexedModList.get(modid).getProcessedVersion
|
||||||
|
|
||||||
|
if (found == null || !req.containsVersion(found)) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.block
|
||||||
|
|
||||||
|
import net.minecraft.block.{ITileEntityProvider, Block}
|
||||||
|
import net.minecraft.world.{IBlockAccess, World}
|
||||||
|
import net.minecraft.tileentity.TileEntity
|
||||||
|
import cpw.mods.fml.common.FMLCommonHandler
|
||||||
|
|
||||||
|
trait HasTE[T] extends Block with ITileEntityProvider {
|
||||||
|
val TEClass: Class[_ <: TileEntity]
|
||||||
|
def createNewTileEntity(world: World): TileEntity = TEClass.newInstance()
|
||||||
|
def getTE(w: IBlockAccess, x: Int, y: Int, z: Int): T = {
|
||||||
|
var t = w.getBlockTileEntity(x, y, z)
|
||||||
|
if ((t == null) || !TEClass.isInstance(t)) {
|
||||||
|
FMLCommonHandler.instance().getFMLLogger.severe("Tile entity for block %s at (%d,%d,%d) is corrupt or missing - recreating".format(this, x, y, z))
|
||||||
|
w match {
|
||||||
|
case ww: World =>
|
||||||
|
t = createNewTileEntity(ww)
|
||||||
|
ww.setBlockTileEntity(x, y, z, t)
|
||||||
|
case _ =>
|
||||||
|
sys.error("Unable to recreate TE")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return t.asInstanceOf[T]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.data
|
||||||
|
|
||||||
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
|
import net.bdew.lib.data.base.{UpdateKind, TileDataSlots, DataSlotVal}
|
||||||
|
|
||||||
|
case class DataSlotBoolean(name: String, parent: TileDataSlots, default: Boolean = false) extends DataSlotVal[Boolean] {
|
||||||
|
var cval = default
|
||||||
|
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setBoolean(name, cval)
|
||||||
|
def load(t: NBTTagCompound, kind: UpdateKind.Value) = cval = t.getBoolean(name)
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.data
|
||||||
|
|
||||||
|
import net.bdew.lib.data.base.{TileDataSlots, UpdateKind, DataSlotVal}
|
||||||
|
import net.minecraftforge.common.ForgeDirection
|
||||||
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
|
|
||||||
|
case class DataSlotDirection(name: String, parent: TileDataSlots) extends DataSlotVal[ForgeDirection] {
|
||||||
|
var cval = ForgeDirection.UP
|
||||||
|
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setByte(name, cval.ordinal().toByte)
|
||||||
|
def load(t: NBTTagCompound, kind: UpdateKind.Value) = cval = ForgeDirection.getOrientation(t.getByte(name))
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.data
|
||||||
|
|
||||||
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
|
import net.bdew.lib.data.base.{UpdateKind, TileDataSlots, DataSlotNumeric}
|
||||||
|
|
||||||
|
case class DataSlotFloat(name: String, parent: TileDataSlots, default: Float = 0) extends DataSlotNumeric[Float](default) {
|
||||||
|
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setFloat(name, cval)
|
||||||
|
def load(t: NBTTagCompound, kind: UpdateKind.Value) = cval = t.getFloat(name)
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.data
|
||||||
|
|
||||||
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
|
import net.bdew.lib.data.base.{UpdateKind, TileDataSlots, DataSlotNumeric}
|
||||||
|
|
||||||
|
case class DataSlotInt(name: String, parent: TileDataSlots, default: Int = 0) extends DataSlotNumeric[Int](default) {
|
||||||
|
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setInteger(name, cval)
|
||||||
|
def load(t: NBTTagCompound, kind: UpdateKind.Value) = cval = t.getInteger(name)
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.data
|
||||||
|
|
||||||
|
import net.bdew.lib.data.base.{TileDataSlots, UpdateKind, DataSlotVal}
|
||||||
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
|
||||||
|
case class DataSlotItemStack(name: String, parent: TileDataSlots) extends DataSlotVal[ItemStack] {
|
||||||
|
var cval: ItemStack = null
|
||||||
|
|
||||||
|
override def update(v: ItemStack) = {
|
||||||
|
if (!ItemStack.areItemStacksEqual(v, cval)) {
|
||||||
|
cval = if (v == null) null else v.copy()
|
||||||
|
parent.dataSlotChanged(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def save(t: NBTTagCompound, kind: UpdateKind.Value) = {
|
||||||
|
val tag = new NBTTagCompound()
|
||||||
|
if (cval != null) cval.writeToNBT(tag)
|
||||||
|
t.setCompoundTag(name, tag)
|
||||||
|
}
|
||||||
|
def load(t: NBTTagCompound, kind: UpdateKind.Value) = cval = ItemStack.loadItemStackFromNBT(t.getCompoundTag(name))
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.data
|
||||||
|
|
||||||
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
|
import net.bdew.lib.data.base.{UpdateKind, TileDataSlots, DataSlotVal}
|
||||||
|
|
||||||
|
case class DataSlotString(name: String, parent: TileDataSlots, default: String = null) extends DataSlotVal[String] {
|
||||||
|
var cval: String = default
|
||||||
|
def save(t: NBTTagCompound, kind: UpdateKind.Value) = if (cval != null) t.setString(name, cval)
|
||||||
|
def load(t: NBTTagCompound, kind: UpdateKind.Value) = cval = if (t.hasKey(name)) t.getString(name) else null
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.data
|
||||||
|
|
||||||
|
import net.minecraftforge.fluids.{IFluidTank, FluidTank, FluidStack}
|
||||||
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
|
import net.bdew.lib.data.base.{UpdateKind, TileDataSlots, DataSlot}
|
||||||
|
|
||||||
|
abstract class DataSlotTankBase(sz: Int) extends FluidTank(sz) with IFluidTank with DataSlot {
|
||||||
|
var oldStack: FluidStack = null
|
||||||
|
var size: Int
|
||||||
|
|
||||||
|
parent.serverTick.listen(checkUpdate)
|
||||||
|
|
||||||
|
updateKind = Set(UpdateKind.GUI, UpdateKind.SAVE)
|
||||||
|
|
||||||
|
def checkUpdate() {
|
||||||
|
if (!isSame(oldStack, fluid)) {
|
||||||
|
oldStack = if (fluid == null) null else fluid.copy()
|
||||||
|
parent.dataSlotChanged(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def isSame(v1: FluidStack, v2: FluidStack): Boolean = {
|
||||||
|
if (v1 == null && v2 == null) return true
|
||||||
|
if (v1 == null || v2 == null) return false
|
||||||
|
return v1.isFluidStackIdentical(v2)
|
||||||
|
}
|
||||||
|
|
||||||
|
def save(t: NBTTagCompound, k: UpdateKind.Value) {
|
||||||
|
val tag = new NBTTagCompound()
|
||||||
|
writeToNBT(tag)
|
||||||
|
if (k == UpdateKind.GUI)
|
||||||
|
tag.setInteger("size", size)
|
||||||
|
t.setCompoundTag(name, tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
def load(t: NBTTagCompound, k: UpdateKind.Value) {
|
||||||
|
val tag = t.getCompoundTag(name)
|
||||||
|
readFromNBT(tag)
|
||||||
|
if (k == UpdateKind.GUI)
|
||||||
|
size = tag.getInteger("size")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case class DataSlotTank(name: String, parent: TileDataSlots, var size: Int) extends DataSlotTankBase(size)
|
||||||
|
|
||||||
|
case class DataSlotTankRestricted(name: String, parent: TileDataSlots, var size: Int, fluidID: Int) extends DataSlotTankBase(size) {
|
||||||
|
def fill(amount: Int, doFill: Boolean) = super.fill(new FluidStack(fluidID, amount), doFill)
|
||||||
|
|
||||||
|
override def fill(resource: FluidStack, doFill: Boolean): Int = {
|
||||||
|
if ((resource != null) && (resource.fluidID != fluidID)) return 0
|
||||||
|
return super.fill(resource, doFill)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.data.base
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.EntityPlayerMP
|
||||||
|
import net.bdew.lib.gui.BaseContainer
|
||||||
|
import net.minecraft.inventory.ICrafting
|
||||||
|
|
||||||
|
trait ContainerDataSlots extends BaseContainer {
|
||||||
|
val dataSource: TileDataSlots
|
||||||
|
var lastSentChange = dataSource.lastChange
|
||||||
|
|
||||||
|
override def addCraftingToCrafters(crafter: ICrafting) {
|
||||||
|
super.addCraftingToCrafters(crafter)
|
||||||
|
if (crafter.isInstanceOf[EntityPlayerMP]) {
|
||||||
|
val pkt = dataSource.getDataSlotPacket
|
||||||
|
crafter.asInstanceOf[EntityPlayerMP].playerNetServerHandler.sendPacketToPlayer(pkt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def detectAndSendChanges() {
|
||||||
|
super.detectAndSendChanges()
|
||||||
|
// only send updates every 10 ticks
|
||||||
|
if (dataSource.lastChange >= lastSentChange + 10 || (dataSource.lastChange > lastSentChange && lastSentChange + 10 < dataSource.worldObj.getTotalWorldTime)) {
|
||||||
|
lastSentChange = dataSource.lastChange
|
||||||
|
val pkt = dataSource.getDataSlotPacket
|
||||||
|
|
||||||
|
for (player <- players)
|
||||||
|
player.playerNetServerHandler.sendPacketToPlayer(pkt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.data.base
|
||||||
|
|
||||||
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base trait for all data slots
|
||||||
|
*/
|
||||||
|
trait DataSlot {
|
||||||
|
/**
|
||||||
|
* Tile Entity that owns this slot
|
||||||
|
* Accessed in constructor, so should be in parameters or a lazy val, otherwise will crash
|
||||||
|
*/
|
||||||
|
val parent: TileDataSlots
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unique name
|
||||||
|
* Accessed in constructor, so should be in parameters or a lazy val, otherwise will crash
|
||||||
|
*/
|
||||||
|
val name: String
|
||||||
|
|
||||||
|
parent.dataSlots += (name -> this)
|
||||||
|
|
||||||
|
// Where should it sync
|
||||||
|
var updateKind = Set(UpdateKind.GUI)
|
||||||
|
|
||||||
|
def save(t: NBTTagCompound, kind: UpdateKind.Value)
|
||||||
|
def load(t: NBTTagCompound, kind: UpdateKind.Value)
|
||||||
|
|
||||||
|
def setUpdate(vals: UpdateKind.Value*): this.type = {
|
||||||
|
updateKind = vals.toSet
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.data.base
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for data slots that hold numeric values
|
||||||
|
* adds convinience operators to modify the value
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class DataSlotNumeric[T](default: T)(implicit n: Numeric[T]) extends DataSlotVal[T] {
|
||||||
|
var cval = default
|
||||||
|
def +=(that: T) = update(n.plus(cval, that))
|
||||||
|
def -=(that: T) = update(n.minus(cval, that))
|
||||||
|
def *=(that: T) = update(n.times(cval, that))
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.data.base
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for data slots that hold values with ordering operators, adds more convinience operators
|
||||||
|
* TODO: Do i need this? normal operators can be used with the implicit conversion
|
||||||
|
*/
|
||||||
|
abstract class DataSlotOrdered[T](implicit n: Ordering[T]) extends DataSlotVal[T] {
|
||||||
|
def :>(that: T) = n.compare(cval, that) > 0
|
||||||
|
def :<(that: T) = n.compare(cval, that) < 0
|
||||||
|
def :>=(that: T) = n.compare(cval, that) >= 0
|
||||||
|
def :<=(that: T) = n.compare(cval, that) <= 0
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.data.base
|
||||||
|
|
||||||
|
import language.implicitConversions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base trait for data slots that hold primitive values
|
||||||
|
* Defines some convinience operators to access the value and an implicit conversion to the value
|
||||||
|
*/
|
||||||
|
|
||||||
|
trait DataSlotVal[T] extends DataSlot {
|
||||||
|
var cval: T
|
||||||
|
|
||||||
|
def isSame(v: T) = v == cval
|
||||||
|
|
||||||
|
def :=(that: T) = update(that)
|
||||||
|
|
||||||
|
def :!=(that: T) = cval != that
|
||||||
|
def :==(that: T) = cval == that
|
||||||
|
|
||||||
|
def update(v: T) {
|
||||||
|
if (!isSame(v)) {
|
||||||
|
cval = v
|
||||||
|
parent.dataSlotChanged(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object DataSlotVal {
|
||||||
|
implicit def slot2val[T](slot: DataSlotVal[T]): T = slot.cval
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.data.base
|
||||||
|
|
||||||
|
import net.minecraft.network.packet.Packet132TileEntityData
|
||||||
|
import scala.collection.mutable
|
||||||
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
|
import net.bdew.lib.tile.TileExtended
|
||||||
|
|
||||||
|
trait TileDataSlots extends TileExtended {
|
||||||
|
val dataSlots = mutable.HashMap.empty[String, DataSlot]
|
||||||
|
var lastChange = 0L
|
||||||
|
|
||||||
|
final val TRACE = true
|
||||||
|
|
||||||
|
def doSave(kind: UpdateKind.Value, t: NBTTagCompound) {
|
||||||
|
for ((n, s) <- dataSlots if s.updateKind.contains(kind)) {
|
||||||
|
s.save(t, kind)
|
||||||
|
if (TRACE) printf("%s: %s S=> %s\n".format(kind, n, t.getTag(n)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def doLoad(kind: UpdateKind.Value, t: NBTTagCompound) {
|
||||||
|
for ((n, s) <- dataSlots if s.updateKind.contains(kind)) {
|
||||||
|
if (TRACE) printf("%s: %s L<= %s\n".format(kind, n, t.getTag(n)))
|
||||||
|
s.load(t, kind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
persistSave.listen(doSave(UpdateKind.SAVE, _))
|
||||||
|
persistLoad.listen(doLoad(UpdateKind.SAVE, _))
|
||||||
|
sendClientUpdate.listen(doSave(UpdateKind.WORLD, _))
|
||||||
|
handleClientUpdate.listen(doLoad(UpdateKind.WORLD, _))
|
||||||
|
|
||||||
|
def dataSlotChanged(slot: DataSlot) {
|
||||||
|
if (worldObj != null) {
|
||||||
|
if (slot.updateKind.contains(UpdateKind.GUI))
|
||||||
|
lastChange = worldObj.getTotalWorldTime
|
||||||
|
if (slot.updateKind.contains(UpdateKind.WORLD))
|
||||||
|
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord)
|
||||||
|
if (slot.updateKind.contains(UpdateKind.SAVE))
|
||||||
|
worldObj.markTileEntityChunkModified(xCoord, yCoord, zCoord, this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def getDataSlotPacket: Packet132TileEntityData = {
|
||||||
|
val tag = new NBTTagCompound()
|
||||||
|
doSave(UpdateKind.GUI, tag)
|
||||||
|
return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, ACT_GUI, tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
override protected def extDataPacket(id: Int, data: NBTTagCompound) {
|
||||||
|
if (id == ACT_GUI)
|
||||||
|
doLoad(UpdateKind.GUI, data)
|
||||||
|
super.extDataPacket(id, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.data.base
|
||||||
|
|
||||||
|
object UpdateKind extends Enumeration {
|
||||||
|
val WORLD = Value("WORLD")
|
||||||
|
val GUI = Value("GUI")
|
||||||
|
val SAVE = Value("SAVE")
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.gui
|
||||||
|
|
||||||
|
import net.minecraft.inventory.{IInventory, Slot, Container}
|
||||||
|
import net.minecraft.entity.player.{EntityPlayerMP, EntityPlayer, InventoryPlayer}
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.bdew.lib.items.ItemUtils
|
||||||
|
import net.bdew.lib.Misc
|
||||||
|
|
||||||
|
abstract class BaseContainer(te: IInventory) extends Container {
|
||||||
|
|
||||||
|
import scala.collection.JavaConversions._
|
||||||
|
|
||||||
|
def players = Misc.filterType(crafters, classOf[EntityPlayerMP])
|
||||||
|
|
||||||
|
protected def bindPlayerInventory(inv: InventoryPlayer, xOffs: Int, yOffsInv: Int, yOffsHotbar: Int) {
|
||||||
|
for (i <- 0 until 3; j <- 0 until 9)
|
||||||
|
addSlotToContainer(new Slot(inv, j + i * 9 + 9, xOffs + j * 18, yOffsInv + i * 18))
|
||||||
|
|
||||||
|
for (i <- 0 until 9)
|
||||||
|
addSlotToContainer(new Slot(inv, i, xOffs + i * 18, yOffsHotbar))
|
||||||
|
}
|
||||||
|
|
||||||
|
override def transferStackInSlot(player: EntityPlayer, slot: Int): ItemStack = {
|
||||||
|
var stack = getSlot(slot).getStack
|
||||||
|
if (getSlot(slot).inventory == player.inventory) {
|
||||||
|
stack = ItemUtils.addStackToSlots(stack, te, 0 until te.getSizeInventory, true)
|
||||||
|
} else {
|
||||||
|
stack = ItemUtils.addStackToSlots(stack, player.inventory, 9 until player.inventory.mainInventory.length, true)
|
||||||
|
// Only put in hotbar if the rest is full
|
||||||
|
if (stack != null)
|
||||||
|
stack = ItemUtils.addStackToSlots(stack, player.inventory, 0 until 9, true)
|
||||||
|
}
|
||||||
|
getSlot(slot).putStack(stack)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.gui
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.inventory.GuiContainer
|
||||||
|
import net.minecraft.inventory.Container
|
||||||
|
import scala.collection.mutable
|
||||||
|
import net.minecraft.client.gui.GuiButton
|
||||||
|
import net.bdew.lib.gui.widgets.Widget
|
||||||
|
import net.minecraft.util.ResourceLocation
|
||||||
|
import org.lwjgl.opengl.GL11
|
||||||
|
|
||||||
|
abstract class BaseScreen(cont: Container, xSz: Int, ySz: Int) extends GuiContainer(cont) {
|
||||||
|
xSize = xSz
|
||||||
|
ySize = ySz
|
||||||
|
|
||||||
|
val widgets = mutable.MutableList.empty[Widget]
|
||||||
|
val texture: ResourceLocation
|
||||||
|
|
||||||
|
def rect = new Rect(guiLeft, guiTop, xSize, ySize)
|
||||||
|
|
||||||
|
def getFontRenderer = fontRenderer
|
||||||
|
|
||||||
|
override def initGui() {
|
||||||
|
super.initGui()
|
||||||
|
widgets.clear()
|
||||||
|
buttonList.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
def addButton[T <: GuiButton](w: T): T = {
|
||||||
|
buttonList.asInstanceOf[java.util.ArrayList[GuiButton]].add(w)
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
def addWidget[T <: Widget](w: T): T = {
|
||||||
|
widgets += w
|
||||||
|
w.parent = this
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override def keyTyped(c: Char, i: Int) {
|
||||||
|
for (w <- widgets)
|
||||||
|
if (w.keyTyped(c, i))
|
||||||
|
return
|
||||||
|
super.keyTyped(c, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override def mouseClicked(x: Int, y: Int, bt: Int) {
|
||||||
|
super.mouseClicked(x, y, bt)
|
||||||
|
val p = new Point(x, y) - rect.origin
|
||||||
|
for (w <- widgets if w.rect.contains(p))
|
||||||
|
w.mouseClicked(p - w.rect.origin, bt)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override def drawGuiContainerForegroundLayer(x: Int, y: Int) {
|
||||||
|
for (w <- widgets)
|
||||||
|
w.draw()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override def drawScreen(x: Int, y: Int, f: Float) {
|
||||||
|
super.drawScreen(x, y, f)
|
||||||
|
|
||||||
|
val tip = mutable.MutableList.empty[String]
|
||||||
|
|
||||||
|
val p = new Point(x, y) - rect.origin
|
||||||
|
for (w <- widgets if w.rect.contains(p))
|
||||||
|
w.handleTooltip(p - w.rect.origin, tip)
|
||||||
|
|
||||||
|
import collection.JavaConversions._
|
||||||
|
|
||||||
|
if (tip.size > 0)
|
||||||
|
drawHoveringText(tip, x, y, fontRenderer)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected def drawGuiContainerBackgroundLayer(f: Float, i: Int, j: Int) {
|
||||||
|
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F)
|
||||||
|
mc.renderEngine.bindTexture(texture)
|
||||||
|
val x = (width - xSize) / 2
|
||||||
|
val y = (height - ySize) / 2
|
||||||
|
this.drawTexturedModalRect(x, y, 0, 0, xSize, ySize)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.gui
|
||||||
|
|
||||||
|
object Direction extends Enumeration {
|
||||||
|
type Direction = Value
|
||||||
|
val UP = Value("UP")
|
||||||
|
val DOWN = Value("UP")
|
||||||
|
val LEFT = Value("UP")
|
||||||
|
val RIGHT = Value("UP")
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.gui
|
||||||
|
|
||||||
|
class Point(val x: Int, val y: Int) {
|
||||||
|
def this(p: Point) = this(p.x, p.y)
|
||||||
|
def +(that: Point) = new Point(this.x + that.x, this.y + that.y)
|
||||||
|
def -(that: Point) = new Point(this.x - that.x, this.y - that.y)
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.gui
|
||||||
|
|
||||||
|
class Rect(val x: Int, val y: Int, val w: Int, val h: Int) {
|
||||||
|
def this(p: Point, w: Int, h: Int) = this(p.x, p.y, w, h)
|
||||||
|
def contains(p: Point) = p.x >= x && p.y >= y && p.x <= x + w && p.y <= y + h
|
||||||
|
def origin = new Point(x, y)
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.gui
|
||||||
|
|
||||||
|
import net.minecraft.inventory.IInventory
|
||||||
|
import net.minecraft.inventory.Slot
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
|
||||||
|
class SlotValidating(inv: IInventory, slot: Int, x: Int, y: Int) extends Slot(inv, slot, x, y) {
|
||||||
|
override def isItemValid(stack: ItemStack) = inventory.isItemValidForSlot(getSlotIndex, stack)
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.gui
|
||||||
|
|
||||||
|
import net.minecraft.util.ResourceLocation
|
||||||
|
|
||||||
|
class TextureLocation(val resource: ResourceLocation, val p: Point) extends Point(p.x, p.y) {
|
||||||
|
def this(resource: ResourceLocation, x: Int, y: Int) = this(resource, new Point(x, y))
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.gui.widgets
|
||||||
|
|
||||||
|
import scala.collection.mutable
|
||||||
|
import net.bdew.lib.gui.{Point, BaseScreen, Rect}
|
||||||
|
import net.minecraft.util.ResourceLocation
|
||||||
|
import net.minecraft.client.Minecraft
|
||||||
|
|
||||||
|
trait Widget {
|
||||||
|
val rect: Rect
|
||||||
|
var parent: BaseScreen = null
|
||||||
|
def handleTooltip(p: Point, tip: mutable.MutableList[String]) {}
|
||||||
|
def mouseClicked(p: Point, button: Int) {}
|
||||||
|
def keyTyped(c: Char, i: Int): Boolean = false
|
||||||
|
def draw() {}
|
||||||
|
|
||||||
|
def bindTexture(res: ResourceLocation) = Minecraft.getMinecraft.renderEngine.bindTexture(res)
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.gui.widgets
|
||||||
|
|
||||||
|
import net.bdew.lib.gui.{TextureLocation, Rect}
|
||||||
|
import net.bdew.lib.gui.Direction
|
||||||
|
import net.bdew.lib.data.base.DataSlotNumeric
|
||||||
|
|
||||||
|
class WidgetFillDataslot[T](val rect: Rect, val texture: TextureLocation, dir: Direction.Direction, dslot: DataSlotNumeric[T], maxval: T)(implicit num: Numeric[T]) extends Widget {
|
||||||
|
|
||||||
|
def getFillArea(max: Int): Int = (num.toFloat(dslot) / num.toFloat(maxval) * max).round
|
||||||
|
|
||||||
|
override def draw() {
|
||||||
|
bindTexture(texture.resource)
|
||||||
|
dir match {
|
||||||
|
case Direction.UP =>
|
||||||
|
val fill = getFillArea(rect.h)
|
||||||
|
parent.drawTexturedModalRect(rect.x, rect.y + rect.h - fill, texture.x, texture.y + rect.h - fill, rect.w, fill)
|
||||||
|
case Direction.DOWN =>
|
||||||
|
val fill = getFillArea(rect.h)
|
||||||
|
parent.drawTexturedModalRect(rect.x, rect.y, texture.x, texture.y, rect.w, fill)
|
||||||
|
case Direction.LEFT =>
|
||||||
|
val fill = getFillArea(rect.w)
|
||||||
|
parent.drawTexturedModalRect(rect.x + rect.w - fill, rect.y, texture.x + rect.w - fill, texture.y, fill, rect.h)
|
||||||
|
case Direction.RIGHT =>
|
||||||
|
val fill = getFillArea(rect.w)
|
||||||
|
parent.drawTexturedModalRect(rect.x, rect.y, texture.x, texture.y, fill, rect.h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.gui.widgets
|
||||||
|
|
||||||
|
import net.bdew.lib.gui.{Point, TextureLocation, Rect}
|
||||||
|
import net.bdew.lib.data.DataSlotTankBase
|
||||||
|
import scala.collection.mutable
|
||||||
|
import net.minecraft.client.renderer.texture.TextureMap
|
||||||
|
import java.text.DecimalFormat
|
||||||
|
import net.bdew.lib.Misc
|
||||||
|
import org.lwjgl.opengl.GL11
|
||||||
|
|
||||||
|
class WidgetFluidGauge(val rect: Rect, overlay: TextureLocation, dslot: DataSlotTankBase) extends Widget {
|
||||||
|
val formater = new DecimalFormat("#,###")
|
||||||
|
|
||||||
|
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) {
|
||||||
|
if (dslot.getFluid != null) {
|
||||||
|
tip += dslot.getFluid.getFluid.getLocalizedName
|
||||||
|
tip += "%s/%s mB".format(formater.format(dslot.getFluidAmount), formater.format(dslot.getCapacity))
|
||||||
|
} else {
|
||||||
|
tip += Misc.toLocal("gendustry.label.empty")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def draw() {
|
||||||
|
GL11.glEnable(GL11.GL_BLEND)
|
||||||
|
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA)
|
||||||
|
|
||||||
|
val fstack = dslot.getFluid
|
||||||
|
if (fstack != null && fstack.getFluid.getStillIcon != null) {
|
||||||
|
val icon = fstack.getFluid.getStillIcon
|
||||||
|
bindTexture(TextureMap.locationBlocksTexture)
|
||||||
|
var fillHeight: Int = (rect.h * fstack.amount / dslot.getCapacity).round
|
||||||
|
var yStart: Int = 0
|
||||||
|
|
||||||
|
while (fillHeight > 0) {
|
||||||
|
if (fillHeight > 16) {
|
||||||
|
parent.drawTexturedModelRectFromIcon(rect.x, rect.y + rect.h - 16 - yStart, icon, 16, 16)
|
||||||
|
fillHeight -= 16
|
||||||
|
} else {
|
||||||
|
parent.drawTexturedModelRectFromIcon(rect.x, rect.y + rect.h - fillHeight - yStart, icon, 16, fillHeight)
|
||||||
|
fillHeight = 0
|
||||||
|
}
|
||||||
|
yStart = yStart + 16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GL11.glDisable(GL11.GL_BLEND)
|
||||||
|
|
||||||
|
bindTexture(overlay.resource)
|
||||||
|
parent.drawTexturedModalRect(rect.x, rect.y, overlay.x, overlay.y, rect.w, rect.h)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.gui.widgets
|
||||||
|
|
||||||
|
import net.bdew.lib.gui.Rect
|
||||||
|
|
||||||
|
class WidgetLabel(text: String, x: Int, y: Int, color: Int) extends Widget {
|
||||||
|
val rect: Rect = new Rect(x, y, 0, 0)
|
||||||
|
override def draw() {
|
||||||
|
parent.getFontRenderer.drawString(text, x, y, color)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.gui.widgets
|
||||||
|
|
||||||
|
import net.bdew.lib.gui.{Point, Direction, TextureLocation, Rect}
|
||||||
|
import net.bdew.lib.data.DataSlotFloat
|
||||||
|
import scala.collection.mutable
|
||||||
|
|
||||||
|
class WidgetProgressBar(rect: Rect, texture: TextureLocation, dslot: DataSlotFloat) extends WidgetFillDataslot[Float](rect, texture, Direction.RIGHT, dslot, 1) {
|
||||||
|
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) = tip += "%.0f".format(dslot.cval * 100) + "%"
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.gui.widgets
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.{FontRenderer, GuiTextField}
|
||||||
|
import net.bdew.lib.gui.{Point, Rect}
|
||||||
|
|
||||||
|
class WidgetTextEdit(val rect: Rect, fr: FontRenderer) extends GuiTextField(fr, rect.x, rect.y, rect.w, rect.h) with Widget {
|
||||||
|
override def mouseClicked(p: Point, button: Int) = super.mouseClicked(p.x + rect.x, p.y + rect.y, button)
|
||||||
|
override def keyTyped(c: Char, i: Int): Boolean = super.textboxKeyTyped(c, i)
|
||||||
|
override def draw() = super.drawTextBox()
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.items
|
||||||
|
|
||||||
|
import net.minecraft.entity.item.EntityItem
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.world.World
|
||||||
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
|
import net.minecraft.inventory.IInventory
|
||||||
|
import net.bdew.lib.Misc
|
||||||
|
|
||||||
|
object ItemUtils {
|
||||||
|
def throwItemAt(world: World, x: Int, y: Int, z: Int, stack: ItemStack) {
|
||||||
|
if ((stack == null) || world.isRemote) return
|
||||||
|
val dx = world.rand.nextFloat * 0.8
|
||||||
|
val dy = world.rand.nextFloat * 0.8
|
||||||
|
val dz = world.rand.nextFloat * 0.8
|
||||||
|
val entityitem: EntityItem = new EntityItem(world, x + dx, y + dy, z + dz, stack)
|
||||||
|
entityitem.motionX = world.rand.nextGaussian * 0.05
|
||||||
|
entityitem.motionY = world.rand.nextGaussian * 0.05 + 0.2
|
||||||
|
entityitem.motionZ = world.rand.nextGaussian * 0.05
|
||||||
|
world.spawnEntityInWorld(entityitem)
|
||||||
|
}
|
||||||
|
|
||||||
|
def dropItemToPlayer(world: World, player: EntityPlayer, stack: ItemStack) {
|
||||||
|
if ((stack == null) || world.isRemote) return
|
||||||
|
world.spawnEntityInWorld(new EntityItem(world, player.posX, player.posY, player.posZ, stack))
|
||||||
|
}
|
||||||
|
|
||||||
|
def isSameItem(stack1: ItemStack, stack2: ItemStack): Boolean = {
|
||||||
|
if (stack1 == null || stack2 == null)
|
||||||
|
return stack1 == stack2
|
||||||
|
if (stack1.itemID != stack2.itemID)
|
||||||
|
return false
|
||||||
|
if (stack1.getHasSubtypes && stack2.getItemDamage != stack1.getItemDamage)
|
||||||
|
return false
|
||||||
|
return ItemStack.areItemStackTagsEqual(stack2, stack1)
|
||||||
|
}
|
||||||
|
|
||||||
|
def addStackToSlots(stack: ItemStack, inv: IInventory, slots: Iterable[Int], checkvalid: Boolean): ItemStack = {
|
||||||
|
if (stack == null) return null
|
||||||
|
|
||||||
|
// Try merging into existing slots
|
||||||
|
for (slot <- slots if (!checkvalid || inv.isItemValidForSlot(slot, stack)) && isSameItem(stack, inv.getStackInSlot(slot))) {
|
||||||
|
val target = inv.getStackInSlot(slot)
|
||||||
|
val toAdd = Misc.min(target.getMaxStackSize - target.stackSize, inv.getInventoryStackLimit - target.stackSize, stack.stackSize)
|
||||||
|
if (toAdd >= stack.stackSize) {
|
||||||
|
target.stackSize += stack.stackSize
|
||||||
|
stack.stackSize = 0
|
||||||
|
inv.onInventoryChanged()
|
||||||
|
return null
|
||||||
|
} else if (toAdd > 0) {
|
||||||
|
target.stackSize += toAdd
|
||||||
|
stack.stackSize -= toAdd
|
||||||
|
inv.onInventoryChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now find empty slots and stick any leftovers there
|
||||||
|
for (slot <- slots if (!checkvalid || inv.isItemValidForSlot(slot, stack)) && inv.getStackInSlot(slot) == null) {
|
||||||
|
if (inv.getInventoryStackLimit < stack.stackSize) {
|
||||||
|
inv.setInventorySlotContents(slot, stack.splitStack(inv.getInventoryStackLimit))
|
||||||
|
} else {
|
||||||
|
inv.setInventorySlotContents(slot, stack.copy())
|
||||||
|
stack.stackSize = 0
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stack
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,181 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.recipes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for everything that can be resolved to ItemStack or recipe component
|
||||||
|
* Actual processing is in:
|
||||||
|
* * [[net.bdew.lib.recipes.RecipeLoader.getRecipeComponent]]
|
||||||
|
* * [[net.bdew.lib.recipes.RecipeLoader.getConcreteStack]]
|
||||||
|
* * [[net.bdew.lib.recipes.RecipeLoader.getAllConcreteStacks]]
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
abstract class StackRef
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ore Dictionary reference
|
||||||
|
* Syntax: OD:{identifier}
|
||||||
|
* Parser: [[net.bdew.lib.recipes.RecipeParser.specOD]]
|
||||||
|
* @param id OD entry name
|
||||||
|
*/
|
||||||
|
case class StackOreDict(id: String) extends StackRef
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mod item reference [[cpw.mods.fml.common.registry.GameRegistry.findItemStack]]
|
||||||
|
* Syntax: {modID}:{name}
|
||||||
|
* Parser: [[net.bdew.lib.recipes.RecipeParser.specModStack]]
|
||||||
|
* @param mod modId of owner mod
|
||||||
|
* @param id name of the stack
|
||||||
|
*/
|
||||||
|
case class StackMod(mod: String, id: String) extends StackRef
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vanilla block reference
|
||||||
|
* Syntax: B:{name} [@ {meta}]
|
||||||
|
* Parser: [[net.bdew.lib.recipes.RecipeParser.specMcBlock]]
|
||||||
|
* @param name Unlocalized name (without "tile.")
|
||||||
|
* @param meta Metadata / Damage
|
||||||
|
*/
|
||||||
|
case class StackMCBlock(name: String, meta: Int) extends StackRef
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vanilla item reference
|
||||||
|
* Syntax: I:{name} [@ {meta}]
|
||||||
|
* Parser: [[net.bdew.lib.recipes.RecipeParser.specMcItem]]
|
||||||
|
* @param name Unlocalized name (without "item.")
|
||||||
|
* @param meta Metadata / Damage
|
||||||
|
*/
|
||||||
|
case class StackMCItem(name: String, meta: Int) extends StackRef
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to an Item/Block/ItemStack pulic static field
|
||||||
|
* Syntax: {path}.{to}.{class}[{field}] [@ {meta}]
|
||||||
|
* Parser: [[net.bdew.lib.recipes.RecipeParser.specReflect]]
|
||||||
|
* @param cls Class name
|
||||||
|
* @param field Field name
|
||||||
|
* @param meta Metadata / Damage (Ignored for ItemStacks)
|
||||||
|
*/
|
||||||
|
case class StackReflect(cls: String, field: String, meta: Int) extends StackRef
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to an Item/Block/ItemStack pulic static getter
|
||||||
|
* Syntax: {path}.{to}.{class}.{method}({string}) [@ {meta}]
|
||||||
|
* Parser: [[net.bdew.lib.recipes.RecipeParser.specGetter]]
|
||||||
|
* @param cls Class name
|
||||||
|
* @param method Method name
|
||||||
|
* @param name Parameter to getter
|
||||||
|
* @param meta Metadata / Damage (Ignored for ItemStacks)
|
||||||
|
*/
|
||||||
|
case class StackGetter(cls: String, method: String, name: String, meta: Int) extends StackRef
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Macro reference to a previous definition
|
||||||
|
* Syntax: ${char}
|
||||||
|
* Parser: [[net.bdew.lib.recipes.RecipeParser.specMacro]]
|
||||||
|
* @param id The underlying character
|
||||||
|
*/
|
||||||
|
case class StackMacro(id: Char) extends StackRef
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for statements
|
||||||
|
* Actual processing is in [[net.bdew.lib.recipes.RecipeLoader.processStatement]]
|
||||||
|
*/
|
||||||
|
abstract class Statement
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Character assignment
|
||||||
|
* Syntax: {char} = {ref}
|
||||||
|
* Parser: [[net.bdew.lib.recipes.RecipeParser.charSpec]]
|
||||||
|
* @param char Character to assign
|
||||||
|
* @param spec ItemStack Reference
|
||||||
|
*/
|
||||||
|
case class StCharAssign(char: Char, spec: StackRef) extends Statement
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define class macro
|
||||||
|
* Syntax: def {id} = {name}
|
||||||
|
* Parser: [[net.bdew.lib.recipes.RecipeParser.classMacro]]
|
||||||
|
* @param id Macro identifier
|
||||||
|
* @param cls Class name
|
||||||
|
*/
|
||||||
|
case class StClassMacro(id: String, cls: String) extends Statement
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conditional block - checks if mod is loaded
|
||||||
|
* Syntax: ifMod {string} { {statements} } [else { {statements} }]
|
||||||
|
* Parser: [[net.bdew.lib.recipes.RecipeParser.ifMod]]
|
||||||
|
* @param mod mod and version to check [[cpw.mods.fml.common.versioning.VersionParser]]
|
||||||
|
* @param thn Statements to run if present
|
||||||
|
* @param els Statements to run otherwise
|
||||||
|
*/
|
||||||
|
case class StIfHaveMod(mod: String, thn: List[Statement], els: List[Statement]) extends Statement
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conditional block - checks if mod is loaded
|
||||||
|
* Syntax: ifOreDict {string} { {statements} } [else { {statements} }]
|
||||||
|
* Parser: [[net.bdew.lib.recipes.RecipeParser.ifOreDict]]
|
||||||
|
* @param id Ore Dictionary Entry
|
||||||
|
* @param thn Statements to run if present
|
||||||
|
* @param els Statements to run otherwise
|
||||||
|
*/
|
||||||
|
case class StIfHaveOD(id: String, thn: List[Statement], els: List[Statement]) extends Statement
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shaped recipe definition
|
||||||
|
*
|
||||||
|
* Syntax:
|
||||||
|
* XXX
|
||||||
|
* XXX => {result} [* {count}]
|
||||||
|
* XXX
|
||||||
|
*
|
||||||
|
* Parser: [[net.bdew.lib.recipes.RecipeParser.recipeShaped3x3]]
|
||||||
|
*
|
||||||
|
* Syntax:
|
||||||
|
* XX
|
||||||
|
* XX => {result} [* {count}]
|
||||||
|
*
|
||||||
|
* Parser: [[net.bdew.lib.recipes.RecipeParser.recipeShaped2x2]]
|
||||||
|
*
|
||||||
|
* Syntax: XXX XXX XXX => {result} [* {count}]
|
||||||
|
* Parser: [[net.bdew.lib.recipes.RecipeParser.recipeShaped9]]
|
||||||
|
*
|
||||||
|
* @param rec Recipe pattern
|
||||||
|
* @param res Result reference
|
||||||
|
* @param cnt Number of output items
|
||||||
|
*/
|
||||||
|
case class StRecipeShaped(rec: Seq[String], res: StackRef, cnt: Int) extends Statement
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shapeless recipe definition
|
||||||
|
* Syntax: shapeless: {characters} => {result} [* {count}]
|
||||||
|
* Parser: [[net.bdew.lib.recipes.RecipeParser.recipeShapeless]]
|
||||||
|
*
|
||||||
|
* @param rec Recipe pattehrn
|
||||||
|
* @param res Result reference
|
||||||
|
* @param cnt Number of output items
|
||||||
|
*/
|
||||||
|
case class StRecipeShapeless(rec: String, res: StackRef, cnt: Int) extends Statement
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smelting recipe definition
|
||||||
|
* Syntax: smelt: {input} => {output}, {XP}
|
||||||
|
* Parser [[net.bdew.lib.recipes.RecipeParser.recipeSmelting]]
|
||||||
|
*
|
||||||
|
* @param in Input Stack
|
||||||
|
* @param out Output Stack
|
||||||
|
* @param cnt Output Count
|
||||||
|
* @param xp XP for smelting
|
||||||
|
*/
|
||||||
|
case class StSmeltRecipe(in: StackRef, out: StackRef, cnt: Int, xp: Float) extends Statement
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used in statement processing to abort the current statement and show an error without a stack trace
|
||||||
|
*/
|
||||||
|
class StatementError(msg: String) extends Exception(msg)
|
||||||
@@ -0,0 +1,319 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.recipes
|
||||||
|
|
||||||
|
import java.io.Reader
|
||||||
|
import net.minecraft.item.{Item, ItemStack}
|
||||||
|
import net.bdew.lib.Misc
|
||||||
|
import net.minecraft.block.Block
|
||||||
|
import cpw.mods.fml.common.registry.GameRegistry
|
||||||
|
import net.minecraftforge.oredict.{ShapelessOreRecipe, OreDictionary}
|
||||||
|
import java.util.logging.Logger
|
||||||
|
import cpw.mods.fml.common.FMLLog
|
||||||
|
import net.minecraft.item.crafting.FurnaceRecipes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main recipe loader class
|
||||||
|
* The input file is parsed by [[net.bdew.lib.recipes.RecipeParser]]
|
||||||
|
* Into a list of [[net.bdew.lib.recipes.Statement]] subclasses
|
||||||
|
* That are then executed here
|
||||||
|
*/
|
||||||
|
|
||||||
|
class RecipeLoader {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new parser, override in subclasses to use an extended parser
|
||||||
|
* @return New ConfigParser (or subclass) instance
|
||||||
|
*/
|
||||||
|
def newParser() = new RecipeParser()
|
||||||
|
|
||||||
|
val log: Logger = Logger.getLogger("RecipeLoader")
|
||||||
|
log.setParent(FMLLog.getLogger)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current map of recipe characters to parser item references
|
||||||
|
*/
|
||||||
|
val currCharMap = collection.mutable.Map.empty[Char, StackRef].withDefault(x => error("Undefined recipe character '%s'", x))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current map of class macros
|
||||||
|
*/
|
||||||
|
val currClassMacros = collection.mutable.Map.empty[String, String].withDefault(x => error("Undefined class macro '%s'", x))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggers an error with formatted string
|
||||||
|
*/
|
||||||
|
def error(msg: String, params: Any*) = throw new StatementError(msg.format(params: _*))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks up a recipe component
|
||||||
|
* @param s Parser ItemStack reference
|
||||||
|
* @return ItemStack or String that can be used as recipe components in MC functions
|
||||||
|
*/
|
||||||
|
def getRecipeComponent(s: StackRef): AnyRef = s match {
|
||||||
|
case StackOreDict(id) => id
|
||||||
|
case StackMacro(ch) => getRecipeComponent(currCharMap(ch))
|
||||||
|
case _ => getConcreteStack(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve class name if it's a macro
|
||||||
|
*/
|
||||||
|
def getRealClassName(s: String): String = {
|
||||||
|
if (s.startsWith("$")) {
|
||||||
|
return currClassMacros(s.stripPrefix("$"))
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sanitize items from reflection
|
||||||
|
* @param x The item
|
||||||
|
* @param source Human readable source (used in errors and warnings)
|
||||||
|
* @param meta Metadata or damage
|
||||||
|
* @param cnt Stack size
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
def sanitizeReflectedItem(x: AnyRef, source: String, meta: Int, cnt: Int): ItemStack = x match {
|
||||||
|
case x: ItemStack =>
|
||||||
|
val l = x.copy()
|
||||||
|
l.stackSize = cnt
|
||||||
|
if (meta != OreDictionary.WILDCARD_VALUE && meta != l.getItemDamage) {
|
||||||
|
log.warning("%s requested with meta %d but specifies %d".format(source, meta, l.getItemDamage))
|
||||||
|
l.setItemDamage(meta)
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
case x: Item =>
|
||||||
|
return new ItemStack(x, cnt, meta)
|
||||||
|
case x: Block =>
|
||||||
|
return new ItemStack(x, cnt, meta)
|
||||||
|
case _ =>
|
||||||
|
error("%s is %s which cannot be translated to an ItemStack", source, x.getClass.getName)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches an ItemStack using reflection from static fields
|
||||||
|
* Item and Block instaces are converted to ItemStacks
|
||||||
|
* @param clsName Name of class to fetch from (can be a class macro)
|
||||||
|
* @param fldName Field name
|
||||||
|
* @param meta Metadata or damage
|
||||||
|
* @param cnt Stack size
|
||||||
|
* @return Matching itemstack
|
||||||
|
*/
|
||||||
|
def reflectStack(clsName: String, fldName: String, meta: Int, cnt: Int): ItemStack = {
|
||||||
|
val realName = getRealClassName(clsName)
|
||||||
|
val cls = Class.forName(realName)
|
||||||
|
val fld = cls.getField(fldName).get(null)
|
||||||
|
return sanitizeReflectedItem(fld, "%s.%s".format(realName, fldName), meta, cnt)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches an ItemStack using reflection from static getters
|
||||||
|
* Item and Block instaces are converted to ItemStacks
|
||||||
|
* @param clsName Name of class to fetch from (can be a class macro)
|
||||||
|
* @param method Method name
|
||||||
|
* @param param Parameter to method
|
||||||
|
* @param meta Metadata or damage
|
||||||
|
* @param cnt Stack size
|
||||||
|
* @return Matching itemstack
|
||||||
|
*/
|
||||||
|
def reflectStackGetter(clsName: String, method: String, param: String, meta: Int, cnt: Int): ItemStack = {
|
||||||
|
var realName: String = clsName
|
||||||
|
var realMethod: String = method
|
||||||
|
|
||||||
|
//Some acrobatics to allow use with macros, even bare ones like $foo(bar)
|
||||||
|
|
||||||
|
if ((realName.length == 0) && realMethod.startsWith("$")) {
|
||||||
|
val v = getRealClassName(realMethod).split('.').reverse
|
||||||
|
realName = v.tail.reverse.mkString(".")
|
||||||
|
realMethod = v.head
|
||||||
|
}
|
||||||
|
if (realName.startsWith("$")) {
|
||||||
|
realName = getRealClassName(clsName)
|
||||||
|
}
|
||||||
|
|
||||||
|
val cls = Class.forName(realName)
|
||||||
|
val meth = cls.getMethod(realMethod, classOf[String])
|
||||||
|
val res = meth.invoke(null, param)
|
||||||
|
return sanitizeReflectedItem(res, "%s.%s(%s)".format(realName, realMethod, param), meta, cnt)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all possible ItemStacks that match a reference
|
||||||
|
* Currently everything except OreDictionary references just returns one item
|
||||||
|
* @param s Parser ItemStack reference
|
||||||
|
* @param cnt Stack size
|
||||||
|
* @return List of matching ItemStacks
|
||||||
|
*/
|
||||||
|
def getAllConcreteStacks(s: StackRef, cnt: Int = 1): Iterable[ItemStack] = s match {
|
||||||
|
case StackOreDict(id) =>
|
||||||
|
import scala.collection.JavaConversions._
|
||||||
|
val c = OreDictionary.getOres(id).map(_.copy())
|
||||||
|
c.foreach(_.stackSize = cnt)
|
||||||
|
return c
|
||||||
|
case _ => Seq(getConcreteStack(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an ItemStack that match a reference
|
||||||
|
* This is the main StackRef resolution method
|
||||||
|
* @param s Parser ItemStack reference
|
||||||
|
* @param cnt Stack size
|
||||||
|
* @return A matching ItemStack
|
||||||
|
*/
|
||||||
|
def getConcreteStack(s: StackRef, cnt: Int = 1): ItemStack = s match {
|
||||||
|
case StackOreDict(id) =>
|
||||||
|
val l = OreDictionary.getOres(id)
|
||||||
|
if (l.size == 0) error("Concrete ItemStack requested for OD entry '%s' that is empty", id)
|
||||||
|
val s = l.get(0).copy()
|
||||||
|
s.stackSize = cnt
|
||||||
|
log.info("Concrete ItemStack for OD entry '%s' -> %s".format(id, s))
|
||||||
|
return s
|
||||||
|
case StackMacro(ch) => getConcreteStack(currCharMap(ch), cnt)
|
||||||
|
case StackMod(mod, id) =>
|
||||||
|
val i = GameRegistry.findItemStack(mod, id, cnt)
|
||||||
|
if (i == null) error("Item %s:%s not found", mod, id)
|
||||||
|
i
|
||||||
|
case StackMCBlock(id, meta) => new ItemStack(Vanilla.blocks(id), cnt, meta)
|
||||||
|
case StackMCItem(id, meta) => new ItemStack(Vanilla.items(id), cnt, meta)
|
||||||
|
case StackReflect(cls, field, meta) => reflectStack(cls, field, meta, cnt)
|
||||||
|
case StackGetter(cls, method, param, meta) => reflectStackGetter(cls, method, param, meta, cnt)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks up all characters used in the recipe
|
||||||
|
* @param s The pattern
|
||||||
|
* @return Map from character to recipe components and a boolean that means OD-aware methods should be used
|
||||||
|
*/
|
||||||
|
def resolveRecipeComponents(s: Iterable[Char]): (Map[Char, AnyRef], Boolean) = {
|
||||||
|
var comp = Map.empty[Char, AnyRef]
|
||||||
|
var needOd = false
|
||||||
|
for (x <- s if !comp.contains(x) && x != '_') {
|
||||||
|
if (!currCharMap.contains(x)) error("Character %s is undefined", x)
|
||||||
|
val r = getRecipeComponent(currCharMap(x))
|
||||||
|
if (r.isInstanceOf[String]) needOd = true
|
||||||
|
log.info("%s -> %s".format(x, r))
|
||||||
|
comp += (x -> r)
|
||||||
|
}
|
||||||
|
return (comp, needOd)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a single statement, override this to add more statements
|
||||||
|
* @param s The statement
|
||||||
|
*/
|
||||||
|
def processStatement(s: Statement): Unit = s match {
|
||||||
|
case StCharAssign(c, r) =>
|
||||||
|
currCharMap(c) = r
|
||||||
|
log.info("Added %s = %s".format(c, r))
|
||||||
|
|
||||||
|
case StClassMacro(id, cls) =>
|
||||||
|
currClassMacros(id) = cls
|
||||||
|
log.info("Added def %s = %s".format(id, cls))
|
||||||
|
|
||||||
|
case StIfHaveMod(mod, thn, els) =>
|
||||||
|
if (Misc.haveModVersion(mod)) {
|
||||||
|
log.info("ifMod: %s found".format(mod))
|
||||||
|
processStatementsSafe(thn)
|
||||||
|
} else {
|
||||||
|
log.info("ifMod: %s not found".format(mod))
|
||||||
|
processStatementsSafe(els)
|
||||||
|
}
|
||||||
|
|
||||||
|
case StIfHaveOD(od, thn, els) =>
|
||||||
|
if (OreDictionary.getOres(od).size() > 0) {
|
||||||
|
log.info("ifOreDict: %s found".format(od))
|
||||||
|
processStatementsSafe(thn)
|
||||||
|
} else {
|
||||||
|
log.info("ifOreDict: %s not found".format(od))
|
||||||
|
processStatementsSafe(els)
|
||||||
|
}
|
||||||
|
|
||||||
|
case StRecipeShaped(rec, res, cnt) =>
|
||||||
|
log.info("Adding shaped recipe %s => %s * %d".format(rec, res, cnt))
|
||||||
|
val (comp, needOd) = resolveRecipeComponents(rec.mkString(""))
|
||||||
|
val resStack = getConcreteStack(res, cnt)
|
||||||
|
|
||||||
|
if (resStack.getItemDamage == OreDictionary.WILDCARD_VALUE) {
|
||||||
|
log.info("Result meta is unset, defaulting to 0")
|
||||||
|
resStack.setItemDamage(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needOd)
|
||||||
|
Misc.addRecipeOD(resStack, rec, comp)
|
||||||
|
else
|
||||||
|
Misc.addRecipe(resStack, rec, comp)
|
||||||
|
|
||||||
|
log.info("Done... result=%s, od=%s".format(resStack, needOd))
|
||||||
|
|
||||||
|
case StRecipeShapeless(rec, res, cnt) =>
|
||||||
|
log.info("Adding shapeless recipe %s => %s * %d".format(rec, res, cnt))
|
||||||
|
val (comp, needOd) = resolveRecipeComponents(rec)
|
||||||
|
val resStack = getConcreteStack(res, cnt)
|
||||||
|
val recTrans = rec.toCharArray.map(comp(_))
|
||||||
|
|
||||||
|
if (resStack.getItemDamage == OreDictionary.WILDCARD_VALUE) {
|
||||||
|
log.info("Result meta is unset, defaulting to 0")
|
||||||
|
resStack.setItemDamage(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needOd)
|
||||||
|
GameRegistry.addRecipe(new ShapelessOreRecipe(resStack, recTrans: _*))
|
||||||
|
else
|
||||||
|
GameRegistry.addShapelessRecipe(resStack, recTrans: _*)
|
||||||
|
|
||||||
|
log.info("Done... result=%s, od=%s".format(resStack, needOd))
|
||||||
|
|
||||||
|
case StSmeltRecipe(in, out, cnt, xp) =>
|
||||||
|
log.info("Adding smelting recipe %s => %s * %d (%f xp)".format(in, out, cnt, xp))
|
||||||
|
val outStack = getConcreteStack(out, cnt)
|
||||||
|
if (outStack.getItemDamage == OreDictionary.WILDCARD_VALUE) {
|
||||||
|
log.info("Result meta is unset, defaulting to 0")
|
||||||
|
outStack.setItemDamage(0)
|
||||||
|
}
|
||||||
|
for (inStack <- getAllConcreteStacks(in, 1)) {
|
||||||
|
if (inStack.getItemDamage == OreDictionary.WILDCARD_VALUE) {
|
||||||
|
FurnaceRecipes.smelting.addSmelting(inStack.itemID, outStack, xp)
|
||||||
|
log.info("added %d -> %s".format(inStack.itemID, outStack))
|
||||||
|
} else {
|
||||||
|
FurnaceRecipes.smelting.addSmelting(inStack.itemID, inStack.getItemDamage, outStack, xp)
|
||||||
|
log.info("added %d@%d -> %s".format(inStack.itemID, inStack.getItemDamage, outStack))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case x =>
|
||||||
|
log.severe("Can't process %s - this is a programing bug!".format(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a list of statements and catch all exceptions
|
||||||
|
* @param r The list to process
|
||||||
|
*/
|
||||||
|
def processStatementsSafe(r: List[Statement]): Unit = {
|
||||||
|
for (s <- r) {
|
||||||
|
try {
|
||||||
|
processStatement(s)
|
||||||
|
} catch {
|
||||||
|
case e: StatementError =>
|
||||||
|
log.severe("Error while processing %s: %s".format(s, e.getMessage))
|
||||||
|
case e: Throwable =>
|
||||||
|
log.severe("Error while processing %s: %s".format(s, e))
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def load(f: Reader) {
|
||||||
|
log.info("Starting parsing")
|
||||||
|
val r = newParser().doParse(f)
|
||||||
|
log.info("Processing %d statements".format(r.size))
|
||||||
|
processStatementsSafe(r)
|
||||||
|
log.info("Done")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.recipes
|
||||||
|
|
||||||
|
import java.io.Reader
|
||||||
|
|
||||||
|
import scala.util.parsing.combinator._
|
||||||
|
import org.apache.commons.lang3.StringEscapeUtils
|
||||||
|
import net.minecraftforge.oredict.OreDictionary
|
||||||
|
|
||||||
|
class RecipeParser extends JavaTokenParsers {
|
||||||
|
// Allows C-style comments
|
||||||
|
protected override val whiteSpace = """(\s|//.*|(?m)/\*(\*(?!/)|[^*])*\*/)+""".r
|
||||||
|
|
||||||
|
// Simple integer without signs
|
||||||
|
def int = "\\d+".r ^^ (_.toInt)
|
||||||
|
|
||||||
|
// Possible metadata suffix (defaults to wildcard value)
|
||||||
|
def maybeMeta = ("@" ~> int).? ^^ (_.getOrElse(OreDictionary.WILDCARD_VALUE))
|
||||||
|
|
||||||
|
// Qualified class name
|
||||||
|
def clsPath = (ident <~ ".").* ~ ident
|
||||||
|
|
||||||
|
// Single character usable in recipes (this could be extended)
|
||||||
|
def recipeChar = "[a-zA-Z0-9]".r ^^ (_.charAt(0))
|
||||||
|
|
||||||
|
// Set of 3 characters for 3x3 recipes (underscore = empty)
|
||||||
|
def recipeTriplet = repN(3, recipeChar | "_") ^^ (_.mkString(""))
|
||||||
|
|
||||||
|
// Set of 2 characters for 2x2 recipes
|
||||||
|
def recipeDuplet = repN(2, recipeChar | "_") ^^ (_.mkString(""))
|
||||||
|
|
||||||
|
// Quoted string with escape characters
|
||||||
|
def unescapeStr = stringLiteral ^^ { case x => StringEscapeUtils.unescapeJava(x.substring(1, x.length - 1)) }
|
||||||
|
|
||||||
|
// Identifier or quoted string
|
||||||
|
def str = ident | unescapeStr
|
||||||
|
|
||||||
|
// === Item references ===
|
||||||
|
|
||||||
|
def specOD = "OD" ~> ":" ~> ident ^^ StackOreDict
|
||||||
|
def specMcBlock = "B" ~> ":" ~> ident ~ maybeMeta ^^ { case b ~ m => StackMCBlock(b, m) }
|
||||||
|
def specMcItem = "I" ~> ":" ~> ident ~ maybeMeta ^^ { case b ~ m => StackMCItem(b, m) }
|
||||||
|
def specModStack = str ~ ":" ~ str ^^ { case m ~ c ~ n => StackMod(m, n) }
|
||||||
|
def specMacro = "$" ~> recipeChar ^^ StackMacro
|
||||||
|
|
||||||
|
def specReflect = clsPath ~ ("[" ~> ident <~ "]") ~ maybeMeta ^^ {
|
||||||
|
case (p ~ cl) ~ id ~ m => StackReflect((p :+ cl).mkString("."), id, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
def specGetter = clsPath ~ ("(" ~> str <~ ")") ~ maybeMeta ^^ {
|
||||||
|
case (p ~ cl) ~ n ~ m => StackGetter(p.mkString("."), cl, n, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
def spec = specMcBlock | specMcItem | specOD | specModStack | specGetter | specReflect | specMacro
|
||||||
|
|
||||||
|
// Spec with possible number of items
|
||||||
|
def specWithCount = spec ~ ("*" ~> int).?
|
||||||
|
|
||||||
|
// === Statements ===
|
||||||
|
|
||||||
|
def charSpec = recipeChar ~ "=" ~ spec ^^ {
|
||||||
|
case ch ~ eq ~ spec => new StCharAssign(ch, spec)
|
||||||
|
}
|
||||||
|
|
||||||
|
def classMacro = ("def" ~> ident <~ "=") ~ clsPath ^^ {
|
||||||
|
case id ~ (p ~ cl) => StClassMacro(id, (p :+ cl).mkString("."))
|
||||||
|
}
|
||||||
|
|
||||||
|
def ifMod = ("ifMod" ~> str) ~ ("{" ~> statements <~ "}") ~ ("else" ~> "{" ~> statements <~ "}").? ^^ {
|
||||||
|
case mod ~ thn ~ els => new StIfHaveMod(mod, thn, els.getOrElse(List.empty[Statement]))
|
||||||
|
}
|
||||||
|
|
||||||
|
def ifOreDict = ("ifOreDict" ~> str) ~ ("{" ~> statements <~ "}") ~ ("else" ~> "{" ~> statements <~ "}").? ^^ {
|
||||||
|
case id ~ thn ~ els => new StIfHaveOD(id, thn, els.getOrElse(List.empty[Statement]))
|
||||||
|
}
|
||||||
|
|
||||||
|
def recipeShaped3x3 = recipeTriplet ~ recipeTriplet ~ ("=>" ~> specWithCount) ~ recipeTriplet ^^ {
|
||||||
|
case r1 ~ r2 ~ (res ~ n) ~ r3 => StRecipeShaped(Seq(r1, r2, r3), res, n.getOrElse(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
def recipeShaped2x2 = recipeDuplet ~ recipeDuplet ~ ("=>" ~> specWithCount) ^^ {
|
||||||
|
case r1 ~ r2 ~ (res ~ n) => StRecipeShaped(Seq(r1, r2), res, n.getOrElse(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
def recipeShaped9 = recipeTriplet ~ recipeTriplet ~ recipeTriplet ~ ("=>" ~> specWithCount) ^^ {
|
||||||
|
case r1 ~ r2 ~ r3 ~ (res ~ n) => StRecipeShaped(Seq(r1, r2, r3), res, n.getOrElse(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
def recipeShapeless = "shapeless" ~> ":" ~> recipeChar.+ ~ ("=>" ~> specWithCount) ^^ {
|
||||||
|
case r ~ (res ~ n) => StRecipeShapeless(r.mkString(""), res, n.getOrElse(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
def recipeSmelting = "smelt" ~> ":" ~> spec ~ ("=>" ~> specWithCount) ~ ("," ~> decimalNumber).? ^^ {
|
||||||
|
case in ~ (out ~ n) ~ xp => StSmeltRecipe(in, out, n.getOrElse(1), xp.getOrElse("0").toFloat)
|
||||||
|
}
|
||||||
|
|
||||||
|
def statement: Parser[Statement] = (
|
||||||
|
charSpec
|
||||||
|
| classMacro
|
||||||
|
| ifMod
|
||||||
|
| recipeShaped3x3
|
||||||
|
| recipeShaped2x2
|
||||||
|
| recipeShaped9
|
||||||
|
| recipeShapeless
|
||||||
|
| recipeSmelting
|
||||||
|
)
|
||||||
|
|
||||||
|
def statements = statement.*
|
||||||
|
|
||||||
|
def doParse(r: Reader): List[Statement] = {
|
||||||
|
parseAll(statements, r) match {
|
||||||
|
case Success(res, next) => return res
|
||||||
|
case NoSuccess(msg, next) => sys.error("Config parsing failed at %s: %s".format(next.pos, msg))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.recipes
|
||||||
|
|
||||||
|
import net.minecraft.block.Block
|
||||||
|
import net.minecraft.item.Item
|
||||||
|
import scala.reflect.ClassTag
|
||||||
|
import java.lang.reflect.Modifier
|
||||||
|
|
||||||
|
object Vanilla {
|
||||||
|
|
||||||
|
// Maps of vanilla blocks and items (without tile. / item. prefixes)
|
||||||
|
|
||||||
|
lazy val blocks = mkMap[Block](_.getUnlocalizedName.stripPrefix("tile.")).withDefault(x => throw new StatementError("Block %s not found".format(x)))
|
||||||
|
lazy val items = mkMap[Item](_.getUnlocalizedName.stripPrefix("item.")).withDefault(x => throw new StatementError("Item %s not found".format(x)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the maps
|
||||||
|
* @tparam T The base class
|
||||||
|
* @param namer A function that converts objects to names
|
||||||
|
*/
|
||||||
|
private def mkMap[T](namer: T => String)(implicit t: ClassTag[T]) = {
|
||||||
|
val c = t.runtimeClass
|
||||||
|
// Grab all the fields
|
||||||
|
c.getFields.filter(x => {
|
||||||
|
// Keep only static fields that match the base Class
|
||||||
|
c.isAssignableFrom(x.getType) && Modifier.isStatic(x.getModifiers)
|
||||||
|
}).map(x => {
|
||||||
|
// Retrieve the static value
|
||||||
|
val f = x.get(null).asInstanceOf[T]
|
||||||
|
// Convert to name -> object tuples
|
||||||
|
namer(f) -> f
|
||||||
|
}).toMap // and finally to a map
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.recipes.gencfg
|
||||||
|
|
||||||
|
abstract class CfgEntry
|
||||||
|
|
||||||
|
case class EntryDouble(v: Double) extends CfgEntry
|
||||||
|
|
||||||
|
case class EntryStr(v: String) extends CfgEntry
|
||||||
|
|
||||||
|
case class ConfigSection(pfx: String = "") extends CfgEntry with Iterable[(String, CfgEntry)] {
|
||||||
|
var raw = Map.empty[String, CfgEntry].withDefault(x => sys.error("Config value '%s%s' is missing".format(pfx,x)))
|
||||||
|
|
||||||
|
def iterator: Iterator[(String, CfgEntry)] = raw.iterator
|
||||||
|
def filterType[T<:CfgEntry](cls: Class[T]): Iterable[(String,T)] = raw.filter(x=>cls.isInstance(x._2)).map(x=>x.asInstanceOf[(String,T)])
|
||||||
|
|
||||||
|
def rawget[T](id: String, t: Class[T]): T = {
|
||||||
|
val v = raw(id)
|
||||||
|
if (t.isInstance(v))
|
||||||
|
return v.asInstanceOf[T]
|
||||||
|
else
|
||||||
|
sys.error("Config value '%s%s' is of the wrong type, expected %s, got %s".format(pfx, id, t.getName, v.getClass.getName))
|
||||||
|
}
|
||||||
|
|
||||||
|
def set(id: String, v: CfgEntry) = raw += id -> v
|
||||||
|
|
||||||
|
def getDouble(id: String) = rawget(id, classOf[EntryDouble]).v
|
||||||
|
def getString(id: String) = rawget(id, classOf[EntryStr]).v
|
||||||
|
def getSection(id: String) = rawget(id, classOf[ConfigSection])
|
||||||
|
|
||||||
|
|
||||||
|
final val trueVals = Set("y", "true", "yes", "on")
|
||||||
|
def getBoolean(id: String) = trueVals.contains(getString(id).toLowerCase)
|
||||||
|
|
||||||
|
def getOrAddSection(id: String) = {
|
||||||
|
if (raw.isDefinedAt(id)) {
|
||||||
|
rawget(id, classOf[ConfigSection])
|
||||||
|
} else {
|
||||||
|
val newSection = new ConfigSection(pfx + id + ".")
|
||||||
|
set(id, newSection)
|
||||||
|
newSection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def getInt(id: String) = getDouble(id).round.toInt
|
||||||
|
def getFloat(id: String) = getDouble(id).toFloat
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.recipes.gencfg
|
||||||
|
|
||||||
|
import net.bdew.lib.recipes.Statement
|
||||||
|
|
||||||
|
abstract class CfgStatement
|
||||||
|
|
||||||
|
case class CfgVal(id: String, value: CfgEntry) extends CfgStatement
|
||||||
|
|
||||||
|
case class CfgSub(id: String, vals: List[CfgStatement]) extends CfgStatement
|
||||||
|
|
||||||
|
case class StCfg(id: String, vals: List[CfgStatement]) extends Statement
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.recipes.gencfg
|
||||||
|
|
||||||
|
import net.bdew.lib.recipes.{Statement, RecipeLoader}
|
||||||
|
|
||||||
|
trait GenericConfigLoader extends RecipeLoader {
|
||||||
|
val cfgStore: ConfigSection
|
||||||
|
|
||||||
|
def processConfigStatement(section: ConfigSection, s: CfgStatement): Unit = s match {
|
||||||
|
case CfgVal(id, v) =>
|
||||||
|
log.info("Config: %s%s = %s".format(section.pfx, id, v))
|
||||||
|
section.set(id, v)
|
||||||
|
case CfgSub(id, st) => processConfigBlock(section.getOrAddSection(id), st)
|
||||||
|
case x =>
|
||||||
|
log.severe("Can't process %s - this is a programing bug!".format(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
def processConfigBlock(view: ConfigSection, block: List[CfgStatement]) = for (s <- block) processConfigStatement(view, s)
|
||||||
|
|
||||||
|
override def processStatement(s: Statement) = s match {
|
||||||
|
case StCfg(id, st) => processConfigBlock(cfgStore.getOrAddSection(id), st)
|
||||||
|
case _ => super.processStatement(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.recipes.gencfg
|
||||||
|
|
||||||
|
import net.bdew.lib.recipes.RecipeParser
|
||||||
|
|
||||||
|
trait GenericConfigParser extends RecipeParser {
|
||||||
|
override def statement = statementCfg | super.statement
|
||||||
|
def cfgStatementNum = ident ~ "=" ~ decimalNumber ^^ { case id ~ eq ~ n => CfgVal(id, EntryDouble(n.toDouble)) }
|
||||||
|
def cfgStatementStr = ident ~ "=" ~ str ^^ { case id ~ eq ~ s => CfgVal(id, EntryStr(s)) }
|
||||||
|
def cfgStatementSub = cfgBlock ^^ { case (id, st) => CfgSub(id, st) }
|
||||||
|
|
||||||
|
def cfgStatement = cfgStatementNum | cfgStatementStr | cfgStatementSub
|
||||||
|
|
||||||
|
// A bit of type acrobatics because this is recursive (via cfgStatementSub), the tuple is translated into the proper class in either cfgStatementSub or cfg
|
||||||
|
def cfgBlock: Parser[(String, List[CfgStatement])] = "cfg" ~> ident ~ ("{" ~> cfgStatement.* <~ "}") ^^ { case id ~ st => (id, st) }
|
||||||
|
|
||||||
|
def statementCfg = cfgBlock ^^ { case (id, st) => StCfg(id, st) }
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.rotate
|
||||||
|
|
||||||
|
import cpw.mods.fml.relauncher.Side
|
||||||
|
import cpw.mods.fml.relauncher.SideOnly
|
||||||
|
import net.minecraft.block.Block
|
||||||
|
import net.minecraft.entity.EntityLivingBase
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.util.Icon
|
||||||
|
import net.minecraft.util.MathHelper
|
||||||
|
import net.minecraft.world.IBlockAccess
|
||||||
|
import net.minecraft.world.World
|
||||||
|
import net.minecraftforge.common.ForgeDirection
|
||||||
|
import java.util.EnumSet
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic logic for block rotatation
|
||||||
|
*/
|
||||||
|
trait BaseRotateableBlock extends Block {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this method to provide your textures, also called when rendering as item
|
||||||
|
*/
|
||||||
|
def getIcon(meta: Int, kind: IconType.Value): Icon
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this method to provide your textures, if you need to check other state
|
||||||
|
*/
|
||||||
|
def getIcon(world: IBlockAccess, x: Int, y: Int, z: Int, kind: IconType.Value): Icon = getIcon(world.getBlockMetadata(x, y, z), kind)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set of valid rotations, default is all of them
|
||||||
|
*/
|
||||||
|
def getValidFacings: EnumSet[ForgeDirection] = {
|
||||||
|
return EnumSet.allOf(classOf[ForgeDirection])
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotation to show when it's unavailable (like rendering item in inventory)
|
||||||
|
*/
|
||||||
|
def getDefaultFacing: ForgeDirection = ForgeDirection.UP
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Those will be overrided to provide concrete storage
|
||||||
|
*/
|
||||||
|
def setFacing(world: World, x: Int, y: Int, z: Int, facing: ForgeDirection)
|
||||||
|
def getFacing(world: IBlockAccess, x: Int, y: Int, z: Int): ForgeDirection
|
||||||
|
|
||||||
|
override def rotateBlock(worldObj: World, x: Int, y: Int, z: Int, axis: ForgeDirection): Boolean = {
|
||||||
|
if (getValidFacings.contains(axis)) {
|
||||||
|
setFacing(worldObj, x, y, z, axis)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
override def getIcon(side: Int, meta: Int): Icon = getIcon(meta, IconType.fromSideAndDir(side, getDefaultFacing))
|
||||||
|
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
override def getBlockTexture(world: IBlockAccess, x: Int, y: Int, z: Int, side: Int): Icon = getIcon(world, x, y, z, IconType.fromSideAndDir(side, getFacing(world, x, y, z)))
|
||||||
|
|
||||||
|
override def getValidRotations(worldObj: World, x: Int, y: Int, z: Int): Array[ForgeDirection] = getValidFacings.toArray(Array.empty[ForgeDirection])
|
||||||
|
|
||||||
|
override def onBlockPlacedBy(world: World, x: Int, y: Int, z: Int, ent: EntityLivingBase, stack: ItemStack) {
|
||||||
|
val validRotations = getValidFacings
|
||||||
|
var dir = getDefaultFacing
|
||||||
|
if (ent != null) {
|
||||||
|
val pitch: Int = Math.round(ent.rotationPitch)
|
||||||
|
val yaw: Int = MathHelper.floor_double(ent.rotationYaw * 4.0F / 360.0F + 0.5D) & 3
|
||||||
|
dir = yaw match {
|
||||||
|
case _ if pitch >= 50 && validRotations.contains(ForgeDirection.UP) => ForgeDirection.UP
|
||||||
|
case _ if pitch <= -50 && validRotations.contains(ForgeDirection.DOWN) => ForgeDirection.DOWN
|
||||||
|
case 0 if validRotations.contains(ForgeDirection.NORTH) => ForgeDirection.NORTH
|
||||||
|
case 1 if validRotations.contains(ForgeDirection.EAST) => ForgeDirection.EAST
|
||||||
|
case 2 if validRotations.contains(ForgeDirection.SOUTH) => ForgeDirection.SOUTH
|
||||||
|
case 3 if validRotations.contains(ForgeDirection.WEST) => ForgeDirection.WEST
|
||||||
|
case _ => dir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setFacing(world, x, y, z, dir)
|
||||||
|
super.onBlockPlacedBy(world, x, y, z, ent, stack)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.rotate
|
||||||
|
|
||||||
|
import net.minecraftforge.common.ForgeDirection
|
||||||
|
|
||||||
|
object IconType extends Enumeration {
|
||||||
|
val BACK = Value(0, "BACK")
|
||||||
|
val FRONT = Value(1, "FRONT")
|
||||||
|
val SIDE = Value(2, "SIDE")
|
||||||
|
|
||||||
|
def fromSideAndDir(side: Int, facing: ForgeDirection) = this(metaSideMap(side)(facing.ordinal))
|
||||||
|
|
||||||
|
val metaSideMap = Array(
|
||||||
|
Array(1, 0, 2, 2, 2, 2),
|
||||||
|
Array(0, 1, 2, 2, 2, 2),
|
||||||
|
Array(2, 2, 1, 0, 2, 2),
|
||||||
|
Array(2, 2, 0, 1, 2, 2),
|
||||||
|
Array(2, 2, 2, 2, 1, 0),
|
||||||
|
Array(2, 2, 2, 2, 0, 1))
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.rotate
|
||||||
|
|
||||||
|
import net.bdew.lib.data.base.{UpdateKind, TileDataSlots}
|
||||||
|
import net.bdew.lib.data.DataSlotDirection
|
||||||
|
|
||||||
|
trait RotateableTile extends TileDataSlots {
|
||||||
|
var rotation = DataSlotDirection("rotation", this).setUpdate(UpdateKind.SAVE, UpdateKind.WORLD)
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.rotate
|
||||||
|
|
||||||
|
import net.minecraft.block.ITileEntityProvider
|
||||||
|
import net.minecraft.world.IBlockAccess
|
||||||
|
import net.minecraft.world.World
|
||||||
|
import net.minecraftforge.common.ForgeDirection
|
||||||
|
import cpw.mods.fml.common.FMLCommonHandler
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores rotation data in tile entity. The TE should implement {@link RotateableTile}
|
||||||
|
*/
|
||||||
|
trait RotateableTileBlock extends BaseRotateableBlock with ITileEntityProvider {
|
||||||
|
def setFacing(world: World, x: Int, y: Int, z: Int, facing: ForgeDirection) {
|
||||||
|
world.getBlockTileEntity(x, y, z).asInstanceOf[RotateableTile].rotation := facing
|
||||||
|
}
|
||||||
|
|
||||||
|
def getFacing(world: IBlockAccess, x: Int, y: Int, z: Int): ForgeDirection = {
|
||||||
|
val te: RotateableTile = world.getBlockTileEntity(x, y, z).asInstanceOf[RotateableTile]
|
||||||
|
if (te == null || te.rotation == null) {
|
||||||
|
FMLCommonHandler.instance().getFMLLogger.warning("Failed gettig rocation for block at %d, %d, %d".format(x, y, z))
|
||||||
|
return getDefaultFacing
|
||||||
|
}
|
||||||
|
return te.rotation
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.tile
|
||||||
|
|
||||||
|
trait Component {
|
||||||
|
def added(p: TileExtended, name: String)
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.tile
|
||||||
|
|
||||||
|
import net.minecraft.tileentity.TileEntity
|
||||||
|
import net.minecraftforge.fluids._
|
||||||
|
import net.minecraftforge.common.ForgeDirection
|
||||||
|
|
||||||
|
trait ExposeTank extends TileEntity with IFluidHandler {
|
||||||
|
def getTankFromDirection(dir: ForgeDirection): IFluidTank
|
||||||
|
|
||||||
|
def fill(from: ForgeDirection, resource: FluidStack, doFill: Boolean): Int = {
|
||||||
|
val tank = getTankFromDirection(from)
|
||||||
|
if (tank == null) return 0
|
||||||
|
return tank.fill(resource, doFill)
|
||||||
|
}
|
||||||
|
|
||||||
|
def drain(from: ForgeDirection, resource: FluidStack, doDrain: Boolean): FluidStack = {
|
||||||
|
val tank = getTankFromDirection(from)
|
||||||
|
if (tank == null || resource == null || !resource.isFluidEqual(tank.getFluid)) return null
|
||||||
|
return tank.drain(resource.amount, doDrain)
|
||||||
|
}
|
||||||
|
|
||||||
|
def drain(from: ForgeDirection, maxDrain: Int, doDrain: Boolean): FluidStack = {
|
||||||
|
val tank = getTankFromDirection(from)
|
||||||
|
if (tank == null) return null
|
||||||
|
getTankFromDirection(from).drain(maxDrain, doDrain)
|
||||||
|
}
|
||||||
|
|
||||||
|
def canFill(from: ForgeDirection, fluid: Fluid): Boolean = getTankFromDirection(from) != null
|
||||||
|
|
||||||
|
def canDrain(from: ForgeDirection, fluid: Fluid): Boolean = getTankFromDirection(from) != null
|
||||||
|
|
||||||
|
def getTankInfo(from: ForgeDirection): Array[FluidTankInfo] = {
|
||||||
|
val tank = getTankFromDirection(from)
|
||||||
|
if (tank == null) return Array.empty[FluidTankInfo]
|
||||||
|
return Array(tank.getInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.tile
|
||||||
|
|
||||||
|
import net.minecraft.tileentity.TileEntity
|
||||||
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
|
import net.minecraft.network.INetworkManager
|
||||||
|
import net.minecraft.network.packet.Packet132TileEntityData
|
||||||
|
import net.bdew.lib.Event
|
||||||
|
|
||||||
|
class TileExtended extends TileEntity {
|
||||||
|
final val ACT_CLIENT = 1
|
||||||
|
final val ACT_GUI = 2
|
||||||
|
|
||||||
|
var clientTick = Event()
|
||||||
|
var serverTick = Event()
|
||||||
|
var persistSave = Event[NBTTagCompound]
|
||||||
|
var persistLoad = Event[NBTTagCompound]
|
||||||
|
var sendClientUpdate = Event[NBTTagCompound]
|
||||||
|
var handleClientUpdate = Event[NBTTagCompound]
|
||||||
|
|
||||||
|
def tickClient() {}
|
||||||
|
def tickServer() {}
|
||||||
|
|
||||||
|
override final def writeToNBT(tag: NBTTagCompound) = {
|
||||||
|
super.writeToNBT(tag)
|
||||||
|
persistSave.trigger(tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
override final def readFromNBT(tag: NBTTagCompound) = {
|
||||||
|
super.readFromNBT(tag)
|
||||||
|
persistLoad.trigger(tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
override final def getDescriptionPacket: Packet132TileEntityData = {
|
||||||
|
if (!sendClientUpdate.hasListeners) return null
|
||||||
|
val tag = new NBTTagCompound
|
||||||
|
sendClientUpdate.trigger(tag)
|
||||||
|
return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, ACT_CLIENT, tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
override final def onDataPacket(net: INetworkManager, pkt: Packet132TileEntityData) {
|
||||||
|
if (pkt.actionType == ACT_CLIENT)
|
||||||
|
handleClientUpdate.trigger(pkt.data)
|
||||||
|
else
|
||||||
|
extDataPacket(pkt.actionType, pkt.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override final def updateEntity() {
|
||||||
|
if (worldObj != null) {
|
||||||
|
if (worldObj.isRemote) {
|
||||||
|
tickClient()
|
||||||
|
clientTick.trigger()
|
||||||
|
} else {
|
||||||
|
tickServer()
|
||||||
|
serverTick.trigger()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected def extDataPacket(id: Int, data: NBTTagCompound) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.tile.inventory
|
||||||
|
|
||||||
|
import net.minecraft.inventory.IInventory
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
|
|
||||||
|
trait BaseInventory extends IInventory {
|
||||||
|
var inv: Array[ItemStack] = new Array(getSizeInventory)
|
||||||
|
|
||||||
|
def getStackInSlot(i: Int): ItemStack = inv(i)
|
||||||
|
|
||||||
|
def getInvName = ""
|
||||||
|
|
||||||
|
def isInvNameLocalized = false
|
||||||
|
|
||||||
|
def getInventoryStackLimit = 64
|
||||||
|
|
||||||
|
def isUseableByPlayer(player: EntityPlayer) = true
|
||||||
|
|
||||||
|
def openChest() = Unit
|
||||||
|
|
||||||
|
def closeChest() = Unit
|
||||||
|
|
||||||
|
def isItemValidForSlot(slot: Int, stack: ItemStack) = true
|
||||||
|
|
||||||
|
def decrStackSize(slot: Int, n: Int): ItemStack = {
|
||||||
|
var item = inv(slot)
|
||||||
|
if (item != null) {
|
||||||
|
if (item.stackSize <= n) {
|
||||||
|
inv(slot) = null
|
||||||
|
onInventoryChanged()
|
||||||
|
return item
|
||||||
|
} else {
|
||||||
|
var newstack = item.splitStack(n)
|
||||||
|
if (item.stackSize == 0) {
|
||||||
|
inv(slot) = null
|
||||||
|
}
|
||||||
|
onInventoryChanged()
|
||||||
|
return newstack
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def getStackInSlotOnClosing(slot: Int): ItemStack = {
|
||||||
|
var tmp = inv(slot)
|
||||||
|
inv(slot) = null
|
||||||
|
onInventoryChanged()
|
||||||
|
return tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
def setInventorySlotContents(slot: Int, stack: ItemStack) = {
|
||||||
|
inv(slot) = stack
|
||||||
|
onInventoryChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.tile.inventory
|
||||||
|
|
||||||
|
import net.minecraft.block.Block
|
||||||
|
import net.minecraft.world.World
|
||||||
|
|
||||||
|
trait BreakableInventoryBlock extends Block {
|
||||||
|
override def breakBlock(world: World, x: Int, y: Int, z: Int, blockId: Int, meta: Int) {
|
||||||
|
if (!world.isRemote) {
|
||||||
|
val te = world.getBlockTileEntity(x, y, z).asInstanceOf[BreakableInventoryTile]
|
||||||
|
if (te != null) {
|
||||||
|
te.dropItems()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.breakBlock(world, x, y, z, blockId, meta)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.tile.inventory
|
||||||
|
|
||||||
|
import net.minecraft.tileentity.TileEntity
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.bdew.lib.items.ItemUtils
|
||||||
|
|
||||||
|
trait BreakableInventoryTile extends TileEntity with BaseInventory {
|
||||||
|
def dropItems() {
|
||||||
|
if (worldObj != null && !worldObj.isRemote) {
|
||||||
|
for (stack <- inv if stack != null) {
|
||||||
|
ItemUtils.throwItemAt(worldObj, xCoord, yCoord, zCoord, stack)
|
||||||
|
}
|
||||||
|
inv = new Array[ItemStack](inv.size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.tile.inventory
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.nbt.{NBTTagList, NBTTagCompound}
|
||||||
|
import net.bdew.lib.Misc
|
||||||
|
import net.bdew.lib.tile.TileExtended
|
||||||
|
|
||||||
|
trait PersistentInventoryTile extends TileExtended with BaseInventory {
|
||||||
|
persistLoad.listen((tag: NBTTagCompound) => {
|
||||||
|
inv = new Array[ItemStack](getSizeInventory)
|
||||||
|
for (nbtItem <- Misc.iterNbtList[NBTTagCompound](tag.getTagList("Items"))) {
|
||||||
|
val slot = nbtItem.getByte("Slot")
|
||||||
|
if (slot >= 0 && slot < inv.size) {
|
||||||
|
inv(slot) = ItemStack.loadItemStackFromNBT(nbtItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
persistSave.listen((tag: NBTTagCompound) => {
|
||||||
|
val itemList = new NBTTagList
|
||||||
|
for ((item, i) <- inv.view.zipWithIndex if item != null) {
|
||||||
|
val itemNbt: NBTTagCompound = new NBTTagCompound
|
||||||
|
itemNbt.setByte("Slot", i.asInstanceOf[Byte])
|
||||||
|
item.writeToNBT(itemNbt)
|
||||||
|
itemList.appendTag(itemNbt)
|
||||||
|
}
|
||||||
|
tag.setTag("Items", itemList)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) bdew, 2013
|
||||||
|
* https://github.com/bdew/bdlib
|
||||||
|
*
|
||||||
|
* 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/bdlib/master/MMPL-1.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.bdew.lib.tile.inventory
|
||||||
|
|
||||||
|
import net.minecraft.inventory.ISidedInventory
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
|
||||||
|
trait SidedInventory extends BaseInventory with ISidedInventory {
|
||||||
|
var allowSided = false
|
||||||
|
|
||||||
|
def getAccessibleSlotsFromSide(side: Int): Array[Int] = (0 until inv.size).toArray
|
||||||
|
|
||||||
|
def canInsertItem(slot: Int, stack: ItemStack, side: Int) = allowSided && isItemValidForSlot(slot, stack)
|
||||||
|
|
||||||
|
def canExtractItem(slot: Int, stack: ItemStack, side: Int) = allowSided
|
||||||
|
}
|
||||||
Reference in new issue
Block a user