├── .gitattributes ├── .gitignore ├── LICENSE.md ├── README.md ├── build.gradle ├── changelog.txt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src └── main ├── java └── amerifrance │ └── guideapi │ ├── ConfigHandler.java │ ├── GuideMod.java │ ├── RegistrarGuideAPI.java │ ├── api │ ├── BookEvent.java │ ├── GuideAPI.java │ ├── GuideBook.java │ ├── IGuideBook.java │ ├── IGuideItem.java │ ├── IGuideLinked.java │ ├── IInfoRenderer.java │ ├── IPage.java │ ├── IRecipeRenderer.java │ ├── SubTexture.java │ ├── button │ │ └── ButtonGuideAPI.java │ ├── impl │ │ ├── Book.java │ │ ├── BookBinder.java │ │ ├── Category.java │ │ ├── Entry.java │ │ ├── Page.java │ │ └── abstraction │ │ │ ├── CategoryAbstract.java │ │ │ └── EntryAbstract.java │ ├── package-info.java │ └── util │ │ ├── BookHelper.java │ │ ├── GuiHelper.java │ │ ├── NBTBookTags.java │ │ ├── PageHelper.java │ │ └── TextHelper.java │ ├── button │ ├── ButtonBack.java │ ├── ButtonNext.java │ ├── ButtonPrev.java │ └── ButtonSearch.java │ ├── category │ ├── CategoryItemStack.java │ └── CategoryResourceLocation.java │ ├── entry │ ├── EntryItemStack.java │ └── EntryResourceLocation.java │ ├── gui │ ├── GuiBase.java │ ├── GuiCategory.java │ ├── GuiEntry.java │ ├── GuiHome.java │ └── GuiSearch.java │ ├── info │ ├── InfoRendererDescription.java │ └── InfoRendererImage.java │ ├── item │ └── ItemGuideBook.java │ ├── network │ ├── PacketHandler.java │ ├── PacketSyncCategory.java │ ├── PacketSyncEntry.java │ └── PacketSyncHome.java │ ├── page │ ├── PageBrewingRecipe.java │ ├── PageFurnaceRecipe.java │ ├── PageIRecipe.java │ ├── PageImage.java │ ├── PageItemStack.java │ ├── PageJsonRecipe.java │ ├── PageSound.java │ ├── PageText.java │ ├── PageTextImage.java │ └── reciperenderer │ │ ├── BasicRecipeRenderer.java │ │ ├── ShapedOreRecipeRenderer.java │ │ ├── ShapedRecipesRenderer.java │ │ ├── ShapelessOreRecipeRenderer.java │ │ └── ShapelessRecipesRenderer.java │ ├── proxy │ ├── ClientProxy.java │ └── CommonProxy.java │ ├── test │ ├── TestBook.java │ ├── TestBook2.java │ └── TestBook3.java │ ├── util │ ├── APISetter.java │ ├── AnnotationHandler.java │ ├── EventHandler.java │ └── LogHelper.java │ └── wrapper │ ├── AbstractWrapper.java │ ├── CategoryWrapper.java │ ├── EntryWrapper.java │ └── PageWrapper.java └── resources ├── assets └── guideapi │ ├── lang │ ├── en_US.lang │ ├── ru_RU.lang │ └── zh_CN.lang │ ├── models │ └── item │ │ └── itemguidebook.json │ └── textures │ ├── gui │ ├── book_colored.png │ ├── book_greyscale.png │ ├── category_left.png │ ├── category_right.png │ ├── recipe_elements.png │ └── testimage.png │ └── items │ ├── book_base.png │ └── book_page.png └── mcmod.info /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #General use .gitignore for Minecraft modding. 2 | 3 | #Folders 4 | /.idea/* 5 | /.gradle/* 6 | /build/* 7 | /eclipse/* 8 | /run/* 9 | /out/* 10 | /asm/* 11 | /bin/* 12 | /lib/* 13 | 14 | #File Extensions 15 | *.psd 16 | *.iml 17 | *.ipr 18 | *.iws 19 | *.classpath 20 | *.project 21 | 22 | #Specific files 23 | curse.gradle 24 | Thumbs.db 25 | /bin/ 26 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) Copyright (c) 2017 TehNut 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Guide-API [![Build Status](http://tehnut.info/jenkins/buildStatus/icon?job=Guide-API/1.7.10)](http://tehnut.info/jenkins/job/Guide-API/job/1.7.10/) 2 | 3 | Library mod for easy creation of guide books. Also allows book creation via JSON files. 4 | 5 | ## Useful Links 6 | * [Jenkins](http://tehnut.info/jenkins/job/Guide-API/) 7 | * [CurseForge](http://minecraft.curseforge.com/mc-mods/228832-guide-api) 8 | * [Javadocs](http://tehnut.info/jenkins/job/Guide-API/javadoc/) 9 | * [ReadTheDocs](http://guide-api.readthedocs.org/en/latest/) 10 | 11 | ## Mods that support Guide-API 12 | The ones we know of at least 13 | 14 | * [Sanguimancy](https://minecraft.curseforge.com/projects/sanguimancy) 15 | * [Creative Concoctions](https://github.com/TeamAmeriFrance/CreativeConcoctions) 16 | * [Overlord](https://minecraft.curseforge.com/projects/overlord) 17 | * [Mechanical Soldiers](https://minecraft.curseforge.com/projects/mechanical-soldiers) 18 | * [Blood Magic](https://minecraft.curseforge.com/projects/blood-magic) (*In progress*) 19 | * [Crossroads](https://github.com/Da-Technomancer/Crossroads) 20 | 21 | ## Issue Reporting 22 | 23 | Please include the following: 24 | 25 | * Minecraft version 26 | * Guide-API version 27 | * Forge version/build 28 | * Versions of any mods potentially related to the issue 29 | * Any relevant screenshots are greatly appreciated 30 | * For crashes: 31 | * Steps to reproduce 32 | * Latest Forge log or crash log 33 | 34 | ## Developer Information 35 | This section has been moved [here](http://guide-api.readthedocs.org/en/latest/). 36 | 37 | ## Modpack Permissions 38 | For full details, view our license. Distributor rights are automatically given to any user who wishes to include the mod in their modpack if the intent is not malicious and/or commercial. We reserve the right to change this section as needed. 39 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | maven { url = "http://files.minecraftforge.net/maven" } 5 | maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" } 6 | } 7 | dependencies { 8 | classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT' 9 | } 10 | } 11 | 12 | plugins { 13 | id 'com.matthewprenger.cursegradle' version '1.1.2' 14 | id "net.minecraftforge.gradle.forge" version "2.0.2" 15 | } 16 | 17 | apply plugin: 'maven-publish' 18 | 19 | def build_number = 'CUSTOM' 20 | 21 | if (System.getenv('BUILD_NUMBER') != null) 22 | build_number = System.getenv('BUILD_NUMBER') 23 | 24 | group = package_group 25 | archivesBaseName = mod_name 26 | version = "${mc_version}-${mod_version}-${build_number}" 27 | 28 | repositories { 29 | maven { url = "http://dvs1.progwml6.com/files/maven" } 30 | } 31 | 32 | dependencies { 33 | deobfCompile "mezz.jei:jei_${mc_version}:${jei_version}" 34 | } 35 | 36 | minecraft { 37 | version = "${mc_version}-${forge_version}" 38 | runDir = "run" 39 | 40 | replace "@VERSION@", project.version 41 | replaceIn "GuideMod.java" 42 | replace "@API_VERSION@", "${api_version}" 43 | replaceIn "package-info.java" 44 | 45 | if (project.hasProperty('mappings_version')) 46 | mappings = project.mappings_version 47 | } 48 | 49 | processResources { 50 | inputs.property "version", project.version 51 | inputs.property "mcversion", project.minecraft.version 52 | 53 | from(sourceSets.main.resources.srcDirs) { 54 | include '**/*.info' 55 | include '**/*.properties' 56 | 57 | expand 'version': project.version, 'mcversion': project.minecraft.version 58 | } 59 | from(sourceSets.main.resources.srcDirs) { 60 | exclude '**/*.info' 61 | exclude '**/*.properties' 62 | } 63 | } 64 | 65 | jar { 66 | classifier = '' 67 | manifest.mainAttributes( 68 | "Built-By": System.getProperty('user.name'), 69 | "Created-By": "${System.getProperty('java.vm.version')} + (${System.getProperty('java.vm.vendor')})", 70 | "Implementation-Title": project.name, 71 | "Implementation-Version": project.version 72 | ) 73 | exclude 'amerifrance/guideapi/test/**/*' 74 | } 75 | 76 | // API jar 77 | task apiJar(type: Jar) { 78 | from sourceSets.main.allSource 79 | from sourceSets.main.output 80 | include 'amerifrance/guideapi/api/**/*' 81 | classifier = 'api' 82 | } 83 | 84 | tasks.build.dependsOn apiJar 85 | 86 | tasks.withType(JavaCompile) { task -> 87 | task.options.encoding = 'UTF-8' 88 | } 89 | 90 | publishing { 91 | tasks.publish.dependsOn 'build' 92 | publications { 93 | mavenJava(MavenPublication) { 94 | artifact jar 95 | artifact sourceJar 96 | } 97 | } 98 | repositories { 99 | if (project.hasProperty('maven_repo')) { 100 | maven { url maven_repo } 101 | } else { 102 | mavenLocal() 103 | } 104 | } 105 | } 106 | 107 | String getChangelogText() { 108 | def changelogFile = new File('changelog.txt') 109 | if (!changelogFile.exists()) 110 | return "" 111 | String str = '' 112 | String separator = '---' 113 | int lineCount = 0 114 | boolean done = false 115 | changelogFile.eachLine { 116 | if (done || it == null) { 117 | return 118 | } 119 | if (lineCount < 3) { 120 | lineCount++ 121 | if (it.startsWith(separator)) { 122 | return 123 | } 124 | } 125 | if (!it.startsWith(separator)) { 126 | str += "$it" + (lineCount < 3 ? ':\n\n' : '\n') 127 | return 128 | } 129 | done = true // once we go past the first version block, parse no more 130 | } 131 | return str 132 | } 133 | 134 | curseforge { 135 | if (project.hasProperty('curse_key')) 136 | apiKey = project.curse_key 137 | 138 | project { 139 | id = "${curse_id}" 140 | changelog = getChangelogText() 141 | releaseType = 'beta' 142 | 143 | addArtifact sourceJar 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /changelog.txt: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------ 2 | Version 2.1.8 3 | ------------------------------------------------------ 4 | 5 | - Return to the page an entry is on when backing out of it 6 | - When opening the search GUI, auto-focus the search bar 7 | - Fix json recipe renderer spamming the log 8 | - Hide categories if they're empty 9 | - Add search button to all views -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | mod_name=Guide-API 2 | package_group=info.amerifrance.guideapi 3 | 4 | mc_version=1.12 5 | forge_version=14.21.1.2443 6 | mappings_version=snapshot_20170819 7 | 8 | mod_version=2.1.8 9 | api_version=2.0.0 10 | curse_id=228832 11 | 12 | jei_version=4.7.1.69 13 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeamAmeriFrance/Guide-API/2c4fa1b077a99ee1068de51d5919b9b19b5e0956/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Sep 14 12:28:28 PDT 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Guide-API' 2 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/ConfigHandler.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi; 2 | 3 | import amerifrance.guideapi.api.GuideAPI; 4 | import amerifrance.guideapi.api.impl.Book; 5 | import com.google.common.collect.Maps; 6 | import net.minecraftforge.common.config.Configuration; 7 | 8 | import java.io.File; 9 | import java.util.Map; 10 | 11 | public class ConfigHandler { 12 | 13 | public static final Map SPAWN_BOOKS = Maps.newHashMap(); 14 | 15 | public static Configuration config; 16 | 17 | // Settings 18 | public static boolean enableLogging; 19 | public static boolean canSpawnWithBooks; 20 | 21 | public static void init(File file) { 22 | config = new Configuration(file); 23 | syncConfig(); 24 | } 25 | 26 | public static void syncConfig() { 27 | String category; 28 | 29 | category = "Books"; 30 | config.addCustomCategoryComment(category, "All settings related to Books."); 31 | canSpawnWithBooks = config.getBoolean("canSpawnWithBooks", category, true, "Allows books to spawn with new players.\nThis is a global override for all books."); 32 | 33 | category = "General"; 34 | config.addCustomCategoryComment(category, "Miscellaneous settings."); 35 | enableLogging = config.getBoolean("enableLogging", category, true, "Enables extra information being printed to the console."); 36 | 37 | config.save(); 38 | } 39 | 40 | public static void handleBookConfigs() { 41 | for (Book book : GuideAPI.getBooks().values()) 42 | SPAWN_BOOKS.put(book, config.getBoolean(book.getRegistryName().toString(), "Books.Spawn", book.shouldSpawnWithBook(), "")); 43 | 44 | config.setCategoryComment("Books.Spawn", "If true, the user will spawn with the book.\nThis defaults to the value the book owner has set and is overridden by this config."); 45 | config.save(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/GuideMod.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi; 2 | 3 | import amerifrance.guideapi.api.GuideAPI; 4 | import amerifrance.guideapi.api.IGuideBook; 5 | import amerifrance.guideapi.api.impl.Book; 6 | import amerifrance.guideapi.network.PacketHandler; 7 | import amerifrance.guideapi.proxy.CommonProxy; 8 | import amerifrance.guideapi.util.AnnotationHandler; 9 | import net.minecraft.launchwrapper.Launch; 10 | import net.minecraftforge.fml.common.Mod; 11 | import net.minecraftforge.fml.common.SidedProxy; 12 | import net.minecraftforge.fml.common.discovery.ASMDataTable; 13 | import net.minecraftforge.fml.common.event.FMLInitializationEvent; 14 | import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; 15 | import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; 16 | import net.minecraftforge.fml.common.network.NetworkRegistry; 17 | import org.apache.commons.lang3.tuple.Pair; 18 | 19 | import java.io.File; 20 | 21 | @Mod(modid = GuideMod.ID, name = GuideMod.NAME, version = GuideMod.VERSION) 22 | public class GuideMod { 23 | 24 | public static final String NAME = "Guide-API"; 25 | public static final String ID = "guideapi"; 26 | public static final String CHANNEL = "GuideAPI"; 27 | public static final String VERSION = "@VERSION@"; 28 | public static final boolean IS_DEV = (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment"); 29 | 30 | @Mod.Instance(ID) 31 | public static GuideMod INSTANCE; 32 | 33 | @SidedProxy(clientSide = "amerifrance.guideapi.proxy.ClientProxy", serverSide = "amerifrance.guideapi.proxy.CommonProxy") 34 | public static CommonProxy PROXY; 35 | 36 | public static File configDir; 37 | public static ASMDataTable dataTable; 38 | 39 | @Mod.EventHandler 40 | public void preInit(FMLPreInitializationEvent event) { 41 | configDir = new File(event.getModConfigurationDirectory(), NAME); 42 | configDir.mkdirs(); 43 | ConfigHandler.init(new File(configDir, NAME + ".cfg")); 44 | 45 | GuideAPI.initialize(); 46 | dataTable = event.getAsmData(); 47 | 48 | NetworkRegistry.INSTANCE.registerGuiHandler(this, PROXY); 49 | PacketHandler.registerPackets(); 50 | } 51 | 52 | @Mod.EventHandler 53 | public void init(FMLInitializationEvent event) { 54 | PROXY.initColors(); 55 | } 56 | 57 | @Mod.EventHandler 58 | public void postInit(FMLPostInitializationEvent event) { 59 | ConfigHandler.handleBookConfigs(); 60 | 61 | for (Pair guide : AnnotationHandler.BOOK_CLASSES) 62 | guide.getRight().handlePost(GuideAPI.getStackFromBook(guide.getLeft())); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/RegistrarGuideAPI.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi; 2 | 3 | import amerifrance.guideapi.api.GuideAPI; 4 | import amerifrance.guideapi.api.IGuideBook; 5 | import amerifrance.guideapi.api.IPage; 6 | import amerifrance.guideapi.api.impl.Book; 7 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 8 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 9 | import amerifrance.guideapi.item.ItemGuideBook; 10 | import amerifrance.guideapi.page.PageJsonRecipe; 11 | import amerifrance.guideapi.util.APISetter; 12 | import amerifrance.guideapi.util.AnnotationHandler; 13 | import net.minecraft.item.Item; 14 | import net.minecraft.item.ItemStack; 15 | import net.minecraft.item.crafting.IRecipe; 16 | import net.minecraft.world.biome.Biome; 17 | import net.minecraftforge.client.event.ModelRegistryEvent; 18 | import net.minecraftforge.event.RegistryEvent; 19 | import net.minecraftforge.fml.common.Mod; 20 | import net.minecraftforge.fml.common.eventhandler.EventPriority; 21 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 22 | import net.minecraftforge.fml.common.registry.ForgeRegistries; 23 | import org.apache.commons.lang3.tuple.Pair; 24 | 25 | @Mod.EventBusSubscriber 26 | public class RegistrarGuideAPI { 27 | 28 | /* 29 | * Why Register? Well, that's an easy one. We need to register our items during the registry event phase so they 30 | * can be properly used during init and beyond. However, we cannot handle it during Register because any mods 31 | * using @ObjectHolder will not have their Item fields populated. Thus, we must use an event that fires *after* 32 | * Item object holders are populated, but *before* the recipe registry. Since the events are fired in alphabetical order, 33 | * we just pick one that starts with a letter before "r". 34 | */ 35 | @SubscribeEvent 36 | public static void registerItemsInADifferentRegistryEventBecauseLoadOrderingAndObjectHoldersAreImportant(RegistryEvent.Register event) { 37 | AnnotationHandler.gatherBooks(GuideMod.dataTable); 38 | 39 | for (Book book : GuideAPI.getBooks().values()) { 40 | Item guideBook = new ItemGuideBook(book); 41 | guideBook.setRegistryName(book.getRegistryName().toString().replace(":", "-")); 42 | ForgeRegistries.ITEMS.register(guideBook); 43 | APISetter.setBookForStack(book, new ItemStack(guideBook)); 44 | } 45 | } 46 | 47 | @SubscribeEvent(priority = EventPriority.LOWEST) 48 | public static void registerRecipes(RegistryEvent.Register event) { 49 | for (Pair guide : AnnotationHandler.BOOK_CLASSES) { 50 | IRecipe recipe = guide.getRight().getRecipe(GuideAPI.getStackFromBook(guide.getLeft())); 51 | if (recipe != null) 52 | event.getRegistry().register(recipe); 53 | } 54 | 55 | for (Book book : GuideAPI.getBooks().values()) 56 | for (CategoryAbstract cat : book.getCategoryList()) 57 | for (EntryAbstract entry : cat.entries.values()) 58 | for (IPage page : entry.pageList) 59 | if (page instanceof PageJsonRecipe) 60 | ((PageJsonRecipe) page).init(); 61 | } 62 | 63 | @SubscribeEvent 64 | public static void registerModels(ModelRegistryEvent event) { 65 | for (Pair guide : AnnotationHandler.BOOK_CLASSES) 66 | guide.getRight().handleModel(GuideAPI.getStackFromBook(guide.getLeft())); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/BookEvent.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import net.minecraft.entity.player.EntityPlayer; 5 | import net.minecraft.item.ItemStack; 6 | import net.minecraft.util.text.ITextComponent; 7 | import net.minecraft.util.text.Style; 8 | import net.minecraft.util.text.TextComponentTranslation; 9 | import net.minecraft.util.text.TextFormatting; 10 | import net.minecraftforge.fml.common.eventhandler.Cancelable; 11 | import net.minecraftforge.fml.common.eventhandler.Event; 12 | 13 | import javax.annotation.Nonnull; 14 | 15 | /** 16 | * Base class for all {@link Book} related events. 17 | * 18 | * {@link #book} is the book being opened. 19 | * {@link #stack} is the ItemStack of the Book. 20 | * {@link #player} is the player opening the book. 21 | */ 22 | public class BookEvent extends Event { 23 | 24 | private final Book book; 25 | private final ItemStack stack; 26 | private final EntityPlayer player; 27 | 28 | protected BookEvent(Book book, ItemStack stack, EntityPlayer player) { 29 | this.book = book; 30 | this.stack = stack; 31 | this.player = player; 32 | } 33 | 34 | public Book getBook() { 35 | return book; 36 | } 37 | 38 | public ItemStack getStack() { 39 | return stack; 40 | } 41 | 42 | public EntityPlayer getPlayer() { 43 | return player; 44 | } 45 | 46 | /** 47 | * Called whenever a book is opened. 48 | * 49 | * {@link #canceledText} is a status message sent to the player when the book fails to open. 50 | */ 51 | @Cancelable 52 | public static class Open extends BookEvent { 53 | 54 | private static final ITextComponent DEFAULT_CANCEL = new TextComponentTranslation("text.open.failed").setStyle(new Style().setColor(TextFormatting.RED)); 55 | 56 | private ITextComponent canceledText = DEFAULT_CANCEL; 57 | 58 | public Open(Book book, ItemStack stack, EntityPlayer player) { 59 | super(book, stack, player); 60 | } 61 | 62 | @Nonnull 63 | public ITextComponent getCanceledText() { 64 | return canceledText; 65 | } 66 | 67 | public void setCanceledText(@Nonnull ITextComponent canceledText) { 68 | this.canceledText = canceledText; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/GuideAPI.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import com.google.common.collect.*; 5 | import net.minecraft.block.Block; 6 | import net.minecraft.client.renderer.block.model.ModelResourceLocation; 7 | import net.minecraft.item.ItemStack; 8 | import net.minecraft.util.ResourceLocation; 9 | import net.minecraftforge.client.model.ModelLoader; 10 | import net.minecraftforge.fml.relauncher.Side; 11 | import net.minecraftforge.fml.relauncher.SideOnly; 12 | 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | public class GuideAPI { 17 | 18 | private static final Map BOOKS = Maps.newHashMap(); 19 | private static final Map BOOK_TO_STACK = Maps.newHashMap(); 20 | private static final Map, IInfoRenderer>> INFO_RENDERERS = Maps.newHashMap(); 21 | private static List indexedBooks = Lists.newArrayList(); 22 | 23 | /** 24 | * Obtains a new ItemStack associated with the provided book. 25 | * 26 | * @param book - The book to get an ItemStack for. 27 | * @return - The ItemStack associated with the provided book. 28 | */ 29 | public static ItemStack getStackFromBook(Book book) { 30 | return BOOK_TO_STACK.get(book) == null ? ItemStack.EMPTY : BOOK_TO_STACK.get(book); 31 | } 32 | 33 | /** 34 | * Registers an IInfoRenderer 35 | * 36 | * @param infoRenderer - The renderer to register 37 | * @param blockClasses - The block classes that this should draw for 38 | */ 39 | public static void registerInfoRenderer(Book book, IInfoRenderer infoRenderer, Class... blockClasses) { 40 | if (!INFO_RENDERERS.containsKey(book)) 41 | INFO_RENDERERS.put(book, ArrayListMultimap., IInfoRenderer>create()); 42 | 43 | for (Class blockClass : blockClasses) 44 | INFO_RENDERERS.get(book).put(blockClass, infoRenderer); 45 | } 46 | 47 | /** 48 | * Helper method for setting a model for your book. 49 | *

50 | * Use if you wish to use a custom model. 51 | *

52 | * Only call AFTER you have registered your book. 53 | * 54 | * @param book - Book to set model for 55 | * @param modelLoc - Location of the model file 56 | * @param variantName - Variant to use 57 | */ 58 | @SideOnly(Side.CLIENT) 59 | public static void setModel(Book book, ResourceLocation modelLoc, String variantName) { 60 | ModelResourceLocation mrl = new ModelResourceLocation(modelLoc, variantName); 61 | ModelLoader.setCustomModelResourceLocation( 62 | getStackFromBook(book).getItem(), 63 | 0, 64 | mrl 65 | ); 66 | } 67 | 68 | /** 69 | * Helper method for setting a model for your book. 70 | *

71 | * Use if you wish to use the default model with color. 72 | *

73 | * Only call AFTER you have registered your book. 74 | * 75 | * @param book - Book to set model for 76 | */ 77 | @SideOnly(Side.CLIENT) 78 | public static void setModel(Book book) { 79 | setModel(book, new ResourceLocation("guideapi", "ItemGuideBook"), "inventory"); 80 | } 81 | 82 | public static void initialize() { 83 | // No-op. Just here to initialize fields. 84 | } 85 | 86 | public static Map getBooks() { 87 | return ImmutableMap.copyOf(BOOKS); 88 | } 89 | 90 | public static Map getBookToStack() { 91 | return ImmutableMap.copyOf(BOOK_TO_STACK); 92 | } 93 | 94 | public static Map, IInfoRenderer>> getInfoRenderers() { 95 | return ImmutableMap.copyOf(INFO_RENDERERS); 96 | } 97 | 98 | public static List getIndexedBooks() { 99 | return ImmutableList.copyOf(indexedBooks); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/GuideBook.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api; 2 | 3 | import net.minecraftforge.fml.common.eventhandler.EventPriority; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * Used to mark a class to be handled for Guide registration. 12 | */ 13 | @Target(ElementType.TYPE) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface GuideBook { 16 | EventPriority priority() default EventPriority.NORMAL; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/IGuideBook.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import net.minecraft.item.ItemStack; 5 | import net.minecraft.item.crafting.IRecipe; 6 | import net.minecraftforge.fml.relauncher.Side; 7 | import net.minecraftforge.fml.relauncher.SideOnly; 8 | 9 | import javax.annotation.Nonnull; 10 | import javax.annotation.Nullable; 11 | 12 | public interface IGuideBook { 13 | 14 | /** 15 | * Build your guide book here. The returned book will be registered for you. The book created here can be modified 16 | * later, so make sure to keep a reference for yourself. 17 | * 18 | * @return a built book to be registered. 19 | */ 20 | @Nullable 21 | Book buildBook(); 22 | 23 | /** 24 | * Use this to handle setting the model of your book. Only exists on the client. 25 | * 26 | * @param bookStack - The ItemStack assigned to your book. 27 | */ 28 | @SideOnly(Side.CLIENT) 29 | default void handleModel(@Nonnull ItemStack bookStack) { 30 | GuideAPI.setModel(((IGuideItem) bookStack.getItem()).getBook(bookStack)); 31 | } 32 | 33 | /** 34 | * An IRecipe to use for your book. Called from {@link net.minecraftforge.event.RegistryEvent.Register} 35 | * 36 | * @return an IRecipe to register for your book or null to not include one. 37 | */ 38 | @Nullable 39 | default IRecipe getRecipe(@Nonnull ItemStack bookStack) { 40 | return null; 41 | } 42 | 43 | /** 44 | * Called during Post Initialization. 45 | */ 46 | default void handlePost(@Nonnull ItemStack bookStack) { 47 | // No-op 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/IGuideItem.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import net.minecraft.item.ItemStack; 5 | 6 | public interface IGuideItem { 7 | 8 | Book getBook(ItemStack stack); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/IGuideLinked.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraft.item.ItemStack; 5 | import net.minecraft.util.ResourceLocation; 6 | import net.minecraft.util.math.BlockPos; 7 | import net.minecraft.world.World; 8 | 9 | import javax.annotation.Nullable; 10 | 11 | public interface IGuideLinked { 12 | 13 | /** 14 | * @param world - The world where the block is 15 | * @param pos - The block's location in the world 16 | * @param player - The player that triggered the method 17 | * @param stack - The ingame book item 18 | * @return the key of the entry to open or null if no entry should be opened 19 | */ 20 | @Nullable 21 | ResourceLocation getLinkedEntry(World world, BlockPos pos, EntityPlayer player, ItemStack stack); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/IInfoRenderer.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import net.minecraft.block.state.IBlockState; 5 | import net.minecraft.entity.player.EntityPlayer; 6 | import net.minecraft.util.math.BlockPos; 7 | import net.minecraft.util.math.RayTraceResult; 8 | import net.minecraft.world.World; 9 | 10 | import javax.annotation.Nonnull; 11 | import javax.annotation.Nullable; 12 | 13 | /** 14 | * Used to render information on screen about a block while a player is looking at and holding the guide. This is only 15 | * called on the client. 16 | *

17 | * Use {@link GuideAPI#registerInfoRenderer(amerifrance.guideapi.api.impl.Book, IInfoRenderer, Class...)} to register your 18 | * handler. You can also implement {@link Block} on a block. 19 | *

20 | * Some example usages can be found in {@link amerifrance.guideapi.info} 21 | *

22 | * You can display recipes, information about what a block does, etc 23 | */ 24 | public interface IInfoRenderer { 25 | 26 | /** 27 | * Draws information on screen while the player is holding the guide and looking at the block. 28 | * 29 | * @param book - The book this instance belongs to 30 | * @param world - The current world 31 | * @param pos - The position of the block being looked at 32 | * @param state - The current state of the block 33 | * @param rayTrace - A RayTraceResult containing data about the block currently looked at 34 | * @param player - The player looking at the block 35 | */ 36 | void drawInformation(Book book, World world, BlockPos pos, IBlockState state, RayTraceResult rayTrace, EntityPlayer player); 37 | 38 | interface Block { 39 | 40 | /** 41 | * Gets an IInfoRenderer for a block. Make sure that the book is yours. 42 | * 43 | * @param book - The book this instance belongs to 44 | * @param world - The current world 45 | * @param pos - The position of the block being looked at 46 | * @param state - The current state of the block 47 | * @param rayTrace - A RayTraceResult containing data about the block currently looked at 48 | * @param player - The player looking at the block 49 | * @return an IInfoRenderer for this block. If no IInfoRenderer is needed, return null. 50 | */ 51 | @Nullable 52 | IInfoRenderer getInfoRenderer(Book book, World world, BlockPos pos, IBlockState state, RayTraceResult rayTrace, EntityPlayer player); 53 | 54 | /** 55 | * @return returns the book required to display information. 56 | */ 57 | @Nonnull 58 | Book getBook(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/IPage.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 5 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 6 | import amerifrance.guideapi.gui.GuiBase; 7 | import amerifrance.guideapi.gui.GuiEntry; 8 | import net.minecraft.client.gui.FontRenderer; 9 | import net.minecraft.entity.player.EntityPlayer; 10 | import net.minecraft.item.ItemStack; 11 | import net.minecraftforge.fml.relauncher.Side; 12 | import net.minecraftforge.fml.relauncher.SideOnly; 13 | 14 | public interface IPage { 15 | 16 | @SideOnly(Side.CLIENT) 17 | void draw(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj); 18 | 19 | @SideOnly(Side.CLIENT) 20 | void drawExtras(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj); 21 | 22 | boolean canSee(Book book, CategoryAbstract category, EntryAbstract entry, EntityPlayer player, ItemStack bookStack, GuiEntry guiEntry); 23 | 24 | @SideOnly(Side.CLIENT) 25 | void onLeftClicked(Book book, CategoryAbstract category, EntryAbstract entry, int mouseX, int mouseY, EntityPlayer player, GuiEntry guiEntry); 26 | 27 | @SideOnly(Side.CLIENT) 28 | void onRightClicked(Book book, CategoryAbstract category, EntryAbstract entry, int mouseX, int mouseY, EntityPlayer player, GuiEntry guiEntry); 29 | 30 | @SideOnly(Side.CLIENT) 31 | void onInit(Book book, CategoryAbstract category, EntryAbstract entry, EntityPlayer player, ItemStack bookStack, GuiEntry guiEntry); 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/IRecipeRenderer.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 5 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 6 | import amerifrance.guideapi.gui.GuiBase; 7 | import com.google.common.collect.Lists; 8 | import net.minecraft.client.gui.FontRenderer; 9 | import net.minecraft.item.crafting.IRecipe; 10 | import net.minecraftforge.fml.relauncher.Side; 11 | import net.minecraftforge.fml.relauncher.SideOnly; 12 | 13 | import java.util.List; 14 | 15 | public interface IRecipeRenderer { 16 | 17 | @SideOnly(Side.CLIENT) 18 | void draw(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj); 19 | 20 | @SideOnly(Side.CLIENT) 21 | void drawExtras(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj); 22 | 23 | abstract class RecipeRendererBase implements IRecipeRenderer { 24 | 25 | protected T recipe; 26 | protected List tooltips = Lists.newArrayList(); 27 | 28 | public RecipeRendererBase(T recipe) { 29 | this.recipe = recipe; 30 | } 31 | 32 | @Override 33 | public void drawExtras(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 34 | guiBase.drawHoveringText(tooltips, mouseX, mouseY); 35 | tooltips.clear(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/SubTexture.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.renderer.BufferBuilder; 5 | import net.minecraft.client.renderer.GlStateManager; 6 | import net.minecraft.client.renderer.Tessellator; 7 | import net.minecraft.client.renderer.vertex.DefaultVertexFormats; 8 | import net.minecraft.util.ResourceLocation; 9 | import net.minecraftforge.fml.relauncher.Side; 10 | import net.minecraftforge.fml.relauncher.SideOnly; 11 | 12 | public class SubTexture { 13 | 14 | private static final ResourceLocation RECIPE_ELEMENTS = new ResourceLocation("guideapi", "textures/gui/recipe_elements.png"); 15 | private static final ResourceLocation OTHER_ELEMENTS = new ResourceLocation("guideapi", "textures/gui/book_colored.png"); 16 | // Grids 17 | public static final SubTexture CRAFTING_GRID = new SubTexture(RECIPE_ELEMENTS, 0, 48, 102, 56); 18 | public static final SubTexture FURNACE_GRID = new SubTexture(RECIPE_ELEMENTS, 0, 104, 68, 28); 19 | public static final SubTexture POTION_GRID = new SubTexture(RECIPE_ELEMENTS, 0, 132, 68, 81); 20 | 21 | // Singletons 22 | public static final SubTexture SINGLE_SLOT = new SubTexture(RECIPE_ELEMENTS, 0, 28, 20, 20); 23 | public static final SubTexture MAGNIFYING_GLASS = new SubTexture(OTHER_ELEMENTS, 0, 241, 15, 15); 24 | 25 | // Large buttons 26 | public static final SubTexture LARGE_BUTTON = new SubTexture(RECIPE_ELEMENTS, 0, 0, 55, 18); 27 | public static final SubTexture LARGE_BUTTON_HOVER = new SubTexture(RECIPE_ELEMENTS, 55, 0, 55, 18); 28 | public static final SubTexture LARGE_BUTTON_PRESS = new SubTexture(RECIPE_ELEMENTS, 110, 0, 55, 18); 29 | 30 | // Small buttons 31 | public static final SubTexture SMALL_BUTTON_BLANK = new SubTexture(RECIPE_ELEMENTS, 0, 0, 10, 10); 32 | public static final SubTexture SMALL_BUTTON_BLANK_HOVER = new SubTexture(RECIPE_ELEMENTS, 40, 0, 10, 10); 33 | public static final SubTexture SMALL_BUTTON_BLANK_PRESS = new SubTexture(RECIPE_ELEMENTS, 80, 0, 10, 10); 34 | public static final SubTexture SMALL_BUTTON_CRAFT = new SubTexture(RECIPE_ELEMENTS, 10, 0, 10, 10); 35 | public static final SubTexture SMALL_BUTTON_CRAFT_HOVER = new SubTexture(RECIPE_ELEMENTS, 50, 0, 10, 10); 36 | public static final SubTexture SMALL_BUTTON_CRAFT_PRESS = new SubTexture(RECIPE_ELEMENTS, 90, 0, 10, 10); 37 | public static final SubTexture SMALL_BUTTON_FURNACE = new SubTexture(RECIPE_ELEMENTS, 20, 0, 10, 10); 38 | public static final SubTexture SMALL_BUTTON_FURNACE_HOVER = new SubTexture(RECIPE_ELEMENTS, 60, 0, 10, 10); 39 | public static final SubTexture SMALL_BUTTON_FURNACE_PRESS = new SubTexture(RECIPE_ELEMENTS, 100, 0, 10, 10); 40 | public static final SubTexture SMALL_BUTTON_POTION = new SubTexture(RECIPE_ELEMENTS, 30, 0, 10, 10); 41 | public static final SubTexture SMALL_BUTTON_POTION_HOVER = new SubTexture(RECIPE_ELEMENTS, 70, 0, 10, 10); 42 | public static final SubTexture SMALL_BUTTON_POTION_PRESS = new SubTexture(RECIPE_ELEMENTS, 110, 0, 10, 10); 43 | 44 | private final ResourceLocation textureLocation; 45 | private final int xPos; 46 | private final int yPos; 47 | private final int width; 48 | private final int height; 49 | 50 | public SubTexture(ResourceLocation textureLocation, int xPos, int yPos, int width, int height) { 51 | this.textureLocation = textureLocation; 52 | this.xPos = xPos; 53 | this.yPos = yPos; 54 | this.width = width; 55 | this.height = height; 56 | } 57 | 58 | @SideOnly(Side.CLIENT) 59 | public void draw(int drawX, int drawY, double zLevel) { 60 | final float someMagicValueFromMojang = 0.00390625F; 61 | 62 | Minecraft.getMinecraft().renderEngine.bindTexture(textureLocation); 63 | GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); 64 | Tessellator tessellator = Tessellator.getInstance(); 65 | BufferBuilder vertexbuffer = tessellator.getBuffer(); 66 | vertexbuffer.begin(7, DefaultVertexFormats.POSITION_TEX); 67 | vertexbuffer.pos((double) drawX, (double) (drawY + height), zLevel).tex((double) ((float) xPos * someMagicValueFromMojang), (double) ((float) (yPos + height) * someMagicValueFromMojang)).endVertex(); 68 | vertexbuffer.pos((double) (drawX + width), (double) (drawY + height), zLevel).tex((double) ((float) (xPos + width) * someMagicValueFromMojang), (double) ((float) (yPos + height) * someMagicValueFromMojang)).endVertex(); 69 | vertexbuffer.pos((double) (drawX + width), (double) drawY, zLevel).tex((double) ((float) (xPos + width) * someMagicValueFromMojang), (double) ((float) yPos * someMagicValueFromMojang)).endVertex(); 70 | vertexbuffer.pos((double) drawX, (double) drawY, zLevel).tex((double) ((float) xPos * someMagicValueFromMojang), (double) ((float) yPos * someMagicValueFromMojang)).endVertex(); 71 | tessellator.draw(); 72 | } 73 | 74 | @SideOnly(Side.CLIENT) 75 | public void draw(int drawX, int drawY) { 76 | draw(drawX, drawY, 0.1D); 77 | } 78 | 79 | public ResourceLocation getTextureLocation() { 80 | return textureLocation; 81 | } 82 | 83 | public int getDrawX() { 84 | return xPos; 85 | } 86 | 87 | public int getDrawY() { 88 | return yPos; 89 | } 90 | 91 | public int getWidth() { 92 | return width; 93 | } 94 | 95 | public int getHeight() { 96 | return height; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/button/ButtonGuideAPI.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api.button; 2 | 3 | import amerifrance.guideapi.gui.GuiBase; 4 | import net.minecraft.client.gui.GuiButton; 5 | 6 | public class ButtonGuideAPI extends GuiButton { 7 | 8 | public GuiBase guiBase; 9 | 10 | public ButtonGuideAPI(int id, int x, int y, GuiBase guiBase) { 11 | super(id, x, y, ""); 12 | this.guiBase = guiBase; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/impl/BookBinder.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api.impl; 2 | 3 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 4 | import com.google.common.base.Strings; 5 | import com.google.common.collect.Lists; 6 | import net.minecraft.creativetab.CreativeTabs; 7 | import net.minecraft.util.ResourceLocation; 8 | import net.minecraftforge.fml.common.Loader; 9 | 10 | import java.awt.Color; 11 | import java.util.List; 12 | 13 | public class BookBinder { 14 | 15 | private final ResourceLocation registryName; 16 | private final List categories = Lists.newArrayList(); 17 | private String guideTitle = "item.guideapi.book.name"; 18 | private String header; 19 | private String itemName; 20 | private String author; 21 | private ResourceLocation pageTexture = new ResourceLocation("guideapi", "textures/gui/book_colored.png"); 22 | private ResourceLocation outlineTexture = new ResourceLocation("guideapi", "textures/gui/book_greyscale.png"); 23 | private boolean hasCustomModel; 24 | private Color color = new Color(171, 70, 30); 25 | private boolean spawnWithBook; 26 | private CreativeTabs creativeTab = CreativeTabs.MISC; 27 | 28 | /** 29 | * Creates a new {@link Book} builder which will provide a much more user-friendly interface for creating books. 30 | * 31 | * @param registryName The registry name for the book to build. Should use your modid as the domain. 32 | */ 33 | public BookBinder(ResourceLocation registryName) { 34 | this.registryName = registryName; 35 | } 36 | 37 | /** 38 | * Adds a new {@link CategoryAbstract} to this book. You should either pre-build or keep a reference of this category 39 | * so you may populate it with entries. 40 | * 41 | * Categories are displayed in the order they are added. 42 | * 43 | * @param category The category to add to this book. 44 | * @return the builder instance for chaining. 45 | */ 46 | public BookBinder addCategory(CategoryAbstract category) { 47 | this.categories.add(category); 48 | return this; 49 | } 50 | 51 | /** 52 | * Sets the title of this book to be displayed in the GUI. 53 | * 54 | * @param guideTitle The title of this guide. 55 | * @return the builder instance for chaining. 56 | */ 57 | public BookBinder setGuideTitle(String guideTitle) { 58 | this.guideTitle = guideTitle; 59 | return this; 60 | } 61 | 62 | /** 63 | * Sets the header text of this book. The header is displayed at the top of the home page above the category listing. 64 | * 65 | * By default, this is the same as {@link #guideTitle}. 66 | * 67 | * @param header The header text to display. 68 | * @return the builder instance for chaining. 69 | */ 70 | public BookBinder setHeader(String header) { 71 | this.header = header; 72 | return this; 73 | } 74 | 75 | /** 76 | * Sets the unlocalized name for the item containing this book. 77 | * 78 | * By default, this is the same as {@link #guideTitle}. 79 | * 80 | * @param itemName The unlocalized name for this item. 81 | * @return the builder instance for chaining. 82 | */ 83 | public BookBinder setItemName(String itemName) { 84 | this.itemName = itemName; 85 | return this; 86 | } 87 | 88 | /** 89 | * The author of this book. If your books are lore-heavy, using an actual author name is acceptable. If not, you can 90 | * just use your mod name. 91 | * 92 | * By default, this uses the name of the mod container obtained from looking up the domain of {@link #registryName}. 93 | * 94 | * @param author The author of this book. 95 | * @return the builder instance for chaining. 96 | */ 97 | public BookBinder setAuthor(String author) { 98 | this.author = author; 99 | return this; 100 | } 101 | 102 | /** 103 | * The texture to use for the pages themselves. These are un-colored and drawn just how they appear in the texture file. 104 | * The dimensions should remain the same as the default texture. 105 | * 106 | * By default, this uses the same page texture as vanilla books. 107 | * 108 | * @param pageTexture The page texture to use for this guide. 109 | * @return the builder instance for chaining. 110 | */ 111 | public BookBinder setPageTexture(ResourceLocation pageTexture) { 112 | this.pageTexture = pageTexture; 113 | return this; 114 | } 115 | 116 | /** 117 | * The texture to use for the border of the book. These are colored with {@link #color}. The dimensions should remain 118 | * the same as the default texture. 119 | * 120 | * By default, this uses a greyscale version of the outline of vanilla books. 121 | * 122 | * @param outlineTexture The outline texture to use for this guide. 123 | * @return the builder instance for chaining. 124 | */ 125 | public BookBinder setOutlineTexture(ResourceLocation outlineTexture) { 126 | this.outlineTexture = outlineTexture; 127 | return this; 128 | } 129 | 130 | /** 131 | * Indicates that the item containing this book has a custom model that you will manually register. 132 | * 133 | * By default, a generic book model will be registered and colored with {@link #color}. 134 | * 135 | * @return the builder instance for chaining. 136 | */ 137 | public BookBinder setHasCustomModel() { 138 | this.hasCustomModel = true; 139 | return this; 140 | } 141 | 142 | /** 143 | * Sets the color to overlay on the book model and GUI border. 144 | * 145 | * By default, this is a reddish-brown color. 146 | * 147 | * @param color The color to overlay with. 148 | * @return the builder instance for chaining. 149 | */ 150 | public BookBinder setColor(Color color) { 151 | this.color = color; 152 | return this; 153 | } 154 | 155 | /** 156 | * An overload that takes an RGB color instead of a {@link Color} instance. 157 | * 158 | * @see #setColor(int) 159 | * 160 | * @param color The color to overlay with. 161 | * @return the builder instance for chaining. 162 | */ 163 | public BookBinder setColor(int color) { 164 | return setColor(new Color(color)); 165 | } 166 | 167 | /** 168 | * Sets the default config option for whether new players should spawn with this book in their inventory. Players may 169 | * override this in the config if they wish. 170 | * 171 | * By default, books will not spawn in the player's inventory. 172 | * 173 | * @return the builder instance for chaining. 174 | */ 175 | public BookBinder setSpawnWithBook() { 176 | this.spawnWithBook = true; 177 | return this; 178 | } 179 | 180 | /** 181 | * Sets the Creative Tab this book should appear in. 182 | * 183 | * By default, all books will appear in {@link CreativeTabs#MISC}. 184 | * 185 | * @param creativeTab The creative tab this book should display in. 186 | * @return the builder instance for chaining. 187 | */ 188 | public BookBinder setCreativeTab(CreativeTabs creativeTab) { 189 | this.creativeTab = creativeTab; 190 | return this; 191 | } 192 | 193 | /** 194 | * Constructs a book from the given data. Will modify specific values if not set so they have defaults. 195 | * @return a constructed book. 196 | */ 197 | public Book build() { 198 | if (Strings.isNullOrEmpty(author)) 199 | this.author = Loader.instance().getIndexedModList().getOrDefault(registryName.getResourceDomain(), Loader.instance().getMinecraftModContainer()).getName(); 200 | 201 | if (header == null) 202 | this.header = guideTitle; 203 | 204 | if (this.itemName == null) 205 | this.itemName = guideTitle.substring(5); 206 | 207 | return new Book(categories, guideTitle, header, itemName, author, pageTexture, outlineTexture, hasCustomModel, color, spawnWithBook, registryName, creativeTab); 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/impl/Category.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api.impl; 2 | 3 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 4 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 5 | import amerifrance.guideapi.gui.GuiBase; 6 | import amerifrance.guideapi.gui.GuiCategory; 7 | import amerifrance.guideapi.gui.GuiHome; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.renderer.RenderItem; 10 | import net.minecraft.entity.player.EntityPlayer; 11 | import net.minecraft.item.ItemStack; 12 | import net.minecraft.util.ResourceLocation; 13 | import net.minecraftforge.fml.relauncher.Side; 14 | import net.minecraftforge.fml.relauncher.SideOnly; 15 | 16 | import java.util.Map; 17 | 18 | public class Category extends CategoryAbstract { 19 | 20 | public Category(Map entryList, String name) { 21 | super(entryList, name); 22 | } 23 | 24 | public Category(String name) { 25 | super(name); 26 | } 27 | 28 | @Override 29 | @SideOnly(Side.CLIENT) 30 | public void draw(Book book, int categoryX, int categoryY, int categoryWidth, int categoryHeight, int mouseX, int mouseY, GuiBase guiBase, boolean drawOnLeft, RenderItem renderItem) { 31 | } 32 | 33 | @Override 34 | @SideOnly(Side.CLIENT) 35 | public void drawExtras(Book book, int categoryX, int categoryY, int categoryWidth, int categoryHeight, int mouseX, int mouseY, GuiBase guiBase, boolean drawOnLeft, RenderItem renderItem) { 36 | } 37 | 38 | @Override 39 | public boolean canSee(EntityPlayer player, ItemStack bookStack) { 40 | return true; 41 | } 42 | 43 | @Override 44 | @SideOnly(Side.CLIENT) 45 | public void onLeftClicked(Book book, int mouseX, int mouseY, EntityPlayer player, ItemStack bookStack) { 46 | Minecraft.getMinecraft().displayGuiScreen(new GuiCategory(book, this, player, bookStack, null)); 47 | } 48 | 49 | @Override 50 | @SideOnly(Side.CLIENT) 51 | public void onRightClicked(Book book, int mouseX, int mouseY, EntityPlayer player, ItemStack bookStack) { 52 | } 53 | 54 | @Override 55 | @SideOnly(Side.CLIENT) 56 | public void onInit(Book book, GuiHome guiHome, EntityPlayer player, ItemStack bookStack) { 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/impl/Entry.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api.impl; 2 | 3 | import amerifrance.guideapi.api.IPage; 4 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 5 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 6 | import amerifrance.guideapi.api.util.GuiHelper; 7 | import amerifrance.guideapi.gui.GuiBase; 8 | import amerifrance.guideapi.gui.GuiCategory; 9 | import amerifrance.guideapi.gui.GuiEntry; 10 | import net.minecraft.client.Minecraft; 11 | import net.minecraft.client.gui.FontRenderer; 12 | import net.minecraft.entity.player.EntityPlayer; 13 | import net.minecraft.item.ItemStack; 14 | import net.minecraftforge.fml.relauncher.Side; 15 | import net.minecraftforge.fml.relauncher.SideOnly; 16 | 17 | import java.awt.Color; 18 | import java.util.Collections; 19 | import java.util.List; 20 | 21 | public class Entry extends EntryAbstract { 22 | 23 | public Entry(List pageList, String name, boolean unicode) { 24 | super(pageList, name, unicode); 25 | } 26 | 27 | public Entry(List pageList, String name) { 28 | super(pageList, name, false); 29 | } 30 | 31 | public Entry(String name, boolean unicode) { 32 | super(name, unicode); 33 | } 34 | 35 | public Entry(String name) { 36 | super(name); 37 | } 38 | 39 | @Override 40 | @SideOnly(Side.CLIENT) 41 | public void draw(Book book, CategoryAbstract category, int entryX, int entryY, int entryWidth, int entryHeight, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 42 | 43 | boolean startFlag = fontRendererObj.getUnicodeFlag(); 44 | 45 | if (unicode) 46 | fontRendererObj.setUnicodeFlag(true); 47 | 48 | // Cutting code ripped from GuiButtonExt#drawButton(...) 49 | String entryName = getLocalizedName(); 50 | int strWidth = fontRendererObj.getStringWidth(entryName); 51 | int ellipsisWidth = fontRendererObj.getStringWidth("..."); 52 | 53 | if (strWidth > guiBase.xSize - 80 && strWidth > ellipsisWidth) 54 | entryName = fontRendererObj.trimStringToWidth(entryName, guiBase.xSize - 80 - ellipsisWidth).trim() + "..."; 55 | 56 | if (GuiHelper.isMouseBetween(mouseX, mouseY, entryX, entryY, entryWidth, entryHeight)) { 57 | fontRendererObj.drawString(entryName, entryX + 12, entryY + 1, new Color(206, 206, 206).getRGB()); 58 | fontRendererObj.drawString(entryName, entryX + 12, entryY, 0x423EBC); 59 | } else { 60 | fontRendererObj.drawString(entryName, entryX + 12, entryY, 0); 61 | } 62 | 63 | if (unicode && !startFlag) 64 | fontRendererObj.setUnicodeFlag(false); 65 | } 66 | 67 | @Override 68 | @SideOnly(Side.CLIENT) 69 | public void drawExtras(Book book, CategoryAbstract category, int entryX, int entryY, int entryWidth, int entryHeight, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 70 | boolean startFlag = fontRendererObj.getUnicodeFlag(); 71 | fontRendererObj.setUnicodeFlag(false); 72 | 73 | // Cutting code ripped from GuiButtonExt#drawButton(...) 74 | int strWidth = fontRendererObj.getStringWidth(getLocalizedName()); 75 | boolean cutString = false; 76 | 77 | if (strWidth > guiBase.xSize - 80 && strWidth > fontRendererObj.getStringWidth("...")) 78 | cutString = true; 79 | 80 | if (GuiHelper.isMouseBetween(mouseX, mouseY, entryX, entryY, entryWidth, entryHeight) && cutString) { 81 | 82 | guiBase.drawHoveringText(Collections.singletonList(getLocalizedName()), entryX, entryY + 12); 83 | fontRendererObj.setUnicodeFlag(unicode); 84 | } 85 | 86 | fontRendererObj.setUnicodeFlag(startFlag); 87 | } 88 | 89 | @Override 90 | public boolean canSee(EntityPlayer player, ItemStack bookStack) { 91 | return true; 92 | } 93 | 94 | @Override 95 | @SideOnly(Side.CLIENT) 96 | public void onLeftClicked(Book book, CategoryAbstract category, int mouseX, int mouseY, EntityPlayer player, GuiCategory guiCategory) { 97 | Minecraft.getMinecraft().displayGuiScreen(new GuiEntry(book, category, this, player, guiCategory.bookStack)); 98 | } 99 | 100 | @Override 101 | @SideOnly(Side.CLIENT) 102 | public void onRightClicked(Book book, CategoryAbstract category, int mouseX, int mouseY, EntityPlayer player, GuiCategory guiCategory) { 103 | } 104 | 105 | @Override 106 | @SideOnly(Side.CLIENT) 107 | public void onInit(Book book, CategoryAbstract category, GuiCategory guiCategory, EntityPlayer player, ItemStack bookStack) { 108 | } 109 | } -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/impl/Page.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api.impl; 2 | 3 | import amerifrance.guideapi.api.IPage; 4 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 5 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 6 | import amerifrance.guideapi.gui.GuiBase; 7 | import amerifrance.guideapi.gui.GuiEntry; 8 | import net.minecraft.client.gui.FontRenderer; 9 | import net.minecraft.entity.player.EntityPlayer; 10 | import net.minecraft.item.ItemStack; 11 | import net.minecraftforge.fml.relauncher.Side; 12 | import net.minecraftforge.fml.relauncher.SideOnly; 13 | 14 | public class Page implements IPage { 15 | 16 | protected boolean unicode; 17 | 18 | @Override 19 | @SideOnly(Side.CLIENT) 20 | public void draw(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 21 | } 22 | 23 | @Override 24 | @SideOnly(Side.CLIENT) 25 | public void drawExtras(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 26 | } 27 | 28 | @Override 29 | public boolean canSee(Book book, CategoryAbstract category, EntryAbstract entry, EntityPlayer player, ItemStack bookStack, GuiEntry guiEntry) { 30 | return true; 31 | } 32 | 33 | @Override 34 | @SideOnly(Side.CLIENT) 35 | public void onLeftClicked(Book book, CategoryAbstract category, EntryAbstract entry, int mouseX, int mouseY, EntityPlayer player, GuiEntry guiEntry) { 36 | } 37 | 38 | @Override 39 | @SideOnly(Side.CLIENT) 40 | public void onRightClicked(Book book, CategoryAbstract category, EntryAbstract entry, int mouseX, int mouseY, EntityPlayer player, GuiEntry guiEntry) { 41 | } 42 | 43 | @Override 44 | @SideOnly(Side.CLIENT) 45 | public void onInit(Book book, CategoryAbstract category, EntryAbstract entry, EntityPlayer player, ItemStack bookStack, GuiEntry guiEntry) { 46 | } 47 | 48 | public void setUnicodeFlag(boolean flag) { 49 | this.unicode = flag; 50 | } 51 | 52 | @Override 53 | public boolean equals(Object o) { 54 | if (this == o) return true; 55 | if (o == null) return false; 56 | if (getClass() != o.getClass()) return false; 57 | return true; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/impl/abstraction/CategoryAbstract.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api.impl.abstraction; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import amerifrance.guideapi.api.util.TextHelper; 5 | import amerifrance.guideapi.gui.GuiBase; 6 | import amerifrance.guideapi.gui.GuiHome; 7 | import com.google.common.base.Strings; 8 | import com.google.common.collect.Lists; 9 | import com.google.common.collect.Maps; 10 | import net.minecraft.client.renderer.RenderItem; 11 | import net.minecraft.entity.player.EntityPlayer; 12 | import net.minecraft.item.ItemStack; 13 | import net.minecraft.util.ResourceLocation; 14 | import net.minecraftforge.fml.relauncher.Side; 15 | import net.minecraftforge.fml.relauncher.SideOnly; 16 | 17 | import java.util.List; 18 | import java.util.Map; 19 | 20 | public abstract class CategoryAbstract { 21 | 22 | public final Map entries; 23 | public final String name; 24 | private String keyBase; 25 | 26 | public CategoryAbstract(Map entries, String name) { 27 | this.entries = entries; 28 | this.name = name; 29 | } 30 | 31 | public CategoryAbstract(String name) { 32 | this(Maps.newLinkedHashMap(), name); 33 | } 34 | 35 | /** 36 | * Adds an entry to this category. 37 | * 38 | * @param key - The key of the entry to add. 39 | * @param entry - The entry to add. 40 | */ 41 | public void addEntry(ResourceLocation key, EntryAbstract entry) { 42 | entries.put(key, entry); 43 | } 44 | 45 | /** 46 | * Adds an entry to this category. 47 | *

48 | * Shorthand of {@link #addEntry(ResourceLocation, EntryAbstract)}. Requires {@link #withKeyBase(String)} to have been called. 49 | * 50 | * @param key - The key of the entry to add. 51 | * @param entry - The entry to add. 52 | */ 53 | public void addEntry(String key, EntryAbstract entry) { 54 | if (Strings.isNullOrEmpty(keyBase)) 55 | throw new RuntimeException("keyBase in category with name '" + name + "' must be set."); 56 | 57 | addEntry(new ResourceLocation(keyBase, key), entry); 58 | } 59 | 60 | public void removeEntry(ResourceLocation key) { 61 | entries.remove(key); 62 | } 63 | 64 | public void addEntries(Map entries) { 65 | this.entries.putAll(entries); 66 | } 67 | 68 | public void removeEntries(List keys) { 69 | for (ResourceLocation key : keys) 70 | if (entries.containsKey(key)) 71 | entries.remove(key); 72 | } 73 | 74 | /** 75 | * Obtains an entry from this category. 76 | *

77 | * This can be null, however it is not marked as nullable to avoid annoying IDE warnings. I am making the 78 | * assumption that this will only be called while creating the book and thus the caller knows it exists. 79 | *

80 | * If you are calling at any other time, make sure to nullcheck this. 81 | * 82 | * @param key - The key of the entry to obtain. 83 | * @return the found entry. 84 | */ 85 | public EntryAbstract getEntry(ResourceLocation key) { 86 | return entries.get(key); 87 | } 88 | 89 | /** 90 | * Obtains an entry from this category. 91 | *

92 | * Shorthand of {@link #getEntry(ResourceLocation)}. Requires {@link #withKeyBase(String)} to have been called. 93 | *

94 | * This can be null, however it is not marked as nullable to avoid annoying IDE warnings. I am making the 95 | * assumption that this will only be called while creating the book and thus the caller knows it exists. 96 | *

97 | * If you are calling at any other time, make sure to nullcheck this. 98 | * 99 | * @param key - The key of the entry to obtain. 100 | * @return the found entry. 101 | */ 102 | public EntryAbstract getEntry(String key) { 103 | if (Strings.isNullOrEmpty(keyBase)) 104 | throw new RuntimeException("keyBase in category with name '" + name + "' must be set."); 105 | 106 | return getEntry(new ResourceLocation(keyBase, key)); 107 | } 108 | 109 | /** 110 | * Sets the domain to use for all ResourceLocation keys passed through {@link #getEntry(String)} and 111 | * {@link #addEntry(String, EntryAbstract)} 112 | *

113 | * Required in order to use those. 114 | * 115 | * @param keyBase - The base domain for this entry. 116 | * @return self for chaining. 117 | */ 118 | public CategoryAbstract withKeyBase(String keyBase) { 119 | this.keyBase = keyBase; 120 | return this; 121 | } 122 | 123 | /** 124 | * Obtains a localized copy of this category's name. 125 | * 126 | * @return a localized copy of this category's name. 127 | */ 128 | public String getLocalizedName() { 129 | return TextHelper.localizeEffect(name); 130 | } 131 | 132 | public List getTooltip() { 133 | return Lists.newArrayList(getLocalizedName()); 134 | } 135 | 136 | @SideOnly(Side.CLIENT) 137 | public abstract void draw(Book book, int categoryX, int categoryY, int categoryWidth, int categoryHeight, int mouseX, int mouseY, GuiBase guiBase, boolean drawOnLeft, RenderItem renderItem); 138 | 139 | @SideOnly(Side.CLIENT) 140 | public abstract void drawExtras(Book book, int categoryX, int categoryY, int categoryWidth, int categoryHeight, int mouseX, int mouseY, GuiBase guiBase, boolean drawOnLeft, RenderItem renderItem); 141 | 142 | public abstract boolean canSee(EntityPlayer player, ItemStack bookStack); 143 | 144 | @SideOnly(Side.CLIENT) 145 | public abstract void onLeftClicked(Book book, int mouseX, int mouseY, EntityPlayer player, ItemStack bookStack); 146 | 147 | @SideOnly(Side.CLIENT) 148 | public abstract void onRightClicked(Book book, int mouseX, int mouseY, EntityPlayer player, ItemStack bookStack); 149 | 150 | @SideOnly(Side.CLIENT) 151 | public abstract void onInit(Book book, GuiHome guiHome, EntityPlayer player, ItemStack bookStack); 152 | 153 | @Override 154 | public boolean equals(Object o) { 155 | if (this == o) return true; 156 | if (o == null || getClass() != o.getClass()) return false; 157 | 158 | CategoryAbstract that = (CategoryAbstract) o; 159 | if (entries != null ? !entries.equals(that.entries) : that.entries != null) return false; 160 | if (name != null ? !name.equals(that.name) : that.name != null) 161 | return false; 162 | 163 | return true; 164 | } 165 | 166 | @Override 167 | public int hashCode() { 168 | int result = entries != null ? entries.hashCode() : 0; 169 | result = 31 * result + (name != null ? name.hashCode() : 0); 170 | return result; 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/impl/abstraction/EntryAbstract.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api.impl.abstraction; 2 | 3 | import amerifrance.guideapi.api.IPage; 4 | import amerifrance.guideapi.api.impl.Book; 5 | import amerifrance.guideapi.api.util.TextHelper; 6 | import amerifrance.guideapi.gui.GuiBase; 7 | import amerifrance.guideapi.gui.GuiCategory; 8 | import com.google.common.collect.Lists; 9 | import net.minecraft.client.gui.FontRenderer; 10 | import net.minecraft.entity.player.EntityPlayer; 11 | import net.minecraft.item.ItemStack; 12 | import net.minecraftforge.fml.relauncher.Side; 13 | import net.minecraftforge.fml.relauncher.SideOnly; 14 | 15 | import java.util.List; 16 | 17 | public abstract class EntryAbstract { 18 | 19 | public final List pageList; 20 | public final String name; 21 | public boolean unicode; 22 | 23 | public EntryAbstract(List pageList, String name, boolean unicode) { 24 | this.pageList = pageList; 25 | this.name = name; 26 | this.unicode = unicode; 27 | } 28 | 29 | public EntryAbstract(List pageList, String name) { 30 | this(pageList, name, false); 31 | } 32 | 33 | public EntryAbstract(String name, boolean unicode) { 34 | this(Lists.newArrayList(), name, unicode); 35 | } 36 | 37 | public EntryAbstract(String name) { 38 | this(name, false); 39 | } 40 | 41 | public void addPage(IPage page) { 42 | this.pageList.add(page); 43 | } 44 | 45 | public void removePage(IPage page) { 46 | this.pageList.remove(page); 47 | } 48 | 49 | public void addPageList(List pages) { 50 | this.pageList.addAll(pages); 51 | } 52 | 53 | public void removePageList(List pages) { 54 | this.pageList.removeAll(pages); 55 | } 56 | 57 | public String getLocalizedName() { 58 | return TextHelper.localizeEffect(name); 59 | } 60 | 61 | @SideOnly(Side.CLIENT) 62 | public abstract void draw(Book book, CategoryAbstract category, int entryX, int entryY, int entryWidth, int entryHeight, int mouseX, int mouseY, GuiBase guiBase, FontRenderer renderer); 63 | 64 | @SideOnly(Side.CLIENT) 65 | public abstract void drawExtras(Book book, CategoryAbstract category, int entryX, int entryY, int entryWidth, int entryHeight, int mouseX, int mouseY, GuiBase guiBase, FontRenderer renderer); 66 | 67 | public abstract boolean canSee(EntityPlayer player, ItemStack bookStack); 68 | 69 | @SideOnly(Side.CLIENT) 70 | public abstract void onLeftClicked(Book book, CategoryAbstract category, int mouseX, int mouseY, EntityPlayer player, GuiCategory guiCategory); 71 | 72 | @SideOnly(Side.CLIENT) 73 | public abstract void onRightClicked(Book book, CategoryAbstract category, int mouseX, int mouseY, EntityPlayer player, GuiCategory guiCategory); 74 | 75 | @SideOnly(Side.CLIENT) 76 | public abstract void onInit(Book book, CategoryAbstract category, GuiCategory guiCategory, EntityPlayer player, ItemStack bookStack); 77 | 78 | @Override 79 | public boolean equals(Object o) { 80 | if (this == o) return true; 81 | if (o == null || getClass() != o.getClass()) return false; 82 | 83 | EntryAbstract that = (EntryAbstract) o; 84 | if (pageList != null ? !pageList.equals(that.pageList) : that.pageList != null) return false; 85 | if (name != null ? !name.equals(that.name) : that.name != null) 86 | return false; 87 | 88 | return true; 89 | } 90 | 91 | @Override 92 | public int hashCode() { 93 | int result = pageList != null ? pageList.hashCode() : 0; 94 | result = 31 * result + (name != null ? name.hashCode() : 0); 95 | return result; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/package-info.java: -------------------------------------------------------------------------------- 1 | @API(owner = "guideapi", apiVersion = "@API_VERSION@", provides = "Guide-API|API") 2 | package amerifrance.guideapi.api; 3 | 4 | import net.minecraftforge.fml.common.API; -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/util/BookHelper.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api.util; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 5 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 6 | 7 | public class BookHelper { 8 | 9 | public static CategoryAbstract getCategoryFromName(Book book, String unlocName) { 10 | for (CategoryAbstract category : book.getCategoryList()) { 11 | if (category.name.equals(unlocName)) 12 | return category; 13 | } 14 | return null; 15 | } 16 | 17 | public static EntryAbstract getEntryFromName(CategoryAbstract category, String unlocName) { 18 | for (EntryAbstract entry : category.entries.values()) { 19 | if (entry.name.equals(unlocName)) 20 | return entry; 21 | } 22 | return null; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/util/NBTBookTags.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api.util; 2 | 3 | public class NBTBookTags { 4 | 5 | public static String BOOK_TAG = "G-API_Book"; 6 | public static String CATEGORY_TAG = "G-API_Category"; 7 | public static String CATEGORY_PAGE_TAG = CATEGORY_TAG + "_Page"; 8 | public static String ENTRY_TAG = "G-API_Entry"; 9 | public static String ENTRY_PAGE_TAG = ENTRY_TAG + "_Page"; 10 | public static String PAGE_TAG = "G-API_Page"; 11 | public static String KEY_TAG = "G-API_Key"; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/util/PageHelper.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api.util; 2 | 3 | import amerifrance.guideapi.api.IPage; 4 | import amerifrance.guideapi.api.impl.Page; 5 | import amerifrance.guideapi.gui.GuiBase; 6 | import amerifrance.guideapi.page.PageItemStack; 7 | import amerifrance.guideapi.page.PageText; 8 | import net.minecraft.block.Block; 9 | import net.minecraft.client.Minecraft; 10 | import net.minecraft.client.gui.FontRenderer; 11 | import net.minecraft.item.Item; 12 | import net.minecraft.item.ItemStack; 13 | import net.minecraft.item.crafting.IRecipe; 14 | import org.apache.commons.lang3.StringEscapeUtils; 15 | import org.apache.commons.lang3.text.WordUtils; 16 | 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | 20 | public class PageHelper { 21 | 22 | public static List setPagesToUnicode(List pages) { 23 | for (IPage page : pages) 24 | if (page instanceof Page) 25 | ((Page) page).setUnicodeFlag(true); 26 | 27 | return pages; 28 | } 29 | 30 | public static List pagesForLongText(String locText, int maxLength) { 31 | List pageList = new ArrayList(); 32 | for (String s : WordUtils.wrap(locText, maxLength, "/cut", false).split("/cut")) pageList.add(new PageText(s)); 33 | return pageList; 34 | } 35 | 36 | /** 37 | * @param locText - Text 38 | * @return a list of IPages with the text cut to fit on page 39 | */ 40 | public static List pagesForLongText(String locText) { 41 | return pagesForLongText(locText, 450); 42 | } 43 | 44 | public static List pagesForLongText(String locText, ItemStack stack) { 45 | List pageList = new ArrayList(); 46 | String[] strings = WordUtils.wrap(locText, 450, "/cut", false).split("/cut"); 47 | for (int i = 0; i < strings.length; i++) { 48 | if (i == 0) pageList.add(new PageItemStack(strings[i], stack)); 49 | else pageList.add(new PageText(strings[i])); 50 | } 51 | return pageList; 52 | } 53 | 54 | public static void drawFormattedText(int x, int y, GuiBase guiBase, String toDraw) { 55 | FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; 56 | toDraw = StringEscapeUtils.unescapeJava(toDraw).replaceAll("\\t", " "); 57 | String[] lines = toDraw.split("\n"); 58 | for (String line : lines) { 59 | List cutLines = fontRenderer.listFormattedStringToWidth(line, 3 * guiBase.xSize / 5); 60 | for (String cut : cutLines) { 61 | fontRenderer.drawString(cut, x, y, 0); 62 | y += 10; 63 | } 64 | } 65 | } 66 | 67 | /** 68 | * @param locText - Text 69 | * @param item - The item to put on the first page 70 | * @return a list of IPages with the text cut to fit on page 71 | */ 72 | public static List pagesForLongText(String locText, Item item) { 73 | return pagesForLongText(locText, new ItemStack(item)); 74 | } 75 | 76 | /** 77 | * @param locText - Text 78 | * @param block - The block to put on the first page 79 | * @return a list of IPages with the text cut to fit on page 80 | */ 81 | public static List pagesForLongText(String locText, Block block) { 82 | return pagesForLongText(locText, new ItemStack(block)); 83 | } 84 | 85 | /** 86 | * @param recipe1 - The first IRecipe to compare 87 | * @param recipe2 - The second IRecipe to compare 88 | * @return whether or not the class, size and the output of the recipes are the same 89 | */ 90 | public static boolean areIRecipesEqual(IRecipe recipe1, IRecipe recipe2) { 91 | if (recipe1 == recipe2) return true; 92 | if (recipe1 == null || recipe2 == null || recipe1.getClass() != recipe2.getClass()) return false; 93 | if (recipe1.equals(recipe2)) return true; 94 | if (!recipe1.getRecipeOutput().isItemEqual(recipe2.getRecipeOutput())) return false; 95 | // if (recipe1.getRecipeSize() != recipe2.getRecipeSize()) return false;//FN was removed, there is no size now 96 | return true; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/api/util/TextHelper.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.api.util; 2 | 3 | import net.minecraft.util.text.translation.I18n; 4 | import org.apache.commons.lang3.text.WordUtils; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class TextHelper { 10 | 11 | public static String getFormattedText(String string) { 12 | return string.replaceAll("&", "\u00A7"); 13 | } 14 | 15 | public static String localize(String input, Object... format) { 16 | return I18n.translateToLocalFormatted(input, format); 17 | } 18 | 19 | public static String localizeEffect(String input, Object... format) { 20 | return getFormattedText(localize(input, format)); 21 | } 22 | 23 | public static String[] localizeAll(String[] input) { 24 | String[] ret = new String[input.length]; 25 | for (int i = 0; i < input.length; i++) 26 | ret[i] = localize(input[i]); 27 | 28 | return ret; 29 | } 30 | 31 | public static String[] localizeAllEffect(String[] input) { 32 | String[] ret = new String[input.length]; 33 | for (int i = 0; i < input.length; i++) 34 | ret[i] = localizeEffect(input[i]); 35 | 36 | return ret; 37 | } 38 | 39 | public static ArrayList localizeAll(List input) { 40 | ArrayList ret = new ArrayList(input.size()); 41 | for (int i = 0; i < input.size(); i++) 42 | ret.add(i, localize(input.get(i))); 43 | 44 | return ret; 45 | } 46 | 47 | public static ArrayList localizeAllEffect(List input) { 48 | ArrayList ret = new ArrayList(input.size()); 49 | for (int i = 0; i < input.size(); i++) 50 | ret.add(i, localizeEffect(input.get(i))); 51 | 52 | return ret; 53 | } 54 | 55 | public static String[] cutWithFormatting(String string) { 56 | return string.split("\\n"); 57 | } 58 | 59 | public static String[] cutLongString(String string, int characters) { 60 | return WordUtils.wrap(string, characters, "/cut", false).split("/cut"); 61 | } 62 | 63 | public static String[] cutLongString(String string) { 64 | return cutLongString(string, 30); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/button/ButtonBack.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.button; 2 | 3 | import amerifrance.guideapi.GuideMod; 4 | import amerifrance.guideapi.api.button.ButtonGuideAPI; 5 | import amerifrance.guideapi.api.util.GuiHelper; 6 | import amerifrance.guideapi.api.util.TextHelper; 7 | import amerifrance.guideapi.gui.GuiBase; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.renderer.GlStateManager; 10 | import net.minecraft.client.renderer.RenderHelper; 11 | import net.minecraft.util.ResourceLocation; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | public class ButtonBack extends ButtonGuideAPI { 17 | 18 | public ButtonBack(int id, int x, int y, GuiBase guiBase) { 19 | super(id, x, y, guiBase); 20 | width = 18; 21 | height = 10; 22 | } 23 | 24 | @Override 25 | public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks) { 26 | if (this.visible) { 27 | RenderHelper.enableGUIStandardItemLighting(); 28 | GlStateManager.enableBlend(); 29 | GlStateManager.disableLighting(); 30 | GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); 31 | minecraft.getTextureManager().bindTexture(new ResourceLocation(GuideMod.ID, "textures/gui/book_colored.png")); 32 | if (GuiHelper.isMouseBetween(mouseX, mouseY, x, y, width, height)) { 33 | this.drawTexturedModalRect(x, y + 1, 70, 201, 18, 10); 34 | guiBase.drawHoveringText(getHoveringText(), mouseX, mouseY, Minecraft.getMinecraft().fontRenderer); 35 | } else { 36 | this.drawTexturedModalRect(x, y, 94, 201, 18, 10); 37 | } 38 | GlStateManager.disableBlend(); 39 | RenderHelper.disableStandardItemLighting(); 40 | } 41 | } 42 | 43 | public List getHoveringText() { 44 | ArrayList list = new ArrayList(); 45 | String s = TextHelper.localizeEffect("button.back.name"); 46 | list.add(s); 47 | return list; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/button/ButtonNext.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.button; 2 | 3 | import amerifrance.guideapi.GuideMod; 4 | import amerifrance.guideapi.api.button.ButtonGuideAPI; 5 | import amerifrance.guideapi.api.util.GuiHelper; 6 | import amerifrance.guideapi.api.util.TextHelper; 7 | import amerifrance.guideapi.gui.GuiBase; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.renderer.GlStateManager; 10 | import net.minecraft.client.renderer.RenderHelper; 11 | import net.minecraft.util.ResourceLocation; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | public class ButtonNext extends ButtonGuideAPI { 17 | 18 | public ButtonNext(int id, int x, int y, GuiBase guiBase) { 19 | super(id, x, y, guiBase); 20 | width = 18; 21 | height = 10; 22 | } 23 | 24 | @Override 25 | public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks) { 26 | if (this.visible) { 27 | RenderHelper.enableGUIStandardItemLighting(); 28 | GlStateManager.enableBlend(); 29 | GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); 30 | GlStateManager.disableLighting(); 31 | minecraft.getTextureManager().bindTexture(new ResourceLocation(GuideMod.ID, "textures/gui/book_colored.png")); 32 | if (GuiHelper.isMouseBetween(mouseX, mouseY, x, y, width, height)) { 33 | this.drawTexturedModalRect(x, y + 1, 47, 201, 18, 10); 34 | guiBase.drawHoveringText(getHoveringText(), mouseX, mouseY, Minecraft.getMinecraft().fontRenderer); 35 | } else { 36 | this.drawTexturedModalRect(x, y, 24, 201, 18, 10); 37 | } 38 | GlStateManager.disableBlend(); 39 | RenderHelper.disableStandardItemLighting(); 40 | } 41 | } 42 | 43 | public List getHoveringText() { 44 | ArrayList list = new ArrayList(); 45 | list.add(TextHelper.localizeEffect("button.next.name")); 46 | return list; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/button/ButtonPrev.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.button; 2 | 3 | import amerifrance.guideapi.GuideMod; 4 | import amerifrance.guideapi.api.button.ButtonGuideAPI; 5 | import amerifrance.guideapi.api.util.GuiHelper; 6 | import amerifrance.guideapi.api.util.TextHelper; 7 | import amerifrance.guideapi.gui.GuiBase; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.renderer.GlStateManager; 10 | import net.minecraft.client.renderer.RenderHelper; 11 | import net.minecraft.util.ResourceLocation; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | public class ButtonPrev extends ButtonGuideAPI { 17 | 18 | public ButtonPrev(int id, int x, int y, GuiBase guiBase) { 19 | super(id, x, y, guiBase); 20 | width = 18; 21 | height = 10; 22 | } 23 | 24 | @Override 25 | public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks) { 26 | if (this.visible) { 27 | RenderHelper.enableGUIStandardItemLighting(); 28 | GlStateManager.enableBlend(); 29 | GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); 30 | GlStateManager.disableLighting(); 31 | minecraft.getTextureManager().bindTexture(new ResourceLocation(GuideMod.ID, "textures/gui/book_colored.png")); 32 | if (GuiHelper.isMouseBetween(mouseX, mouseY, x, y, width, height)) { 33 | this.drawTexturedModalRect(x, y + 1, 47, 214, 18, 10); 34 | guiBase.drawHoveringText(getHoveringText(), mouseX, mouseY, Minecraft.getMinecraft().fontRenderer); 35 | } else { 36 | this.drawTexturedModalRect(x, y, 24, 214, 18, 10); 37 | } 38 | GlStateManager.disableBlend(); 39 | RenderHelper.disableStandardItemLighting(); 40 | } 41 | } 42 | 43 | public List getHoveringText() { 44 | ArrayList list = new ArrayList(); 45 | list.add(TextHelper.localizeEffect("button.prev.name")); 46 | return list; 47 | } 48 | } -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/button/ButtonSearch.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.button; 2 | 3 | import amerifrance.guideapi.api.SubTexture; 4 | import amerifrance.guideapi.api.button.ButtonGuideAPI; 5 | import amerifrance.guideapi.api.util.GuiHelper; 6 | import amerifrance.guideapi.api.util.TextHelper; 7 | import amerifrance.guideapi.gui.GuiBase; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.renderer.GlStateManager; 10 | import net.minecraft.client.renderer.RenderHelper; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | public class ButtonSearch extends ButtonGuideAPI { 16 | 17 | public ButtonSearch(int id, int x, int y, GuiBase guiBase) { 18 | super(id, x, y, guiBase); 19 | width = 15; 20 | height = 15; 21 | } 22 | 23 | @Override 24 | public void drawButton(Minecraft mc, int mouseX, int mouseY, float partialTicks) { 25 | if (this.visible) { 26 | RenderHelper.enableGUIStandardItemLighting(); 27 | GlStateManager.enableBlend(); 28 | GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); 29 | GlStateManager.disableLighting(); 30 | if (GuiHelper.isMouseBetween(mouseX, mouseY, x, y, width, height)) { 31 | SubTexture.MAGNIFYING_GLASS.draw(x, y + 1); 32 | guiBase.drawHoveringText(getHoveringText(), mouseX, mouseY, Minecraft.getMinecraft().fontRenderer); 33 | } else { 34 | SubTexture.MAGNIFYING_GLASS.draw(x, y); 35 | } 36 | GlStateManager.disableBlend(); 37 | RenderHelper.disableStandardItemLighting(); 38 | } 39 | } 40 | 41 | public List getHoveringText() { 42 | ArrayList list = new ArrayList(); 43 | list.add(TextHelper.localizeEffect("button.search.name")); 44 | return list; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/category/CategoryItemStack.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.category; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import amerifrance.guideapi.api.impl.Category; 5 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 6 | import amerifrance.guideapi.api.util.GuiHelper; 7 | import amerifrance.guideapi.gui.GuiBase; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.renderer.RenderItem; 10 | import net.minecraft.item.ItemStack; 11 | import net.minecraft.util.ResourceLocation; 12 | import net.minecraftforge.fml.relauncher.Side; 13 | import net.minecraftforge.fml.relauncher.SideOnly; 14 | 15 | import java.util.Map; 16 | 17 | public class CategoryItemStack extends Category { 18 | 19 | public ItemStack stack; 20 | 21 | public CategoryItemStack(Map entries, String name, ItemStack stack) { 22 | super(entries, name); 23 | this.stack = stack; 24 | } 25 | 26 | public CategoryItemStack(String name, ItemStack stack) { 27 | super(name); 28 | this.stack = stack; 29 | } 30 | 31 | @Override 32 | @SideOnly(Side.CLIENT) 33 | public void draw(Book book, int categoryX, int categoryY, int categoryWidth, int categoryHeight, int mouseX, int mouseY, GuiBase guiBase, boolean drawOnLeft, RenderItem renderItem) { 34 | GuiHelper.drawScaledItemStack(this.stack, categoryX, categoryY, 1.5F); 35 | } 36 | 37 | @Override 38 | @SideOnly(Side.CLIENT) 39 | public void drawExtras(Book book, int categoryX, int categoryY, int categoryWidth, int categoryHeight, int mouseX, int mouseY, GuiBase guiBase, boolean drawOnLeft, RenderItem renderItem) { 40 | if (canSee(guiBase.player, guiBase.bookStack) && GuiHelper.isMouseBetween(mouseX, mouseY, categoryX, categoryY, categoryWidth, categoryHeight)) 41 | guiBase.drawHoveringText(this.getTooltip(), mouseX, mouseY, Minecraft.getMinecraft().fontRenderer); 42 | } 43 | 44 | @Override 45 | public boolean equals(Object o) { 46 | if (this == o) return true; 47 | if (!(o instanceof CategoryItemStack)) return false; 48 | if (!super.equals(o)) return false; 49 | 50 | CategoryItemStack that = (CategoryItemStack) o; 51 | 52 | return stack != null ? stack.equals(that.stack) : that.stack == null; 53 | } 54 | 55 | @Override 56 | public int hashCode() { 57 | int result = super.hashCode(); 58 | result = 31 * result + (stack != null ? stack.hashCode() : 0); 59 | return result; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/category/CategoryResourceLocation.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.category; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import amerifrance.guideapi.api.impl.Category; 5 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 6 | import amerifrance.guideapi.api.util.GuiHelper; 7 | import amerifrance.guideapi.gui.GuiBase; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.renderer.RenderItem; 10 | import net.minecraft.util.ResourceLocation; 11 | import net.minecraftforge.fml.relauncher.Side; 12 | import net.minecraftforge.fml.relauncher.SideOnly; 13 | 14 | import java.util.Map; 15 | 16 | public class CategoryResourceLocation extends Category { 17 | 18 | public ResourceLocation resourceLocation; 19 | 20 | public CategoryResourceLocation(Map entries, String unlocCategoryName, ResourceLocation resourceLocation) { 21 | super(entries, unlocCategoryName); 22 | this.resourceLocation = resourceLocation; 23 | } 24 | 25 | public CategoryResourceLocation(String name, ResourceLocation resourceLocation) { 26 | super(name); 27 | this.resourceLocation = resourceLocation; 28 | } 29 | 30 | @Override 31 | @SideOnly(Side.CLIENT) 32 | public void draw(Book book, int categoryX, int categoryY, int categoryWidth, int categoryHeight, int mouseX, int mouseY, GuiBase guiBase, boolean drawOnLeft, RenderItem renderItem) { 33 | Minecraft.getMinecraft().getTextureManager().bindTexture(resourceLocation); 34 | GuiHelper.drawSizedIconWithoutColor(categoryX, categoryY, 48, 48, 0); 35 | } 36 | 37 | @Override 38 | @SideOnly(Side.CLIENT) 39 | public void drawExtras(Book book, int categoryX, int categoryY, int categoryWidth, int categoryHeight, int mouseX, int mouseY, GuiBase guiBase, boolean drawOnLeft, RenderItem renderItem) { 40 | if (canSee(guiBase.player, guiBase.bookStack) && GuiHelper.isMouseBetween(mouseX, mouseY, categoryX, categoryY, categoryWidth, categoryHeight)) 41 | guiBase.drawHoveringText(this.getTooltip(), mouseX, mouseY, Minecraft.getMinecraft().fontRenderer); 42 | } 43 | 44 | @Override 45 | public boolean equals(Object o) { 46 | if (this == o) return true; 47 | if (!(o instanceof CategoryResourceLocation)) return false; 48 | if (!super.equals(o)) return false; 49 | 50 | CategoryResourceLocation that = (CategoryResourceLocation) o; 51 | 52 | return resourceLocation != null ? resourceLocation.equals(that.resourceLocation) : that.resourceLocation == null; 53 | } 54 | 55 | @Override 56 | public int hashCode() { 57 | int result = super.hashCode(); 58 | result = 31 * result + (resourceLocation != null ? resourceLocation.hashCode() : 0); 59 | return result; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/entry/EntryItemStack.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.entry; 2 | 3 | import amerifrance.guideapi.api.IPage; 4 | import amerifrance.guideapi.api.impl.Book; 5 | import amerifrance.guideapi.api.impl.Entry; 6 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 7 | import amerifrance.guideapi.api.util.GuiHelper; 8 | import amerifrance.guideapi.gui.GuiBase; 9 | import net.minecraft.client.gui.FontRenderer; 10 | import net.minecraft.item.ItemStack; 11 | import net.minecraftforge.fml.relauncher.Side; 12 | import net.minecraftforge.fml.relauncher.SideOnly; 13 | 14 | import java.util.List; 15 | 16 | public class EntryItemStack extends Entry { 17 | 18 | public ItemStack stack; 19 | 20 | public EntryItemStack(List pageList, String name, ItemStack stack, boolean unicode) { 21 | super(pageList, name, unicode); 22 | this.stack = stack; 23 | } 24 | 25 | public EntryItemStack(List pageList, String name, ItemStack stack) { 26 | this(pageList, name, stack, false); 27 | } 28 | 29 | public EntryItemStack(String name, boolean unicode, ItemStack stack) { 30 | super(name, unicode); 31 | this.stack = stack; 32 | } 33 | 34 | public EntryItemStack(String name, ItemStack stack) { 35 | super(name); 36 | this.stack = stack; 37 | } 38 | 39 | @Override 40 | @SideOnly(Side.CLIENT) 41 | public void drawExtras(Book book, CategoryAbstract category, int entryX, int entryY, int entryWidth, int entryHeight, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 42 | if (stack != null) 43 | GuiHelper.drawScaledItemStack(stack, entryX + 2, entryY, 0.5F); 44 | 45 | super.drawExtras(book, category, entryX, entryY, entryWidth, entryHeight, mouseX, mouseY, guiBase, fontRendererObj); 46 | } 47 | 48 | @Override 49 | public boolean equals(Object o) { 50 | if (this == o) return true; 51 | if (!(o instanceof EntryItemStack)) return false; 52 | if (!super.equals(o)) return false; 53 | 54 | EntryItemStack that = (EntryItemStack) o; 55 | 56 | return stack != null ? stack.equals(that.stack) : that.stack == null; 57 | } 58 | 59 | @Override 60 | public int hashCode() { 61 | int result = super.hashCode(); 62 | result = 31 * result + (stack != null ? stack.hashCode() : 0); 63 | return result; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/entry/EntryResourceLocation.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.entry; 2 | 3 | import amerifrance.guideapi.api.IPage; 4 | import amerifrance.guideapi.api.impl.Book; 5 | import amerifrance.guideapi.api.impl.Entry; 6 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 7 | import amerifrance.guideapi.api.util.GuiHelper; 8 | import amerifrance.guideapi.gui.GuiBase; 9 | import net.minecraft.client.Minecraft; 10 | import net.minecraft.client.gui.FontRenderer; 11 | import net.minecraft.util.ResourceLocation; 12 | import net.minecraftforge.fml.relauncher.Side; 13 | import net.minecraftforge.fml.relauncher.SideOnly; 14 | 15 | import java.util.List; 16 | 17 | public class EntryResourceLocation extends Entry { 18 | 19 | public ResourceLocation image; 20 | 21 | public EntryResourceLocation(List pageList, String name, ResourceLocation resourceLocation, boolean unicode) { 22 | super(pageList, name, unicode); 23 | this.image = resourceLocation; 24 | } 25 | 26 | public EntryResourceLocation(List pageList, String name, ResourceLocation resourceLocation) { 27 | this(pageList, name, resourceLocation, false); 28 | } 29 | 30 | public EntryResourceLocation(String name, boolean unicode, ResourceLocation image) { 31 | super(name, unicode); 32 | this.image = image; 33 | } 34 | 35 | public EntryResourceLocation(String name, ResourceLocation image) { 36 | super(name); 37 | this.image = image; 38 | } 39 | 40 | @Override 41 | @SideOnly(Side.CLIENT) 42 | public void drawExtras(Book book, CategoryAbstract category, int entryX, int entryY, int entryWidth, int entryHeight, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 43 | Minecraft.getMinecraft().getTextureManager().bindTexture(image); 44 | GuiHelper.drawSizedIconWithoutColor(entryX + 2, entryY, 16, 16, 1F); 45 | 46 | super.drawExtras(book, category, entryX, entryY, entryWidth, entryHeight, mouseX, mouseY, guiBase, fontRendererObj); 47 | } 48 | 49 | @Override 50 | public boolean equals(Object o) { 51 | if (this == o) return true; 52 | if (!(o instanceof EntryResourceLocation)) return false; 53 | if (!super.equals(o)) return false; 54 | 55 | EntryResourceLocation that = (EntryResourceLocation) o; 56 | 57 | return image != null ? image.equals(that.image) : that.image == null; 58 | } 59 | 60 | @Override 61 | public int hashCode() { 62 | int result = super.hashCode(); 63 | result = 31 * result + (image != null ? image.hashCode() : 0); 64 | return result; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/gui/GuiBase.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.gui; 2 | 3 | import net.minecraft.client.gui.FontRenderer; 4 | import net.minecraft.client.gui.GuiScreen; 5 | import net.minecraft.client.renderer.RenderHelper; 6 | import net.minecraft.client.renderer.Tessellator; 7 | import net.minecraft.client.renderer.vertex.DefaultVertexFormats; 8 | import net.minecraft.entity.player.EntityPlayer; 9 | import net.minecraft.item.ItemStack; 10 | import org.lwjgl.input.Keyboard; 11 | import org.lwjgl.opengl.GL11; 12 | 13 | import java.awt.Color; 14 | import java.util.List; 15 | 16 | import static net.minecraft.client.renderer.GlStateManager.*; 17 | 18 | public class GuiBase extends GuiScreen { 19 | 20 | public int guiLeft, guiTop; 21 | public int xSize = 192; 22 | public int ySize = 192; 23 | public EntityPlayer player; 24 | public ItemStack bookStack; 25 | public float publicZLevel; 26 | 27 | public GuiBase(EntityPlayer player, ItemStack bookStack) { 28 | this.player = player; 29 | this.bookStack = bookStack; 30 | this.publicZLevel = zLevel; 31 | } 32 | 33 | @Override 34 | public boolean doesGuiPauseGame() { 35 | return false; 36 | } 37 | 38 | @Override 39 | public void keyTyped(char typedChar, int keyCode) { 40 | if (keyCode == Keyboard.KEY_ESCAPE || keyCode == this.mc.gameSettings.keyBindInventory.getKeyCode()) { 41 | this.mc.displayGuiScreen(null); 42 | this.mc.setIngameFocus(); 43 | } 44 | } 45 | 46 | public void drawTexturedModalRectWithColor(int x, int y, int textureX, int textureY, int width, int height, Color color) { 47 | pushMatrix(); 48 | enableBlend(); 49 | blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); 50 | float f = 0.00390625F; 51 | float f1 = 0.00390625F; 52 | disableLighting(); 53 | color((float) color.getRed() / 255F, (float) color.getGreen() / 255F, (float) color.getBlue() / 255F); 54 | Tessellator tessellator = Tessellator.getInstance(); 55 | tessellator.getBuffer().begin(7, DefaultVertexFormats.POSITION_TEX); 56 | tessellator.getBuffer().pos((double) (x), (double) (y + height), (double) this.zLevel).tex((double) ((float) (textureX) * f), (double) ((float) (textureY + height) * f1)).endVertex(); 57 | tessellator.getBuffer().pos((double) (x + width), (double) (y + height), (double) this.zLevel).tex((double) ((float) (textureX + width) * f), (double) ((float) (textureY + height) * f1)).endVertex(); 58 | tessellator.getBuffer().pos((double) (x + width), (double) (y), (double) this.zLevel).tex((double) ((float) (textureX + width) * f), (double) ((float) (textureY) * f1)).endVertex(); 59 | tessellator.getBuffer().pos((double) (x), (double) (y), (double) this.zLevel).tex((double) ((float) (textureX) * f), (double) ((float) (textureY) * f1)).endVertex(); 60 | tessellator.draw(); 61 | disableBlend(); 62 | popMatrix(); 63 | } 64 | 65 | @Override 66 | public void drawCenteredString(FontRenderer fontRendererObj, String string, int x, int y, int color) { 67 | RenderHelper.disableStandardItemLighting(); 68 | fontRendererObj.drawString(string, x - fontRendererObj.getStringWidth(string) / 2, y, color); 69 | RenderHelper.disableStandardItemLighting(); 70 | } 71 | 72 | public void drawCenteredStringWithShadow(FontRenderer fontRendererObj, String string, int x, int y, int color) { 73 | super.drawCenteredString(fontRendererObj, string, x, y, color); 74 | } 75 | 76 | @Override 77 | public void drawTexturedModalRect(int x, int y, int textureX, int textureY, int width, int height) { 78 | pushMatrix(); 79 | color(1.0F, 1.0F, 1.0F, 1.0F); 80 | super.drawTexturedModalRect(x, y, textureX, textureY, width, height); 81 | popMatrix(); 82 | } 83 | 84 | @Override 85 | public void drawHoveringText(List list, int x, int y, FontRenderer font) { 86 | disableLighting(); 87 | RenderHelper.disableStandardItemLighting(); 88 | super.drawHoveringText(list, x, y, font); 89 | RenderHelper.enableStandardItemLighting(); 90 | enableLighting(); 91 | } 92 | 93 | @Override 94 | public void drawHoveringText(List list, int x, int y) { 95 | disableLighting(); 96 | RenderHelper.disableStandardItemLighting(); 97 | super.drawHoveringText(list, x, y); 98 | RenderHelper.enableStandardItemLighting(); 99 | enableLighting(); 100 | } 101 | 102 | @Override 103 | public void renderToolTip(ItemStack stack, int x, int y) { 104 | super.renderToolTip(stack, x, y); 105 | } 106 | 107 | @Override 108 | public void onGuiClosed() { 109 | super.onGuiClosed(); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/gui/GuiCategory.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.gui; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 5 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 6 | import amerifrance.guideapi.button.ButtonBack; 7 | import amerifrance.guideapi.button.ButtonNext; 8 | import amerifrance.guideapi.button.ButtonPrev; 9 | import amerifrance.guideapi.button.ButtonSearch; 10 | import amerifrance.guideapi.network.PacketHandler; 11 | import amerifrance.guideapi.network.PacketSyncCategory; 12 | import amerifrance.guideapi.wrapper.EntryWrapper; 13 | import com.google.common.collect.HashMultimap; 14 | import com.google.common.collect.Lists; 15 | import net.minecraft.client.Minecraft; 16 | import net.minecraft.client.gui.GuiButton; 17 | import net.minecraft.entity.player.EntityPlayer; 18 | import net.minecraft.item.ItemStack; 19 | import net.minecraft.util.ResourceLocation; 20 | import net.minecraft.util.math.MathHelper; 21 | import org.lwjgl.input.Keyboard; 22 | import org.lwjgl.input.Mouse; 23 | 24 | import java.awt.Color; 25 | import java.io.IOException; 26 | import java.util.List; 27 | 28 | import javax.annotation.Nullable; 29 | 30 | public class GuiCategory extends GuiBase { 31 | 32 | public ResourceLocation outlineTexture; 33 | public ResourceLocation pageTexture; 34 | public Book book; 35 | public CategoryAbstract category; 36 | public HashMultimap entryWrapperMap = HashMultimap.create(); 37 | public ButtonBack buttonBack; 38 | public ButtonNext buttonNext; 39 | public ButtonPrev buttonPrev; 40 | public ButtonSearch buttonSearch; 41 | public int entryPage; 42 | @Nullable public EntryAbstract startEntry; 43 | 44 | public GuiCategory(Book book, CategoryAbstract category, EntityPlayer player, ItemStack bookStack, @Nullable EntryAbstract startEntry) { 45 | super(player, bookStack); 46 | this.book = book; 47 | this.category = category; 48 | this.pageTexture = book.getPageTexture(); 49 | this.outlineTexture = book.getOutlineTexture(); 50 | this.entryPage = 0; 51 | this.startEntry = startEntry; 52 | } 53 | 54 | @Override 55 | public void initGui() { 56 | super.initGui(); 57 | this.buttonList.clear(); 58 | this.entryWrapperMap.clear(); 59 | 60 | guiLeft = (this.width - this.xSize) / 2; 61 | guiTop = (this.height - this.ySize) / 2; 62 | 63 | this.buttonList.add(buttonBack = new ButtonBack(0, guiLeft + xSize / 6, guiTop, this)); 64 | this.buttonList.add(buttonNext = new ButtonNext(1, guiLeft + 4 * xSize / 6, guiTop + 5 * ySize / 6, this)); 65 | this.buttonList.add(buttonPrev = new ButtonPrev(2, guiLeft + xSize / 5, guiTop + 5 * ySize / 6, this)); 66 | this.buttonList.add(buttonSearch = new ButtonSearch(3, (guiLeft + xSize / 6) - 25, guiTop + 5, this)); 67 | 68 | int eX = guiLeft + 37; 69 | int eY = guiTop + 15; 70 | int i = 0; 71 | int pageNumber = 0; 72 | List entries = Lists.newArrayList(category.entries.values()); 73 | for (EntryAbstract entry : entries) { 74 | entry.onInit(book, category, this, player, bookStack); 75 | entryWrapperMap.put(pageNumber, new EntryWrapper(this, book, category, entry, eX, eY, 4 * xSize / 6, 10, player, this.fontRenderer, bookStack)); 76 | if (entry.equals(this.startEntry)) { 77 | this.startEntry = null; 78 | this.entryPage = pageNumber; 79 | } 80 | eY += 13; 81 | i++; 82 | 83 | if (i >= 11) { 84 | i = 0; 85 | eY = guiTop + 15; 86 | pageNumber++; 87 | } 88 | } 89 | } 90 | 91 | @Override 92 | public void drawScreen(int mouseX, int mouseY, float renderPartialTicks) { 93 | Minecraft.getMinecraft().getTextureManager().bindTexture(pageTexture); 94 | drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize); 95 | Minecraft.getMinecraft().getTextureManager().bindTexture(outlineTexture); 96 | drawTexturedModalRectWithColor(guiLeft, guiTop, 0, 0, xSize, ySize, book.getColor()); 97 | 98 | entryPage = MathHelper.clamp(entryPage, 0, entryWrapperMap.size() - 1); 99 | 100 | for (EntryWrapper wrapper : this.entryWrapperMap.get(entryPage)) { 101 | if (wrapper.canPlayerSee()) { 102 | wrapper.draw(mouseX, mouseY, this); 103 | wrapper.drawExtras(mouseX, mouseY, this); 104 | } 105 | if (wrapper.isMouseOnWrapper(mouseX, mouseY) && wrapper.canPlayerSee()) { 106 | wrapper.onHoverOver(mouseX, mouseY); 107 | } 108 | } 109 | 110 | drawCenteredString(fontRenderer, String.format("%d/%d", entryPage + 1, entryWrapperMap.asMap().size()), guiLeft + xSize / 2, guiTop + 5 * ySize / 6, 0); 111 | drawCenteredStringWithShadow(fontRenderer, category.getLocalizedName(), guiLeft + xSize / 2, guiTop - 10, Color.WHITE.getRGB()); 112 | 113 | buttonPrev.visible = entryPage != 0; 114 | buttonNext.visible = entryPage != entryWrapperMap.asMap().size() - 1 && !entryWrapperMap.asMap().isEmpty(); 115 | 116 | super.drawScreen(mouseX, mouseY, renderPartialTicks); 117 | } 118 | 119 | @Override 120 | public void mouseClicked(int mouseX, int mouseY, int typeofClick) throws IOException { 121 | super.mouseClicked(mouseX, mouseY, typeofClick); 122 | 123 | for (EntryWrapper wrapper : this.entryWrapperMap.get(entryPage)) { 124 | if (wrapper.isMouseOnWrapper(mouseX, mouseY) && wrapper.canPlayerSee()) { 125 | if (typeofClick == 0) wrapper.entry.onLeftClicked(book, category, mouseX, mouseY, player, this); 126 | else if (typeofClick == 1) 127 | wrapper.entry.onRightClicked(book, category, mouseX, mouseY, player, this); 128 | } 129 | } 130 | 131 | if (typeofClick == 1) 132 | this.mc.displayGuiScreen(new GuiHome(book, player, bookStack)); 133 | } 134 | 135 | @Override 136 | public void handleMouseInput() throws IOException { 137 | super.handleMouseInput(); 138 | 139 | int movement = Mouse.getEventDWheel(); 140 | if (movement < 0) 141 | nextPage(); 142 | else if (movement > 0) 143 | prevPage(); 144 | } 145 | 146 | @Override 147 | public void keyTyped(char typedChar, int keyCode) { 148 | super.keyTyped(typedChar, keyCode); 149 | if (keyCode == Keyboard.KEY_BACK || keyCode == this.mc.gameSettings.keyBindUseItem.getKeyCode()) 150 | this.mc.displayGuiScreen(new GuiHome(book, player, bookStack)); 151 | if ((keyCode == Keyboard.KEY_UP || keyCode == Keyboard.KEY_RIGHT) && entryPage + 1 < entryWrapperMap.asMap().size()) 152 | nextPage(); 153 | if ((keyCode == Keyboard.KEY_DOWN || keyCode == Keyboard.KEY_LEFT) && entryPage > 0) 154 | prevPage(); 155 | } 156 | 157 | @Override 158 | public void actionPerformed(GuiButton button) { 159 | if (button.id == 0) 160 | this.mc.displayGuiScreen(new GuiHome(book, player, bookStack)); 161 | else if (button.id == 1 && entryPage + 1 < entryWrapperMap.asMap().size()) 162 | nextPage(); 163 | else if (button.id == 2 && entryPage > 0) 164 | prevPage(); 165 | else if (button.id == 3) 166 | this.mc.displayGuiScreen(new GuiSearch(book, player, bookStack, this)); 167 | } 168 | 169 | @Override 170 | public void onGuiClosed() { 171 | super.onGuiClosed(); 172 | 173 | PacketHandler.INSTANCE.sendToServer(new PacketSyncCategory(book.getCategoryList().indexOf(category), entryPage)); 174 | } 175 | 176 | public void nextPage() { 177 | if (entryPage >= entryWrapperMap.asMap().size()) 178 | entryPage = entryWrapperMap.asMap().size() - 1; 179 | if (entryPage != entryWrapperMap.asMap().size() - 1 && !entryWrapperMap.asMap().isEmpty()) 180 | entryPage++; 181 | } 182 | 183 | public void prevPage() { 184 | if (entryPage >= entryWrapperMap.asMap().size()) 185 | entryPage = entryWrapperMap.asMap().size() - 1; 186 | if (entryPage != 0) 187 | entryPage--; 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/gui/GuiEntry.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.gui; 2 | 3 | import amerifrance.guideapi.api.IPage; 4 | import amerifrance.guideapi.api.impl.Book; 5 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 6 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 7 | import amerifrance.guideapi.button.ButtonBack; 8 | import amerifrance.guideapi.button.ButtonNext; 9 | import amerifrance.guideapi.button.ButtonPrev; 10 | import amerifrance.guideapi.button.ButtonSearch; 11 | import amerifrance.guideapi.network.PacketHandler; 12 | import amerifrance.guideapi.network.PacketSyncEntry; 13 | import amerifrance.guideapi.wrapper.PageWrapper; 14 | import net.minecraft.client.Minecraft; 15 | import net.minecraft.client.gui.GuiButton; 16 | import net.minecraft.entity.player.EntityPlayer; 17 | import net.minecraft.item.ItemStack; 18 | import net.minecraft.util.ResourceLocation; 19 | import net.minecraft.util.math.MathHelper; 20 | import org.lwjgl.input.Keyboard; 21 | import org.lwjgl.input.Mouse; 22 | 23 | import java.awt.Color; 24 | import java.io.IOException; 25 | import java.util.ArrayList; 26 | import java.util.List; 27 | import java.util.Map; 28 | 29 | public class GuiEntry extends GuiBase { 30 | 31 | public ResourceLocation outlineTexture; 32 | public ResourceLocation pageTexture; 33 | public Book book; 34 | public CategoryAbstract category; 35 | public EntryAbstract entry; 36 | public List pageWrapperList = new ArrayList(); 37 | public ButtonBack buttonBack; 38 | public ButtonNext buttonNext; 39 | public ButtonPrev buttonPrev; 40 | public ButtonSearch buttonSearch; 41 | public int pageNumber; 42 | 43 | public GuiEntry(Book book, CategoryAbstract category, EntryAbstract entry, EntityPlayer player, ItemStack bookStack) { 44 | super(player, bookStack); 45 | this.book = book; 46 | this.category = category; 47 | this.entry = entry; 48 | this.pageTexture = book.getPageTexture(); 49 | this.outlineTexture = book.getOutlineTexture(); 50 | this.pageNumber = 0; 51 | } 52 | 53 | @Override 54 | public void initGui() { 55 | super.initGui(); 56 | entry.onInit(book, category, null, player, bookStack); 57 | this.buttonList.clear(); 58 | this.pageWrapperList.clear(); 59 | 60 | guiLeft = (this.width - this.xSize) / 2; 61 | guiTop = (this.height - this.ySize) / 2; 62 | 63 | this.buttonList.add(buttonBack = new ButtonBack(0, guiLeft + xSize / 6, guiTop, this)); 64 | this.buttonList.add(buttonNext = new ButtonNext(1, guiLeft + 4 * xSize / 6, guiTop + 5 * ySize / 6, this)); 65 | this.buttonList.add(buttonPrev = new ButtonPrev(2, guiLeft + xSize / 5, guiTop + 5 * ySize / 6, this)); 66 | this.buttonList.add(buttonSearch = new ButtonSearch(3, (guiLeft + xSize / 6) - 25, guiTop + 5, this)); 67 | 68 | for (IPage page : this.entry.pageList) { 69 | page.onInit(book, category, entry, player, bookStack, this); 70 | pageWrapperList.add(new PageWrapper(this, book, category, entry, page, guiLeft, guiTop, player, this.fontRenderer, bookStack)); 71 | } 72 | } 73 | 74 | @Override 75 | public void drawScreen(int mouseX, int mouseY, float renderPartialTicks) { 76 | Minecraft.getMinecraft().getTextureManager().bindTexture(pageTexture); 77 | drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize); 78 | Minecraft.getMinecraft().getTextureManager().bindTexture(outlineTexture); 79 | drawTexturedModalRectWithColor(guiLeft, guiTop, 0, 0, xSize, ySize, book.getColor()); 80 | 81 | pageNumber = MathHelper.clamp(pageNumber, 0, pageWrapperList.size() - 1); 82 | 83 | if (pageNumber < pageWrapperList.size()) { 84 | if (pageWrapperList.get(pageNumber).canPlayerSee()) { 85 | pageWrapperList.get(pageNumber).draw(mouseX, mouseY, this); 86 | pageWrapperList.get(pageNumber).drawExtras(mouseX, mouseY, this); 87 | } 88 | } 89 | 90 | drawCenteredString(fontRenderer, String.format("%d/%d", pageNumber + 1, pageWrapperList.size()), guiLeft + xSize / 2, guiTop + 5 * ySize / 6, 0); 91 | drawCenteredStringWithShadow(fontRenderer, entry.getLocalizedName(), guiLeft + xSize / 2, guiTop - 10, Color.WHITE.getRGB()); 92 | 93 | buttonPrev.visible = pageNumber != 0; 94 | buttonNext.visible = pageNumber != pageWrapperList.size() - 1 && !pageWrapperList.isEmpty(); 95 | 96 | super.drawScreen(mouseX, mouseY, renderPartialTicks); 97 | } 98 | 99 | @Override 100 | public void mouseClicked(int mouseX, int mouseY, int typeofClick) throws IOException { 101 | super.mouseClicked(mouseX, mouseY, typeofClick); 102 | for (PageWrapper wrapper : this.pageWrapperList) { 103 | if (wrapper.isMouseOnWrapper(mouseX, mouseY) && wrapper.canPlayerSee()) { 104 | if (typeofClick == 0) { 105 | pageWrapperList.get(pageNumber).page.onLeftClicked(book, category, entry, mouseX, mouseY, player, this); 106 | } 107 | if (typeofClick == 1) { 108 | pageWrapperList.get(pageNumber).page.onRightClicked(book, category, entry, mouseX, mouseY, player, this); 109 | } 110 | } 111 | } 112 | 113 | if (typeofClick == 1) { 114 | this.mc.displayGuiScreen(new GuiCategory(book, category, player, bookStack, entry)); 115 | } 116 | } 117 | 118 | @Override 119 | public void handleMouseInput() throws IOException { 120 | super.handleMouseInput(); 121 | 122 | int movement = Mouse.getEventDWheel(); 123 | if (movement < 0) 124 | nextPage(); 125 | else if (movement > 0) 126 | prevPage(); 127 | } 128 | 129 | @Override 130 | public void keyTyped(char typedChar, int keyCode) { 131 | super.keyTyped(typedChar, keyCode); 132 | if (keyCode == Keyboard.KEY_BACK || keyCode == this.mc.gameSettings.keyBindUseItem.getKeyCode()) 133 | this.mc.displayGuiScreen(new GuiCategory(book, category, player, bookStack, entry)); 134 | if ((keyCode == Keyboard.KEY_UP || keyCode == Keyboard.KEY_RIGHT) && pageNumber + 1 < pageWrapperList.size()) 135 | nextPage(); 136 | if ((keyCode == Keyboard.KEY_DOWN || keyCode == Keyboard.KEY_LEFT) && pageNumber > 0) 137 | prevPage(); 138 | } 139 | 140 | @Override 141 | public void actionPerformed(GuiButton button) { 142 | if (button.id == 0) 143 | this.mc.displayGuiScreen(new GuiCategory(book, category, player, bookStack, entry)); 144 | else if (button.id == 1 && pageNumber + 1 < pageWrapperList.size()) 145 | nextPage(); 146 | else if (button.id == 2 && pageNumber > 0) 147 | prevPage(); 148 | else if (button.id == 3) 149 | this.mc.displayGuiScreen(new GuiSearch(book, player, bookStack, this)); 150 | } 151 | 152 | @Override 153 | public void onGuiClosed() { 154 | super.onGuiClosed(); 155 | 156 | ResourceLocation key = null; 157 | for (Map.Entry mapEntry : category.entries.entrySet()) 158 | if (mapEntry.getValue().equals(entry)) 159 | key = mapEntry.getKey(); 160 | 161 | if (key != null) 162 | PacketHandler.INSTANCE.sendToServer(new PacketSyncEntry(book.getCategoryList().indexOf(category), key, pageNumber)); 163 | } 164 | 165 | public void nextPage() { 166 | if (pageNumber != pageWrapperList.size() - 1 && !pageWrapperList.isEmpty()) 167 | pageNumber++; 168 | } 169 | 170 | public void prevPage() { 171 | if (pageNumber != 0) 172 | pageNumber--; 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/info/InfoRendererDescription.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.info; 2 | 3 | import amerifrance.guideapi.api.IInfoRenderer; 4 | import amerifrance.guideapi.api.impl.Book; 5 | import amerifrance.guideapi.api.util.GuiHelper; 6 | import net.minecraft.block.state.IBlockState; 7 | import net.minecraft.client.Minecraft; 8 | import net.minecraft.client.gui.FontRenderer; 9 | import net.minecraft.client.gui.ScaledResolution; 10 | import net.minecraft.client.renderer.GlStateManager; 11 | import net.minecraft.entity.player.EntityPlayer; 12 | import net.minecraft.item.ItemStack; 13 | import net.minecraft.util.math.BlockPos; 14 | import net.minecraft.util.math.RayTraceResult; 15 | import net.minecraft.util.text.ITextComponent; 16 | import net.minecraft.world.World; 17 | import org.apache.commons.lang3.StringEscapeUtils; 18 | 19 | import java.awt.Color; 20 | import java.util.List; 21 | 22 | public class InfoRendererDescription implements IInfoRenderer { 23 | 24 | private final ItemStack stack; 25 | private final ITextComponent description; 26 | private boolean tiny; 27 | private int yOffset; 28 | 29 | public InfoRendererDescription(ItemStack stack, ITextComponent description) { 30 | this.stack = stack; 31 | this.description = description; 32 | } 33 | 34 | @Override 35 | public void drawInformation(Book book, World world, BlockPos pos, IBlockState state, RayTraceResult rayTrace, EntityPlayer player) { 36 | if (tiny) { 37 | GlStateManager.pushMatrix(); 38 | GlStateManager.scale(0.5F, 0.5F, 0.5F); 39 | } 40 | ScaledResolution resolution = new ScaledResolution(Minecraft.getMinecraft()); 41 | FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; 42 | int scaleMulti = tiny ? 2 : 1; 43 | 44 | GuiHelper.drawItemStack(stack, (resolution.getScaledWidth() / 2 + 55) * scaleMulti, ((resolution.getScaledHeight() / 2 - (tiny ? 20 : 30)) + yOffset) * scaleMulti); 45 | 46 | int y = 0; 47 | String toDraw = StringEscapeUtils.unescapeJava(description.getFormattedText()).replaceAll("\\t", " "); 48 | String[] lines = toDraw.split("\n"); 49 | for (String line : lines) { 50 | List cutLines = fontRenderer.listFormattedStringToWidth(line, 100 * scaleMulti); 51 | for (String cut : cutLines) { 52 | fontRenderer.drawStringWithShadow(cut, (resolution.getScaledWidth() / 2 + 20) * scaleMulti, (((resolution.getScaledHeight() / 2 - 10) - y) * scaleMulti) + yOffset, Color.WHITE.getRGB()); 53 | y -= 10 / scaleMulti; 54 | } 55 | } 56 | if (tiny) 57 | GlStateManager.popMatrix(); 58 | } 59 | 60 | public InfoRendererDescription setTiny(boolean tiny) { 61 | this.tiny = tiny; 62 | return this; 63 | } 64 | 65 | public InfoRendererDescription setOffsetY(int yOffset) { 66 | this.yOffset = yOffset; 67 | return this; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/info/InfoRendererImage.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.info; 2 | 3 | import amerifrance.guideapi.api.IInfoRenderer; 4 | import amerifrance.guideapi.api.impl.Book; 5 | import net.minecraft.block.state.IBlockState; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.gui.Gui; 8 | import net.minecraft.client.gui.ScaledResolution; 9 | import net.minecraft.entity.player.EntityPlayer; 10 | import net.minecraft.util.ResourceLocation; 11 | import net.minecraft.util.math.BlockPos; 12 | import net.minecraft.util.math.RayTraceResult; 13 | import net.minecraft.world.World; 14 | 15 | public class InfoRendererImage implements IInfoRenderer { 16 | 17 | private final ResourceLocation image; 18 | private final int imageX; 19 | private final int imageY; 20 | private final int imageWidth; 21 | private final int imageHeight; 22 | 23 | public InfoRendererImage(ResourceLocation image, int imageX, int imageY, int imageWidth, int imageHeight) { 24 | this.image = image; 25 | this.imageX = imageX; 26 | this.imageY = imageY; 27 | this.imageWidth = imageWidth; 28 | this.imageHeight = imageHeight; 29 | } 30 | 31 | @Override 32 | public void drawInformation(Book book, World world, BlockPos pos, IBlockState state, RayTraceResult rayTrace, EntityPlayer player) { 33 | ScaledResolution resolution = new ScaledResolution(Minecraft.getMinecraft()); 34 | Minecraft.getMinecraft().renderEngine.bindTexture(image); 35 | Gui.drawModalRectWithCustomSizedTexture(resolution.getScaledWidth() / 2 + 20, resolution.getScaledHeight() / 2 - imageHeight / 2, imageX, imageY, imageWidth, imageHeight, imageWidth, imageHeight); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/item/ItemGuideBook.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.item; 2 | 3 | import amerifrance.guideapi.GuideMod; 4 | import amerifrance.guideapi.api.BookEvent; 5 | import amerifrance.guideapi.api.GuideAPI; 6 | import amerifrance.guideapi.api.IGuideItem; 7 | import amerifrance.guideapi.api.IGuideLinked; 8 | import amerifrance.guideapi.api.impl.Book; 9 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 10 | import amerifrance.guideapi.api.util.TextHelper; 11 | import com.google.common.base.Strings; 12 | import net.minecraft.block.state.IBlockState; 13 | import net.minecraft.client.util.ITooltipFlag; 14 | import net.minecraft.client.util.ITooltipFlag.TooltipFlags; 15 | import net.minecraft.entity.player.EntityPlayer; 16 | import net.minecraft.item.Item; 17 | import net.minecraft.item.ItemStack; 18 | import net.minecraft.util.*; 19 | import net.minecraft.util.math.BlockPos; 20 | import net.minecraft.util.text.translation.I18n; 21 | import net.minecraft.world.World; 22 | import net.minecraftforge.common.MinecraftForge; 23 | 24 | import javax.annotation.Nonnull; 25 | import javax.annotation.Nullable; 26 | import java.util.List; 27 | 28 | public class ItemGuideBook extends Item implements IGuideItem { 29 | 30 | @Nonnull 31 | private final Book book; 32 | 33 | public ItemGuideBook(@Nonnull Book book) { 34 | this.book = book; 35 | 36 | setMaxStackSize(1); 37 | setCreativeTab(book.getCreativeTab()); 38 | setUnlocalizedName(GuideMod.ID + ".book." + book.getRegistryName().getResourceDomain() + "." + book.getRegistryName().getResourcePath()); 39 | } 40 | 41 | @Override 42 | public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { 43 | ItemStack heldStack = player.getHeldItem(hand); 44 | 45 | BookEvent.Open event = new BookEvent.Open(book, heldStack, player); 46 | if (MinecraftForge.EVENT_BUS.post(event)) { 47 | player.sendStatusMessage(event.getCanceledText(), true); 48 | return ActionResult.newResult(EnumActionResult.FAIL, heldStack); 49 | } 50 | 51 | player.openGui(GuideMod.INSTANCE, GuideAPI.getIndexedBooks().indexOf(book), world, hand.ordinal(), 0, 0); 52 | return ActionResult.newResult(EnumActionResult.SUCCESS, heldStack); 53 | } 54 | 55 | @Override 56 | public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { 57 | if (!world.isRemote || !player.isSneaking()) 58 | return EnumActionResult.PASS; 59 | 60 | ItemStack stack = player.getHeldItem(hand); 61 | IBlockState state = world.getBlockState(pos); 62 | 63 | if (state.getBlock() instanceof IGuideLinked) { 64 | IGuideLinked guideLinked = (IGuideLinked) state.getBlock(); 65 | ResourceLocation entryKey = guideLinked.getLinkedEntry(world, pos, player, stack); 66 | if (entryKey == null) 67 | return EnumActionResult.FAIL; 68 | 69 | for (CategoryAbstract category : book.getCategoryList()) { 70 | if (category.entries.containsKey(entryKey)) { 71 | GuideMod.PROXY.openEntry(book, category, category.entries.get(entryKey), player, stack); 72 | return EnumActionResult.SUCCESS; 73 | } 74 | } 75 | } 76 | 77 | return EnumActionResult.PASS; 78 | } 79 | 80 | @Override 81 | public String getItemStackDisplayName(ItemStack stack) { 82 | return !Strings.isNullOrEmpty(book.getItemName()) ? I18n.translateToLocal(getBook(stack).getItemName()) : super.getItemStackDisplayName(stack); 83 | } 84 | 85 | @Override 86 | public void addInformation(ItemStack stack, World playerIn, List tooltip, ITooltipFlag advanced) { 87 | if (!Strings.isNullOrEmpty(book.getAuthor())) 88 | tooltip.add(TextHelper.localizeEffect(book.getAuthor())); 89 | if (!Strings.isNullOrEmpty(book.getAuthor()) && (advanced == TooltipFlags.ADVANCED)) 90 | tooltip.add(book.getRegistryName().toString()); 91 | } 92 | 93 | @Nullable 94 | // @Override TODO - Soft override because this hasn't been merged into Forge yet. https://github.com/MinecraftForge/MinecraftForge/pull/4330 95 | public String getCreatorModId(ItemStack stack) { 96 | return book.getRegistryName().getResourceDomain(); 97 | } 98 | 99 | // IGuideItem 100 | 101 | @Override 102 | public Book getBook(ItemStack stack) { 103 | return book; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/network/PacketHandler.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.network; 2 | 3 | import amerifrance.guideapi.GuideMod; 4 | import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; 5 | import net.minecraftforge.fml.relauncher.Side; 6 | 7 | public class PacketHandler { 8 | 9 | public static SimpleNetworkWrapper INSTANCE = new SimpleNetworkWrapper(GuideMod.CHANNEL); 10 | 11 | public static void registerPackets() { 12 | INSTANCE.registerMessage(PacketSyncHome.class, PacketSyncHome.class, 0, Side.SERVER); 13 | INSTANCE.registerMessage(PacketSyncCategory.class, PacketSyncCategory.class, 1, Side.SERVER); 14 | INSTANCE.registerMessage(PacketSyncEntry.class, PacketSyncEntry.class, 2, Side.SERVER); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/network/PacketSyncCategory.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.network; 2 | 3 | import amerifrance.guideapi.api.IGuideItem; 4 | import amerifrance.guideapi.api.util.NBTBookTags; 5 | import io.netty.buffer.ByteBuf; 6 | import net.minecraft.item.ItemStack; 7 | import net.minecraft.nbt.NBTTagCompound; 8 | import net.minecraftforge.fml.common.network.simpleimpl.IMessage; 9 | import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; 10 | import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; 11 | 12 | public class PacketSyncCategory implements IMessage, IMessageHandler { 13 | 14 | public int category; 15 | public int page; 16 | 17 | public PacketSyncCategory() { 18 | this.category = -1; 19 | this.page = -1; 20 | } 21 | 22 | public PacketSyncCategory(int category, int page) { 23 | this.category = category; 24 | this.page = page; 25 | } 26 | 27 | @Override 28 | public void fromBytes(ByteBuf buf) { 29 | this.category = buf.readInt(); 30 | this.page = buf.readInt(); 31 | } 32 | 33 | @Override 34 | public void toBytes(ByteBuf buf) { 35 | buf.writeInt(category); 36 | buf.writeInt(page); 37 | } 38 | 39 | @Override 40 | public IMessage onMessage(PacketSyncCategory message, MessageContext ctx) { 41 | ItemStack book = ctx.getServerHandler().player.getHeldItemOffhand(); 42 | if (book.isEmpty() || !(book.getItem() instanceof IGuideItem)) 43 | book = ctx.getServerHandler().player.getHeldItemMainhand(); 44 | 45 | if (!book.isEmpty() && book.getItem() instanceof IGuideItem) { 46 | if (message.category != -1 && message.page != -1) { 47 | if (!book.hasTagCompound()) 48 | book.setTagCompound(new NBTTagCompound()); 49 | 50 | book.getTagCompound().setInteger(NBTBookTags.CATEGORY_TAG, message.category); 51 | book.getTagCompound().setInteger(NBTBookTags.ENTRY_PAGE_TAG, message.page); 52 | book.getTagCompound().removeTag(NBTBookTags.ENTRY_TAG); 53 | } 54 | } 55 | return null; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/network/PacketSyncEntry.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.network; 2 | 3 | import amerifrance.guideapi.api.IGuideItem; 4 | import amerifrance.guideapi.api.util.NBTBookTags; 5 | import io.netty.buffer.ByteBuf; 6 | import net.minecraft.item.ItemStack; 7 | import net.minecraft.nbt.NBTTagCompound; 8 | import net.minecraft.util.ResourceLocation; 9 | import net.minecraftforge.fml.common.network.ByteBufUtils; 10 | import net.minecraftforge.fml.common.network.simpleimpl.IMessage; 11 | import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; 12 | import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; 13 | 14 | public class PacketSyncEntry implements IMessage, IMessageHandler { 15 | 16 | public int category; 17 | public ResourceLocation entry; 18 | public int page; 19 | 20 | public PacketSyncEntry() { 21 | this.category = -1; 22 | this.entry = new ResourceLocation("guideapi", "none"); 23 | this.page = -1; 24 | } 25 | 26 | public PacketSyncEntry(int category, ResourceLocation entry, int page) { 27 | this.category = category; 28 | this.entry = entry; 29 | this.page = page; 30 | } 31 | 32 | @Override 33 | public void fromBytes(ByteBuf buf) { 34 | this.category = buf.readInt(); 35 | this.entry = new ResourceLocation(ByteBufUtils.readUTF8String(buf)); 36 | this.page = buf.readInt(); 37 | } 38 | 39 | @Override 40 | public void toBytes(ByteBuf buf) { 41 | buf.writeInt(category); 42 | ByteBufUtils.writeUTF8String(buf, entry.toString()); 43 | buf.writeInt(page); 44 | } 45 | 46 | @Override 47 | public IMessage onMessage(PacketSyncEntry message, MessageContext ctx) { 48 | ItemStack book = ctx.getServerHandler().player.getHeldItemOffhand(); 49 | if (book.isEmpty() || !(book.getItem() instanceof IGuideItem)) 50 | book = ctx.getServerHandler().player.getHeldItemMainhand(); 51 | 52 | if (!book.isEmpty() && book.getItem() instanceof IGuideItem) { 53 | if (message.category != -1 && !message.entry.equals(new ResourceLocation("guideapi", "none")) && message.page != -1) { 54 | if (!book.hasTagCompound()) 55 | book.setTagCompound(new NBTTagCompound()); 56 | 57 | book.getTagCompound().setInteger(NBTBookTags.CATEGORY_TAG, message.category); 58 | book.getTagCompound().setString(NBTBookTags.ENTRY_TAG, message.entry.toString()); 59 | book.getTagCompound().setInteger(NBTBookTags.PAGE_TAG, message.page); 60 | } 61 | } 62 | return null; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/network/PacketSyncHome.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.network; 2 | 3 | import amerifrance.guideapi.api.IGuideItem; 4 | import amerifrance.guideapi.api.util.NBTBookTags; 5 | import io.netty.buffer.ByteBuf; 6 | import net.minecraft.item.ItemStack; 7 | import net.minecraft.nbt.NBTTagCompound; 8 | import net.minecraftforge.fml.common.network.simpleimpl.IMessage; 9 | import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; 10 | import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; 11 | 12 | public class PacketSyncHome implements IMessage, IMessageHandler { 13 | 14 | public int page; 15 | 16 | public PacketSyncHome() { 17 | this.page = -1; 18 | } 19 | 20 | public PacketSyncHome(int page) { 21 | this.page = page; 22 | } 23 | 24 | @Override 25 | public void fromBytes(ByteBuf buf) { 26 | this.page = buf.readInt(); 27 | } 28 | 29 | @Override 30 | public void toBytes(ByteBuf buf) { 31 | buf.writeInt(page); 32 | } 33 | 34 | @Override 35 | public IMessage onMessage(PacketSyncHome message, MessageContext ctx) { 36 | ItemStack book = ctx.getServerHandler().player.getHeldItemOffhand(); 37 | if (book.isEmpty() || !(book.getItem() instanceof IGuideItem)) 38 | book = ctx.getServerHandler().player.getHeldItemMainhand(); 39 | 40 | if (!book.isEmpty() && book.getItem() instanceof IGuideItem && message.page != -1) { 41 | if (!book.hasTagCompound()) 42 | book.setTagCompound(new NBTTagCompound()); 43 | book.getTagCompound().setInteger(NBTBookTags.CATEGORY_PAGE_TAG, message.page); 44 | book.getTagCompound().removeTag(NBTBookTags.CATEGORY_TAG); 45 | book.getTagCompound().removeTag(NBTBookTags.ENTRY_TAG); 46 | } 47 | return null; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/page/PageBrewingRecipe.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.page; 2 | 3 | import amerifrance.guideapi.api.SubTexture; 4 | import amerifrance.guideapi.api.impl.Book; 5 | import amerifrance.guideapi.api.impl.Page; 6 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 7 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 8 | import amerifrance.guideapi.api.util.GuiHelper; 9 | import amerifrance.guideapi.api.util.TextHelper; 10 | import amerifrance.guideapi.gui.GuiBase; 11 | import net.minecraft.client.gui.FontRenderer; 12 | import net.minecraft.init.Blocks; 13 | import net.minecraft.item.Item; 14 | import net.minecraft.item.ItemStack; 15 | import net.minecraftforge.common.brewing.BrewingRecipe; 16 | import net.minecraftforge.fml.relauncher.Side; 17 | import net.minecraftforge.fml.relauncher.SideOnly; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | 22 | public class PageBrewingRecipe extends Page { 23 | 24 | public BrewingRecipe recipe; 25 | public ItemStack ingredient; 26 | public ItemStack input; 27 | public ItemStack output; 28 | 29 | /** 30 | * Your brewing recipe - what you pass to BrewingRecipeRegistry.addRecipe 31 | * 32 | * @param recipe 33 | */ 34 | public PageBrewingRecipe(BrewingRecipe recipe) { 35 | this.recipe = recipe; 36 | this.ingredient = recipe.getIngredient(); 37 | this.input = recipe.getInput(); 38 | this.output = recipe.getOutput(); 39 | } 40 | 41 | /** 42 | * @param input - The top slot of our brewing recipe 43 | * @param ingredient - What goes in the three bottle slots 44 | * @param output - Result of recipe 45 | */ 46 | public PageBrewingRecipe(ItemStack input, ItemStack ingredient, ItemStack output) { 47 | this.input = input; 48 | this.output = ingredient; 49 | this.ingredient = output; 50 | } 51 | 52 | @Override 53 | @SideOnly(Side.CLIENT) 54 | public void draw(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 55 | 56 | int xStart = guiLeft + 62; 57 | int yStart = guiTop + 52; 58 | 59 | SubTexture.POTION_GRID.draw(xStart, yStart); 60 | 61 | List badTip = new ArrayList(); 62 | badTip.add(TextHelper.localizeEffect("text.brewing.error")); 63 | 64 | guiBase.drawCenteredString(fontRendererObj, TextHelper.localizeEffect("text.brewing.brew"), guiLeft + guiBase.xSize / 2, guiTop + 12, 0); 65 | 66 | //int xmiddle = guiLeft + guiBase.xSize / 2 - 6; 67 | int x = xStart + 25;//since item stack is approx 16 wide 68 | int y = yStart + 1; 69 | //start input 70 | GuiHelper.drawItemStack(ingredient, x, y); 71 | 72 | List tooltip = null; 73 | if (GuiHelper.isMouseBetween(mouseX, mouseY, x, y, 15, 15)) 74 | tooltip = GuiHelper.getTooltip(ingredient); 75 | 76 | //the three bottles 77 | y += 39; 78 | GuiHelper.drawItemStack(input, x, y); 79 | if (GuiHelper.isMouseBetween(mouseX, mouseY, x, y, 15, 15)) 80 | tooltip = GuiHelper.getTooltip(input); 81 | int hSpacing = 24; 82 | x -= hSpacing; 83 | y -= 8; 84 | GuiHelper.drawItemStack(input, x, y); 85 | if (GuiHelper.isMouseBetween(mouseX, mouseY, x, y, 15, 15)) 86 | tooltip = GuiHelper.getTooltip(input); 87 | x += hSpacing * 2; 88 | GuiHelper.drawItemStack(input, x, y); 89 | if (GuiHelper.isMouseBetween(mouseX, mouseY, x, y, 15, 15)) 90 | tooltip = GuiHelper.getTooltip(input); 91 | 92 | if (output.isEmpty()) 93 | output = new ItemStack(Blocks.BARRIER); 94 | 95 | //start output 96 | x = xStart + 25; 97 | y += 31; 98 | GuiHelper.drawItemStack(output, x, y); 99 | if (GuiHelper.isMouseBetween(mouseX, mouseY, x, y, 15, 15)) 100 | tooltip = output.getItem() == Item.getItemFromBlock(Blocks.BARRIER) ? badTip : GuiHelper.getTooltip(output); 101 | 102 | if (output.getItem() == Item.getItemFromBlock(Blocks.BARRIER)) 103 | guiBase.drawCenteredString(fontRendererObj, TextHelper.localizeEffect("text.brewing.error"), guiLeft + guiBase.xSize / 2, guiTop + 4 * guiBase.ySize / 6, 0xED073D); 104 | 105 | if (tooltip != null) 106 | guiBase.drawHoveringText(tooltip, mouseX, mouseY); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/page/PageFurnaceRecipe.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.page; 2 | 3 | import amerifrance.guideapi.api.SubTexture; 4 | import amerifrance.guideapi.api.impl.Book; 5 | import amerifrance.guideapi.api.impl.Page; 6 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 7 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 8 | import amerifrance.guideapi.api.util.GuiHelper; 9 | import amerifrance.guideapi.api.util.TextHelper; 10 | import amerifrance.guideapi.gui.GuiBase; 11 | import net.minecraft.block.Block; 12 | import net.minecraft.client.gui.FontRenderer; 13 | import net.minecraft.init.Blocks; 14 | import net.minecraft.item.Item; 15 | import net.minecraft.item.ItemStack; 16 | import net.minecraft.item.crafting.FurnaceRecipes; 17 | import net.minecraftforge.fml.relauncher.Side; 18 | import net.minecraftforge.fml.relauncher.SideOnly; 19 | import net.minecraftforge.oredict.OreDictionary; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | public class PageFurnaceRecipe extends Page { 25 | 26 | public ItemStack input; 27 | public ItemStack output; 28 | 29 | /** 30 | * @param input - Input ItemStack to draw smelting result of 31 | */ 32 | public PageFurnaceRecipe(ItemStack input) { 33 | this.input = input; 34 | this.output = FurnaceRecipes.instance().getSmeltingResult(input); 35 | } 36 | 37 | /** 38 | * @param input - Input Item to draw smelting result of 39 | */ 40 | public PageFurnaceRecipe(Item input) { 41 | this.input = new ItemStack(input); 42 | this.output = FurnaceRecipes.instance().getSmeltingResult(new ItemStack(input)); 43 | } 44 | 45 | /** 46 | * @param input - Input Block to draw smelting result of 47 | */ 48 | public PageFurnaceRecipe(Block input) { 49 | this.input = new ItemStack(input); 50 | this.output = FurnaceRecipes.instance().getSmeltingResult(new ItemStack(input)); 51 | } 52 | 53 | /** 54 | * @param input - Input OreDict entry to draw smelting result of 55 | */ 56 | public PageFurnaceRecipe(String input) { 57 | 58 | this.input = new ItemStack(Blocks.FIRE); 59 | 60 | if (!OreDictionary.getOres(input).isEmpty()) 61 | for (int i = 0; i < OreDictionary.getOres(input).size(); i++) { 62 | ItemStack stack = OreDictionary.getOres(input).get(i); 63 | 64 | this.input = stack; 65 | this.output = FurnaceRecipes.instance().getSmeltingResult(stack); 66 | } 67 | } 68 | 69 | @Override 70 | @SideOnly(Side.CLIENT) 71 | @SuppressWarnings("unchecked") 72 | public void draw(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 73 | SubTexture.FURNACE_GRID.draw(guiLeft + 64, guiTop + 71); 74 | 75 | List badTip = new ArrayList(); 76 | badTip.add(TextHelper.localizeEffect("text.furnace.error")); 77 | 78 | guiBase.drawCenteredString(fontRendererObj, TextHelper.localizeEffect("text.furnace.smelting"), guiLeft + guiBase.xSize / 2, guiTop + 12, 0); 79 | 80 | int x = guiLeft + 66; 81 | int y = guiTop + 77; 82 | GuiHelper.drawItemStack(input, x, y); 83 | 84 | List tooltip = null; 85 | if (GuiHelper.isMouseBetween(mouseX, mouseY, x, y, 15, 15)) 86 | tooltip = GuiHelper.getTooltip(input); 87 | 88 | if (output.isEmpty()) 89 | output = new ItemStack(Blocks.BARRIER); 90 | 91 | x = guiLeft + 109; 92 | GuiHelper.drawItemStack(output, x, y); 93 | if (GuiHelper.isMouseBetween(mouseX, mouseY, x, y, 15, 15)) 94 | tooltip = output.getItem() == Item.getItemFromBlock(Blocks.BARRIER) ? badTip : GuiHelper.getTooltip(output); 95 | 96 | if (output.getItem() == Item.getItemFromBlock(Blocks.BARRIER)) 97 | guiBase.drawCenteredString(fontRendererObj, TextHelper.localizeEffect("text.furnace.error"), guiLeft + guiBase.xSize / 2, guiTop + 4 * guiBase.ySize / 6, 0xED073D); 98 | 99 | if (tooltip != null) 100 | guiBase.drawHoveringText(tooltip, mouseX, mouseY); 101 | } 102 | 103 | @Override 104 | public boolean equals(Object o) { 105 | if (this == o) return true; 106 | if (!(o instanceof PageFurnaceRecipe)) return false; 107 | if (!super.equals(o)) return false; 108 | 109 | PageFurnaceRecipe that = (PageFurnaceRecipe) o; 110 | 111 | if (input != null ? !input.equals(that.input) : that.input != null) return false; 112 | return output != null ? output.equals(that.output) : that.output == null; 113 | } 114 | 115 | @Override 116 | public int hashCode() { 117 | int result = input != null ? input.hashCode() : 0; 118 | result = 31 * result + (output != null ? output.hashCode() : 0); 119 | return result; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/page/PageIRecipe.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.page; 2 | 3 | import amerifrance.guideapi.api.IRecipeRenderer; 4 | import amerifrance.guideapi.api.impl.Book; 5 | import amerifrance.guideapi.api.impl.Page; 6 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 7 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 8 | import amerifrance.guideapi.gui.GuiBase; 9 | import amerifrance.guideapi.gui.GuiEntry; 10 | import amerifrance.guideapi.page.reciperenderer.ShapedOreRecipeRenderer; 11 | import amerifrance.guideapi.page.reciperenderer.ShapedRecipesRenderer; 12 | import amerifrance.guideapi.page.reciperenderer.ShapelessOreRecipeRenderer; 13 | import amerifrance.guideapi.page.reciperenderer.ShapelessRecipesRenderer; 14 | import amerifrance.guideapi.util.LogHelper; 15 | import net.minecraft.client.gui.FontRenderer; 16 | import net.minecraft.entity.player.EntityPlayer; 17 | import net.minecraft.item.ItemStack; 18 | import net.minecraft.item.crafting.IRecipe; 19 | import net.minecraft.item.crafting.ShapedRecipes; 20 | import net.minecraft.item.crafting.ShapelessRecipes; 21 | import net.minecraftforge.fml.relauncher.Side; 22 | import net.minecraftforge.fml.relauncher.SideOnly; 23 | import net.minecraftforge.oredict.ShapedOreRecipe; 24 | import net.minecraftforge.oredict.ShapelessOreRecipe; 25 | 26 | public class PageIRecipe extends Page { 27 | 28 | public IRecipe recipe; 29 | public IRecipeRenderer iRecipeRenderer; 30 | protected boolean isValid; 31 | 32 | /** 33 | * Use this if you are creating a page for a standard recipe, one of: 34 | *

35 | *

    36 | *
  • {@link ShapedRecipes}
  • 37 | *
  • {@link ShapelessRecipes}
  • 38 | *
  • {@link ShapedOreRecipe}
  • 39 | *
  • {@link ShapelessOreRecipe}
  • 40 | *
41 | * 42 | * @param recipe - Recipe to draw 43 | */ 44 | public PageIRecipe(IRecipe recipe) { 45 | this(recipe, getRenderer(recipe)); 46 | } 47 | 48 | /** 49 | * @param recipe - Recipe to draw 50 | * @param iRecipeRenderer - Your custom Recipe drawer 51 | */ 52 | public PageIRecipe(IRecipe recipe, IRecipeRenderer iRecipeRenderer) { 53 | this.recipe = recipe; 54 | this.iRecipeRenderer = iRecipeRenderer; 55 | isValid = recipe != null && iRecipeRenderer != null; 56 | } 57 | 58 | @Override 59 | @SideOnly(Side.CLIENT) 60 | public void draw(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 61 | if(isValid) { 62 | super.draw(book, category, entry, guiLeft, guiTop, mouseX, mouseY, guiBase, fontRendererObj); 63 | iRecipeRenderer.draw(book, category, entry, guiLeft, guiTop, mouseX, mouseY, guiBase, fontRendererObj); 64 | } 65 | } 66 | 67 | @Override 68 | @SideOnly(Side.CLIENT) 69 | public void drawExtras(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 70 | if(isValid) { 71 | super.drawExtras(book, category, entry, guiLeft, guiTop, mouseX, mouseY, guiBase, fontRendererObj); 72 | iRecipeRenderer.drawExtras(book, category, entry, guiLeft, guiTop, mouseX, mouseY, guiBase, fontRendererObj); 73 | } 74 | } 75 | 76 | @Override 77 | public boolean canSee(Book book, CategoryAbstract category, EntryAbstract entry, EntityPlayer player, ItemStack bookStack, GuiEntry guiEntry) { 78 | return isValid; 79 | } 80 | 81 | public static PageIRecipe newShaped(ItemStack output, Object... input) { 82 | return new PageIRecipe(new ShapedOreRecipe(null, output, input)); 83 | } 84 | 85 | public static PageIRecipe newShapeless(ItemStack output, Object... input) { 86 | return new PageIRecipe(new ShapelessOreRecipe(null, output, input)); 87 | } 88 | 89 | static IRecipeRenderer getRenderer(IRecipe recipe) { 90 | if (recipe == null) { 91 | LogHelper.error("Cannot get renderer for null recipe."); 92 | return null; 93 | } else if (recipe instanceof ShapedRecipes) { 94 | return new ShapedRecipesRenderer((ShapedRecipes) recipe); 95 | } else if (recipe instanceof ShapelessRecipes) { 96 | return new ShapelessRecipesRenderer((ShapelessRecipes) recipe); 97 | } else if (recipe instanceof ShapedOreRecipe) { 98 | return new ShapedOreRecipeRenderer((ShapedOreRecipe) recipe); 99 | } else if (recipe instanceof ShapelessOreRecipe) { 100 | return new ShapelessOreRecipeRenderer((ShapelessOreRecipe) recipe); 101 | } else { 102 | LogHelper.error("Cannot get renderer for recipe type "+recipe.getClass().toString()); 103 | return null; 104 | } 105 | } 106 | 107 | @Override 108 | public boolean equals(Object o) { 109 | if (this == o) return true; 110 | if (!(o instanceof PageIRecipe)) return false; 111 | if (!super.equals(o)) return false; 112 | 113 | PageIRecipe that = (PageIRecipe) o; 114 | 115 | if (recipe != null ? !recipe.equals(that.recipe) : that.recipe != null) return false; 116 | return iRecipeRenderer != null ? iRecipeRenderer.equals(that.iRecipeRenderer) : that.iRecipeRenderer == null; 117 | } 118 | 119 | @Override 120 | public int hashCode() { 121 | int result = super.hashCode(); 122 | result = 31 * result + (recipe != null ? recipe.hashCode() : 0); 123 | result = 31 * result + (iRecipeRenderer != null ? iRecipeRenderer.hashCode() : 0); 124 | return result; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/page/PageImage.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.page; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import amerifrance.guideapi.api.impl.Page; 5 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 6 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 7 | import amerifrance.guideapi.api.util.GuiHelper; 8 | import amerifrance.guideapi.gui.GuiBase; 9 | import net.minecraft.client.Minecraft; 10 | import net.minecraft.client.gui.FontRenderer; 11 | import net.minecraft.util.ResourceLocation; 12 | import net.minecraftforge.fml.relauncher.Side; 13 | import net.minecraftforge.fml.relauncher.SideOnly; 14 | 15 | public class PageImage extends Page { 16 | 17 | public ResourceLocation image; 18 | 19 | /** 20 | * @param image - Image to draw 21 | */ 22 | public PageImage(ResourceLocation image) { 23 | this.image = image; 24 | } 25 | 26 | @Override 27 | @SideOnly(Side.CLIENT) 28 | public void draw(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 29 | Minecraft.getMinecraft().getTextureManager().bindTexture(image); 30 | GuiHelper.drawSizedIconWithoutColor(guiLeft + 50, guiTop + 34, guiBase.xSize, guiBase.ySize, 1F); 31 | } 32 | 33 | @Override 34 | public boolean equals(Object o) { 35 | if (this == o) return true; 36 | if (!(o instanceof PageImage)) return false; 37 | if (!super.equals(o)) return false; 38 | 39 | PageImage pageImage = (PageImage) o; 40 | 41 | return image != null ? image.equals(pageImage.image) : pageImage.image == null; 42 | } 43 | 44 | @Override 45 | public int hashCode() { 46 | return image != null ? image.hashCode() : 0; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/page/PageItemStack.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.page; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 5 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 6 | import amerifrance.guideapi.api.util.GuiHelper; 7 | import amerifrance.guideapi.gui.GuiBase; 8 | import net.minecraft.block.Block; 9 | import net.minecraft.client.gui.FontRenderer; 10 | import net.minecraft.init.Blocks; 11 | import net.minecraft.item.Item; 12 | import net.minecraft.item.ItemStack; 13 | import net.minecraftforge.fml.relauncher.Side; 14 | import net.minecraftforge.fml.relauncher.SideOnly; 15 | import net.minecraftforge.oredict.OreDictionary; 16 | 17 | public class PageItemStack extends PageText { 18 | 19 | public ItemStack stack; 20 | 21 | /** 22 | * @param draw - Unlocalized text to draw 23 | * @param stack - ItemStack to render 24 | */ 25 | public PageItemStack(String draw, ItemStack stack) { 26 | super(draw, 60); 27 | this.stack = stack; 28 | } 29 | 30 | /** 31 | * @param draw - Unlocalized text to draw 32 | * @param item - Item to render 33 | */ 34 | public PageItemStack(String draw, Item item) { 35 | this(draw, new ItemStack(item)); 36 | } 37 | 38 | /** 39 | * @param draw - Unlocalized text to draw 40 | * @param block - Block to render 41 | */ 42 | public PageItemStack(String draw, Block block) { 43 | this(draw, new ItemStack(block)); 44 | } 45 | 46 | /** 47 | * @param draw - Unlocalized text to draw 48 | * @param entry - OreDict entry to render 49 | */ 50 | public PageItemStack(String draw, String entry) { 51 | super(draw, 60); 52 | this.stack = new ItemStack(Blocks.FIRE); 53 | 54 | if (!OreDictionary.getOres(entry).isEmpty()) { 55 | for (int i = 0; i < OreDictionary.getOres(entry).size(); i++) { 56 | ItemStack stack = OreDictionary.getOres(entry).get(i); 57 | this.stack = stack; 58 | } 59 | } 60 | } 61 | 62 | @Override 63 | @SideOnly(Side.CLIENT) 64 | public void drawExtras(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 65 | GuiHelper.drawScaledItemStack(stack, guiLeft + 75, guiTop + 20, 3); 66 | } 67 | 68 | @Override 69 | public boolean equals(Object o) { 70 | if (this == o) return true; 71 | if (!(o instanceof PageItemStack)) return false; 72 | if (!super.equals(o)) return false; 73 | 74 | PageItemStack that = (PageItemStack) o; 75 | 76 | return stack != null ? stack.equals(that.stack) : that.stack == null; 77 | } 78 | 79 | @Override 80 | public int hashCode() { 81 | int result = super.hashCode(); 82 | result = 31 * result + (stack != null ? stack.hashCode() : 0); 83 | return result; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/page/PageJsonRecipe.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.page; 2 | 3 | import net.minecraft.util.ResourceLocation; 4 | import net.minecraftforge.fml.common.registry.ForgeRegistries; 5 | 6 | public class PageJsonRecipe extends PageIRecipe { 7 | 8 | private final ResourceLocation recipeId; 9 | 10 | public PageJsonRecipe(ResourceLocation recipeId) { 11 | super(null, null); 12 | 13 | this.recipeId = recipeId; 14 | } 15 | 16 | public void init() { 17 | this.recipe = ForgeRegistries.RECIPES.getValue(recipeId); 18 | this.iRecipeRenderer = getRenderer(recipe); 19 | this.isValid = recipe != null && iRecipeRenderer != null; 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/page/PageSound.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.page; 2 | 3 | import amerifrance.guideapi.GuideMod; 4 | import amerifrance.guideapi.api.IPage; 5 | import amerifrance.guideapi.api.impl.Book; 6 | import amerifrance.guideapi.api.impl.Page; 7 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 8 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 9 | import amerifrance.guideapi.gui.GuiBase; 10 | import amerifrance.guideapi.gui.GuiEntry; 11 | import net.minecraft.client.gui.FontRenderer; 12 | import net.minecraft.entity.player.EntityPlayer; 13 | import net.minecraft.item.ItemStack; 14 | import net.minecraft.util.SoundEvent; 15 | import net.minecraftforge.fml.relauncher.Side; 16 | import net.minecraftforge.fml.relauncher.SideOnly; 17 | 18 | public class PageSound extends Page { 19 | 20 | public IPage pageToEmulate; 21 | public SoundEvent sound; 22 | 23 | /** 24 | * @param pageToEmulate - Which page to use as a base 25 | * @param sound - Sound to play 26 | */ 27 | public PageSound(IPage pageToEmulate, SoundEvent sound) { 28 | this.pageToEmulate = pageToEmulate; 29 | this.sound = sound; 30 | } 31 | 32 | @Override 33 | @SideOnly(Side.CLIENT) 34 | public void draw(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 35 | pageToEmulate.draw(book, category, entry, guiLeft, guiTop, mouseX, mouseY, guiBase, fontRendererObj); 36 | } 37 | 38 | @Override 39 | @SideOnly(Side.CLIENT) 40 | public void drawExtras(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 41 | pageToEmulate.drawExtras(book, category, entry, guiLeft, guiTop, mouseX, mouseY, guiBase, fontRendererObj); 42 | } 43 | 44 | @Override 45 | public boolean canSee(Book book, CategoryAbstract category, EntryAbstract entry, EntityPlayer player, ItemStack bookStack, GuiEntry guiEntry) { 46 | return pageToEmulate.canSee(book, category, entry, player, bookStack, guiEntry); 47 | } 48 | 49 | @Override 50 | @SideOnly(Side.CLIENT) 51 | public void onLeftClicked(Book book, CategoryAbstract category, EntryAbstract entry, int mouseX, int mouseY, EntityPlayer player, GuiEntry guiEntry) { 52 | GuideMod.PROXY.playSound(sound); 53 | pageToEmulate.onLeftClicked(book, category, entry, mouseX, mouseY, player, guiEntry); 54 | } 55 | 56 | @Override 57 | @SideOnly(Side.CLIENT) 58 | public void onRightClicked(Book book, CategoryAbstract category, EntryAbstract entry, int mouseX, int mouseY, EntityPlayer player, GuiEntry guiEntry) { 59 | pageToEmulate.onRightClicked(book, category, entry, mouseX, mouseY, player, guiEntry); 60 | } 61 | 62 | @Override 63 | public boolean equals(Object o) { 64 | if (this == o) return true; 65 | if (!(o instanceof PageSound)) return false; 66 | if (!super.equals(o)) return false; 67 | 68 | PageSound pageSound = (PageSound) o; 69 | 70 | if (pageToEmulate != null ? !pageToEmulate.equals(pageSound.pageToEmulate) : pageSound.pageToEmulate != null) 71 | return false; 72 | return sound != null ? sound.equals(pageSound.sound) : pageSound.sound == null; 73 | } 74 | 75 | @Override 76 | public int hashCode() { 77 | int result = pageToEmulate != null ? pageToEmulate.hashCode() : 0; 78 | result = 31 * result + (sound != null ? sound.hashCode() : 0); 79 | return result; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/page/PageText.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.page; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import amerifrance.guideapi.api.impl.Page; 5 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 6 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 7 | import amerifrance.guideapi.api.util.PageHelper; 8 | import amerifrance.guideapi.gui.GuiBase; 9 | import net.minecraft.client.gui.FontRenderer; 10 | import net.minecraft.client.resources.I18n; 11 | import net.minecraftforge.fml.relauncher.Side; 12 | import net.minecraftforge.fml.relauncher.SideOnly; 13 | 14 | public class PageText extends Page { 15 | 16 | public String draw; 17 | private int yOffset; 18 | 19 | /** 20 | * @param draw - Text to draw. Checks for localization. 21 | * @param yOffset - How many pixels to offset the text on the Y value 22 | */ 23 | public PageText(String draw, int yOffset) { 24 | this.draw = draw; 25 | this.yOffset = yOffset; 26 | } 27 | 28 | public PageText(String draw) { 29 | this(draw, 0); 30 | } 31 | 32 | @Override 33 | @SideOnly(Side.CLIENT) 34 | public void draw(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 35 | boolean startFlag = fontRendererObj.getUnicodeFlag(); 36 | 37 | if (unicode) 38 | fontRendererObj.setUnicodeFlag(true); 39 | 40 | PageHelper.drawFormattedText(guiLeft + 39, guiTop + 12 + yOffset, guiBase, I18n.format(draw)); 41 | 42 | if (unicode && !startFlag) 43 | fontRendererObj.setUnicodeFlag(false); 44 | } 45 | 46 | @Override 47 | public boolean equals(Object o) { 48 | if (this == o) return true; 49 | if (!(o instanceof PageText)) return false; 50 | if (!super.equals(o)) return false; 51 | 52 | PageText pageText = (PageText) o; 53 | 54 | if (yOffset != pageText.yOffset) return false; 55 | return draw != null ? draw.equals(pageText.draw) : pageText.draw == null; 56 | } 57 | 58 | @Override 59 | public int hashCode() { 60 | int result = draw != null ? draw.hashCode() : 0; 61 | result = 31 * result + yOffset; 62 | return result; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/page/PageTextImage.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.page; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import amerifrance.guideapi.api.impl.Page; 5 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 6 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 7 | import amerifrance.guideapi.api.util.GuiHelper; 8 | import amerifrance.guideapi.gui.GuiBase; 9 | import net.minecraft.client.Minecraft; 10 | import net.minecraft.client.gui.FontRenderer; 11 | import net.minecraft.util.ResourceLocation; 12 | import net.minecraftforge.fml.relauncher.Side; 13 | import net.minecraftforge.fml.relauncher.SideOnly; 14 | 15 | public class PageTextImage extends Page { 16 | 17 | public PageText pageText; 18 | public ResourceLocation image; 19 | public boolean drawAtTop; 20 | 21 | /** 22 | * @param draw - Localized text to draw 23 | * @param image - Image to draw 24 | * @param drawAtTop - Draw Image at top and text at bottom. False reverses this. 25 | */ 26 | public PageTextImage(String draw, ResourceLocation image, boolean drawAtTop) { 27 | this.pageText = new PageText(draw, drawAtTop ? 0 : 100); 28 | this.image = image; 29 | this.drawAtTop = drawAtTop; 30 | } 31 | 32 | @Override 33 | @SideOnly(Side.CLIENT) 34 | public void draw(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 35 | Minecraft.getMinecraft().getTextureManager().bindTexture(image); 36 | GuiHelper.drawSizedIconWithoutColor(guiLeft + 50, guiTop + (drawAtTop ? 60 : 12), guiBase.xSize, guiBase.ySize, 0); 37 | 38 | pageText.setUnicodeFlag(unicode); 39 | pageText.draw(book, category, entry, guiLeft, guiTop, mouseX, mouseY, guiBase, fontRendererObj); 40 | } 41 | 42 | @Override 43 | public boolean equals(Object o) { 44 | if (this == o) return true; 45 | if (!(o instanceof PageTextImage)) return false; 46 | if (!super.equals(o)) return false; 47 | 48 | PageTextImage that = (PageTextImage) o; 49 | 50 | if (drawAtTop != that.drawAtTop) return false; 51 | if (pageText != null ? !pageText.equals(that.pageText) : that.pageText != null) return false; 52 | return image != null ? image.equals(that.image) : that.image == null; 53 | } 54 | 55 | @Override 56 | public int hashCode() { 57 | int result = pageText != null ? pageText.hashCode() : 0; 58 | result = 31 * result + (image != null ? image.hashCode() : 0); 59 | result = 31 * result + (drawAtTop ? 1 : 0); 60 | return result; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/page/reciperenderer/BasicRecipeRenderer.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.page.reciperenderer; 2 | 3 | import amerifrance.guideapi.api.IRecipeRenderer.RecipeRendererBase; 4 | import amerifrance.guideapi.api.SubTexture; 5 | import amerifrance.guideapi.api.impl.Book; 6 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 7 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 8 | import amerifrance.guideapi.api.util.GuiHelper; 9 | import amerifrance.guideapi.api.util.TextHelper; 10 | import amerifrance.guideapi.gui.GuiBase; 11 | import com.google.common.base.Strings; 12 | import net.minecraft.client.Minecraft; 13 | import net.minecraft.client.gui.FontRenderer; 14 | import net.minecraft.creativetab.CreativeTabs; 15 | import net.minecraft.item.ItemStack; 16 | import net.minecraft.item.crafting.IRecipe; 17 | import net.minecraft.util.NonNullList; 18 | import net.minecraftforge.oredict.OreDictionary; 19 | 20 | import java.util.Random; 21 | 22 | public class BasicRecipeRenderer extends RecipeRendererBase { 23 | 24 | private long lastCycle = -1; 25 | private int cycleIdx = 0; 26 | private Random rand = new Random(); 27 | private String customDisplay; 28 | 29 | public BasicRecipeRenderer(T recipe) { 30 | super(recipe); 31 | } 32 | 33 | @Override 34 | public void draw(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 35 | Minecraft mc = Minecraft.getMinecraft(); 36 | 37 | long time = mc.world.getTotalWorldTime(); 38 | if (lastCycle < 0 || lastCycle < time - 20) { 39 | if (lastCycle > 0) { 40 | cycleIdx++; 41 | cycleIdx = Math.max(0, cycleIdx); 42 | } 43 | lastCycle = mc.world.getTotalWorldTime(); 44 | } 45 | 46 | SubTexture.CRAFTING_GRID.draw(guiLeft + 42, guiTop + 53); 47 | 48 | String recipeName = Strings.isNullOrEmpty(customDisplay) ? getRecipeName() : customDisplay; 49 | guiBase.drawCenteredString(fontRendererObj, recipeName, guiLeft + guiBase.xSize / 2, guiTop + 12, 0); 50 | 51 | int outputX = (5 * 18) + (guiLeft + guiBase.xSize / 7) + 5; 52 | int outputY = (2 * 18) + (guiTop + guiBase.xSize / 5); 53 | 54 | ItemStack stack = recipe.getRecipeOutput(); 55 | 56 | if (!stack.isEmpty() && stack.getItemDamage() == OreDictionary.WILDCARD_VALUE) 57 | stack = getNextItem(stack, 0); 58 | 59 | GuiHelper.drawItemStack(stack, outputX, outputY); 60 | if (GuiHelper.isMouseBetween(mouseX, mouseY, outputX, outputY, 15, 15)) 61 | tooltips = GuiHelper.getTooltip(recipe.getRecipeOutput()); 62 | } 63 | 64 | protected ItemStack getNextItem(ItemStack stack, int position) { 65 | NonNullList subItems = NonNullList.create(); 66 | stack.getItem().getSubItems(CreativeTabs.SEARCH, subItems); 67 | return subItems.get(getRandomizedCycle(position, subItems.size())); 68 | } 69 | 70 | protected int getRandomizedCycle(int index, int max) { 71 | rand.setSeed(index); 72 | return (index + rand.nextInt(max) + cycleIdx) % max; 73 | } 74 | 75 | protected String getRecipeName() { 76 | return TextHelper.localizeEffect("text.shaped.crafting"); 77 | } 78 | 79 | public void setCustomTitle(String customDisplay) { 80 | this.customDisplay = customDisplay; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/page/reciperenderer/ShapedOreRecipeRenderer.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.page.reciperenderer; 2 | 3 | import net.minecraft.item.crafting.ShapedRecipes; 4 | import net.minecraftforge.oredict.ShapedOreRecipe; 5 | 6 | // TODO: Fix rendering of recipe 7 | public class ShapedOreRecipeRenderer extends ShapedRecipesRenderer { 8 | 9 | public ShapedOreRecipeRenderer(ShapedOreRecipe recipe) { 10 | super(new ShapedRecipes(recipe.getGroup(), recipe.getWidth(), recipe.getHeight(), recipe.getIngredients(), recipe.getRecipeOutput())); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/page/reciperenderer/ShapedRecipesRenderer.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.page.reciperenderer; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 5 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 6 | import amerifrance.guideapi.api.util.GuiHelper; 7 | import amerifrance.guideapi.gui.GuiBase; 8 | import net.minecraft.client.gui.FontRenderer; 9 | import net.minecraft.item.ItemStack; 10 | import net.minecraft.item.crafting.Ingredient; 11 | import net.minecraft.item.crafting.ShapedRecipes; 12 | import net.minecraftforge.oredict.OreDictionary; 13 | 14 | import java.util.Arrays; 15 | import java.util.List; 16 | 17 | public class ShapedRecipesRenderer extends BasicRecipeRenderer { 18 | 19 | public ShapedRecipesRenderer(ShapedRecipes recipe) { 20 | super(recipe); 21 | } 22 | 23 | @Override 24 | public void draw(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 25 | super.draw(book, category, entry, guiLeft, guiTop, mouseX, mouseY, guiBase, fontRendererObj); 26 | for (int y = 0; y < recipe.recipeHeight; y++) { 27 | for (int x = 0; x < recipe.recipeWidth; x++) { 28 | int stackX = (x + 1) * 17 + (guiLeft + 27) + x; 29 | int stackY = (y + 1) * 17 + (guiTop + 38) + y; 30 | 31 | Ingredient ingredient = recipe.getIngredients().get(y * recipe.recipeWidth + x); 32 | List list = Arrays.asList(ingredient.getMatchingStacks()); 33 | if (!list.isEmpty()) { 34 | ItemStack stack = list.get(getRandomizedCycle(x + (y * 3), list.size())); 35 | if (stack.getItemDamage() == OreDictionary.WILDCARD_VALUE) 36 | stack = getNextItem(stack, x); 37 | GuiHelper.drawItemStack(stack, stackX, stackY); 38 | if (GuiHelper.isMouseBetween(mouseX, mouseY, stackX, stackY, 15, 15)) 39 | tooltips = GuiHelper.getTooltip(stack); 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/page/reciperenderer/ShapelessOreRecipeRenderer.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.page.reciperenderer; 2 | 3 | import net.minecraft.item.crafting.ShapelessRecipes; 4 | import net.minecraftforge.oredict.ShapelessOreRecipe; 5 | 6 | public class ShapelessOreRecipeRenderer extends ShapelessRecipesRenderer { 7 | 8 | public ShapelessOreRecipeRenderer(ShapelessOreRecipe recipe) { 9 | super(new ShapelessRecipes(recipe.getGroup(), recipe.getRecipeOutput(), recipe.getIngredients())); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/page/reciperenderer/ShapelessRecipesRenderer.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.page.reciperenderer; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 5 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 6 | import amerifrance.guideapi.api.util.GuiHelper; 7 | import amerifrance.guideapi.api.util.TextHelper; 8 | import amerifrance.guideapi.gui.GuiBase; 9 | import net.minecraft.client.gui.FontRenderer; 10 | import net.minecraft.item.ItemStack; 11 | import net.minecraft.item.crafting.Ingredient; 12 | import net.minecraft.item.crafting.ShapelessRecipes; 13 | import net.minecraftforge.oredict.OreDictionary; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | 18 | public class ShapelessRecipesRenderer extends BasicRecipeRenderer { 19 | 20 | public ShapelessRecipesRenderer(ShapelessRecipes recipe) { 21 | super(recipe); 22 | } 23 | 24 | @Override 25 | public void draw(Book book, CategoryAbstract category, EntryAbstract entry, int guiLeft, int guiTop, int mouseX, int mouseY, GuiBase guiBase, FontRenderer fontRendererObj) { 26 | super.draw(book, category, entry, guiLeft, guiTop, mouseX, mouseY, guiBase, fontRendererObj); 27 | for (int y = 0; y < 3; y++) { 28 | for (int x = 0; x < 3; x++) { 29 | int i = 3 * y + x; 30 | int stackX = (x + 1) * 17 + (guiLeft + 27) + x; 31 | int stackY = (y + 1) * 17 + (guiTop + 38) + y; 32 | if (i < recipe.getIngredients().size()) { 33 | Ingredient ingredient = recipe.getIngredients().get(i); 34 | List list = Arrays.asList(ingredient.getMatchingStacks()); 35 | if (!list.isEmpty()) { 36 | ItemStack stack = list.get(getRandomizedCycle(x + (y * 3), list.size())); 37 | if (stack.getItemDamage() == OreDictionary.WILDCARD_VALUE) 38 | stack = getNextItem(stack, x); 39 | 40 | GuiHelper.drawItemStack(stack, stackX, stackY); 41 | if (GuiHelper.isMouseBetween(mouseX, mouseY, stackX, stackY, 15, 15)) 42 | tooltips = GuiHelper.getTooltip(stack); 43 | } 44 | } 45 | } 46 | } 47 | } 48 | 49 | @Override 50 | protected String getRecipeName() { 51 | return TextHelper.localizeEffect("text.shapeless.crafting"); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/proxy/ClientProxy.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.proxy; 2 | 3 | import amerifrance.guideapi.api.BookEvent; 4 | import amerifrance.guideapi.api.GuideAPI; 5 | import amerifrance.guideapi.api.IGuideItem; 6 | import amerifrance.guideapi.api.impl.Book; 7 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 8 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 9 | import amerifrance.guideapi.gui.GuiEntry; 10 | import net.minecraft.client.Minecraft; 11 | import net.minecraft.client.audio.PositionedSoundRecord; 12 | import net.minecraft.entity.player.EntityPlayer; 13 | import net.minecraft.item.ItemStack; 14 | import net.minecraft.util.SoundEvent; 15 | import net.minecraftforge.common.MinecraftForge; 16 | 17 | public class ClientProxy extends CommonProxy { 18 | 19 | @Override 20 | public void playSound(SoundEvent sound) { 21 | Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(sound, 1.0F)); 22 | } 23 | 24 | @Override 25 | public void openEntry(Book book, CategoryAbstract categoryAbstract, EntryAbstract entryAbstract, EntityPlayer player, ItemStack stack) { 26 | BookEvent.Open event = new BookEvent.Open(book, stack, player); 27 | if (MinecraftForge.EVENT_BUS.post(event)) { 28 | player.sendStatusMessage(event.getCanceledText(), true); 29 | return; 30 | } 31 | 32 | Minecraft.getMinecraft().displayGuiScreen(new GuiEntry(book, categoryAbstract, entryAbstract, player, stack)); 33 | } 34 | 35 | @Override 36 | public void initColors() { 37 | for (ItemStack bookStack : GuideAPI.getBookToStack().values()) { 38 | Minecraft.getMinecraft().getItemColors().registerItemColorHandler((stack, tintIndex) -> { 39 | IGuideItem guideItem = (IGuideItem) stack.getItem(); 40 | if (guideItem.getBook(stack) != null && tintIndex == 0) 41 | return guideItem.getBook(stack).getColor().getRGB(); 42 | 43 | return -1; 44 | }, bookStack.getItem()); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/proxy/CommonProxy.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.proxy; 2 | 3 | import amerifrance.guideapi.api.GuideAPI; 4 | import amerifrance.guideapi.api.IGuideItem; 5 | import amerifrance.guideapi.api.impl.Book; 6 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 7 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 8 | import amerifrance.guideapi.api.util.NBTBookTags; 9 | import amerifrance.guideapi.gui.GuiCategory; 10 | import amerifrance.guideapi.gui.GuiEntry; 11 | import amerifrance.guideapi.gui.GuiHome; 12 | import net.minecraft.entity.player.EntityPlayer; 13 | import net.minecraft.item.ItemStack; 14 | import net.minecraft.nbt.NBTTagCompound; 15 | import net.minecraft.util.EnumHand; 16 | import net.minecraft.util.ResourceLocation; 17 | import net.minecraft.util.SoundEvent; 18 | import net.minecraft.world.World; 19 | import net.minecraftforge.fml.common.network.IGuiHandler; 20 | 21 | public class CommonProxy implements IGuiHandler { 22 | 23 | @Override 24 | public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { 25 | return null; 26 | } 27 | 28 | @Override 29 | public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { 30 | ItemStack bookStack = player.getHeldItem(EnumHand.values()[x]); 31 | 32 | if (!bookStack.isEmpty() && bookStack.getItem() instanceof IGuideItem) { 33 | Book book = GuideAPI.getIndexedBooks().get(ID); 34 | try { 35 | if (bookStack.hasTagCompound()) { 36 | NBTTagCompound tagCompound = bookStack.getTagCompound(); 37 | if (tagCompound.hasKey(NBTBookTags.ENTRY_TAG) && tagCompound.hasKey(NBTBookTags.CATEGORY_TAG)) { 38 | CategoryAbstract category = book.getCategoryList().get(tagCompound.getInteger(NBTBookTags.CATEGORY_TAG)); 39 | EntryAbstract entry = category.entries.get(new ResourceLocation(tagCompound.getString(NBTBookTags.ENTRY_TAG))); 40 | int pageNumber = tagCompound.getInteger(NBTBookTags.PAGE_TAG); 41 | GuiEntry guiEntry = new GuiEntry(book, category, entry, player, bookStack); 42 | guiEntry.pageNumber = pageNumber; 43 | return guiEntry; 44 | } else if (tagCompound.hasKey(NBTBookTags.CATEGORY_TAG)) { 45 | CategoryAbstract category = book.getCategoryList().get(tagCompound.getInteger(NBTBookTags.CATEGORY_TAG)); 46 | int entryPage = tagCompound.getInteger(NBTBookTags.ENTRY_PAGE_TAG); 47 | GuiCategory guiCategory = new GuiCategory(book, category, player, bookStack, null); 48 | guiCategory.entryPage = entryPage; 49 | return guiCategory; 50 | } else { 51 | int categoryNumber = tagCompound.getInteger(NBTBookTags.CATEGORY_PAGE_TAG); 52 | GuiHome guiHome = new GuiHome(book, player, bookStack); 53 | guiHome.categoryPage = categoryNumber; 54 | return guiHome; 55 | } 56 | } 57 | } catch (Exception e) { 58 | // No-op: If the linked content doesn't exist anymore 59 | } 60 | 61 | return new GuiHome(book, player, bookStack); 62 | } 63 | 64 | return null; 65 | } 66 | 67 | public void playSound(SoundEvent sound) { 68 | } 69 | 70 | public void openEntry(Book book, CategoryAbstract categoryAbstract, EntryAbstract entryAbstract, EntityPlayer player, ItemStack stack) { 71 | } 72 | 73 | public void initColors() { 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/test/TestBook.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.test; 2 | 3 | import amerifrance.guideapi.api.GuideBook; 4 | import amerifrance.guideapi.api.IGuideBook; 5 | import amerifrance.guideapi.api.IPage; 6 | import amerifrance.guideapi.api.impl.Book; 7 | import amerifrance.guideapi.api.impl.Entry; 8 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 9 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 10 | import amerifrance.guideapi.category.CategoryItemStack; 11 | import amerifrance.guideapi.entry.EntryItemStack; 12 | import amerifrance.guideapi.page.PageFurnaceRecipe; 13 | import amerifrance.guideapi.page.PageIRecipe; 14 | import amerifrance.guideapi.page.PageJsonRecipe; 15 | import amerifrance.guideapi.page.PageText; 16 | import com.google.common.collect.Lists; 17 | import com.google.common.collect.Maps; 18 | import net.minecraft.init.Blocks; 19 | import net.minecraft.init.Items; 20 | import net.minecraft.item.ItemStack; 21 | import net.minecraft.item.crafting.IRecipe; 22 | import net.minecraft.util.ResourceLocation; 23 | import net.minecraftforge.oredict.ShapedOreRecipe; 24 | 25 | import javax.annotation.Nonnull; 26 | import javax.annotation.Nullable; 27 | import java.awt.Color; 28 | import java.util.List; 29 | import java.util.Map; 30 | 31 | @GuideBook 32 | public class TestBook implements IGuideBook { 33 | 34 | public static Book book; 35 | 36 | @Nullable 37 | @Override 38 | public Book buildBook() { 39 | book = new Book(); 40 | book.setAuthor("TehNut"); 41 | book.setColor(Color.GRAY); 42 | book.setDisplayName("Display Name"); 43 | book.setTitle("Title message"); 44 | book.setWelcomeMessage("Is this still a thing?"); 45 | 46 | List categories = Lists.newArrayList(); 47 | Map entries = Maps.newHashMap(); 48 | 49 | List pages = Lists.newArrayList(); 50 | pages.add(new PageText("Hello, this is\nsome text")); 51 | pages.add(new PageFurnaceRecipe(Blocks.COBBLESTONE)); 52 | pages.add(PageIRecipe.newShaped(new ItemStack(Items.ACACIA_BOAT), "X X", "XXX", 'X', "plankWood")); 53 | pages.add(new PageJsonRecipe(new ResourceLocation("minecraft", "acacia_fence"))); 54 | Entry entry = new EntryItemStack(pages, "test.entry.name", new ItemStack(Items.POTATO)); 55 | entries.put(new ResourceLocation("guideapi", "entry"), entry); 56 | 57 | pages.add(PageIRecipe.newShapeless(new ItemStack(Blocks.IRON_BLOCK), "ingotIron", "ingotIron", "ingotIron", "ingotIron", "ingotIron", "ingotIron", "ingotIron", "ingotIron", "ingotIron")); 58 | pages.add(PageIRecipe.newShapeless(new ItemStack(Blocks.PLANKS, 4), new ItemStack(Blocks.LOG))); 59 | 60 | categories.add(new CategoryItemStack(entries, "test.category.name", new ItemStack(Items.BANNER))); 61 | book.setCategoryList(categories); 62 | book.setRegistryName(new ResourceLocation("guideapi", "test_book")); 63 | return book; 64 | } 65 | 66 | @Override 67 | public IRecipe getRecipe(@Nonnull ItemStack bookStack) { 68 | return new ShapedOreRecipe(null, bookStack, " X ", "X X", " X ", 'X', "ingotIron").setRegistryName(book.getRegistryName()); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/test/TestBook2.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.test; 2 | 3 | import amerifrance.guideapi.api.GuideBook; 4 | import amerifrance.guideapi.api.IGuideBook; 5 | import amerifrance.guideapi.api.impl.Book; 6 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 7 | import amerifrance.guideapi.category.CategoryItemStack; 8 | import amerifrance.guideapi.entry.EntryItemStack; 9 | import amerifrance.guideapi.page.*; 10 | import net.minecraft.init.Blocks; 11 | import net.minecraft.init.Items; 12 | import net.minecraft.init.PotionTypes; 13 | import net.minecraft.item.ItemStack; 14 | import net.minecraft.item.crafting.IRecipe; 15 | import net.minecraft.potion.PotionUtils; 16 | import net.minecraft.util.ResourceLocation; 17 | import net.minecraftforge.common.brewing.BrewingRecipe; 18 | import net.minecraftforge.oredict.ShapedOreRecipe; 19 | 20 | import javax.annotation.Nonnull; 21 | import javax.annotation.Nullable; 22 | import java.awt.Color; 23 | 24 | @GuideBook 25 | public class TestBook2 implements IGuideBook { 26 | 27 | public static Book book; 28 | 29 | @Nullable 30 | @Override 31 | public Book buildBook() { 32 | book = new Book(); 33 | book.setAuthor("TehNut"); 34 | book.setColor(Color.GREEN); 35 | book.setDisplayName("Display Name"); 36 | book.setTitle("Title message"); 37 | book.setWelcomeMessage("Is this still a thing?"); 38 | 39 | CategoryAbstract testCategory = new CategoryItemStack("test.category.name", new ItemStack(Items.BANNER)).withKeyBase("guideapi"); 40 | testCategory.addEntry("entry", new EntryItemStack("test.entry.name", new ItemStack(Items.POTATO))); 41 | testCategory.getEntry("entry").addPage(new PageText("Hello, this is\nsome text")); 42 | testCategory.getEntry("entry").addPage(new PageFurnaceRecipe(Blocks.COBBLESTONE)); 43 | testCategory.getEntry("entry").addPage(PageIRecipe.newShaped(new ItemStack(Items.ACACIA_BOAT), "X X", "XXX", 'X', new ItemStack(Blocks.PLANKS, 1, 4))); 44 | testCategory.getEntry("entry").addPage(new PageBrewingRecipe(new BrewingRecipe( 45 | PotionUtils.addPotionToItemStack(new ItemStack(Items.POTIONITEM), PotionTypes.AWKWARD), 46 | new ItemStack(Items.SPECKLED_MELON), 47 | PotionUtils.addPotionToItemStack(new ItemStack(Items.POTIONITEM), PotionTypes.HEALING))) 48 | ); 49 | testCategory.getEntry("entry").addPage(new PageJsonRecipe(new ResourceLocation("bread"))); 50 | book.addCategory(testCategory); 51 | 52 | book.setRegistryName(new ResourceLocation("guideapi", "test_book2")); 53 | return book; 54 | } 55 | 56 | @Nullable 57 | @Override 58 | public IRecipe getRecipe(@Nonnull ItemStack bookStack) { 59 | return new ShapedOreRecipe(null, bookStack, "X X", " X ", "X X", 'X', "ingotIron").setRegistryName(book.getRegistryName()); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/test/TestBook3.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.test; 2 | 3 | import amerifrance.guideapi.GuideMod; 4 | import amerifrance.guideapi.api.BookEvent; 5 | import amerifrance.guideapi.api.GuideBook; 6 | import amerifrance.guideapi.api.IGuideBook; 7 | import amerifrance.guideapi.api.impl.Book; 8 | import amerifrance.guideapi.api.impl.BookBinder; 9 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 10 | import amerifrance.guideapi.category.CategoryItemStack; 11 | import amerifrance.guideapi.entry.EntryItemStack; 12 | import amerifrance.guideapi.page.*; 13 | import net.minecraft.creativetab.CreativeTabs; 14 | import net.minecraft.init.Blocks; 15 | import net.minecraft.init.Items; 16 | import net.minecraft.init.PotionTypes; 17 | import net.minecraft.item.ItemStack; 18 | import net.minecraft.potion.PotionUtils; 19 | import net.minecraft.util.ResourceLocation; 20 | import net.minecraft.util.text.TextComponentString; 21 | import net.minecraftforge.common.MinecraftForge; 22 | import net.minecraftforge.common.brewing.BrewingRecipe; 23 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 24 | 25 | import javax.annotation.Nullable; 26 | 27 | @GuideBook 28 | public class TestBook3 implements IGuideBook { 29 | 30 | public static Book book; 31 | 32 | @Nullable 33 | @Override 34 | public Book buildBook() { 35 | MinecraftForge.EVENT_BUS.register(this); 36 | 37 | BookBinder binder = new BookBinder(new ResourceLocation(GuideMod.ID, "test_book3")) 38 | .setAuthor("TunHet") 39 | .setColor(0x7EF67F) 40 | .setCreativeTab(CreativeTabs.COMBAT) 41 | .setGuideTitle("some.guide.title") 42 | .setHeader("some.header.text") 43 | .setSpawnWithBook(); 44 | 45 | CategoryAbstract testCategory = new CategoryItemStack("test.category.name", new ItemStack(Items.BANNER)).withKeyBase("guideapi"); 46 | testCategory.addEntry("entry", new EntryItemStack("test.entry.name", new ItemStack(Items.POTATO))); 47 | testCategory.getEntry("entry").addPage(new PageText("Hello, this is\nsome text")); 48 | testCategory.getEntry("entry").addPage(new PageFurnaceRecipe(Blocks.COBBLESTONE)); 49 | testCategory.getEntry("entry").addPage(PageIRecipe.newShaped(new ItemStack(Items.ACACIA_BOAT), "X X", "XXX", 'X', new ItemStack(Blocks.PLANKS, 1, 4))); 50 | testCategory.getEntry("entry").addPage(new PageBrewingRecipe(new BrewingRecipe( 51 | PotionUtils.addPotionToItemStack(new ItemStack(Items.POTIONITEM), PotionTypes.AWKWARD), 52 | new ItemStack(Items.SPECKLED_MELON), 53 | PotionUtils.addPotionToItemStack(new ItemStack(Items.POTIONITEM), PotionTypes.HEALING))) 54 | ); 55 | testCategory.getEntry("entry").addPage(new PageJsonRecipe(new ResourceLocation("bread"))); 56 | binder.addCategory(testCategory); 57 | 58 | return book = binder.build(); 59 | } 60 | 61 | @SubscribeEvent 62 | public void onBookOpen(BookEvent.Open event) { 63 | if (event.getBook() == book && event.getPlayer().isSneaking()) { 64 | event.setCanceledText(new TextComponentString("No snek allowed")); 65 | event.setCanceled(true); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/util/APISetter.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.util; 2 | 3 | import amerifrance.guideapi.GuideMod; 4 | import amerifrance.guideapi.api.GuideAPI; 5 | import amerifrance.guideapi.api.impl.Book; 6 | import com.google.common.base.Throwables; 7 | import net.minecraft.item.ItemStack; 8 | import net.minecraft.util.ResourceLocation; 9 | import net.minecraftforge.fml.common.Loader; 10 | import net.minecraftforge.fml.common.ModContainer; 11 | 12 | import java.lang.reflect.Field; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | /** 17 | * This class is for internal use only. Do not use this from outside. 18 | */ 19 | @SuppressWarnings("unchecked") 20 | public class APISetter { 21 | 22 | public static void registerBook(Book book) { 23 | try { 24 | sanityCheck(); 25 | } catch (IllegalAccessException e) { 26 | Throwables.propagate(e); 27 | return; 28 | } 29 | 30 | try { 31 | Field books = GuideAPI.class.getDeclaredField("BOOKS"); 32 | books.setAccessible(true); 33 | Map BOOKS = (Map) books.get(null); 34 | BOOKS.put(book.getRegistryName(), book); 35 | } catch (Exception e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | 40 | public static void setBookForStack(Book book, ItemStack stack) { 41 | try { 42 | sanityCheck(); 43 | } catch (IllegalAccessException e) { 44 | Throwables.propagate(e); 45 | return; 46 | } 47 | 48 | try { 49 | Field stacks = GuideAPI.class.getDeclaredField("BOOK_TO_STACK"); 50 | stacks.setAccessible(true); 51 | Map BOOK_TO_STACK = (Map) stacks.get(null); 52 | BOOK_TO_STACK.put(book, stack); 53 | } catch (Exception e) { 54 | e.printStackTrace(); 55 | } 56 | } 57 | 58 | public static void setIndexedBooks(List books) { 59 | try { 60 | sanityCheck(); 61 | } catch (IllegalAccessException e) { 62 | Throwables.propagate(e); 63 | return; 64 | } 65 | 66 | try { 67 | Field indexedBooks = GuideAPI.class.getDeclaredField("indexedBooks"); 68 | indexedBooks.setAccessible(true); 69 | indexedBooks.set(null, books); 70 | } catch (Exception e) { 71 | e.printStackTrace(); 72 | } 73 | } 74 | 75 | private static void sanityCheck() throws IllegalAccessException { 76 | ModContainer activeMod = Loader.instance().activeModContainer(); 77 | if (!activeMod.getModId().equals(GuideMod.ID)) 78 | throw new IllegalAccessException("Mod " + activeMod.getModId() + " tried to access an internal-only method in GuideAPI. Please report this."); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/util/AnnotationHandler.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.util; 2 | 3 | import amerifrance.guideapi.api.GuideAPI; 4 | import amerifrance.guideapi.api.GuideBook; 5 | import amerifrance.guideapi.api.IGuideBook; 6 | import amerifrance.guideapi.api.impl.Book; 7 | import com.google.common.collect.Lists; 8 | import net.minecraftforge.fml.common.discovery.ASMDataTable; 9 | import net.minecraftforge.fml.common.discovery.asm.ModAnnotation; 10 | import net.minecraftforge.fml.common.eventhandler.EventPriority; 11 | import org.apache.commons.lang3.tuple.Pair; 12 | 13 | import java.util.List; 14 | 15 | public class AnnotationHandler { 16 | 17 | public static final List> BOOK_CLASSES = Lists.newArrayList(); 18 | 19 | public static void gatherBooks(ASMDataTable dataTable) { 20 | for (EventPriority priority : EventPriority.values()) 21 | for (ASMDataTable.ASMData data : dataTable.getAll(GuideBook.class.getCanonicalName())) { 22 | try { 23 | Class genericClass = Class.forName(data.getClassName()); 24 | if (!IGuideBook.class.isAssignableFrom(genericClass)) 25 | continue; 26 | 27 | IGuideBook guideBook = (IGuideBook) genericClass.newInstance(); 28 | ModAnnotation.EnumHolder holder = (ModAnnotation.EnumHolder) data.getAnnotationInfo().get("priority"); 29 | EventPriority bookPriority = holder == null ? EventPriority.NORMAL : EventPriority.valueOf(holder.getValue()); 30 | if (priority != bookPriority) 31 | continue; 32 | Book book = guideBook.buildBook(); 33 | if (book == null) 34 | continue; 35 | APISetter.registerBook(book); 36 | BOOK_CLASSES.add(Pair.of(book, guideBook)); 37 | } catch (Exception e) { 38 | LogHelper.error("Error registering book for class " + data.getClassName()); 39 | e.printStackTrace(); 40 | } 41 | } 42 | 43 | APISetter.setIndexedBooks(Lists.newArrayList(GuideAPI.getBooks().values())); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/util/EventHandler.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.util; 2 | 3 | import amerifrance.guideapi.ConfigHandler; 4 | import amerifrance.guideapi.GuideMod; 5 | import amerifrance.guideapi.api.GuideAPI; 6 | import amerifrance.guideapi.api.IGuideItem; 7 | import amerifrance.guideapi.api.IGuideLinked; 8 | import amerifrance.guideapi.api.IInfoRenderer; 9 | import amerifrance.guideapi.api.impl.Book; 10 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 11 | import amerifrance.guideapi.api.util.TextHelper; 12 | import com.google.common.base.Strings; 13 | import com.google.common.collect.Multimap; 14 | import net.minecraft.block.Block; 15 | import net.minecraft.block.state.IBlockState; 16 | import net.minecraft.client.Minecraft; 17 | import net.minecraft.client.gui.FontRenderer; 18 | import net.minecraft.client.gui.ScaledResolution; 19 | import net.minecraft.entity.player.EntityPlayer; 20 | import net.minecraft.item.ItemStack; 21 | import net.minecraft.nbt.NBTTagCompound; 22 | import net.minecraft.util.EnumHand; 23 | import net.minecraft.util.ResourceLocation; 24 | import net.minecraft.util.math.RayTraceResult; 25 | import net.minecraft.util.text.TextFormatting; 26 | import net.minecraft.world.World; 27 | import net.minecraftforge.client.event.RenderGameOverlayEvent; 28 | import net.minecraftforge.event.entity.EntityJoinWorldEvent; 29 | import net.minecraftforge.fml.common.Mod; 30 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 31 | import net.minecraftforge.fml.relauncher.Side; 32 | import net.minecraftforge.fml.relauncher.SideOnly; 33 | import net.minecraftforge.items.ItemHandlerHelper; 34 | 35 | import java.util.Collection; 36 | 37 | @Mod.EventBusSubscriber(modid = GuideMod.ID) 38 | public class EventHandler { 39 | 40 | @SubscribeEvent 41 | public static void onPlayerJoinWorld(EntityJoinWorldEvent event) { 42 | if (!event.getEntity().world.isRemote && event.getEntity() instanceof EntityPlayer) { 43 | EntityPlayer player = (EntityPlayer) event.getEntity(); 44 | NBTTagCompound tag = getModTag(player, GuideMod.ID); 45 | if (ConfigHandler.canSpawnWithBooks) { 46 | for (Book book : GuideAPI.getBooks().values()) { 47 | if (ConfigHandler.SPAWN_BOOKS.getOrDefault(book, false) && !tag.getBoolean("hasInitial" + book.getTitle())) { 48 | ItemHandlerHelper.giveItemToPlayer(player, GuideAPI.getStackFromBook(book)); 49 | tag.setBoolean("hasInitial" + book.getTitle(), true); 50 | } 51 | } 52 | } 53 | } 54 | } 55 | 56 | @SideOnly(Side.CLIENT) 57 | @SubscribeEvent 58 | public static void renderOverlay(RenderGameOverlayEvent.Pre event) { 59 | if (event.getType() != RenderGameOverlayEvent.ElementType.CROSSHAIRS) 60 | return; 61 | 62 | RayTraceResult rayTrace = Minecraft.getMinecraft().objectMouseOver; 63 | if (rayTrace == null || rayTrace.typeOfHit != RayTraceResult.Type.BLOCK) 64 | return; 65 | 66 | EntityPlayer player = Minecraft.getMinecraft().player; 67 | World world = Minecraft.getMinecraft().world; 68 | ItemStack held = ItemStack.EMPTY; 69 | Book book = null; 70 | for (EnumHand hand : EnumHand.values()) { 71 | ItemStack heldStack = player.getHeldItem(hand); 72 | if (heldStack.getItem() instanceof IGuideItem) { 73 | held = heldStack; 74 | book = ((IGuideItem) heldStack.getItem()).getBook(heldStack); 75 | break; 76 | } 77 | } 78 | 79 | if (book == null) 80 | return; 81 | 82 | IBlockState state = world.getBlockState(rayTrace.getBlockPos()); 83 | String linkedEntry = null; 84 | if (state.getBlock() instanceof IGuideLinked) { 85 | IGuideLinked linked = (IGuideLinked) state.getBlock(); 86 | ResourceLocation entryKey = linked.getLinkedEntry(world, rayTrace.getBlockPos(), player, held); 87 | if (entryKey != null) { 88 | for (CategoryAbstract category : book.getCategoryList()) { 89 | if (category.entries.containsKey(entryKey)) { 90 | linkedEntry = category.getEntry(entryKey).getLocalizedName(); 91 | break; 92 | } 93 | } 94 | } 95 | } 96 | 97 | if (!Strings.isNullOrEmpty(linkedEntry)) { 98 | FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; 99 | ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); 100 | int drawX = scaledResolution.getScaledWidth() / 2 + 10; 101 | int drawY = scaledResolution.getScaledHeight() / 2 - 8; 102 | 103 | Minecraft.getMinecraft().getRenderItem().renderItemIntoGUI(held, drawX, drawY); 104 | 105 | drawY -= 2; 106 | drawX += 20; 107 | fontRenderer.drawStringWithShadow(TextFormatting.WHITE + linkedEntry, drawX, drawY, 0); 108 | fontRenderer.drawStringWithShadow(TextFormatting.WHITE.toString() + TextFormatting.ITALIC.toString() + TextHelper.localize("text.linked.open"), drawX, drawY + 12, 0); 109 | } 110 | 111 | if (state.getBlock() instanceof IInfoRenderer.Block) { 112 | IInfoRenderer infoRenderer = ((IInfoRenderer.Block) state.getBlock()).getInfoRenderer(book, world, rayTrace.getBlockPos(), state, rayTrace, player); 113 | if (book == ((IInfoRenderer.Block) state.getBlock()).getBook() && infoRenderer != null) 114 | infoRenderer.drawInformation(book, world, rayTrace.getBlockPos(), state, rayTrace, player); 115 | } 116 | 117 | Multimap, IInfoRenderer> bookRenderers = GuideAPI.getInfoRenderers().get(book); 118 | if (bookRenderers == null) 119 | return; 120 | 121 | Collection renderers = bookRenderers.get(state.getBlock().getClass()); 122 | for (IInfoRenderer renderer : renderers) 123 | renderer.drawInformation(book, world, rayTrace.getBlockPos(), state, rayTrace, player); 124 | } 125 | 126 | public static NBTTagCompound getModTag(EntityPlayer player, String modName) { 127 | NBTTagCompound tag = player.getEntityData(); 128 | NBTTagCompound persistTag; 129 | 130 | if (tag.hasKey(EntityPlayer.PERSISTED_NBT_TAG)) 131 | persistTag = tag.getCompoundTag(EntityPlayer.PERSISTED_NBT_TAG); 132 | else { 133 | persistTag = new NBTTagCompound(); 134 | tag.setTag(EntityPlayer.PERSISTED_NBT_TAG, persistTag); 135 | } 136 | 137 | NBTTagCompound modTag; 138 | if (persistTag.hasKey(modName)) { 139 | modTag = persistTag.getCompoundTag(modName); 140 | } else { 141 | modTag = new NBTTagCompound(); 142 | persistTag.setTag(modName, modTag); 143 | } 144 | return modTag; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/util/LogHelper.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.util; 2 | 3 | import amerifrance.guideapi.ConfigHandler; 4 | import amerifrance.guideapi.GuideMod; 5 | import org.apache.logging.log4j.LogManager; 6 | import org.apache.logging.log4j.Logger; 7 | 8 | public class LogHelper { 9 | 10 | private static Logger logger = LogManager.getLogger(GuideMod.NAME); 11 | 12 | /** 13 | * @param info - String to log to the info level 14 | */ 15 | 16 | public static void info(Object info) { 17 | if (ConfigHandler.enableLogging) 18 | logger.info(info); 19 | } 20 | 21 | /** 22 | * @param error - String to log to the error level 23 | */ 24 | 25 | public static void error(Object error) { 26 | if (ConfigHandler.enableLogging) 27 | logger.error(error); 28 | } 29 | 30 | /** 31 | * @param debug - String to log to the debug level 32 | */ 33 | 34 | public static void debug(Object debug) { 35 | if (ConfigHandler.enableLogging) 36 | logger.debug(debug); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/wrapper/AbstractWrapper.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.wrapper; 2 | 3 | import amerifrance.guideapi.gui.GuiBase; 4 | 5 | public abstract class AbstractWrapper { 6 | 7 | public abstract void onHoverOver(int mouseX, int mouseY); 8 | 9 | public abstract boolean canPlayerSee(); 10 | 11 | public abstract void draw(int mouseX, int mouseY, GuiBase gui); 12 | 13 | public abstract void drawExtras(int mouseX, int mouseY, GuiBase gui); 14 | 15 | public abstract boolean isMouseOnWrapper(int mouseX, int mouseY); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/wrapper/CategoryWrapper.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.wrapper; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 5 | import amerifrance.guideapi.api.util.GuiHelper; 6 | import amerifrance.guideapi.gui.GuiBase; 7 | import net.minecraft.client.gui.FontRenderer; 8 | import net.minecraft.client.renderer.RenderItem; 9 | import net.minecraft.entity.player.EntityPlayer; 10 | import net.minecraft.item.ItemStack; 11 | 12 | public class CategoryWrapper extends AbstractWrapper { 13 | 14 | public Book book; 15 | public CategoryAbstract category; 16 | public int x, y, width, height; 17 | public EntityPlayer player; 18 | public FontRenderer renderer; 19 | public RenderItem renderItem; 20 | public boolean drawOnLeft; 21 | public ItemStack bookStack; 22 | 23 | public CategoryWrapper(Book book, CategoryAbstract category, int x, int y, int width, int height, EntityPlayer player, FontRenderer renderer, RenderItem renderItem, boolean drawOnLeft, ItemStack bookStack) { 24 | this.book = book; 25 | this.category = category; 26 | this.x = x; 27 | this.y = y; 28 | this.width = width; 29 | this.height = height; 30 | this.player = player; 31 | this.renderer = renderer; 32 | this.renderItem = renderItem; 33 | this.drawOnLeft = drawOnLeft; 34 | this.bookStack = bookStack; 35 | } 36 | 37 | @Override 38 | public void onHoverOver(int mouseX, int mouseY) { 39 | } 40 | 41 | @Override 42 | public boolean canPlayerSee() { 43 | return category.canSee(player, bookStack); 44 | } 45 | 46 | @Override 47 | public void draw(int mouseX, int mouseY, GuiBase gui) { 48 | category.draw(book, x, y, width, height, mouseX, mouseY, gui, drawOnLeft, renderItem); 49 | } 50 | 51 | @Override 52 | public void drawExtras(int mouseX, int mouseY, GuiBase gui) { 53 | category.drawExtras(book, x, y, width, height, mouseX, mouseY, gui, drawOnLeft, renderItem); 54 | } 55 | 56 | @Override 57 | public boolean isMouseOnWrapper(int mouseX, int mouseY) { 58 | return GuiHelper.isMouseBetween(mouseX, mouseY, x, y, width, height); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/wrapper/EntryWrapper.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.wrapper; 2 | 3 | import amerifrance.guideapi.api.impl.Book; 4 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 5 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 6 | import amerifrance.guideapi.api.util.GuiHelper; 7 | import amerifrance.guideapi.gui.GuiBase; 8 | import amerifrance.guideapi.gui.GuiCategory; 9 | import net.minecraft.client.Minecraft; 10 | import net.minecraft.client.gui.FontRenderer; 11 | import net.minecraft.entity.player.EntityPlayer; 12 | import net.minecraft.item.ItemStack; 13 | 14 | public class EntryWrapper extends AbstractWrapper { 15 | 16 | public Book book; 17 | public CategoryAbstract category; 18 | public EntryAbstract entry; 19 | public int x, y, width, height; 20 | public EntityPlayer player; 21 | public FontRenderer renderer; 22 | public GuiCategory categoryGui; 23 | public ItemStack bookStack; 24 | 25 | public EntryWrapper(GuiCategory categoryGui, Book book, CategoryAbstract category, EntryAbstract entry, int x, int y, int width, int height, EntityPlayer player, FontRenderer renderer, ItemStack bookStack) { 26 | this.book = book; 27 | this.category = category; 28 | this.entry = entry; 29 | this.x = x; 30 | this.y = y; 31 | this.width = width; 32 | this.height = height; 33 | this.player = player; 34 | this.renderer = renderer; 35 | this.categoryGui = categoryGui; 36 | this.bookStack = bookStack; 37 | } 38 | 39 | @Override 40 | public void onHoverOver(int mouseX, int mouseY) { 41 | } 42 | 43 | @Override 44 | public boolean canPlayerSee() { 45 | return entry.canSee(player, bookStack); 46 | } 47 | 48 | @Override 49 | public void draw(int mouseX, int mouseY, GuiBase gui) { 50 | entry.draw(book, category, x, y, width, height, mouseX, mouseY, gui, Minecraft.getMinecraft().fontRenderer); 51 | } 52 | 53 | @Override 54 | public void drawExtras(int mouseX, int mouseY, GuiBase gui) { 55 | entry.drawExtras(book, category, x, y, width, height, mouseX, mouseY, gui, Minecraft.getMinecraft().fontRenderer); 56 | } 57 | 58 | @Override 59 | public boolean isMouseOnWrapper(int mouseX, int mouseY) { 60 | return GuiHelper.isMouseBetween(mouseX, mouseY, x, y, width, height); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/amerifrance/guideapi/wrapper/PageWrapper.java: -------------------------------------------------------------------------------- 1 | package amerifrance.guideapi.wrapper; 2 | 3 | import amerifrance.guideapi.api.IPage; 4 | import amerifrance.guideapi.api.impl.Book; 5 | import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract; 6 | import amerifrance.guideapi.api.impl.abstraction.EntryAbstract; 7 | import amerifrance.guideapi.gui.GuiBase; 8 | import amerifrance.guideapi.gui.GuiEntry; 9 | import net.minecraft.client.Minecraft; 10 | import net.minecraft.client.gui.FontRenderer; 11 | import net.minecraft.entity.player.EntityPlayer; 12 | import net.minecraft.item.ItemStack; 13 | 14 | public class PageWrapper extends AbstractWrapper { 15 | 16 | public GuiEntry guiEntry; 17 | public Book book; 18 | public CategoryAbstract category; 19 | public EntryAbstract entry; 20 | public IPage page; 21 | public int guiLeft, guiTop; 22 | public EntityPlayer player; 23 | public FontRenderer renderer; 24 | public ItemStack bookStack; 25 | 26 | public PageWrapper(GuiEntry guiEntry, Book book, CategoryAbstract category, EntryAbstract entry, IPage page, int guiLeft, int guiTop, EntityPlayer player, FontRenderer renderer, ItemStack bookStack) { 27 | this.guiEntry = guiEntry; 28 | this.book = book; 29 | this.category = category; 30 | this.entry = entry; 31 | this.page = page; 32 | this.guiLeft = guiLeft; 33 | this.guiTop = guiTop; 34 | this.player = player; 35 | this.renderer = renderer; 36 | this.bookStack = bookStack; 37 | } 38 | 39 | @Override 40 | public void onHoverOver(int mouseX, int mouseY) { 41 | } 42 | 43 | @Override 44 | public boolean canPlayerSee() { 45 | return page.canSee(book, category, entry, player, bookStack, guiEntry); 46 | } 47 | 48 | @Override 49 | public void draw(int mouseX, int mouseY, GuiBase gui) { 50 | page.draw(book, category, entry, guiLeft, guiTop, mouseX, mouseY, gui, Minecraft.getMinecraft().fontRenderer); 51 | } 52 | 53 | @Override 54 | public void drawExtras(int mouseX, int mouseY, GuiBase gui) { 55 | page.drawExtras(book, category, entry, guiLeft, guiTop, mouseX, mouseY, gui, Minecraft.getMinecraft().fontRenderer); 56 | } 57 | 58 | @Override 59 | public boolean isMouseOnWrapper(int mouseX, int mouseY) { 60 | return true; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/resources/assets/guideapi/lang/en_US.lang: -------------------------------------------------------------------------------- 1 | #Creative Tab 2 | itemGroup.guideapi.creativeTab=Guide-API 3 | 4 | #Item 5 | item.guideapi.book.name=Guide Book 6 | 7 | #Button hovering text 8 | button.back.name=Back 9 | button.next.name=Next 10 | button.prev.name=Previous 11 | button.search.name=Search 12 | 13 | #Text to draw 14 | text.shaped.crafting=Shaped Crafting 15 | text.shapeless.crafting=Shapeless Crafting 16 | text.furnace.smelting=Smelting 17 | text.furnace.error=&cError in the recipe 18 | text.book.warning=&c[WARNING] Delete this item, it has no associated book! 19 | text.book.creative=Creative Book 20 | text.book=Book: %s 21 | text.category=Category: %s 22 | text.entry=Entry: %s 23 | text.page=Page: %s 24 | text.brewing.brew=Brewing 25 | text.brewing.error=&cError in the recipe 26 | text.linked.open=Sneak + Use to open 27 | text.open.failed=Something stopped you from opening this book 28 | 29 | #Test 30 | test.guide.format=This i\ns a formatting\n\ttest 31 | test.category.name=Test Category 32 | test.entry.name=Test Entry -------------------------------------------------------------------------------- /src/main/resources/assets/guideapi/lang/ru_RU.lang: -------------------------------------------------------------------------------- 1 | #Creative Tab 2 | itemGroup.guideapi.creativeTab=Guide-API 3 | 4 | #Item 5 | item.GuideBook.name=Стандартная книга Guide-API 6 | 7 | #Button hovering text 8 | button.back.name=Назад 9 | button.next.name=След. 10 | button.prev.name=Пред. 11 | 12 | #Text to draw 13 | text.shaped.crafting=Форменное создание 14 | text.shapeless.crafting=Бесформенное создание 15 | text.furnace.smelting=Плавка 16 | text.furnace.error=&cОшибка в рецепте 17 | text.book.warning=&c[ВНИМАНИЕ] Выкиньте этот предмет, у него нет связанной книги! 18 | text.book.creative=Творческая книга 19 | text.book=Книга: %s 20 | text.category=Категория: %s 21 | text.entry=Запись: %s 22 | text.page=Страница: %s 23 | -------------------------------------------------------------------------------- /src/main/resources/assets/guideapi/lang/zh_CN.lang: -------------------------------------------------------------------------------- 1 | #Creative Tab 2 | itemGroup.guideapi.creativeTab=Guide-API 3 | 4 | #Item 5 | item.guideapi.book.name=Guide-API 默认书 6 | 7 | #Button hovering text 8 | button.back.name=返回 9 | button.next.name=下一页 10 | button.prev.name=上一页 11 | 12 | #Text to draw 13 | text.shaped.crafting=普通配方 14 | text.shapeless.crafting=无形配方 15 | text.furnace.smelting=冶炼 16 | text.furnace.error=&c合成配方出错 17 | text.book.warning=&c[警告] 删除这个物品, 它没有关联的书! 18 | text.book.creative=创造模式书本 19 | text.book=书: %s 20 | text.category=类别: %s 21 | text.entry=条目: %s 22 | text.page=页码: %s 23 | -------------------------------------------------------------------------------- /src/main/resources/assets/guideapi/models/item/itemguidebook.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent":"item/generated", 3 | "textures": { 4 | "layer0": "guideapi:items/book_base", 5 | "layer1": "guideapi:items/book_page" 6 | }, 7 | "display": { 8 | "firstperson_lefthand": { 9 | "rotation": [ 0, 90, -25 ], 10 | "translation": [ 1.13, 3.2, 1.13 ], 11 | "scale": [ 0.68, 0.68, 0.68 ] 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/assets/guideapi/textures/gui/book_colored.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeamAmeriFrance/Guide-API/2c4fa1b077a99ee1068de51d5919b9b19b5e0956/src/main/resources/assets/guideapi/textures/gui/book_colored.png -------------------------------------------------------------------------------- /src/main/resources/assets/guideapi/textures/gui/book_greyscale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeamAmeriFrance/Guide-API/2c4fa1b077a99ee1068de51d5919b9b19b5e0956/src/main/resources/assets/guideapi/textures/gui/book_greyscale.png -------------------------------------------------------------------------------- /src/main/resources/assets/guideapi/textures/gui/category_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeamAmeriFrance/Guide-API/2c4fa1b077a99ee1068de51d5919b9b19b5e0956/src/main/resources/assets/guideapi/textures/gui/category_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/guideapi/textures/gui/category_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeamAmeriFrance/Guide-API/2c4fa1b077a99ee1068de51d5919b9b19b5e0956/src/main/resources/assets/guideapi/textures/gui/category_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/guideapi/textures/gui/recipe_elements.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeamAmeriFrance/Guide-API/2c4fa1b077a99ee1068de51d5919b9b19b5e0956/src/main/resources/assets/guideapi/textures/gui/recipe_elements.png -------------------------------------------------------------------------------- /src/main/resources/assets/guideapi/textures/gui/testimage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeamAmeriFrance/Guide-API/2c4fa1b077a99ee1068de51d5919b9b19b5e0956/src/main/resources/assets/guideapi/textures/gui/testimage.png -------------------------------------------------------------------------------- /src/main/resources/assets/guideapi/textures/items/book_base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeamAmeriFrance/Guide-API/2c4fa1b077a99ee1068de51d5919b9b19b5e0956/src/main/resources/assets/guideapi/textures/items/book_base.png -------------------------------------------------------------------------------- /src/main/resources/assets/guideapi/textures/items/book_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeamAmeriFrance/Guide-API/2c4fa1b077a99ee1068de51d5919b9b19b5e0956/src/main/resources/assets/guideapi/textures/items/book_page.png -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "modid": "guideapi", 4 | "name": "Guide-API", 5 | "description": "Simple mod guide creation.", 6 | "version": "${version}", 7 | "mcversion": "${mcversion}", 8 | "url": "", 9 | "updateUrl": "http://tehnut.info/jenkins/", 10 | "authorList": [ "Tombenpotter", "TehNut" ], 11 | "credits": "", 12 | "logoFile": "", 13 | "screenshots": [], 14 | "dependencies": [] 15 | } 16 | ] 17 | --------------------------------------------------------------------------------