├── LICENSE ├── README.md ├── build.gradle ├── gradle └── wrapper │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src └── main ├── java └── com │ └── llamalad7 │ └── betterchat │ ├── BetterChat.java │ ├── ChatSettings.java │ ├── command │ └── CommandConfig.java │ ├── gui │ ├── GuiBetterChat.java │ └── GuiConfig.java │ ├── handlers │ └── InjectHandler.java │ └── utils │ └── AnimationTools.java └── resources ├── assets └── betterchat │ └── lang │ ├── de_DE.lang │ ├── en_US.lang │ ├── es_ES.lang │ ├── fr_FR.lang │ ├── it_IT.lang │ ├── ko_KR.lang │ └── zh_CN.lang └── mcmod.info /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Better Chat 2 | 3 | Forge mod by [LlamaLad7](https://github.com/LlamaLad7) which lets you customize the chat. 4 | 5 | Options: 6 | 7 | * Animated Chat (Messages slide up when received) 8 | 9 | * Clear Chat Background 10 | 11 | * Move the chat to where you want it 12 | 13 | * Change its Scale 14 | 15 | Downloads are on my [CurseForge](https://www.curseforge.com/minecraft/mc-mods/better-chat). 16 | 17 | Friend me on Discord (LlamaLad7#7444) for support / feature suggestions. 18 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | jcenter() 4 | maven { url = "https://files.minecraftforge.net/maven" } 5 | } 6 | dependencies { 7 | classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT' 8 | } 9 | } 10 | apply plugin: 'net.minecraftforge.gradle.forge' 11 | //Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. 12 | 13 | 14 | version = "1.5" 15 | group = "com.llamalad7.betterchat" // http://maven.apache.org/guides/mini/guide-naming-conventions.html 16 | archivesBaseName = "betterchat" 17 | 18 | sourceCompatibility = targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. 19 | compileJava { 20 | sourceCompatibility = targetCompatibility = '1.8' 21 | } 22 | 23 | minecraft { 24 | version = "1.12.2-14.23.5.2847" 25 | runDir = "run" 26 | 27 | // the mappings can be changed at any time, and must be in the following format. 28 | // snapshot_YYYYMMDD snapshot are built nightly. 29 | // stable_# stables are built at the discretion of the MCP team. 30 | // Use non-default mappings at your own risk. they may not always work. 31 | // simply re-run your setup task after changing the mappings to update your workspace. 32 | mappings = 'stable_39' 33 | // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. 34 | } 35 | 36 | dependencies { 37 | // you may put jars on which you depend on in ./libs 38 | // or you may define them like so.. 39 | //compile "some.group:artifact:version:classifier" 40 | //compile "some.group:artifact:version" 41 | 42 | // real examples 43 | //compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env 44 | //compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env 45 | 46 | // the 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime. 47 | //provided 'com.mod-buildcraft:buildcraft:6.0.8:dev' 48 | 49 | // the deobf configurations: 'deobfCompile' and 'deobfProvided' are the same as the normal compile and provided, 50 | // except that these dependencies get remapped to your current MCP mappings 51 | //deobfCompile 'com.mod-buildcraft:buildcraft:6.0.8:dev' 52 | //deobfProvided 'com.mod-buildcraft:buildcraft:6.0.8:dev' 53 | 54 | // for more info... 55 | // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html 56 | // http://www.gradle.org/docs/current/userguide/dependency_management.html 57 | 58 | } 59 | 60 | processResources { 61 | // this will ensure that this task is redone when the versions change. 62 | inputs.property "version", project.version 63 | inputs.property "mcversion", project.minecraft.version 64 | 65 | // replace stuff in mcmod.info, nothing else 66 | from(sourceSets.main.resources.srcDirs) { 67 | include 'mcmod.info' 68 | 69 | // replace version and mcversion 70 | expand 'version':project.version, 'mcversion':project.minecraft.version 71 | } 72 | 73 | // copy everything else except the mcmod.info 74 | from(sourceSets.main.resources.srcDirs) { 75 | exclude 'mcmod.info' 76 | } 77 | } 78 | task moveResources { 79 | doLast { 80 | ant.move file: "${buildDir}/resources/main", 81 | todir: "${buildDir}/classes/java" 82 | } 83 | } 84 | 85 | moveResources.dependsOn processResources 86 | classes.dependsOn moveResources 87 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Feb 22 13:24:50 GMT 2020 2 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-all.zip 3 | distributionBase=GRADLE_USER_HOME 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 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 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /src/main/java/com/llamalad7/betterchat/BetterChat.java: -------------------------------------------------------------------------------- 1 | package com.llamalad7.betterchat; 2 | 3 | import com.llamalad7.betterchat.command.CommandConfig; 4 | import com.llamalad7.betterchat.handlers.InjectHandler; 5 | import net.minecraftforge.client.ClientCommandHandler; 6 | import net.minecraftforge.common.MinecraftForge; 7 | import net.minecraftforge.common.config.Configuration; 8 | import net.minecraftforge.fml.common.Mod; 9 | import net.minecraftforge.fml.common.Mod.EventHandler; 10 | import net.minecraftforge.fml.common.event.FMLInitializationEvent; 11 | import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; 12 | import net.minecraftforge.fml.relauncher.Side; 13 | import net.minecraftforge.fml.relauncher.SideOnly; 14 | 15 | @Mod(modid = BetterChat.MODID, name = BetterChat.NAME, version = BetterChat.VERSION) 16 | @SideOnly(Side.CLIENT) 17 | public class BetterChat 18 | { 19 | public static final String MODID = "betterchat"; 20 | public static final String NAME = "Better Chat"; 21 | public static final String VERSION = "1.5"; 22 | private static ChatSettings settings; 23 | 24 | @EventHandler 25 | public void preInit(FMLPreInitializationEvent event) { 26 | settings = new ChatSettings(new Configuration(event.getSuggestedConfigurationFile())); 27 | settings.loadConfig(); 28 | } 29 | 30 | @EventHandler 31 | public void init(FMLInitializationEvent event) 32 | { 33 | MinecraftForge.EVENT_BUS.register(new InjectHandler()); 34 | ClientCommandHandler.instance.registerCommand(new CommandConfig()); 35 | } 36 | public static ChatSettings getSettings() { 37 | return settings; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/llamalad7/betterchat/ChatSettings.java: -------------------------------------------------------------------------------- 1 | package com.llamalad7.betterchat; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraftforge.common.config.Configuration; 5 | import net.minecraftforge.common.config.Property; 6 | 7 | 8 | public class ChatSettings { 9 | private Configuration config; 10 | public boolean smooth; 11 | public boolean clear; 12 | public int xOffset; 13 | public int yOffset; 14 | 15 | public ChatSettings(Configuration config) { 16 | this.config = config; 17 | } 18 | 19 | public void saveConfig() { 20 | updateConfig(false); 21 | config.save(); 22 | } 23 | 24 | public void loadConfig() { 25 | config.load(); 26 | updateConfig(true); 27 | } 28 | 29 | public void resetConfig() { 30 | Property prop; 31 | 32 | prop = config.get("All", "Clear", false); 33 | prop.set(clear = false); 34 | 35 | prop = config.get("All", "Smooth", true); 36 | prop.set(smooth = true); 37 | 38 | prop = config.get("All", "xOffset", 0); 39 | prop.set(xOffset = 0); 40 | 41 | prop = config.get("All", "yOffset", 0); 42 | prop.set(yOffset = 0); 43 | Minecraft.getMinecraft().gameSettings.chatScale = 1.0f; 44 | Minecraft.getMinecraft().gameSettings.chatWidth = 1.0f; 45 | config.save(); 46 | } 47 | 48 | private void updateConfig(boolean load) { 49 | Property prop; 50 | 51 | prop = config.get("All", "Clear", false); 52 | if (load) clear = prop.getBoolean(); 53 | else prop.set(clear); 54 | 55 | prop = config.get("All", "Smooth", true); 56 | if (load) smooth = prop.getBoolean(); 57 | else prop.set(smooth); 58 | 59 | prop = config.get("All", "xOffset", 0); 60 | if (load) xOffset = prop.getInt(); 61 | else prop.set(xOffset); 62 | 63 | prop = config.get("All", "yOffset", 0); 64 | if (load) yOffset = prop.getInt(); 65 | else prop.set(yOffset); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/llamalad7/betterchat/command/CommandConfig.java: -------------------------------------------------------------------------------- 1 | package com.llamalad7.betterchat.command; 2 | 3 | import com.llamalad7.betterchat.gui.GuiConfig; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.command.CommandBase; 6 | import net.minecraft.command.CommandException; 7 | import net.minecraft.command.ICommandSender; 8 | import net.minecraft.server.MinecraftServer; 9 | import net.minecraftforge.common.MinecraftForge; 10 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 11 | import net.minecraftforge.fml.common.gameevent.TickEvent; 12 | 13 | public class CommandConfig extends CommandBase { 14 | 15 | @Override 16 | public String getName() { 17 | return "betterchat"; 18 | } 19 | 20 | @Override 21 | public String getUsage(ICommandSender sender) { 22 | return "/betterchat"; 23 | } 24 | 25 | @Override 26 | public boolean checkPermission(MinecraftServer server, ICommandSender sender) { 27 | return true; 28 | } 29 | 30 | @Override 31 | public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { 32 | MinecraftForge.EVENT_BUS.register(this); 33 | } 34 | 35 | @SubscribeEvent 36 | public void onClientTick(TickEvent.ClientTickEvent event) { 37 | MinecraftForge.EVENT_BUS.unregister(this); 38 | Minecraft.getMinecraft().displayGuiScreen(new GuiConfig()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/llamalad7/betterchat/gui/GuiBetterChat.java: -------------------------------------------------------------------------------- 1 | package com.llamalad7.betterchat.gui; 2 | 3 | import com.google.common.collect.Lists; 4 | import com.llamalad7.betterchat.BetterChat; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.client.gui.*; 7 | import net.minecraft.client.renderer.GlStateManager; 8 | import net.minecraft.entity.player.EntityPlayer; 9 | import net.minecraft.util.math.MathHelper; 10 | import net.minecraft.util.text.ITextComponent; 11 | import net.minecraft.util.text.TextComponentString; 12 | import net.minecraftforge.fml.relauncher.Side; 13 | import net.minecraftforge.fml.relauncher.SideOnly; 14 | import org.apache.logging.log4j.LogManager; 15 | import org.apache.logging.log4j.Logger; 16 | 17 | import javax.annotation.Nullable; 18 | import java.util.Iterator; 19 | import java.util.List; 20 | 21 | import static com.llamalad7.betterchat.utils.AnimationTools.clamp; 22 | 23 | @SideOnly(Side.CLIENT) 24 | public class GuiBetterChat extends GuiNewChat { 25 | private static final Logger LOGGER = LogManager.getLogger(); 26 | private final Minecraft mc; 27 | /** 28 | * A list of messages previously sent through the chat GUI 29 | */ 30 | private final List sentMessages = Lists.newArrayList(); 31 | /** 32 | * Chat lines to be displayed in the chat box 33 | */ 34 | private final List chatLines = Lists.newArrayList(); 35 | /** 36 | * List of the ChatLines currently drawn 37 | */ 38 | private final List drawnChatLines = Lists.newArrayList(); 39 | private int scrollPos; 40 | private boolean isScrolled; 41 | public static float percentComplete = 0.0F; 42 | public static int newLines; 43 | public static long prevMillis = -1; 44 | public boolean configuring; 45 | 46 | public GuiBetterChat(Minecraft mcIn) { 47 | super(mcIn); 48 | this.mc = mcIn; 49 | } 50 | 51 | public static void updatePercentage(long diff) { 52 | if (percentComplete < 1) percentComplete += 0.004f * diff; 53 | percentComplete = clamp(percentComplete, 0, 1); 54 | } 55 | 56 | public void drawChat(int updateCounter) { 57 | if (configuring) return; 58 | if (prevMillis == -1) { 59 | prevMillis = System.currentTimeMillis(); 60 | return; 61 | } 62 | long current = System.currentTimeMillis(); 63 | long diff = current - prevMillis; 64 | prevMillis = current; 65 | updatePercentage(diff); 66 | float t = percentComplete; 67 | float percent = 1 - (--t) * t * t * t; 68 | percent = clamp(percent, 0, 1); 69 | if (this.mc.gameSettings.chatVisibility != EntityPlayer.EnumChatVisibility.HIDDEN) { 70 | int i = this.getLineCount(); 71 | int j = this.drawnChatLines.size(); 72 | float f = this.mc.gameSettings.chatOpacity * 0.9F + 0.1F; 73 | 74 | if (j > 0) { 75 | boolean flag = false; 76 | 77 | if (this.getChatOpen()) { 78 | flag = true; 79 | } 80 | 81 | float f1 = this.getChatScale(); 82 | int k = MathHelper.ceil((float) this.getChatWidth() / f1); 83 | GlStateManager.pushMatrix(); 84 | if (BetterChat.getSettings().smooth && !this.isScrolled) GlStateManager.translate(2.0F + BetterChat.getSettings().xOffset, 8.0F + BetterChat.getSettings().yOffset + (9 - 9*percent)*f1, 0.0F); 85 | else GlStateManager.translate(2.0F + BetterChat.getSettings().xOffset, 8.0F + BetterChat.getSettings().yOffset, 0.0F); 86 | GlStateManager.scale(f1, f1, 1.0F); 87 | int l = 0; 88 | 89 | for (int i1 = 0; i1 + this.scrollPos < this.drawnChatLines.size() && i1 < i; ++i1) { 90 | ChatLine chatline = this.drawnChatLines.get(i1 + this.scrollPos); 91 | 92 | if (chatline != null) { 93 | int j1 = updateCounter - chatline.getUpdatedCounter(); 94 | 95 | if (j1 < 200 || flag) { 96 | double d0 = (double) j1 / 200.0D; 97 | d0 = 1.0D - d0; 98 | d0 = d0 * 10.0D; 99 | d0 = MathHelper.clamp(d0, 0.0D, 1.0D); 100 | d0 = d0 * d0; 101 | int l1 = (int) (255.0D * d0); 102 | 103 | if (flag) { 104 | l1 = 255; 105 | } 106 | 107 | l1 = (int) ((float) l1 * f); 108 | ++l; 109 | 110 | if (l1 > 3) { 111 | int i2 = 0; 112 | int j2 = -i1 * 9; 113 | if (!BetterChat.getSettings().clear) { 114 | drawRect(-2, j2 - 9, i2 + k + 4, j2, l1 / 2 << 24); 115 | } 116 | String s = chatline.getChatComponent().getFormattedText(); 117 | GlStateManager.enableBlend(); 118 | if (BetterChat.getSettings().smooth && i1 <= newLines) { 119 | this.mc.fontRenderer.drawStringWithShadow(s, 0.0F, (j2 - 8), 16777215 + ((int) (l1 * percent) << 24)); 120 | } else { 121 | this.mc.fontRenderer.drawStringWithShadow(s, (float) i2, (float) (j2 - 8), 16777215 + (l1 << 24)); 122 | } 123 | GlStateManager.disableAlpha(); 124 | GlStateManager.disableBlend(); 125 | } 126 | } 127 | } 128 | } 129 | 130 | if (flag) { 131 | int k2 = this.mc.fontRenderer.FONT_HEIGHT; 132 | GlStateManager.translate(-3.0F, 0.0F, 0.0F); 133 | int l2 = j * k2 + j; 134 | int i3 = l * k2 + l; 135 | int j3 = this.scrollPos * i3 / j; 136 | int k1 = i3 * i3 / l2; 137 | 138 | if (l2 != i3) { 139 | int k3 = j3 > 0 ? 170 : 96; 140 | int l3 = this.isScrolled ? 13382451 : 3355562; 141 | drawRect(0, -j3, 2, -j3 - k1, l3 + (k3 << 24)); 142 | drawRect(2, -j3, 1, -j3 - k1, 13421772 + (k3 << 24)); 143 | } 144 | } 145 | 146 | GlStateManager.popMatrix(); 147 | } 148 | } 149 | } 150 | 151 | /** 152 | * Clears the chat. 153 | */ 154 | public void clearChatMessages(boolean p_146231_1_) { 155 | this.drawnChatLines.clear(); 156 | this.chatLines.clear(); 157 | 158 | if (p_146231_1_) { 159 | this.sentMessages.clear(); 160 | } 161 | } 162 | 163 | public void printChatMessage(ITextComponent chatComponent) { 164 | this.printChatMessageWithOptionalDeletion(chatComponent, 0); 165 | } 166 | 167 | /** 168 | * prints the ChatComponent to Chat. If the ID is not 0, deletes an existing Chat Line of that ID from the GUI 169 | */ 170 | public void printChatMessageWithOptionalDeletion(ITextComponent chatComponent, int chatLineId) { 171 | percentComplete = 0.0F; 172 | this.setChatLine(chatComponent, chatLineId, this.mc.ingameGUI.getUpdateCounter(), false); 173 | LOGGER.info("[CHAT] {}", (Object) chatComponent.getUnformattedText().replaceAll("\r", "\\\\r").replaceAll("\n", "\\\\n")); 174 | } 175 | 176 | private void setChatLine(ITextComponent chatComponent, int chatLineId, int updateCounter, boolean displayOnly) { 177 | if (chatLineId != 0) { 178 | this.deleteChatLine(chatLineId); 179 | } 180 | 181 | int i = MathHelper.floor((float) this.getChatWidth() / this.getChatScale()); 182 | List list = GuiUtilRenderComponents.splitText(chatComponent, i, this.mc.fontRenderer, false, false); 183 | boolean flag = this.getChatOpen(); 184 | newLines = list.size() - 1; 185 | 186 | for (ITextComponent itextcomponent : list) { 187 | if (flag && this.scrollPos > 0) { 188 | this.isScrolled = true; 189 | this.scroll(1); 190 | } 191 | 192 | this.drawnChatLines.add(0, new ChatLine(updateCounter, itextcomponent, chatLineId)); 193 | } 194 | 195 | while (this.drawnChatLines.size() > 100) { 196 | this.drawnChatLines.remove(this.drawnChatLines.size() - 1); 197 | } 198 | 199 | if (!displayOnly) { 200 | this.chatLines.add(0, new ChatLine(updateCounter, chatComponent, chatLineId)); 201 | 202 | while (this.chatLines.size() > 100) { 203 | this.chatLines.remove(this.chatLines.size() - 1); 204 | } 205 | } 206 | } 207 | 208 | public void refreshChat() { 209 | this.drawnChatLines.clear(); 210 | this.resetScroll(); 211 | 212 | for (int i = this.chatLines.size() - 1; i >= 0; --i) { 213 | ChatLine chatline = this.chatLines.get(i); 214 | this.setChatLine(chatline.getChatComponent(), chatline.getChatLineID(), chatline.getUpdatedCounter(), true); 215 | } 216 | } 217 | 218 | /** 219 | * Gets the list of messages previously sent through the chat GUI 220 | */ 221 | public List getSentMessages() { 222 | return this.sentMessages; 223 | } 224 | 225 | /** 226 | * Adds this string to the list of sent messages, for recall using the up/down arrow keys 227 | */ 228 | public void addToSentMessages(String message) { 229 | if (this.sentMessages.isEmpty() || !((String) this.sentMessages.get(this.sentMessages.size() - 1)).equals(message)) { 230 | this.sentMessages.add(message); 231 | } 232 | } 233 | 234 | /** 235 | * Resets the chat scroll (executed when the GUI is closed, among others) 236 | */ 237 | public void resetScroll() { 238 | this.scrollPos = 0; 239 | this.isScrolled = false; 240 | } 241 | 242 | /** 243 | * Scrolls the chat by the given number of lines. 244 | */ 245 | public void scroll(int amount) { 246 | this.scrollPos += amount; 247 | int i = this.drawnChatLines.size(); 248 | 249 | if (this.scrollPos > i - this.getLineCount()) { 250 | this.scrollPos = i - this.getLineCount(); 251 | } 252 | 253 | if (this.scrollPos <= 0) { 254 | this.scrollPos = 0; 255 | this.isScrolled = false; 256 | } 257 | } 258 | 259 | /** 260 | * Gets the chat component under the mouse 261 | */ 262 | @Nullable 263 | public ITextComponent getChatComponent(int mouseX, int mouseY) { 264 | if (!this.getChatOpen()) { 265 | return null; 266 | } else { 267 | ScaledResolution scaledresolution = new ScaledResolution(this.mc); 268 | int i = scaledresolution.getScaleFactor(); 269 | float f = this.getChatScale(); 270 | int j = mouseX / i - 2 - BetterChat.getSettings().xOffset; 271 | int k = mouseY / i - 40 + BetterChat.getSettings().yOffset; 272 | j = MathHelper.floor((float) j / f); 273 | k = MathHelper.floor((float) k / f); 274 | 275 | if (j >= 0 && k >= 0) { 276 | int l = Math.min(this.getLineCount(), this.drawnChatLines.size()); 277 | 278 | if (j <= MathHelper.floor((float) this.getChatWidth() / this.getChatScale()) && k < this.mc.fontRenderer.FONT_HEIGHT * l + l) { 279 | int i1 = k / this.mc.fontRenderer.FONT_HEIGHT + this.scrollPos; 280 | 281 | if (i1 >= 0 && i1 < this.drawnChatLines.size()) { 282 | ChatLine chatline = this.drawnChatLines.get(i1); 283 | int j1 = 0; 284 | 285 | for (ITextComponent itextcomponent : chatline.getChatComponent()) { 286 | if (itextcomponent instanceof TextComponentString) { 287 | j1 += this.mc.fontRenderer.getStringWidth(GuiUtilRenderComponents.removeTextColorsIfConfigured(((TextComponentString) itextcomponent).getText(), false)); 288 | 289 | if (j1 > j) { 290 | return itextcomponent; 291 | } 292 | } 293 | } 294 | } 295 | 296 | return null; 297 | } else { 298 | return null; 299 | } 300 | } else { 301 | return null; 302 | } 303 | } 304 | } 305 | 306 | /** 307 | * Returns true if the chat GUI is open 308 | */ 309 | public boolean getChatOpen() { 310 | return this.mc.currentScreen instanceof GuiChat; 311 | } 312 | 313 | /** 314 | * finds and deletes a Chat line by ID 315 | */ 316 | public void deleteChatLine(int id) { 317 | Iterator iterator = this.drawnChatLines.iterator(); 318 | 319 | while (iterator.hasNext()) { 320 | ChatLine chatline = iterator.next(); 321 | 322 | if (chatline.getChatLineID() == id) { 323 | iterator.remove(); 324 | } 325 | } 326 | 327 | iterator = this.chatLines.iterator(); 328 | 329 | while (iterator.hasNext()) { 330 | ChatLine chatline1 = iterator.next(); 331 | 332 | if (chatline1.getChatLineID() == id) { 333 | iterator.remove(); 334 | break; 335 | } 336 | } 337 | } 338 | 339 | public int getChatWidth() { 340 | return calculateChatboxWidth(this.mc.gameSettings.chatWidth); 341 | } 342 | 343 | public int getChatHeight() { 344 | return calculateChatboxHeight(this.getChatOpen() ? this.mc.gameSettings.chatHeightFocused : this.mc.gameSettings.chatHeightUnfocused); 345 | } 346 | 347 | /** 348 | * Returns the chatscale from mc.gameSettings.chatScale 349 | */ 350 | public float getChatScale() { 351 | return this.mc.gameSettings.chatScale; 352 | } 353 | 354 | public static int calculateChatboxWidth(float scale) { 355 | int i = 320; 356 | int j = 40; 357 | return MathHelper.floor(scale * 280.0F + 40.0F); 358 | } 359 | 360 | public static int calculateChatboxHeight(float scale) { 361 | int i = 180; 362 | int j = 20; 363 | return MathHelper.floor(scale * 160.0F + 20.0F); 364 | } 365 | 366 | public int getLineCount() { 367 | return this.getChatHeight() / 9; 368 | } 369 | } 370 | -------------------------------------------------------------------------------- /src/main/java/com/llamalad7/betterchat/gui/GuiConfig.java: -------------------------------------------------------------------------------- 1 | package com.llamalad7.betterchat.gui; 2 | 3 | import com.llamalad7.betterchat.BetterChat; 4 | import com.llamalad7.betterchat.ChatSettings; 5 | import com.llamalad7.betterchat.handlers.InjectHandler; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.gui.*; 8 | import net.minecraft.client.renderer.GlStateManager; 9 | import net.minecraft.client.resources.I18n; 10 | import net.minecraft.util.math.MathHelper; 11 | import net.minecraft.util.text.ITextComponent; 12 | import net.minecraft.util.text.TextComponentString; 13 | import net.minecraft.util.text.TextFormatting; 14 | import net.minecraft.world.World; 15 | import net.minecraftforge.fml.client.config.GuiSlider; 16 | 17 | import java.awt.*; 18 | import java.io.IOException; 19 | import java.util.ArrayList; 20 | import java.util.Collections; 21 | import java.util.List; 22 | 23 | import static net.minecraft.client.gui.GuiNewChat.calculateChatboxWidth; 24 | 25 | public class GuiConfig extends GuiScreen { 26 | private ChatSettings settings; 27 | private List exampleChat = new ArrayList<>(); 28 | private boolean dragging = false; 29 | private int chatLeft, chatRight, chatTop, chatBottom, dragStartX, dragStartY; 30 | private GuiButton clearButton, smoothButton; 31 | private GuiSlider scaleSlider, widthSlider; 32 | 33 | 34 | 35 | public GuiConfig() { 36 | this.settings = BetterChat.getSettings(); 37 | exampleChat.add(new TextComponentString(I18n.format("gui.betterchat.text.example3"))); 38 | exampleChat.add(new TextComponentString(I18n.format("gui.betterchat.text.example2"))); 39 | exampleChat.add(new TextComponentString(I18n.format("gui.betterchat.text.example1"))); 40 | } 41 | 42 | @Override 43 | public void initGui() { 44 | InjectHandler.chatGUI.configuring = true; 45 | buttonList.add(clearButton = new GuiButton(0, width / 2 - 120, height / 2 - 50, 240, 20, getPropName("clear") + " " + getColoredBool("clear", settings.clear))); 46 | buttonList.add(smoothButton = new GuiButton(1, width / 2 - 120, height / 2 - 25, 240, 20, getPropName("smooth") + " " + getColoredBool("smooth", settings.smooth))); 47 | buttonList.add(scaleSlider = new GuiSlider(3, width / 2 - 120, height / 2, 240, 20, getPropName("scale") + " ", "%", 0, 100, this.mc.gameSettings.chatScale*100, false, true)); 48 | buttonList.add(widthSlider = new GuiSlider(4, width / 2 - 120, height / 2 + 25, 240, 20, getPropName("width") + " ", "px", 40, 320, calculateChatboxWidth(this.mc.gameSettings.chatWidth), false, true)); 49 | buttonList.add(new GuiButton(2, width / 2 - 120, height / 2 + 50, 240, 20, getPropName("reset"))); 50 | } 51 | 52 | @Override 53 | public void drawScreen(int mouseX, int mouseY, float partialTicks) { 54 | //drawDefaultBackground(); 55 | super.drawScreen(mouseX, mouseY, partialTicks); 56 | drawCenteredString(mc.fontRenderer, I18n.format("gui.betterchat.text.title", TextFormatting.GREEN + TextFormatting.BOLD.toString() + "Better Chat" + TextFormatting.RESET, TextFormatting.AQUA + TextFormatting.BOLD.toString() + "LlamaLad7"), width / 2, height / 2 - 75, 0xFFFFFF); 57 | drawCenteredString(mc.fontRenderer, I18n.format("gui.betterchat.text.drag"), width / 2, height / 2 - 63, 0xFFFFFF); 58 | if (dragging) { 59 | settings.xOffset += mouseX - dragStartX; 60 | settings.yOffset += mouseY - dragStartY; 61 | dragStartX = mouseX; 62 | dragStartY = mouseY; 63 | } 64 | this.mc.gameSettings.chatScale = (float) scaleSlider.getValueInt()/100; 65 | this.mc.gameSettings.chatWidth = ((float) widthSlider.getValueInt()-40)/280; 66 | drawExampleChat(); 67 | } 68 | 69 | public void drawExampleChat() { 70 | List lines = new ArrayList<>(); 71 | int i = MathHelper.floor((float) InjectHandler.chatGUI.getChatWidth() / InjectHandler.chatGUI.getChatScale()); 72 | for (ITextComponent line : exampleChat) { 73 | lines.addAll(GuiUtilRenderComponents.splitText(line, i, this.mc.fontRenderer, false, false)); 74 | } 75 | Collections.reverse(lines); 76 | GlStateManager.pushMatrix(); 77 | ScaledResolution scaledresolution = new ScaledResolution(this.mc); 78 | GlStateManager.translate(2.0F + settings.xOffset, 8.0F + settings.yOffset + scaledresolution.getScaledHeight() - 48, 0.0F); 79 | float f = this.mc.gameSettings.chatOpacity * 0.9F + 0.1F; 80 | float f1 = this.mc.gameSettings.chatScale; 81 | int k = MathHelper.ceil(InjectHandler.chatGUI.getChatWidth() / f1); 82 | GlStateManager.scale(f1, f1, 1.0F); 83 | int i1 = 0; 84 | double d0 = 1.0D; 85 | int l1 = (int)(255.0D * d0); 86 | l1 = (int)((float)l1 * f); 87 | GlStateManager.enableAlpha(); 88 | GlStateManager.enableBlend(); 89 | chatLeft = settings.xOffset; 90 | chatRight = (int) (settings.xOffset + (k+4)*f1); 91 | chatBottom = 8 + settings.yOffset + scaledresolution.getScaledHeight() - 48; 92 | for (ITextComponent message : lines) { 93 | int j2 = -i1 * 9; 94 | if (!settings.clear) drawRect(-2, j2 - 9, k + 4, j2, l1 / 2 << 24); 95 | this.mc.fontRenderer.drawStringWithShadow(message.getFormattedText(), 0.0F, (float)(j2 - 8), 16777215 + (l1 << 24)); 96 | ++i1; 97 | } 98 | chatTop = (int) (8 + settings.yOffset + scaledresolution.getScaledHeight() - 48 + (-i1*9)*f1); 99 | GlStateManager.disableAlpha(); 100 | GlStateManager.disableBlend(); 101 | GlStateManager.popMatrix(); 102 | } 103 | @Override 104 | public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { 105 | super.mouseClicked(mouseX, mouseY, mouseButton); 106 | if (mouseButton == 0) { 107 | if (mouseX >= chatLeft && mouseX <= chatRight && mouseY >= chatTop && mouseY <= chatBottom) { 108 | dragging = true; 109 | dragStartX = mouseX; 110 | dragStartY = mouseY; 111 | } 112 | } 113 | 114 | } 115 | @Override 116 | public void mouseReleased(int mouseX, int mouseY, int mouseButton) { 117 | super.mouseReleased(mouseX, mouseY, mouseButton); 118 | dragging = false; 119 | } 120 | 121 | @Override 122 | public void onGuiClosed() { 123 | settings.saveConfig(); 124 | InjectHandler.chatGUI.configuring = false; 125 | this.mc.gameSettings.saveOptions(); 126 | } 127 | 128 | @Override 129 | protected void actionPerformed(GuiButton button) throws IOException { 130 | switch (button.id) { 131 | case 0: 132 | settings.clear = !settings.clear; 133 | button.displayString = getPropName("clear") + " " + getColoredBool("clear", settings.clear); 134 | break; 135 | case 1: 136 | settings.smooth = !settings.smooth; 137 | button.displayString = getPropName("smooth") + " " + getColoredBool("smooth", settings.smooth); 138 | break; 139 | case 2: 140 | settings.resetConfig(); 141 | clearButton.displayString = getPropName("clear") + " " + getColoredBool("clear", settings.clear); 142 | smoothButton.displayString = getPropName("smooth") + " " + getColoredBool("smooth", settings.smooth); 143 | // this.mc.gameSettings.chatScale = 1.0f; 144 | // this.mc.gameSettings.chatWidth = 1.0f; 145 | scaleSlider.setValue(this.mc.gameSettings.chatScale*100); 146 | scaleSlider.updateSlider(); 147 | widthSlider.setValue(calculateChatboxWidth(this.mc.gameSettings.chatWidth)); 148 | widthSlider.updateSlider(); 149 | } 150 | } 151 | 152 | @Override 153 | public boolean doesGuiPauseGame() { 154 | return false; 155 | } 156 | 157 | private String getColoredBool(String prop, boolean bool) { 158 | if (bool) { 159 | return TextFormatting.GREEN + I18n.format("gui.betterchat.text." + prop + ".enabled"); 160 | } 161 | 162 | return TextFormatting.RED + I18n.format("gui.betterchat.text." + prop + ".disabled"); 163 | } 164 | private String getPropName(String prop) { 165 | return I18n.format("gui.betterchat.text." + prop + ".name"); 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/main/java/com/llamalad7/betterchat/handlers/InjectHandler.java: -------------------------------------------------------------------------------- 1 | package com.llamalad7.betterchat.handlers; 2 | 3 | import com.llamalad7.betterchat.gui.GuiBetterChat; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.gui.GuiIngame; 6 | import net.minecraftforge.common.MinecraftForge; 7 | import net.minecraftforge.fml.common.ObfuscationReflectionHelper; 8 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 9 | import net.minecraftforge.fml.common.gameevent.TickEvent; 10 | 11 | public class InjectHandler { 12 | public static GuiBetterChat chatGUI; 13 | @SubscribeEvent 14 | public void onClientTick(TickEvent.ClientTickEvent event) { 15 | MinecraftForge.EVENT_BUS.unregister(this); 16 | chatGUI = new GuiBetterChat(Minecraft.getMinecraft()); 17 | ObfuscationReflectionHelper.setPrivateValue(GuiIngame.class, Minecraft.getMinecraft().ingameGUI, chatGUI, "field_73840_e"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/llamalad7/betterchat/utils/AnimationTools.java: -------------------------------------------------------------------------------- 1 | package com.llamalad7.betterchat.utils; 2 | 3 | public class AnimationTools { 4 | public static float clamp(float number, float min, float max) { 5 | return number < min ? min : Math.min(number, max); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/assets/betterchat/lang/de_DE.lang: -------------------------------------------------------------------------------- 1 | gui.betterchat.text.title=%1$s von %2$s 2 | gui.betterchat.text.drag=Ziehen Sie den Chat, um es umzustellen 3 | gui.betterchat.text.clear.name=Durchsichtiger Chat Hintergrund: 4 | gui.betterchat.text.clear.enabled=Aktiviert 5 | gui.betterchat.text.clear.disabled=Deaktiviert 6 | gui.betterchat.text.smooth.name=Flüssiger Chatverlauf: 7 | gui.betterchat.text.smooth.enabled=Aktiviert 8 | gui.betterchat.text.smooth.disabled=Deaktiviert 9 | gui.betterchat.text.scale.name=Verhältnis: 10 | gui.betterchat.text.width.name=Breite: 11 | gui.betterchat.text.reset.name=Einstellungen Zurücksetzen 12 | gui.betterchat.text.example1=Chat Beispiel 13 | gui.betterchat.text.example2=Test, Test, 1, 2, 3 14 | gui.betterchat.text.example3=Spielernachrichten wird wie folgt aussehen 15 | -------------------------------------------------------------------------------- /src/main/resources/assets/betterchat/lang/en_US.lang: -------------------------------------------------------------------------------- 1 | gui.betterchat.text.title=%1$s by %2$s 2 | gui.betterchat.text.drag=Drag the chat to reposition it 3 | gui.betterchat.text.clear.name=Clear Chat Background: 4 | gui.betterchat.text.clear.enabled=Enabled 5 | gui.betterchat.text.clear.disabled=Disabled 6 | gui.betterchat.text.smooth.name=Smooth Chat: 7 | gui.betterchat.text.smooth.enabled=Enabled 8 | gui.betterchat.text.smooth.disabled=Disabled 9 | gui.betterchat.text.scale.name=Scale: 10 | gui.betterchat.text.width.name=Width: 11 | gui.betterchat.text.reset.name=Reset Config 12 | gui.betterchat.text.example1=Example Chat 13 | gui.betterchat.text.example2=Testing, testing, 1, 2, 3 14 | gui.betterchat.text.example3=Players' messages will look like this -------------------------------------------------------------------------------- /src/main/resources/assets/betterchat/lang/es_ES.lang: -------------------------------------------------------------------------------- 1 | gui.betterchat.text.title=%1$s hecho por %2$s 2 | gui.betterchat.text.drag=Mueve el chat para reposicionar lo 3 | gui.betterchat.text.clear.name=Transparente Fondo del Chat: 4 | gui.betterchat.text.clear.enabled=Habilitado 5 | gui.betterchat.text.clear.disabled=Deshabilitado 6 | gui.betterchat.text.smooth.name=Fluido Chat: 7 | gui.betterchat.text.smooth.enabled=Habilitado 8 | gui.betterchat.text.smooth.disabled=Deshabilitado 9 | gui.betterchat.text.scale.name=Escala: 10 | gui.betterchat.text.width.name=Anchura: 11 | gui.betterchat.text.reset.name=Reinicia Configuraciones 12 | gui.betterchat.text.example1=Ejemplo del chat 13 | gui.betterchat.text.example2=Test, test, 1, 2, 3 14 | gui.betterchat.text.example3=Los mensajes de los jugadores se van a mirar así 15 | -------------------------------------------------------------------------------- /src/main/resources/assets/betterchat/lang/fr_FR.lang: -------------------------------------------------------------------------------- 1 | gui.betterchat.text.title=%1$s de %2$s 2 | gui.betterchat.text.drag=Deplacez le chat pour le repositionner 3 | gui.betterchat.text.clear.name=Fond du Chat Transparent: 4 | gui.betterchat.text.clear.enabled=Activé 5 | gui.betterchat.text.clear.disabled=Desactivé 6 | gui.betterchat.text.smooth.name=Chat Fluide: 7 | gui.betterchat.text.smooth.enabled=Activé 8 | gui.betterchat.text.smooth.disabled=Desactivé 9 | gui.betterchat.text.scale.name=Échelle: 10 | gui.betterchat.text.width.name=Largeur: 11 | gui.betterchat.text.reset.name=Réinitialiser la Configuration 12 | gui.betterchat.text.example1=Exemple du chat 13 | gui.betterchat.text.example2=Test, test, 1, 2, 3 14 | gui.betterchat.text.example3=Les messages des joueurs vont ressembler à ça 15 | -------------------------------------------------------------------------------- /src/main/resources/assets/betterchat/lang/it_IT.lang: -------------------------------------------------------------------------------- 1 | gui.betterchat.text.title=%1$s realizzata da %2$s 2 | gui.betterchat.text.drag=Sposta la chat per riposizionarla 3 | gui.betterchat.text.clear.name=Sfondo Chat Trasparente: 4 | gui.betterchat.text.clear.enabled=Abilitato 5 | gui.betterchat.text.clear.disabled=Disabilitato 6 | gui.betterchat.text.smooth.name=Chat Animata: 7 | gui.betterchat.text.smooth.enabled=Abilitata 8 | gui.betterchat.text.smooth.disabled=Disabilitata 9 | gui.betterchat.text.scale.name=Zoom: 10 | gui.betterchat.text.width.name=Larghezza: 11 | gui.betterchat.text.reset.name=Reimposta Configurazione 12 | gui.betterchat.text.example1=Chat di Esempio 13 | gui.betterchat.text.example2=Prova, prova, 1, 2, 3 14 | gui.betterchat.text.example3=I messaggi dei giocatori appariranno così 15 | -------------------------------------------------------------------------------- /src/main/resources/assets/betterchat/lang/ko_KR.lang: -------------------------------------------------------------------------------- 1 | gui.betterchat.text.title=%1$s by %2$s 2 | gui.betterchat.text.drag=위치를 바꾸려면 채팅을 드래기하세요. 3 | gui.betterchat.text.clear.name=투명한 배경: 4 | gui.betterchat.text.clear.enabled=활성화 5 | gui.betterchat.text.clear.disabled=비활성화 6 | gui.betterchat.text.smooth.name=부드러운 채팅: 7 | gui.betterchat.text.smooth.enabled=활성화 8 | gui.betterchat.text.smooth.disabled=비활성화 9 | gui.betterchat.text.scale.name=크기: 10 | gui.betterchat.text.width.name=가로: 11 | gui.betterchat.text.reset.name=설정 리셋 12 | gui.betterchat.text.example1=예시 채팅 13 | gui.betterchat.text.example2=아아, 테스트, 테스트, 1, 2, 3 14 | gui.betterchat.text.example3=플레이어들의 메시지는 이렇게 보일 거예요. 15 | -------------------------------------------------------------------------------- /src/main/resources/assets/betterchat/lang/zh_CN.lang: -------------------------------------------------------------------------------- 1 | gui.betterchat.text.title=%1$s 的作者为 %2$s 2 | gui.betterchat.text.drag=你可以拖拽聊天栏去设置它的位置 3 | gui.betterchat.text.clear.name=透明聊天背景: 4 | gui.betterchat.text.clear.enabled=启用 5 | gui.betterchat.text.clear.disabled=禁用 6 | gui.betterchat.text.smooth.name=将聊天栏动画化平滑聊天: 7 | gui.betterchat.text.smooth.enabled=启用 8 | gui.betterchat.text.smooth.disabled=禁用 9 | gui.betterchat.text.scale.name=聊天栏比例: 10 | gui.betterchat.text.width.name=聊天栏宽度: 11 | gui.betterchat.text.reset.name=恢复到默认配置 12 | gui.betterchat.text.example1=示例聊天 13 | gui.betterchat.text.example2=测试,测试,一,二,三 14 | gui.betterchat.text.example3=玩家留言会出现这里 15 | -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "modid": "betterchat", 4 | "name": "Better Chat", 5 | "description": "Makes chat smoother and gives it a clear background.", 6 | "version": "${version}", 7 | "mcversion": "${mcversion}", 8 | "url": "", 9 | "updateUrl": "", 10 | "authorList": ["LlamaLad7"] 11 | } 12 | ] 13 | --------------------------------------------------------------------------------