├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src └── main ├── java └── com │ └── therandomlabs │ └── randomtweaks │ ├── ClientProxy.java │ ├── CommonProxy.java │ ├── RandomTweaks.java │ ├── client │ ├── ArmorEquipSoundHandler.java │ ├── AutoThirdPersonHandler.java │ ├── CapeHandler.java │ ├── CreativeTabHandler.java │ ├── DingHandler.java │ ├── KeyBindingHandler.java │ ├── MiscClientEventHandler.java │ ├── NightVisionHandler.java │ ├── PotionParticlesHandler.java │ ├── StepupHandler.java │ └── TimeOfDayOverlay.java │ ├── common │ ├── AnvilHandler.java │ ├── ArrowImpactHandler.java │ ├── BoneMealHandler.java │ ├── CobwebHandler.java │ ├── ColoredSheepHandler.java │ ├── EntityInteractHandler.java │ ├── MiscEventHandler.java │ ├── NetherPortalSpawnHandler.java │ ├── PlayerHeadDropHandler.java │ ├── RTFoodStats.java │ ├── RTLanguageMap.java │ ├── RespawnHandler.java │ ├── SleepHandler.java │ ├── SquidHandler.java │ ├── TorchHandler.java │ ├── TrampleHandler.java │ ├── ZombieAIHandler.java │ ├── command │ │ ├── CommandDeleteGamerule.java │ │ ├── CommandDisconnect.java │ │ ├── CommandHunger.java │ │ ├── CommandRTGive.java │ │ ├── CommandRTHelp.java │ │ └── CommandRegistry.java │ └── world │ │ ├── ChunkGeneratorVoid.java │ │ ├── ChunkGeneratorVoidIslands.java │ │ ├── RTWorldType.java │ │ ├── WorldGeneratorOceanFloor.java │ │ ├── WorldHandler.java │ │ ├── WorldTypeRealistic.java │ │ ├── WorldTypeRegistry.java │ │ ├── WorldTypeVoid.java │ │ └── WorldTypeVoidIslands.java │ ├── config │ ├── RTConfig.java │ ├── RTData.java │ ├── RTGuiConfig.java │ └── RTGuiConfigFactory.java │ └── util │ ├── Alignment.java │ └── RomanNumerals.java └── resources ├── META-INF └── randomtweaks_at.cfg ├── assets └── randomtweaks │ ├── lang │ ├── de_de.lang │ └── en_us.lang │ ├── logo.png │ └── textures │ └── cape.png ├── mcmod.info └── pack.mcmeta /.gitignore: -------------------------------------------------------------------------------- 1 | # eclipse 2 | bin 3 | *.launch 4 | .settings 5 | .metadata 6 | .classpath 7 | .project 8 | 9 | # idea 10 | out 11 | *.ipr 12 | *.iws 13 | *.iml 14 | .idea 15 | 16 | # gradle 17 | build 18 | .gradle 19 | 20 | # other 21 | eclipse 22 | libs 23 | run 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018-2019 TheRandomLabs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RandomTweaks 2 | 3 | A bunch of random tweaks for Minecraft. Clients running this mod are compatible with vanilla 4 | servers, and servers running this mod are compatible with vanilla clients. 5 | 6 | A full feature list can be found [here](https://minecraft.curseforge.com/projects/randomtweaks). 7 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | jcenter() 4 | 5 | maven { 6 | url "http://files.minecraftforge.net/maven" 7 | } 8 | } 9 | 10 | dependencies { 11 | classpath "net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT" 12 | classpath "com.github.jengelman.gradle.plugins:shadow:2.0.0" 13 | } 14 | } 15 | 16 | apply plugin: "net.minecraftforge.gradle.forge" 17 | apply plugin: "com.github.johnrengelman.shadow" 18 | 19 | version = "1.12.2-2.8.3.1" 20 | group = "com.therandomlabs.randomtweaks" 21 | archivesBaseName = "randomtweaks" 22 | 23 | sourceCompatibility = targetCompatibility = "1.8" 24 | 25 | repositories { 26 | maven { 27 | url "https://jitpack.io" 28 | } 29 | 30 | maven { 31 | url "https://www.cursemaven.com" 32 | } 33 | } 34 | 35 | dependencies { 36 | shadow "com.github.TheRandomLabs:RandomLib:1.12-SNAPSHOT" 37 | compile "com.github.TheRandomLabs:RandomLib:1.12-SNAPSHOT" 38 | deobfCompile "curse.maven:randompatches-285612:3133651" 39 | deobfCompile "curse.maven:randomportals-308137:3136488" 40 | deobfCompile "curse.maven:applecore-224472:2969118" 41 | deobfCompile "curse.maven:llibrary-243298:3116493" 42 | deobfCompile "curse.maven:wings-302584:2829351" 43 | } 44 | 45 | shadowJar { 46 | classifier = "" 47 | relocate "com.therandomlabs.randomlib", "com.therandomlabs.randomtweaks.repackage.com.therandomlabs.randomlib" 48 | configurations = [project.configurations.shadow] 49 | } 50 | 51 | reobf { 52 | shadowJar { 53 | mappingType = "SEARGE" 54 | } 55 | } 56 | 57 | build.dependsOn shadowJar 58 | 59 | artifacts { 60 | archives shadowJar 61 | } 62 | 63 | minecraft { 64 | version = "1.12.2-14.23.5.2838" 65 | runDir = "run" 66 | mappings = "stable_39" 67 | 68 | replace "@VERSION@", project.version 69 | replace "@FINGERPRINT@", project.findProperty("signSHA1") 70 | } 71 | 72 | processResources { 73 | //Ensure this task is redone when the versions change 74 | inputs.property "version", project.version 75 | inputs.property "mcversion", project.minecraft.version 76 | 77 | //Replace version and mcversion in mcmod.info 78 | from(sourceSets.main.resources.srcDirs) { 79 | include "mcmod.info" 80 | expand "version": project.version, "mcversion": project.minecraft.version 81 | } 82 | } 83 | 84 | jar { 85 | manifest { 86 | attributes "FMLAT": "randomtweaks_at.cfg" 87 | } 88 | } 89 | 90 | task signJar(type: SignJar, dependsOn: reobfJar) { 91 | onlyIf { 92 | project.hasProperty("keyStore") 93 | } 94 | 95 | keyStore = project.findProperty("keyStore") 96 | alias = project.findProperty("keyStoreAlias") 97 | storePass = project.findProperty("keyStorePass") 98 | keyPass = project.findProperty("keyStoreKeyPass") 99 | inputFile = jar.archivePath 100 | outputFile = jar.archivePath 101 | } 102 | 103 | build.dependsOn signJar 104 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Sets default memory used for gradle commands. Can be overridden by user or command line properties. 2 | # This is required to provide enough memory for the Minecraft decompilation process. 3 | org.gradle.jvmargs=-Xmx3G 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheRandomLabs/RandomTweaks/6f940dcbaee165ff99b5cd4b5e22c19f6dc8b30a/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip 6 | -------------------------------------------------------------------------------- /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/therandomlabs/randomtweaks/ClientProxy.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks; 2 | 3 | import com.therandomlabs.randomtweaks.client.CapeHandler; 4 | import com.therandomlabs.randomtweaks.client.NightVisionHandler; 5 | import com.therandomlabs.randomtweaks.common.command.CommandRegistry; 6 | import com.therandomlabs.randomtweaks.config.RTConfig; 7 | 8 | public final class ClientProxy extends CommonProxy { 9 | @Override 10 | public void preInit() { 11 | super.preInit(); 12 | 13 | if(RTConfig.Client.contributorCapes) { 14 | CapeHandler.downloadPlayers(); 15 | } 16 | 17 | CommandRegistry.registerClient(); 18 | } 19 | 20 | @Override 21 | public void postInit() { 22 | if(RTConfig.NightVision.enabled && !RandomTweaks.NO_NIGHT_VISION_FLASHING_LOADED) { 23 | NightVisionHandler.initialize(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/CommonProxy.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks; 2 | 3 | import com.therandomlabs.randomlib.config.ConfigManager; 4 | import com.therandomlabs.randomtweaks.common.ArrowImpactHandler; 5 | import com.therandomlabs.randomtweaks.common.NetherPortalSpawnHandler; 6 | import com.therandomlabs.randomtweaks.common.RTFoodStats; 7 | import com.therandomlabs.randomtweaks.common.RTLanguageMap; 8 | import com.therandomlabs.randomtweaks.common.TrampleHandler; 9 | import com.therandomlabs.randomtweaks.common.world.WorldGeneratorOceanFloor; 10 | import com.therandomlabs.randomtweaks.common.world.WorldTypeRegistry; 11 | import com.therandomlabs.randomtweaks.config.RTConfig; 12 | import net.minecraftforge.common.ForgeVersion; 13 | import net.minecraftforge.common.MinecraftForge; 14 | import net.minecraftforge.fml.common.registry.GameRegistry; 15 | 16 | public class CommonProxy { 17 | public void preInit() { 18 | ConfigManager.register(RTConfig.class); 19 | RTLanguageMap.replaceLanguageMaps(); 20 | } 21 | 22 | public void init() { 23 | ConfigManager.reloadFromDisk(RTConfig.class); 24 | 25 | if(ForgeVersion.getBuildVersion() > 2526) { 26 | MinecraftForge.EVENT_BUS.register(ArrowImpactHandler.class); 27 | 28 | if(ForgeVersion.getBuildVersion() > 2718) { 29 | MinecraftForge.EVENT_BUS.register(TrampleHandler.class); 30 | } 31 | 32 | if(RandomTweaks.RANDOMPORTALS_LOADED) { 33 | MinecraftForge.EVENT_BUS.register(NetherPortalSpawnHandler.RandomPortals.class); 34 | } else { 35 | MinecraftForge.EVENT_BUS.register(NetherPortalSpawnHandler.Vanilla.class); 36 | } 37 | } 38 | 39 | WorldTypeRegistry.registerWorldTypes(); 40 | 41 | if(RTConfig.OceanFloor.enabled && !RandomTweaks.OCEAN_FLOOR_LOADED) { 42 | GameRegistry.registerWorldGenerator(new WorldGeneratorOceanFloor(), 0); 43 | } 44 | 45 | if(RTConfig.Hunger.enabled && RandomTweaks.APPLECORE_LOADED) { 46 | MinecraftForge.EVENT_BUS.register(RTFoodStats.AppleCoreEventHandler.class); 47 | } 48 | } 49 | 50 | public void postInit() {} 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/RandomTweaks.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks; 2 | 3 | import com.therandomlabs.randomtweaks.common.command.CommandRegistry; 4 | import net.minecraftforge.fml.common.Loader; 5 | import net.minecraftforge.fml.common.Mod; 6 | import net.minecraftforge.fml.common.SidedProxy; 7 | import net.minecraftforge.fml.common.event.FMLInitializationEvent; 8 | import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; 9 | import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; 10 | import net.minecraftforge.fml.common.event.FMLServerStartedEvent; 11 | import net.minecraftforge.fml.common.event.FMLServerStartingEvent; 12 | import org.apache.logging.log4j.LogManager; 13 | import org.apache.logging.log4j.Logger; 14 | 15 | @Mod( 16 | modid = RandomTweaks.MOD_ID, version = RandomTweaks.VERSION, 17 | acceptedMinecraftVersions = RandomTweaks.ACCEPTED_MINECRAFT_VERSIONS, 18 | acceptableRemoteVersions = RandomTweaks.ACCEPTABLE_REMOTE_VERSIONS, 19 | guiFactory = RandomTweaks.GUI_FACTORY, updateJSON = RandomTweaks.UPDATE_JSON, 20 | certificateFingerprint = RandomTweaks.CERTIFICATE_FINGERPRINT 21 | ) 22 | public final class RandomTweaks { 23 | public static final String MOD_ID = "randomtweaks"; 24 | public static final String VERSION = "@VERSION@"; 25 | public static final String ACCEPTED_MINECRAFT_VERSIONS = "[1.12,1.13)"; 26 | public static final String ACCEPTABLE_REMOTE_VERSIONS = "*"; 27 | public static final String GUI_FACTORY = 28 | "com.therandomlabs.randomtweaks.config.RTGuiConfigFactory"; 29 | public static final String UPDATE_JSON = 30 | "https://raw.githubusercontent.com/TheRandomLabs/RandomTweaks/misc/versions.json"; 31 | public static final String CERTIFICATE_FINGERPRINT = "@FINGERPRINT@"; 32 | 33 | public static final Logger LOGGER = LogManager.getLogger(MOD_ID); 34 | 35 | public static final boolean APPLECORE_LOADED = Loader.isModLoaded("applecore"); 36 | public static final boolean CAKE_CHOMPS_LOADED = Loader.isModLoaded("cakechomps"); 37 | public static final boolean CALM_DOWN_ZOMBIE_GUY_LOADED = 38 | Loader.isModLoaded("calmdownzombieguy"); 39 | public static final boolean COLORFUL_SHEEP_LOADED = Loader.isModLoaded("colorful-sheep"); 40 | public static final boolean DING_LOADED = Loader.isModLoaded("ding"); 41 | public static final boolean DYNAMIC_SURROUNDINGS_LOADED = Loader.isModLoaded("dsurround"); 42 | public static final boolean ENTITY_NAN_HEALTH_FIX_LOADED = Loader.isModLoaded("nanfix"); 43 | public static final boolean EXPANDED_BONEMEAL_LOADED = Loader.isModLoaded("expandedbonemeal"); 44 | public static final boolean HEADCRUMBS_LOADED = Loader.isModLoaded("headcrumbs"); 45 | public static final boolean HELPFIXER_LOADED = Loader.isModLoaded("helpfixer"); 46 | public static final boolean NO_NIGHT_VISION_FLASHING_LOADED = Loader.isModLoaded("nonvflash"); 47 | public static final boolean PLAYERS_DROP_HEADS_LOADED = Loader.isModLoaded("playersdropheads"); 48 | public static final boolean POTION_CORE_LOADED = Loader.isModLoaded("potioncore"); 49 | public static final boolean QUARK_LOADED = Loader.isModLoaded("quark"); 50 | public static final boolean OCEAN_FLOOR_LOADED = Loader.isModLoaded("samsocean"); 51 | public static final boolean RANDOMCONFIGS_LOADED = Loader.isModLoaded("randomconfigs"); 52 | public static final boolean RANDOMPATCHES_LOADED = Loader.isModLoaded("randompatches"); 53 | public static final boolean RANDOMPORTALS_LOADED = Loader.isModLoaded("randomportals"); 54 | public static final boolean VANILLATWEAKS_LOADED = Loader.isModLoaded("vt"); 55 | public static final boolean WINGS_LOADED = Loader.isModLoaded("wings"); 56 | 57 | @SidedProxy( 58 | clientSide = "com.therandomlabs.randomtweaks.ClientProxy", 59 | serverSide = "com.therandomlabs.randomtweaks.CommonProxy" 60 | ) 61 | public static CommonProxy proxy; 62 | 63 | @Mod.EventHandler 64 | public static void preInit(FMLPreInitializationEvent event) { 65 | proxy.preInit(); 66 | } 67 | 68 | @Mod.EventHandler 69 | public static void init(FMLInitializationEvent event) { 70 | proxy.init(); 71 | } 72 | 73 | @Mod.EventHandler 74 | public static void postInit(FMLPostInitializationEvent event) { 75 | proxy.postInit(); 76 | } 77 | 78 | @Mod.EventHandler 79 | public static void serverStarting(FMLServerStartingEvent event) { 80 | CommandRegistry.register(event); 81 | } 82 | 83 | @Mod.EventHandler 84 | public static void serverStarted(FMLServerStartedEvent event) { 85 | CommandRegistry.serverStarted(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/client/ArmorEquipSoundHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.client; 2 | 3 | import java.util.List; 4 | import com.therandomlabs.randomtweaks.config.RTConfig; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.init.Blocks; 7 | import net.minecraft.item.Item; 8 | import net.minecraft.item.ItemArmor; 9 | import net.minecraft.item.ItemElytra; 10 | import net.minecraft.item.ItemSkull; 11 | import net.minecraft.item.ItemStack; 12 | import net.minecraft.util.NonNullList; 13 | import net.minecraft.util.SoundEvent; 14 | 15 | public final class ArmorEquipSoundHandler { 16 | private static final List previousArmor = NonNullList.withSize(4, ItemStack.EMPTY); 17 | 18 | private ArmorEquipSoundHandler() {} 19 | 20 | public static void onClientTick() { 21 | final Minecraft mc = Minecraft.getMinecraft(); 22 | 23 | if(!RTConfig.ArmorEquipSounds.enabled || mc.player == null) { 24 | return; 25 | } 26 | 27 | for(int i = 0; i < 4; i++) { 28 | final ItemStack previousStack = previousArmor.get(i); 29 | 30 | final ItemStack stack = mc.player.inventory.armorInventory.get(i); 31 | previousArmor.set(i, stack == ItemStack.EMPTY ? stack : stack.copy()); 32 | 33 | if(!ItemStack.areItemsEqualIgnoreDurability(stack, previousStack)) { 34 | SoundEvent sound = getSound(stack); 35 | 36 | if(sound == null) { 37 | sound = getSound(previousStack); 38 | } 39 | 40 | if(sound != null) { 41 | mc.player.playSound(sound, 1.0F, 1.0F); 42 | } 43 | } 44 | } 45 | } 46 | 47 | public static SoundEvent getSound(ItemStack stack) { 48 | final Minecraft mc = Minecraft.getMinecraft(); 49 | 50 | if(mc.player.ticksExisted < 20) { 51 | return null; 52 | } 53 | 54 | final Item item = stack.getItem(); 55 | 56 | if(item instanceof ItemArmor) { 57 | return ((ItemArmor) item).getArmorMaterial().getSoundEvent(); 58 | } 59 | 60 | if(item instanceof ItemElytra) { 61 | return RTConfig.ArmorEquipSounds.elytraSound; 62 | } 63 | 64 | if(item == Item.getItemFromBlock(Blocks.PUMPKIN)) { 65 | return RTConfig.ArmorEquipSounds.pumpkinSound; 66 | } 67 | 68 | if(item instanceof ItemSkull) { 69 | return RTConfig.ArmorEquipSounds.skullSound; 70 | } 71 | 72 | return null; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/client/AutoThirdPersonHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.client; 2 | 3 | import com.therandomlabs.randomtweaks.RandomTweaks; 4 | import com.therandomlabs.randomtweaks.config.RTConfig; 5 | import me.paulf.wings.server.flight.Flight; 6 | import me.paulf.wings.server.flight.Flights; 7 | import net.minecraft.client.Minecraft; 8 | import net.minecraft.entity.Entity; 9 | import net.minecraft.entity.item.EntityBoat; 10 | import net.minecraft.entity.item.EntityMinecart; 11 | import net.minecraft.entity.passive.AbstractHorse; 12 | import net.minecraft.entity.passive.EntityPig; 13 | 14 | public final class AutoThirdPersonHandler { 15 | private static final Minecraft mc = Minecraft.getMinecraft(); 16 | 17 | private static final int THIRD_PERSON = 1; 18 | 19 | private static final int WINGS = -2; 20 | private static final int ELYTRA = -1; 21 | private static final int NO_ENTITY = 0; 22 | 23 | private static int lastID = NO_ENTITY; 24 | private static int originalPerspective; 25 | 26 | private static int wingsFlyingTicks; 27 | 28 | private AutoThirdPersonHandler() {} 29 | 30 | public static void onClientTick() { 31 | if (!RTConfig.AutoThirdPerson.enabled || mc.world == null || mc.player == null || 32 | mc.isGamePaused()) { 33 | return; 34 | } 35 | 36 | if (RandomTweaks.WINGS_LOADED && RTConfig.AutoThirdPerson.wings) { 37 | final Flight flight = Flights.get(mc.player); 38 | 39 | if (flight != null && flight.isFlying()) { 40 | if (wingsFlyingTicks++ == RTConfig.AutoThirdPerson.wingsFlyingTickDelay) { 41 | lastID = WINGS; 42 | originalPerspective = mc.gameSettings.thirdPersonView; 43 | mc.gameSettings.thirdPersonView = THIRD_PERSON; 44 | } 45 | 46 | return; 47 | } else { 48 | if (lastID == WINGS) { 49 | lastID = NO_ENTITY; 50 | mc.gameSettings.thirdPersonView = originalPerspective; 51 | } 52 | 53 | wingsFlyingTicks = 0; 54 | } 55 | } else { 56 | wingsFlyingTicks = 0; 57 | } 58 | 59 | if (mc.player.isElytraFlying()) { 60 | if (!RTConfig.AutoThirdPerson.elytra || lastID == ELYTRA) { 61 | return; 62 | } 63 | 64 | lastID = ELYTRA; 65 | originalPerspective = mc.gameSettings.thirdPersonView; 66 | mc.gameSettings.thirdPersonView = THIRD_PERSON; 67 | 68 | return; 69 | } 70 | 71 | if(mc.player.isRiding()) { 72 | final Entity entity = mc.player.getRidingEntity(); 73 | 74 | if(lastID == entity.getEntityId()) { 75 | return; 76 | } 77 | 78 | if(lastID == NO_ENTITY) { 79 | originalPerspective = mc.gameSettings.thirdPersonView; 80 | } 81 | 82 | lastID = entity.getEntityId(); 83 | 84 | if(entity instanceof AbstractHorse) { 85 | if(!RTConfig.AutoThirdPerson.horse) { 86 | return; 87 | } 88 | } else if(entity instanceof EntityPig) { 89 | if(!RTConfig.AutoThirdPerson.pig) { 90 | return; 91 | } 92 | } else if(entity instanceof EntityBoat) { 93 | if(!RTConfig.AutoThirdPerson.boat) { 94 | return; 95 | } 96 | } else if(entity instanceof EntityMinecart) { 97 | if(!RTConfig.AutoThirdPerson.minecart) { 98 | return; 99 | } 100 | } else { 101 | lastID = NO_ENTITY; 102 | mc.gameSettings.thirdPersonView = originalPerspective; 103 | return; 104 | } 105 | 106 | mc.gameSettings.thirdPersonView = THIRD_PERSON; 107 | 108 | return; 109 | } 110 | 111 | if(lastID != NO_ENTITY) { 112 | lastID = NO_ENTITY; 113 | mc.gameSettings.thirdPersonView = originalPerspective; 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/client/CapeHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.client; 2 | 3 | import java.io.IOException; 4 | import java.net.HttpURLConnection; 5 | import java.net.URL; 6 | import java.nio.charset.StandardCharsets; 7 | import java.util.Collections; 8 | import java.util.List; 9 | import com.mojang.authlib.minecraft.MinecraftProfileTexture; 10 | import com.therandomlabs.randomlib.TRLUtils; 11 | import com.therandomlabs.randomtweaks.RandomTweaks; 12 | import com.therandomlabs.randomtweaks.config.RTConfig; 13 | import net.minecraft.client.entity.AbstractClientPlayer; 14 | import net.minecraft.client.network.NetworkPlayerInfo; 15 | import net.minecraft.entity.player.EntityPlayer; 16 | import net.minecraft.util.ResourceLocation; 17 | import net.minecraftforge.client.event.RenderPlayerEvent; 18 | import net.minecraftforge.fml.common.Mod; 19 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 20 | import net.minecraftforge.fml.relauncher.Side; 21 | import org.apache.commons.io.IOUtils; 22 | 23 | @Mod.EventBusSubscriber(value = Side.CLIENT, modid = RandomTweaks.MOD_ID) 24 | public final class CapeHandler { 25 | public static final ResourceLocation CAPE_LOCATION = 26 | new ResourceLocation(RandomTweaks.MOD_ID, "textures/cape.png"); 27 | 28 | public static final String CONTRIBUTORS_URL = 29 | "https://raw.githubusercontent.com/TheRandomLabs/RandomTweaks/misc/contributors.txt"; 30 | 31 | private static List contributors = Collections.emptyList(); 32 | 33 | @SubscribeEvent 34 | public static void onRenderPlayerPre(RenderPlayerEvent.Pre event) { 35 | if(!RTConfig.Client.contributorCapes) { 36 | return; 37 | } 38 | 39 | final AbstractClientPlayer player = (AbstractClientPlayer) event.getEntityPlayer(); 40 | 41 | if(!hasCape(player)) { 42 | return; 43 | } 44 | 45 | NetworkPlayerInfo info = player.getPlayerInfo(); 46 | 47 | if(info == null) { 48 | info = new NetworkPlayerInfo(player.getGameProfile()); 49 | //So onRenderPlayerPost knows to set playerInfo back to null 50 | info.responseTime = Integer.MIN_VALUE; 51 | player.playerInfo = info; 52 | } 53 | 54 | if(info.playerTextures.get(MinecraftProfileTexture.Type.CAPE) == null) { 55 | info.playerTextures.put(MinecraftProfileTexture.Type.CAPE, CAPE_LOCATION); 56 | info.playerTextures.put(MinecraftProfileTexture.Type.ELYTRA, CAPE_LOCATION); 57 | } 58 | } 59 | 60 | @SubscribeEvent 61 | public static void onRenderPlayerPost(RenderPlayerEvent.Post event) { 62 | if(!RTConfig.Client.contributorCapes) { 63 | return; 64 | } 65 | 66 | final AbstractClientPlayer player = (AbstractClientPlayer) event.getEntityPlayer(); 67 | 68 | if(hasCape(player) && player.playerInfo != null && 69 | player.playerInfo.responseTime == Integer.MIN_VALUE) { 70 | player.playerInfo = null; 71 | } 72 | } 73 | 74 | public static void downloadPlayers() { 75 | new Thread(() -> { 76 | try { 77 | final HttpURLConnection connection = 78 | (HttpURLConnection) new URL(CONTRIBUTORS_URL).openConnection(); 79 | connection.setConnectTimeout(1000); 80 | 81 | contributors = IOUtils.readLines( 82 | connection.getInputStream(), StandardCharsets.UTF_8 83 | ); 84 | 85 | connection.disconnect(); 86 | } catch(IOException ex) { 87 | RandomTweaks.LOGGER.error("Failed to download conbtributor list", ex); 88 | } 89 | }).start(); 90 | } 91 | 92 | public static boolean hasCape(EntityPlayer player) { 93 | return TRLUtils.IS_DEOBFUSCATED || contributors.contains(player.getUniqueID().toString()); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/client/CreativeTabHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.client; 2 | 3 | import java.lang.reflect.Field; 4 | import com.therandomlabs.randomlib.TRLUtils; 5 | import com.therandomlabs.randomtweaks.RandomTweaks; 6 | import com.therandomlabs.randomtweaks.config.RTConfig; 7 | import net.minecraft.client.gui.inventory.GuiContainerCreative; 8 | import net.minecraft.creativetab.CreativeTabs; 9 | import net.minecraft.entity.EntityList; 10 | import net.minecraft.init.Blocks; 11 | import net.minecraft.init.Items; 12 | import net.minecraft.item.ItemMonsterPlacer; 13 | import net.minecraft.item.ItemStack; 14 | import net.minecraft.nbt.NBTTagCompound; 15 | import net.minecraft.util.NonNullList; 16 | import net.minecraft.util.ResourceLocation; 17 | import net.minecraftforge.event.entity.player.ItemTooltipEvent; 18 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 19 | import net.minecraftforge.fml.relauncher.Side; 20 | import net.minecraftforge.fml.relauncher.SideOnly; 21 | import org.apache.commons.lang3.ArrayUtils; 22 | 23 | //A lot of this is there just so creative tab configuration options can be toggled in-game 24 | //Worth it? Maybe 25 | public final class CreativeTabHandler { 26 | public static final CreativeTabs SPAWN_EGGS = new CreativeTabs("spawnEggs") { 27 | @SideOnly(Side.CLIENT) 28 | @Override 29 | public ItemStack createIcon() { 30 | final ItemStack stack = new ItemStack(Items.SPAWN_EGG); 31 | ItemMonsterPlacer.applyEntityIdToItemStack(stack, new ResourceLocation("chicken")); 32 | return stack; 33 | } 34 | 35 | @Override 36 | public void displayAllRelevantItems(NonNullList itemList) { 37 | super.displayAllRelevantItems(itemList); 38 | 39 | if(!RTConfig.CreativeTabs.noAISpawnEggs) { 40 | return; 41 | } 42 | 43 | for(ResourceLocation id : EntityList.ENTITY_EGGS.keySet()) { 44 | final ItemStack stack = new ItemStack(Items.SPAWN_EGG); 45 | 46 | ItemMonsterPlacer.applyEntityIdToItemStack(stack, id); 47 | 48 | final NBTTagCompound tag = stack.getTagCompound().getCompoundTag("EntityTag"); 49 | tag.setBoolean("NoAI", true); 50 | 51 | itemList.add(stack); 52 | } 53 | } 54 | }; 55 | 56 | public static final Field TAB_PAGE = TRLUtils.findField(GuiContainerCreative.class, "tabPage"); 57 | 58 | private static CreativeTabs originalBucketTab; 59 | private static boolean bucketSetBefore; 60 | 61 | private static CreativeTabs originalCommandBlockTab; 62 | private static boolean commandBlockSetBefore; 63 | 64 | private static CreativeTabs originalDragonEggTab; 65 | private static boolean dragonEggSetBefore; 66 | 67 | private static CreativeTabs originalSpawnEggsTab; 68 | 69 | @SubscribeEvent 70 | public static void onItemTooltip(ItemTooltipEvent event) { 71 | final ItemStack stack = event.getItemStack(); 72 | 73 | if(stack == null || stack.getItem() != Items.SPAWN_EGG) { 74 | return; 75 | } 76 | 77 | final NBTTagCompound stackTag = stack.getTagCompound(); 78 | 79 | if(stackTag != null && stackTag.hasKey("EntityTag")) { 80 | final NBTTagCompound entityTag = stackTag.getCompoundTag("EntityTag"); 81 | 82 | if(entityTag.getBoolean("NoAI")) { 83 | event.getToolTip().add(TRLUtils.localize("spawnEgg.noAI")); 84 | } 85 | } 86 | } 87 | 88 | public static void initialize() { 89 | if(RTConfig.CreativeTabs.moveBucketCreativeTab) { 90 | originalBucketTab = Items.BUCKET.getCreativeTab(); 91 | bucketSetBefore = true; 92 | Items.BUCKET.setCreativeTab(CreativeTabs.TOOLS); 93 | } else if(bucketSetBefore) { 94 | Items.BUCKET.setCreativeTab(originalBucketTab); 95 | } 96 | 97 | if(RTConfig.CreativeTabs.setCommandBlockCreativeTab) { 98 | originalCommandBlockTab = Blocks.COMMAND_BLOCK.getCreativeTab(); 99 | commandBlockSetBefore = true; 100 | 101 | Blocks.COMMAND_BLOCK.setCreativeTab(CreativeTabs.REDSTONE); 102 | Blocks.CHAIN_COMMAND_BLOCK.setCreativeTab(CreativeTabs.REDSTONE); 103 | Blocks.REPEATING_COMMAND_BLOCK.setCreativeTab(CreativeTabs.REDSTONE); 104 | } else if(commandBlockSetBefore) { 105 | Blocks.COMMAND_BLOCK.setCreativeTab(originalCommandBlockTab); 106 | Blocks.CHAIN_COMMAND_BLOCK.setCreativeTab(originalCommandBlockTab); 107 | Blocks.REPEATING_COMMAND_BLOCK.setCreativeTab(originalCommandBlockTab); 108 | } 109 | 110 | if(RTConfig.CreativeTabs.setDragonEggCreativeTab) { 111 | originalDragonEggTab = Blocks.DRAGON_EGG.getCreativeTab(); 112 | dragonEggSetBefore = true; 113 | 114 | Blocks.DRAGON_EGG.setCreativeTab(CreativeTabs.DECORATIONS); 115 | } else if(dragonEggSetBefore) { 116 | Blocks.DRAGON_EGG.setCreativeTab(originalDragonEggTab); 117 | } 118 | 119 | registerSpawnEggsTab(); 120 | } 121 | 122 | private static void registerSpawnEggsTab() { 123 | if(RTConfig.CreativeTabs.spawnEggsCreativeTab) { 124 | if(!ArrayUtils.contains(CreativeTabs.CREATIVE_TAB_ARRAY, SPAWN_EGGS)) { 125 | CreativeTabs.CREATIVE_TAB_ARRAY = 126 | ArrayUtils.add(CreativeTabs.CREATIVE_TAB_ARRAY, SPAWN_EGGS); 127 | SPAWN_EGGS.index = CreativeTabs.CREATIVE_TAB_ARRAY.length - 1; 128 | } 129 | 130 | originalSpawnEggsTab = Items.SPAWN_EGG.getCreativeTab(); 131 | Items.SPAWN_EGG.setCreativeTab(SPAWN_EGGS); 132 | 133 | return; 134 | } 135 | 136 | final int index = ArrayUtils.indexOf(CreativeTabs.CREATIVE_TAB_ARRAY, SPAWN_EGGS); 137 | 138 | if(index != ArrayUtils.INDEX_NOT_FOUND) { 139 | CreativeTabs.CREATIVE_TAB_ARRAY = 140 | ArrayUtils.remove(CreativeTabs.CREATIVE_TAB_ARRAY, index); 141 | 142 | for(int i = index; i < CreativeTabs.CREATIVE_TAB_ARRAY.length; i++) { 143 | CreativeTabs.CREATIVE_TAB_ARRAY[i].index = i; 144 | } 145 | 146 | GuiContainerCreative.selectedTabIndex = CreativeTabs.BUILDING_BLOCKS.index; 147 | 148 | try { 149 | TAB_PAGE.set(null, 0); 150 | } catch(Exception ex) { 151 | RandomTweaks.LOGGER.error("Error while disabling creative tab", ex); 152 | } 153 | } 154 | 155 | if(originalSpawnEggsTab != null) { 156 | Items.SPAWN_EGG.setCreativeTab(originalSpawnEggsTab); 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/client/DingHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.client; 2 | 3 | import java.lang.reflect.Field; 4 | import java.util.Random; 5 | import com.therandomlabs.randomtweaks.RandomTweaks; 6 | import com.therandomlabs.randomtweaks.config.RTConfig; 7 | import net.minecraft.client.Minecraft; 8 | import net.minecraft.client.audio.ISound; 9 | import net.minecraft.client.audio.PositionedSoundRecord; 10 | import net.minecraft.client.audio.SoundHandler; 11 | import net.minecraft.util.SoundCategory; 12 | import net.minecraft.util.SoundEvent; 13 | import net.minecraftforge.common.MinecraftForge; 14 | import net.minecraftforge.fml.common.Mod; 15 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 16 | import net.minecraftforge.fml.common.gameevent.TickEvent; 17 | import net.minecraftforge.fml.common.network.FMLNetworkEvent; 18 | import net.minecraftforge.fml.relauncher.Side; 19 | import paulscode.sound.SoundSystem; 20 | 21 | @Mod.EventBusSubscriber(value = Side.CLIENT, modid = RandomTweaks.MOD_ID) 22 | public final class DingHandler { 23 | private static final Class GENERAL_MOD_OPTIONS; 24 | private static final Class BACKGROUND_MUTE; 25 | 26 | private static final Random random = new Random(); 27 | private static final Minecraft mc = Minecraft.getMinecraft(); 28 | 29 | private static boolean playWorld; 30 | 31 | private static ISound sound; 32 | 33 | static { 34 | if(RandomTweaks.DYNAMIC_SURROUNDINGS_LOADED) { 35 | GENERAL_MOD_OPTIONS = getDsurroundClass("ModOptions$general"); 36 | BACKGROUND_MUTE = getDsurroundClass("client.sound.BackgroundMute"); 37 | } else { 38 | GENERAL_MOD_OPTIONS = null; 39 | BACKGROUND_MUTE = null; 40 | } 41 | } 42 | 43 | public static void onGameStarted() { 44 | if(!RandomTweaks.DING_LOADED && RTConfig.Ding.startupSounds.length != 0 && 45 | isDsurroundStartupSoundDisabled()) { 46 | playSound( 47 | RTConfig.Ding.startupSounds, 48 | RTConfig.Ding.startupSoundPitch, 49 | RTConfig.Ding.startupSoundVolume 50 | ); 51 | } 52 | } 53 | 54 | @SubscribeEvent 55 | public static void onConnectToServer(FMLNetworkEvent.ClientConnectedToServerEvent event) { 56 | if(!RandomTweaks.DING_LOADED && RTConfig.Ding.worldLoadSounds.length != 0) { 57 | playWorld = true; 58 | } 59 | } 60 | 61 | @SubscribeEvent 62 | public static void onWorldTick(TickEvent.WorldTickEvent event) { 63 | if(!playWorld || event.phase != TickEvent.Phase.END || mc.player == null) { 64 | return; 65 | } 66 | 67 | if(mc.player.ticksExisted >= 20 || mc.isGamePaused()) { 68 | playSound( 69 | RTConfig.Ding.worldLoadSounds, 70 | RTConfig.Ding.worldLoadSoundPitch, 71 | RTConfig.Ding.worldLoadSoundVolume 72 | ); 73 | playWorld = false; 74 | } 75 | } 76 | 77 | public static void onClientTick() { 78 | if(sound == null) { 79 | return; 80 | } 81 | 82 | //Dynamics Surroundings compatibility 83 | 84 | final SoundHandler soundHandler = mc.getSoundHandler(); 85 | 86 | if(!soundHandler.isSoundPlaying(sound)) { 87 | MinecraftForge.EVENT_BUS.register(BACKGROUND_MUTE); 88 | } 89 | } 90 | 91 | public static void playSound(SoundEvent[] soundEvents, double pitch, double volume) { 92 | final SoundEvent soundEvent = soundEvents[random.nextInt(soundEvents.length)]; 93 | 94 | final SoundHandler soundHandler = mc.getSoundHandler(); 95 | final ISound sound = PositionedSoundRecord.getRecord( 96 | soundEvent, (float) pitch, (float) volume 97 | ); 98 | 99 | if(!RTConfig.Ding.ignoreDsurroundMuteWhenBackground || BACKGROUND_MUTE == null) { 100 | soundHandler.playSound(sound); 101 | return; 102 | } 103 | 104 | //Dynamics Surroundings compatibility 105 | 106 | ((SoundSystem) soundHandler.sndManager.sndSystem).setMasterVolume( 107 | mc.gameSettings.getSoundLevel(SoundCategory.MASTER) 108 | ); 109 | 110 | soundHandler.playSound(sound); 111 | 112 | DingHandler.sound = sound; 113 | MinecraftForge.EVENT_BUS.unregister(BACKGROUND_MUTE); 114 | } 115 | 116 | public static boolean isDsurroundStartupSoundDisabled() { 117 | if(GENERAL_MOD_OPTIONS == null) { 118 | return true; 119 | } 120 | 121 | try { 122 | final Field startupSoundListField = 123 | GENERAL_MOD_OPTIONS.getDeclaredField("startupSoundList"); 124 | final String[] startupSoundList = (String[]) startupSoundListField.get(null); 125 | 126 | return startupSoundList.length == 0; 127 | } catch(Exception ex) { 128 | RandomTweaks.LOGGER.error( 129 | "Failed to check if Dynamic Surrounding's startup sound list is empty", ex 130 | ); 131 | } 132 | 133 | return true; 134 | } 135 | 136 | public static Class getDsurroundClass(String name) { 137 | try { 138 | return Class.forName("org.orecruncher.dsurround." + name); 139 | } catch(ClassNotFoundException ex) { 140 | try { 141 | return Class.forName("org.blockartistry.DynSurround." + name); 142 | } catch(ClassNotFoundException ex2) { 143 | RandomTweaks.LOGGER.error( 144 | "Failed to find Dynamic Surroundings class: " + name, ex2 145 | ); 146 | } 147 | } 148 | 149 | return null; 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/client/KeyBindingHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.client; 2 | 3 | import com.therandomlabs.randomtweaks.RandomTweaks; 4 | import com.therandomlabs.randomtweaks.config.RTConfig; 5 | import com.therandomlabs.randomtweaks.config.RTData; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.settings.GameSettings; 8 | import net.minecraft.client.settings.KeyBinding; 9 | import net.minecraft.util.text.TextComponentTranslation; 10 | import net.minecraftforge.client.settings.KeyConflictContext; 11 | import net.minecraftforge.client.settings.KeyModifier; 12 | import net.minecraftforge.fml.common.Mod; 13 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 14 | import net.minecraftforge.fml.common.gameevent.InputEvent; 15 | import net.minecraftforge.fml.relauncher.Side; 16 | import org.apache.commons.lang3.ArrayUtils; 17 | import org.lwjgl.input.Keyboard; 18 | 19 | @Mod.EventBusSubscriber(value = Side.CLIENT, modid = RandomTweaks.MOD_ID) 20 | public final class KeyBindingHandler { 21 | public static final KeyBinding TOGGLE_FOV_CHANGES = new KeyBinding( 22 | "key.toggleFoVChanges", 23 | KeyConflictContext.IN_GAME, 24 | KeyModifier.SHIFT, 25 | Keyboard.KEY_COMMA, 26 | "key.categories.randomtweaks" 27 | ); 28 | 29 | public static final KeyBinding RELOAD_SOUND_SYSTEM = new KeyBinding( 30 | "key.reloadSoundSystem", 31 | KeyConflictContext.IN_GAME, 32 | KeyModifier.SHIFT, 33 | Keyboard.KEY_F8, 34 | "key.categories.randomtweaks" 35 | ); 36 | 37 | public static final KeyBinding TOGGLE_TIME_OF_DAY_OVERLAY = new KeyBinding( 38 | "key.toggleTimeOfDayOverlay", 39 | KeyConflictContext.IN_GAME, 40 | Keyboard.KEY_NONE, 41 | "key.categories.randomtweaks" 42 | ); 43 | 44 | public static final KeyBinding TOGGLE_AUTO_JUMP = new KeyBinding( 45 | "key.toggleAutoJump", 46 | KeyConflictContext.IN_GAME, 47 | Keyboard.KEY_B, 48 | "key.categories.randomtweaks" 49 | ); 50 | 51 | public static final KeyBinding TOGGLE_POTION_PARTICLES = new KeyBinding( 52 | "key.togglePotionParticles", 53 | KeyConflictContext.IN_GAME, 54 | KeyModifier.CONTROL, 55 | Keyboard.KEY_F8, 56 | "key.categories.randomtweaks" 57 | ); 58 | 59 | private static final Minecraft mc = Minecraft.getMinecraft(); 60 | 61 | private static boolean categoryEnabled; 62 | 63 | public static void registerKeyBindings() { 64 | categoryEnabled = false; 65 | 66 | register(RTConfig.Keybinds.toggleFoVChanges, TOGGLE_FOV_CHANGES); 67 | register(RTConfig.Keybinds.reloadSoundSystem, RELOAD_SOUND_SYSTEM); 68 | register( 69 | RTConfig.TimeOfDay.enabled && RTConfig.Keybinds.toggleTimeOfDayOverlay, 70 | TOGGLE_TIME_OF_DAY_OVERLAY 71 | ); 72 | register(RTConfig.Client.stepup, TOGGLE_AUTO_JUMP); 73 | register(RTConfig.Client.togglePotionParticlesKeybind, TOGGLE_POTION_PARTICLES); 74 | 75 | //Forge just isn't designed to allow keybinds to be toggled in-game 76 | if (categoryEnabled) { 77 | KeyBinding.getKeybinds().add("key.categories.randomtweaks"); 78 | } else { 79 | //If none of the keybinds are enabled, then GuiKeyBindingList.getListEntry 80 | //returns null for one of the indexes, which causes a NullPointerException 81 | KeyBinding.getKeybinds().remove("key.categories.randomtweaks"); 82 | } 83 | } 84 | 85 | @SubscribeEvent 86 | public static void onKeyInput(InputEvent.KeyInputEvent event) { 87 | if(!Keyboard.getEventKeyState()) { 88 | return; 89 | } 90 | 91 | final int key = Keyboard.getEventKey(); 92 | 93 | if(TOGGLE_FOV_CHANGES.isActiveAndMatches(key)) { 94 | if(RTConfig.Keybinds.toggleFoVChanges) { 95 | toggleFoVChanges(); 96 | } 97 | } else if(RELOAD_SOUND_SYSTEM.isActiveAndMatches(key)) { 98 | if(RTConfig.Keybinds.reloadSoundSystem) { 99 | reloadSoundSystem(); 100 | } 101 | } else if(TOGGLE_TIME_OF_DAY_OVERLAY.isActiveAndMatches(key)) { 102 | if(RTConfig.TimeOfDay.enabled && RTConfig.Keybinds.toggleTimeOfDayOverlay) { 103 | TimeOfDayOverlay.toggle(); 104 | } 105 | } else if (TOGGLE_AUTO_JUMP.isActiveAndMatches(key) && RTConfig.Client.stepup) { 106 | StepupHandler.toggle(); 107 | } else if (TOGGLE_POTION_PARTICLES.isActiveAndMatches(key) && 108 | RTConfig.Client.togglePotionParticlesKeybind) { 109 | PotionParticlesHandler.toggle(); 110 | } 111 | } 112 | 113 | public static void toggleFoVChanges() { 114 | final RTData data = RTData.get(); 115 | data.fovChanges = !data.fovChanges; 116 | RTData.save(); 117 | 118 | if(RTConfig.Keybinds.fovChangesStatusMessage) { 119 | mc.player.sendStatusMessage(new TextComponentTranslation( 120 | "toggleFoVChanges." + (data.fovChanges ? "enabled" : "disabled") 121 | ), true); 122 | } 123 | } 124 | 125 | public static void reloadSoundSystem() { 126 | if(!RTConfig.Keybinds.reloadSoundSystem || !Keyboard.getEventKeyState() || 127 | !RELOAD_SOUND_SYSTEM.isActiveAndMatches(Keyboard.getEventKey())) { 128 | return; 129 | } 130 | 131 | mc.getSoundHandler().sndManager.reloadSoundSystem(); 132 | mc.player.sendStatusMessage( 133 | new TextComponentTranslation("reloadSoundSystem.success"), true 134 | ); 135 | } 136 | 137 | private static void register(boolean flag, KeyBinding keyBinding) { 138 | final GameSettings gameSettings = mc.gameSettings; 139 | 140 | if(flag) { 141 | if(!ArrayUtils.contains(gameSettings.keyBindings, keyBinding)) { 142 | gameSettings.keyBindings = ArrayUtils.add(gameSettings.keyBindings, keyBinding); 143 | } 144 | 145 | categoryEnabled = true; 146 | } else { 147 | final int index = ArrayUtils.indexOf(gameSettings.keyBindings, keyBinding); 148 | 149 | if(index != ArrayUtils.INDEX_NOT_FOUND) { 150 | gameSettings.keyBindings = ArrayUtils.remove(gameSettings.keyBindings, index); 151 | } 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/client/MiscClientEventHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.client; 2 | 3 | import com.therandomlabs.randomtweaks.RandomTweaks; 4 | import com.therandomlabs.randomtweaks.config.RTConfig; 5 | import com.therandomlabs.randomtweaks.config.RTData; 6 | import net.minecraft.block.material.Material; 7 | import net.minecraft.client.Minecraft; 8 | import net.minecraft.client.gui.GuiMainMenu; 9 | import net.minecraft.client.gui.GuiMultiplayer; 10 | import net.minecraft.client.gui.GuiScreen; 11 | import net.minecraftforge.client.event.EntityViewRenderEvent; 12 | import net.minecraftforge.client.event.FOVUpdateEvent; 13 | import net.minecraftforge.client.event.GuiOpenEvent; 14 | import net.minecraftforge.client.event.GuiScreenEvent; 15 | import net.minecraftforge.client.event.RenderGameOverlayEvent; 16 | import net.minecraftforge.client.event.sound.PlaySoundEvent; 17 | import net.minecraftforge.fml.common.Mod; 18 | import net.minecraftforge.fml.common.eventhandler.EventPriority; 19 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 20 | import net.minecraftforge.fml.common.gameevent.TickEvent; 21 | import net.minecraftforge.fml.relauncher.Side; 22 | 23 | @Mod.EventBusSubscriber(value = Side.CLIENT, modid = RandomTweaks.MOD_ID) 24 | public final class MiscClientEventHandler { 25 | private static final Minecraft mc = Minecraft.getMinecraft(); 26 | private static boolean gameStarted; 27 | 28 | @SubscribeEvent 29 | public static void onGuiOpen(GuiOpenEvent event) { 30 | final GuiScreen gui = event.getGui(); 31 | 32 | if(!gameStarted && gui instanceof GuiMainMenu) { 33 | DingHandler.onGameStarted(); 34 | 35 | if(RTConfig.Client.startOnMultiplayerScreen) { 36 | mc.displayGuiScreen(new GuiMultiplayer(gui)); 37 | event.setCanceled(true); 38 | } 39 | 40 | gameStarted = true; 41 | } 42 | } 43 | 44 | @SubscribeEvent 45 | public static void onRenderFog(EntityViewRenderEvent.FogDensity event) { 46 | if(RTConfig.Client.clearWater && event.getState().getMaterial() == Material.WATER) { 47 | event.setDensity(0); 48 | event.setCanceled(true); 49 | } 50 | } 51 | 52 | @SubscribeEvent 53 | public static void onPotionShift(GuiScreenEvent.PotionShiftEvent event) { 54 | if(RTConfig.Client.disablePotionShift) { 55 | event.setCanceled(true); 56 | } 57 | } 58 | 59 | @SubscribeEvent(priority = EventPriority.LOWEST) 60 | public static void onSoundPlay(PlaySoundEvent event) { 61 | if(event.getName().equals("entity.wither.spawn")) { 62 | if(RTConfig.Client.disableWitherSpawnSound) { 63 | event.setResultSound(null); 64 | } 65 | 66 | return; 67 | } 68 | 69 | if(event.getName().equals("entity.enderdragon.death") && 70 | RTConfig.Client.disableEnderDragonDeathSound) { 71 | event.setResultSound(null); 72 | } 73 | } 74 | 75 | @SubscribeEvent 76 | public static void onFoVUpdate(FOVUpdateEvent event) { 77 | if(!RTData.get().fovChanges) { 78 | event.setNewfov(1.0F); 79 | } 80 | } 81 | 82 | @SubscribeEvent 83 | public static void onRenderGameOverlay(RenderGameOverlayEvent.Pre event) { 84 | if(RTConfig.Client.disablePotionIcons && 85 | event.getType() == RenderGameOverlayEvent.ElementType.POTION_ICONS) { 86 | event.setCanceled(true); 87 | } 88 | } 89 | 90 | @SubscribeEvent 91 | public static void onClientTick(TickEvent.ClientTickEvent event) { 92 | if(event.phase == TickEvent.Phase.END) { 93 | return; 94 | } 95 | 96 | AutoThirdPersonHandler.onClientTick(); 97 | ArmorEquipSoundHandler.onClientTick(); 98 | DingHandler.onClientTick(); 99 | PotionParticlesHandler.onClientTick(); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/client/NightVisionHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.client; 2 | 3 | import com.therandomlabs.randomtweaks.config.RTConfig; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.renderer.EntityRenderer; 6 | import net.minecraft.client.resources.SimpleReloadableResourceManager; 7 | import net.minecraft.entity.EntityLivingBase; 8 | import net.minecraft.init.MobEffects; 9 | import net.minecraft.util.math.MathHelper; 10 | 11 | //Taken and adapted from: 12 | //https://github.com/CoFH/NoNVFlash/blob/1.12/src/main/java/cofh/nonvflash/NoNVFlash.java 13 | public final class NightVisionHandler { 14 | private NightVisionHandler() {} 15 | 16 | public static void initialize() { 17 | final Minecraft mc = Minecraft.getMinecraft(); 18 | 19 | //Avoid conflicts. 20 | if (mc.entityRenderer.getClass() != EntityRenderer.class) { 21 | return; 22 | } 23 | 24 | final SimpleReloadableResourceManager manager = 25 | (SimpleReloadableResourceManager) mc.getResourceManager(); 26 | 27 | manager.reloadListeners.remove(mc.entityRenderer); 28 | 29 | mc.entityRenderer = new EntityRenderer(mc, mc.getResourceManager()) { 30 | @Override 31 | public float getNightVisionBrightness(EntityLivingBase entity, float partialTicks) { 32 | final int duration = 33 | entity.getActivePotionEffect(MobEffects.NIGHT_VISION).getDuration(); 34 | 35 | if(duration > 200 || !RTConfig.NightVision.fadeOut) { 36 | return RTConfig.NightVision.brightness; 37 | } 38 | 39 | if(!RTConfig.NightVision.disableFlashing) { 40 | return 0.7F + MathHelper.sin( 41 | (duration - partialTicks) * (float) Math.PI * 0.2F 42 | ) * 0.3F; 43 | } 44 | 45 | if(duration > RTConfig.NightVision.fadeOutTicks) { 46 | return RTConfig.NightVision.brightness; 47 | } 48 | 49 | return duration * RTConfig.NightVision.fadeOutRate; 50 | } 51 | }; 52 | 53 | manager.registerReloadListener(mc.entityRenderer); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/client/PotionParticlesHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.client; 2 | 3 | import java.lang.ref.WeakReference; 4 | import java.util.Collection; 5 | 6 | import com.therandomlabs.randomtweaks.config.RTConfig; 7 | import net.minecraft.client.Minecraft; 8 | import net.minecraft.entity.EntityLivingBase; 9 | import net.minecraft.potion.PotionEffect; 10 | import net.minecraft.potion.PotionUtils; 11 | 12 | public final class PotionParticlesHandler { 13 | public static final String TAG = "PotionParticlesDisabled"; 14 | 15 | public static boolean disablePotionParticles = RTConfig.Client.potionParticlesEnabledByDefault; 16 | 17 | private static final Minecraft mc = Minecraft.getMinecraft(); 18 | private static WeakReference previousEntityReference = 19 | new WeakReference<>(null); 20 | 21 | public static void toggle() { 22 | disablePotionParticles = !disablePotionParticles; 23 | } 24 | 25 | public static void onClientTick() { 26 | final EntityLivingBase entity; 27 | 28 | if (disablePotionParticles || !(mc.getRenderViewEntity() instanceof EntityLivingBase)) { 29 | entity = null; 30 | } else { 31 | entity = (EntityLivingBase) mc.getRenderViewEntity(); 32 | } 33 | 34 | final EntityLivingBase previousEntity = previousEntityReference.get(); 35 | 36 | if (previousEntity != entity) { 37 | if (previousEntity != null && previousEntity.getEntityData().getBoolean(TAG)) { 38 | //Restore potion effects. 39 | final Collection effects = previousEntity.getActivePotionEffects(); 40 | 41 | if (!effects.isEmpty()) { 42 | previousEntity.getDataManager().set( 43 | EntityLivingBase.POTION_EFFECTS, 44 | PotionUtils.getPotionColorFromEffectList(effects) 45 | ); 46 | } 47 | } 48 | 49 | previousEntityReference = new WeakReference<>(entity); 50 | } 51 | 52 | if (entity != null) { 53 | entity.getDataManager().set(EntityLivingBase.POTION_EFFECTS, 0); 54 | entity.getEntityData().setBoolean(TAG, true); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/client/StepupHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.client; 2 | 3 | import com.therandomlabs.randomtweaks.RandomTweaks; 4 | import com.therandomlabs.randomtweaks.config.RTConfig; 5 | import com.therandomlabs.randomtweaks.config.RTData; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.settings.GameSettings; 8 | import net.minecraft.potion.Potion; 9 | import net.minecraft.potion.PotionEffect; 10 | import net.minecraft.util.text.TextComponentTranslation; 11 | import net.minecraftforge.fml.common.Mod; 12 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 13 | import net.minecraftforge.fml.common.gameevent.TickEvent; 14 | import net.minecraftforge.fml.relauncher.Side; 15 | 16 | @Mod.EventBusSubscriber(value = Side.CLIENT, modid = RandomTweaks.MOD_ID) 17 | public final class StepupHandler { 18 | private enum Mode { 19 | NO_AUTO_JUMP(VANILLA_STEP_HEIGHT, false, "autoJump.disabled"), 20 | VANILLA_AUTO_JUMP(VANILLA_STEP_HEIGHT, true, "autoJump.enabled"), 21 | STEPUP_AUTO_JUMP(STEPUP_STEP_HEIGHT, false, "autoJump.enabledStepup"); 22 | 23 | final float stepHeight; 24 | final boolean enabled; 25 | final String message; 26 | 27 | Mode(float stepHeight, boolean enabled, String message) { 28 | this.stepHeight = stepHeight; 29 | this.enabled = enabled; 30 | this.message = message; 31 | } 32 | } 33 | 34 | public static final float VANILLA_STEP_HEIGHT = 0.6F; 35 | public static final float STEPUP_STEP_HEIGHT = 1.2F; 36 | 37 | private static final Minecraft mc = Minecraft.getMinecraft(); 38 | 39 | private static Potion jumpBoost; 40 | private static Mode mode; 41 | 42 | @SubscribeEvent 43 | public static void onClientTick(TickEvent.ClientTickEvent event) { 44 | if(!RTConfig.Client.stepup || mc.player == null) { 45 | return; 46 | } 47 | 48 | if(mode == null) { 49 | final RTData data = RTData.get(); 50 | if(data.stepup) { 51 | //This will be set to STEPUP_AUTO_JUMP 52 | mode = Mode.VANILLA_AUTO_JUMP; 53 | toggle(false); 54 | } else { 55 | return; 56 | } 57 | } 58 | 59 | if(mc.player.isSneaking()) { 60 | mc.player.stepHeight = VANILLA_STEP_HEIGHT; 61 | } else { 62 | mc.player.stepHeight = mode.stepHeight; 63 | 64 | if (mode == Mode.STEPUP_AUTO_JUMP && RTConfig.Client.jumpBoostAffectsStepup) { 65 | if (jumpBoost == null) { 66 | jumpBoost = Potion.getPotionFromResourceLocation("jump_boost"); 67 | } 68 | 69 | final PotionEffect effect = mc.player.getActivePotionEffect(jumpBoost); 70 | 71 | if (effect != null) { 72 | mc.player.stepHeight += (effect.getAmplifier() + 1) * 0.75F; 73 | } 74 | } 75 | } 76 | } 77 | 78 | public static void toggle() { 79 | if(mc.player != null) { 80 | toggle(true); 81 | } 82 | } 83 | 84 | public static void toggle(boolean sendStatusMessage) { 85 | final RTData data = RTData.get(); 86 | final boolean autoJump = 87 | mc.gameSettings.getOptionOrdinalValue(GameSettings.Options.AUTO_JUMP); 88 | 89 | if(mode == null) { 90 | if(data.stepup) { 91 | mode = Mode.STEPUP_AUTO_JUMP; 92 | } else { 93 | mode = autoJump ? Mode.VANILLA_AUTO_JUMP : Mode.NO_AUTO_JUMP; 94 | } 95 | } 96 | 97 | if(mode == Mode.NO_AUTO_JUMP) { 98 | mode = Mode.VANILLA_AUTO_JUMP; 99 | } else if(mode == Mode.VANILLA_AUTO_JUMP) { 100 | mode = Mode.STEPUP_AUTO_JUMP; 101 | } else { 102 | mode = Mode.NO_AUTO_JUMP; 103 | } 104 | 105 | data.stepup = mode == Mode.STEPUP_AUTO_JUMP; 106 | RTData.save(); 107 | 108 | if(autoJump) { 109 | if(!mode.enabled) { 110 | //setOptionValue toggles auto jump regardless of value 111 | mc.gameSettings.setOptionValue(GameSettings.Options.AUTO_JUMP, 0); 112 | } 113 | } else { 114 | if(mode.enabled) { 115 | //No point in setting it to 1 here - just for clarity 116 | mc.gameSettings.setOptionValue(GameSettings.Options.AUTO_JUMP, 1); 117 | } 118 | } 119 | 120 | if(sendStatusMessage) { 121 | mc.player.sendStatusMessage(new TextComponentTranslation(mode.message), true); 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/client/TimeOfDayOverlay.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.client; 2 | 3 | import java.io.File; 4 | import java.util.Map; 5 | import com.therandomlabs.randomlib.TRLUtils; 6 | import com.therandomlabs.randomtweaks.RandomTweaks; 7 | import com.therandomlabs.randomtweaks.config.RTConfig; 8 | import com.therandomlabs.randomtweaks.config.RTData; 9 | import net.minecraft.client.Minecraft; 10 | import net.minecraft.client.gui.ScaledResolution; 11 | import net.minecraft.client.multiplayer.ServerData; 12 | import net.minecraft.world.GameType; 13 | import net.minecraft.world.World; 14 | import net.minecraftforge.common.DimensionManager; 15 | import net.minecraftforge.fml.common.Mod; 16 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 17 | import net.minecraftforge.fml.common.gameevent.TickEvent; 18 | import net.minecraftforge.fml.relauncher.Side; 19 | 20 | //Some code has been taken and adapted from https://github.com/Lunatrius/InGame-Info-XML 21 | @Mod.EventBusSubscriber(value = Side.CLIENT, modid = RandomTweaks.MOD_ID) 22 | public final class TimeOfDayOverlay { 23 | private static final Minecraft mc = Minecraft.getMinecraft(); 24 | private static boolean shouldHide; 25 | 26 | @SubscribeEvent 27 | public static void onClientTick(TickEvent.ClientTickEvent event) { 28 | shouldHide = mc.gameSettings.showDebugInfo || mc.gameSettings.hideGUI; 29 | } 30 | 31 | @SubscribeEvent 32 | public static void onRenderTick(TickEvent.RenderTickEvent event) { 33 | if(shouldHide() || !isEnabledForCurrentWorld()) { 34 | return; 35 | } 36 | 37 | final World world = mc.player.getEntityWorld(); 38 | 39 | final long time = world.getWorldTime(); 40 | long hour = (time / 1000L + 6L) % 24L; 41 | final long minute = (time % 1000L) * 60L / 1000L; 42 | 43 | //Day 1, 23:00 is 17000 44 | //Day 2, 00:00 is 18000 45 | final long day = (time + 6000L) / 24000L + 1L; 46 | 47 | final String ampm; 48 | 49 | if(RTConfig.TimeOfDay.twentyFourHourTime) { 50 | ampm = ""; 51 | } else { 52 | if(hour >= 12) { 53 | if(hour != 12) { 54 | hour -= 12; 55 | } 56 | 57 | ampm = " " + TRLUtils.localize("timeOfDayOverlay.pm"); 58 | } else { 59 | //Midnight 60 | if(hour == 0) { 61 | hour = 12; 62 | } 63 | 64 | ampm = " " + TRLUtils.localize("timeOfDayOverlay.am"); 65 | } 66 | } 67 | 68 | final String hourString = hour < 10 ? "0" + hour : Long.toString(hour); 69 | final String minuteString = minute < 10 ? "0" + minute : Long.toString(minute); 70 | 71 | final String dayOrNight; 72 | 73 | if(world.calculateSkylightSubtracted(1.0F) < 4) { 74 | dayOrNight = TRLUtils.localize( 75 | "timeOfDayOverlay." + (RTConfig.TimeOfDay.lightOrDark ? "light" : "dayTime") 76 | ); 77 | } else { 78 | dayOrNight = TRLUtils.localize( 79 | "timeOfDayOverlay." + (RTConfig.TimeOfDay.lightOrDark ? "dark" : "nightTime") 80 | ); 81 | } 82 | 83 | final String timeString = TRLUtils.localize( 84 | "timeOfDayOverlay.text", day, hourString, minuteString, ampm, dayOrNight 85 | ); 86 | 87 | final int textWidth = mc.fontRenderer.getStringWidth(timeString); 88 | final int textHeight = mc.fontRenderer.FONT_HEIGHT; 89 | 90 | final int x = RTConfig.TimeOfDay.x; 91 | final int y = RTConfig.TimeOfDay.y; 92 | 93 | final ScaledResolution scaled = new ScaledResolution(mc); 94 | final int displayWidth = scaled.getScaledWidth(); 95 | final int displayHeight = scaled.getScaledHeight(); 96 | 97 | final int actualX = RTConfig.TimeOfDay.alignment.getX(x, displayWidth, textWidth); 98 | final int actualY = RTConfig.TimeOfDay.alignment.getY(y, displayHeight, textHeight); 99 | 100 | mc.fontRenderer.drawStringWithShadow(timeString, actualX, actualY, 0xFFFFFF); 101 | } 102 | 103 | public static boolean shouldHide() { 104 | if(!RTConfig.TimeOfDay.enabled || shouldHide || mc.world == null || 105 | !Minecraft.isGuiEnabled()) { 106 | return true; 107 | } 108 | 109 | if(mc.currentScreen != null && RTConfig.TimeOfDay.disableInGUIs) { 110 | return true; 111 | } 112 | 113 | if(RTConfig.TimeOfDay.disableIfNoDaylightCycle && 114 | !mc.world.getGameRules().getBoolean("doDaylightCycle")) { 115 | return true; 116 | } 117 | 118 | return RTConfig.TimeOfDay.disableInAdventureMode && 119 | mc.world.getWorldInfo().getGameType() == GameType.ADVENTURE; 120 | } 121 | 122 | public static boolean isEnabledForCurrentWorld() { 123 | final Map worlds = RTData.get().timeOfDayOverlay; 124 | final File saveDirectory = DimensionManager.getCurrentSaveRootDirectory(); 125 | 126 | if(saveDirectory != null) { 127 | final String name = saveDirectory.getName(); 128 | 129 | if(!worlds.containsKey(name)) { 130 | worlds.put(name, RTConfig.TimeOfDay.enabledByDefault); 131 | RTData.save(); 132 | } 133 | 134 | return worlds.get(name); 135 | } 136 | 137 | final ServerData serverData = mc.getCurrentServerData(); 138 | 139 | if(serverData == null) { 140 | return false; 141 | } 142 | 143 | final String ip = serverData.serverIP; 144 | 145 | if(ip == null) { 146 | return false; 147 | } 148 | 149 | if(!RTData.get().timeOfDayOverlay.containsKey(ip)) { 150 | worlds.put(ip, RTConfig.TimeOfDay.enabledByDefault); 151 | RTData.save(); 152 | } 153 | 154 | return worlds.get(ip); 155 | } 156 | 157 | public static void toggle() { 158 | if(shouldHide()) { 159 | return; 160 | } 161 | 162 | final File saveDirectory = DimensionManager.getCurrentSaveRootDirectory(); 163 | final Map worlds = RTData.get().timeOfDayOverlay; 164 | final String name = saveDirectory != null ? 165 | saveDirectory.getName() : mc.getCurrentServerData().serverIP; 166 | 167 | if(!worlds.containsKey(name)) { 168 | worlds.put(name, !RTConfig.TimeOfDay.enabledByDefault); 169 | } else { 170 | worlds.put(name, !worlds.get(name)); 171 | } 172 | 173 | RTData.save(); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/AnvilHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import com.therandomlabs.randomtweaks.RandomTweaks; 4 | import com.therandomlabs.randomtweaks.config.RTConfig; 5 | import net.minecraft.item.ItemStack; 6 | import net.minecraftforge.event.AnvilUpdateEvent; 7 | import net.minecraftforge.event.entity.player.AnvilRepairEvent; 8 | import net.minecraftforge.fml.common.Mod; 9 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 10 | 11 | @Mod.EventBusSubscriber(modid = RandomTweaks.MOD_ID) 12 | public final class AnvilHandler { 13 | @SubscribeEvent 14 | public static void onAnvilUpdate(AnvilUpdateEvent event) { 15 | if(RTConfig.Misc.disableCumulativeAnvilCosts) { 16 | removeRepairCost(event.getLeft()); 17 | removeRepairCost(event.getRight()); 18 | } 19 | } 20 | 21 | @SubscribeEvent 22 | public static void onAnvilRepair(AnvilRepairEvent event) { 23 | if(RTConfig.Misc.disableCumulativeAnvilCosts) { 24 | removeRepairCost(event.getItemResult()); 25 | } 26 | } 27 | 28 | public static void removeRepairCost(ItemStack stack) { 29 | if(!stack.isEmpty() && stack.hasTagCompound()) { 30 | stack.getTagCompound().removeTag("RepairCost"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/ArrowImpactHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import com.therandomlabs.randomtweaks.config.RTConfig; 4 | import net.minecraft.entity.monster.EntitySkeleton; 5 | import net.minecraft.entity.projectile.EntityArrow; 6 | import net.minecraft.init.Blocks; 7 | import net.minecraft.util.math.BlockPos; 8 | import net.minecraft.util.math.RayTraceResult; 9 | import net.minecraft.util.math.Vec3d; 10 | import net.minecraft.world.World; 11 | import net.minecraftforge.event.entity.ProjectileImpactEvent; 12 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 13 | 14 | public final class ArrowImpactHandler { 15 | @SubscribeEvent 16 | public static void onArrowImpact(ProjectileImpactEvent.Arrow event) { 17 | if(!RTConfig.Misc.burningArrowsSetBlocksOnFire && !RTConfig.Misc.pickUpSkeletonArrows) { 18 | return; 19 | } 20 | 21 | final EntityArrow arrow = event.getArrow(); 22 | final World world = arrow.getEntityWorld(); 23 | 24 | if(world.isRemote) { 25 | return; 26 | } 27 | 28 | if(RTConfig.Misc.pickUpSkeletonArrows && arrow.shootingEntity instanceof EntitySkeleton && 29 | arrow.pickupStatus == EntityArrow.PickupStatus.DISALLOWED) { 30 | arrow.pickupStatus = EntityArrow.PickupStatus.ALLOWED; 31 | } 32 | 33 | if(!RTConfig.Misc.burningArrowsSetBlocksOnFire || !arrow.isBurning()) { 34 | return; 35 | } 36 | 37 | final Vec3d start = arrow.getPositionVector(); 38 | final Vec3d end = start.add(arrow.motionX, arrow.motionY, arrow.motionZ); 39 | 40 | final RayTraceResult result = world.rayTraceBlocks(start, end, false, true, false); 41 | 42 | if(result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) { 43 | final BlockPos firePos = result.getBlockPos().up(); 44 | 45 | if(world.isAirBlock(firePos)) { 46 | //11 = NOTIFY_NEIGHBORS | SEND_TO_CLIENTS | RERENDER_MAIN_THREAD 47 | //Taken from ItemFlintAndSteel#onItemUse 48 | world.setBlockState(firePos, Blocks.FIRE.getDefaultState(), 11); 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/BoneMealHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import com.therandomlabs.randomtweaks.RandomTweaks; 4 | import com.therandomlabs.randomtweaks.config.RTConfig; 5 | import net.minecraft.block.Block; 6 | import net.minecraft.block.BlockCactus; 7 | import net.minecraft.block.BlockNetherWart; 8 | import net.minecraft.block.BlockReed; 9 | import net.minecraft.block.properties.PropertyInteger; 10 | import net.minecraft.block.state.IBlockState; 11 | import net.minecraft.init.Blocks; 12 | import net.minecraft.util.math.BlockPos; 13 | import net.minecraft.world.World; 14 | import net.minecraftforge.event.entity.player.BonemealEvent; 15 | import net.minecraftforge.fml.common.Mod; 16 | import net.minecraftforge.fml.common.eventhandler.Event; 17 | import net.minecraftforge.fml.common.eventhandler.Event.Result; 18 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 19 | 20 | @Mod.EventBusSubscriber(modid = RandomTweaks.MOD_ID) 21 | public final class BoneMealHandler { 22 | @SubscribeEvent 23 | public static void onBoneMeal(BonemealEvent event) { 24 | if(RandomTweaks.EXPANDED_BONEMEAL_LOADED) { 25 | return; 26 | } 27 | 28 | final World world = event.getWorld(); 29 | 30 | if(world.isRemote) { 31 | return; 32 | } 33 | 34 | final IBlockState state = event.getBlock(); 35 | final Block block = state.getBlock(); 36 | final BlockPos pos = event.getPos(); 37 | 38 | if(block == Blocks.CACTUS) { 39 | if(RTConfig.BoneMeal.cacti != 0) { 40 | grow(world, block, pos, BlockCactus.AGE, RTConfig.BoneMeal.cacti, event); 41 | } 42 | } else if(block == Blocks.REEDS) { 43 | if(RTConfig.BoneMeal.sugarCanes != 0) { 44 | grow(world, block, pos, BlockReed.AGE, RTConfig.BoneMeal.sugarCanes, event); 45 | } 46 | } else if(block == Blocks.NETHER_WART && RTConfig.BoneMeal.netherWart) { 47 | final int age = state.getValue(BlockNetherWart.AGE); 48 | 49 | if(age < 3) { 50 | world.setBlockState(pos, state.withProperty(BlockNetherWart.AGE, age + 1), 2); 51 | event.setResult(Event.Result.ALLOW); 52 | } 53 | } 54 | } 55 | 56 | public static void grow( 57 | World world, Block block, BlockPos pos, PropertyInteger ageProperty, int stages, 58 | BonemealEvent event 59 | ) { 60 | BlockPos tempPos; 61 | int i = 0; 62 | 63 | while(world.getBlockState((tempPos = pos.down())).getBlock() == block) { 64 | pos = tempPos; 65 | 66 | if(++i > 1) { 67 | return; 68 | } 69 | } 70 | 71 | i = 0; 72 | 73 | while(world.getBlockState((tempPos = pos.up())).getBlock() == block) { 74 | pos = tempPos; 75 | 76 | if(++i > 1) { 77 | return; 78 | } 79 | } 80 | 81 | IBlockState state = world.getBlockState(pos); 82 | 83 | final int originalStage = state.getValue(ageProperty); 84 | int newStage = originalStage + stages - 1; 85 | 86 | if(newStage > 15) { 87 | newStage = 15; 88 | } 89 | 90 | if(originalStage == newStage) { 91 | return; 92 | } 93 | 94 | state = state.withProperty(ageProperty, newStage); 95 | 96 | world.setBlockState(pos, state, 4); 97 | block.updateTick(world, pos, state, world.rand); 98 | 99 | event.setResult(Result.ALLOW); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/CobwebHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import java.util.Random; 4 | import com.therandomlabs.randomtweaks.RandomTweaks; 5 | import com.therandomlabs.randomtweaks.config.RTConfig; 6 | import net.minecraft.entity.player.EntityPlayer; 7 | import net.minecraft.init.Blocks; 8 | import net.minecraft.item.Item; 9 | import net.minecraft.item.ItemStack; 10 | import net.minecraft.util.EnumParticleTypes; 11 | import net.minecraft.util.SoundCategory; 12 | import net.minecraft.util.math.BlockPos; 13 | import net.minecraft.world.World; 14 | import net.minecraft.world.WorldServer; 15 | import net.minecraftforge.event.entity.player.PlayerInteractEvent; 16 | import net.minecraftforge.fml.common.Mod; 17 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 18 | import org.apache.commons.lang3.ArrayUtils; 19 | 20 | @Mod.EventBusSubscriber(modid = RandomTweaks.MOD_ID) 21 | public final class CobwebHandler { 22 | private static final Random random = new Random(); 23 | 24 | @SubscribeEvent 25 | public static void onRightClickBlock(PlayerInteractEvent.RightClickBlock event) { 26 | final World world = event.getWorld(); 27 | final ItemStack stack = event.getItemStack(); 28 | 29 | if(stack.isEmpty()) { 30 | return; 31 | } 32 | 33 | final EntityPlayer player = event.getEntityPlayer(); 34 | 35 | if(RTConfig.CobwebBurning.disableBurningIfSneaking && player.isSneaking()) { 36 | return; 37 | } 38 | 39 | final Item item = stack.getItem(); 40 | 41 | if(!ArrayUtils.contains(RTConfig.CobwebBurning.items, item)) { 42 | return; 43 | } 44 | 45 | final BlockPos pos = event.getPos(); 46 | 47 | if(world.getBlockState(pos).getBlock() != Blocks.WEB) { 48 | return; 49 | } 50 | 51 | world.setBlockToAir(pos); 52 | 53 | if(!player.capabilities.isCreativeMode) { 54 | if(stack.isItemStackDamageable()) { 55 | stack.damageItem(RTConfig.CobwebBurning.damageAmount, player); 56 | } else { 57 | stack.shrink(RTConfig.CobwebBurning.consumeAmount); 58 | } 59 | } 60 | 61 | if(RTConfig.CobwebBurning.burnSound != null) { 62 | world.playSound( 63 | player, 64 | pos, 65 | RTConfig.CobwebBurning.burnSound, 66 | SoundCategory.BLOCKS, 67 | 1.0F, 68 | random.nextFloat() * 0.4F + 0.8F 69 | ); 70 | } 71 | 72 | if(!world.isRemote) { 73 | //Values taken from 74 | //https://github.com/NerdHubMC/Realistic-Cobwebs/blob/master/src/main/java/mod/ 75 | //upcraftlp/cobwebs/Main.java 76 | ((WorldServer) world).spawnParticle( 77 | EnumParticleTypes.FLAME, 78 | pos.getX() + 0.5, 79 | pos.getY() + 0.5, 80 | pos.getZ() + 0.5, 81 | random.nextInt(40) + 7, 82 | random.nextDouble() * 0.5, 83 | random.nextDouble() * 0.5, 84 | random.nextDouble() * 0.5, 85 | 0.005 86 | ); 87 | } 88 | 89 | event.setCanceled(true); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/ColoredSheepHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import com.therandomlabs.randomtweaks.config.RTConfig; 6 | import net.minecraft.entity.passive.EntitySheep; 7 | import net.minecraft.item.EnumDyeColor; 8 | 9 | public final class ColoredSheepHandler { 10 | private static final Map queue = new HashMap<>(); 11 | 12 | public static void onSheepSpawn(EntitySheep sheep) { 13 | final double result = sheep.getRNG().nextDouble() * RTConfig.SheepColorWeights.totalWeight; 14 | double totalWeight = 0.0; 15 | 16 | for(Map.Entry weight : 17 | RTConfig.SheepColorWeights.weights.entrySet()) { 18 | totalWeight += weight.getValue(); 19 | 20 | if(totalWeight >= result) { 21 | queue.put(sheep.getEntityId(), weight.getKey()); 22 | break; 23 | } 24 | } 25 | } 26 | 27 | public static void onSheepTick(EntitySheep sheep) { 28 | final int id = sheep.getEntityId(); 29 | final EnumDyeColor color = queue.get(id); 30 | 31 | if(color != null) { 32 | sheep.setFleeceColor(color); 33 | queue.remove(id); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/EntityInteractHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import java.util.Random; 4 | import java.util.Set; 5 | 6 | import com.google.common.collect.ImmutableSet; 7 | import com.therandomlabs.randomtweaks.RandomTweaks; 8 | import com.therandomlabs.randomtweaks.config.RTConfig; 9 | import net.minecraft.entity.Entity; 10 | import net.minecraft.entity.item.EntityItem; 11 | import net.minecraft.entity.monster.EntityCreeper; 12 | import net.minecraft.entity.passive.EntityOcelot; 13 | import net.minecraft.entity.passive.EntityParrot; 14 | import net.minecraft.entity.passive.EntityTameable; 15 | import net.minecraft.entity.passive.EntityVillager; 16 | import net.minecraft.entity.player.EntityPlayer; 17 | import net.minecraft.init.Items; 18 | import net.minecraft.init.SoundEvents; 19 | import net.minecraft.item.Item; 20 | import net.minecraft.item.ItemFood; 21 | import net.minecraft.item.ItemShears; 22 | import net.minecraft.item.ItemStack; 23 | import net.minecraftforge.event.entity.player.PlayerInteractEvent; 24 | import net.minecraftforge.fml.common.Mod; 25 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 26 | 27 | @Mod.EventBusSubscriber(modid = RandomTweaks.MOD_ID) 28 | public final class EntityInteractHandler { 29 | public static final ImmutableSet OCELOT_HEAL_ITEMS = ImmutableSet.of( 30 | Items.FISH 31 | ); 32 | 33 | public static final ImmutableSet PARROT_HEAL_ITEMS = ImmutableSet.of( 34 | Items.WHEAT_SEEDS, 35 | Items.MELON_SEEDS, 36 | Items.PUMPKIN_SEEDS, 37 | Items.BEETROOT_SEEDS 38 | ); 39 | 40 | @SubscribeEvent 41 | public static void onEntityInteract(PlayerInteractEvent.EntityInteract event) { 42 | if (event.getWorld().isRemote) { 43 | return; 44 | } 45 | 46 | final ItemStack stack = event.getItemStack(); 47 | 48 | if (stack.isEmpty()) { 49 | return; 50 | } 51 | 52 | final EntityPlayer player = event.getEntityPlayer(); 53 | final Entity target = event.getTarget(); 54 | 55 | if (target instanceof EntityVillager) { 56 | onVillagerInteract(player, (EntityVillager) target, stack, event); 57 | return; 58 | } 59 | 60 | if (target instanceof EntityCreeper) { 61 | onCreeperInteract(player, (EntityCreeper) target, stack, event); 62 | return; 63 | } 64 | 65 | final Set healItems; 66 | 67 | if (target instanceof EntityOcelot) { 68 | if (!RTConfig.Animals.ocelotsCanBeHealed) { 69 | return; 70 | } 71 | 72 | healItems = OCELOT_HEAL_ITEMS; 73 | } else if (target instanceof EntityParrot) { 74 | if (!RTConfig.Animals.parrotsCanBeHealed) { 75 | return; 76 | } 77 | 78 | healItems = PARROT_HEAL_ITEMS; 79 | } else { 80 | return; 81 | } 82 | 83 | final EntityTameable tameable = (EntityTameable) target; 84 | final int healAmount = getHealAmount(tameable, stack, healItems); 85 | 86 | if(healAmount != 0) { 87 | event.setCanceled(true); 88 | 89 | if(!player.capabilities.isCreativeMode) { 90 | stack.shrink(1); 91 | } 92 | 93 | tameable.heal(healAmount); 94 | } 95 | } 96 | 97 | private static int getHealAmount(EntityTameable entity, ItemStack stack, Set healItems) { 98 | if(!entity.isTamed() || entity.getHealth() >= entity.getMaxHealth()) { 99 | return 0; 100 | } 101 | 102 | final Item item = stack.getItem(); 103 | 104 | if(!healItems.contains(item)) { 105 | return 0; 106 | } 107 | 108 | return item instanceof ItemFood ? ((ItemFood) item).getHealAmount(stack) : 1; 109 | } 110 | 111 | private static void onVillagerInteract( 112 | EntityPlayer player, EntityVillager villager, ItemStack stack, 113 | PlayerInteractEvent.EntityInteract event 114 | ) { 115 | if (!RTConfig.Animals.leashableVillagers) { 116 | return; 117 | } 118 | 119 | if (villager.getLeashed() && villager.getLeashHolder() == player) { 120 | villager.clearLeashed(true, !player.capabilities.isCreativeMode); 121 | event.setCanceled(true); 122 | return; 123 | } 124 | 125 | if (stack.getItem() != Items.LEAD) { 126 | return; 127 | } 128 | 129 | villager.setLeashHolder(player, true); 130 | 131 | if (!player.capabilities.isCreativeMode) { 132 | stack.shrink(1); 133 | } 134 | 135 | event.setCanceled(true); 136 | } 137 | 138 | private static void onCreeperInteract( 139 | EntityPlayer player, EntityCreeper creeper, ItemStack stack, 140 | PlayerInteractEvent.EntityInteract event 141 | ) { 142 | if (!RTConfig.Misc.shearableCreepers) { 143 | return; 144 | } 145 | 146 | if (creeper.getEntityData().getBoolean("Sheared")) { 147 | return; 148 | } 149 | 150 | if (!(stack.getItem() instanceof ItemShears)) { 151 | return; 152 | } 153 | 154 | creeper.playSound(SoundEvents.ENTITY_SHEEP_SHEAR, 1.0F, 1.0F); 155 | 156 | final int dropCount = 1 + creeper.getRNG().nextInt(3); 157 | final Random random = new Random(); 158 | 159 | for (int i = 0; i < dropCount; i++) { 160 | final EntityItem item = creeper.entityDropItem(new ItemStack(Items.GUNPOWDER), 1.0F); 161 | item.motionY += random.nextFloat() * 0.05F; 162 | item.motionX += (random.nextFloat() - random.nextFloat()) * 0.1F; 163 | item.motionZ += (random.nextFloat() - random.nextFloat()) * 0.1F; 164 | } 165 | 166 | creeper.getEntityData().setBoolean("Sheared", true); 167 | creeper.targetTasks.taskEntries.clear(); 168 | stack.damageItem(1, player); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/MiscEventHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.Random; 6 | import java.util.UUID; 7 | 8 | import com.therandomlabs.randomlib.EntityUtils; 9 | import com.therandomlabs.randomtweaks.RandomTweaks; 10 | import com.therandomlabs.randomtweaks.client.ArmorEquipSoundHandler; 11 | import com.therandomlabs.randomtweaks.config.RTConfig; 12 | import net.minecraft.block.Block; 13 | import net.minecraft.block.BlockCake; 14 | import net.minecraft.block.BlockSponge; 15 | import net.minecraft.block.state.IBlockState; 16 | import net.minecraft.enchantment.EnchantmentHelper; 17 | import net.minecraft.entity.Entity; 18 | import net.minecraft.entity.EntityAgeable; 19 | import net.minecraft.entity.EntityLiving; 20 | import net.minecraft.entity.EntityLivingBase; 21 | import net.minecraft.entity.IEntityOwnable; 22 | import net.minecraft.entity.SharedMonsterAttributes; 23 | import net.minecraft.entity.ai.attributes.IAttributeInstance; 24 | import net.minecraft.entity.item.EntityArmorStand; 25 | import net.minecraft.entity.monster.EntityCreeper; 26 | import net.minecraft.entity.monster.EntityZombie; 27 | import net.minecraft.entity.passive.EntityBat; 28 | import net.minecraft.entity.passive.EntitySheep; 29 | import net.minecraft.entity.player.EntityPlayer; 30 | import net.minecraft.init.Blocks; 31 | import net.minecraft.init.Enchantments; 32 | import net.minecraft.init.Items; 33 | import net.minecraft.init.SoundEvents; 34 | import net.minecraft.inventory.EntityEquipmentSlot; 35 | import net.minecraft.item.Item; 36 | import net.minecraft.item.ItemStack; 37 | import net.minecraft.util.ActionResult; 38 | import net.minecraft.util.DamageSource; 39 | import net.minecraft.util.EnumActionResult; 40 | import net.minecraft.util.EnumParticleTypes; 41 | import net.minecraft.util.SoundCategory; 42 | import net.minecraft.util.SoundEvent; 43 | import net.minecraft.util.math.BlockPos; 44 | import net.minecraft.util.math.Vec3d; 45 | import net.minecraft.world.World; 46 | import net.minecraft.world.WorldServer; 47 | import net.minecraftforge.common.BiomeDictionary; 48 | import net.minecraftforge.common.util.FakePlayerFactory; 49 | import net.minecraftforge.event.entity.EntityJoinWorldEvent; 50 | import net.minecraftforge.event.entity.living.LivingAttackEvent; 51 | import net.minecraftforge.event.entity.living.LivingDeathEvent; 52 | import net.minecraftforge.event.entity.living.LivingDropsEvent; 53 | import net.minecraftforge.event.entity.living.LivingEvent; 54 | import net.minecraftforge.event.entity.living.LivingHurtEvent; 55 | import net.minecraftforge.event.entity.living.LivingSpawnEvent; 56 | import net.minecraftforge.event.entity.player.ArrowNockEvent; 57 | import net.minecraftforge.event.entity.player.AttackEntityEvent; 58 | import net.minecraftforge.event.entity.player.PlayerInteractEvent; 59 | import net.minecraftforge.event.world.BlockEvent; 60 | import net.minecraftforge.fml.common.Mod; 61 | import net.minecraftforge.fml.common.eventhandler.Event; 62 | import net.minecraftforge.fml.common.eventhandler.EventPriority; 63 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 64 | import net.minecraftforge.fml.common.gameevent.TickEvent; 65 | import net.minecraftforge.fml.common.registry.EntityEntry; 66 | import net.minecraftforge.fml.common.registry.EntityRegistry; 67 | import org.apache.commons.lang3.ArrayUtils; 68 | 69 | @Mod.EventBusSubscriber(modid = RandomTweaks.MOD_ID) 70 | public final class MiscEventHandler { 71 | @SubscribeEvent(priority = EventPriority.HIGH) 72 | public static void onEntityJoinWorld(EntityJoinWorldEvent event) { 73 | if (event.getWorld().isRemote) { 74 | return; 75 | } 76 | 77 | final Entity entity = event.getEntity(); 78 | 79 | if (entity instanceof EntityPlayer) { 80 | onPlayerJoinWorld((EntityPlayer) entity); 81 | return; 82 | } 83 | 84 | if (entity instanceof EntityZombie) { 85 | ZombieAIHandler.onZombieJoinWorld((EntityZombie) entity); 86 | } 87 | 88 | if (RTConfig.Misc.shearableCreepers && entity instanceof EntityCreeper && 89 | entity.getEntityData().getBoolean("Sheared")) { 90 | ((EntityCreeper) entity).targetTasks.taskEntries.clear(); 91 | } 92 | } 93 | 94 | public static void onPlayerJoinWorld(EntityPlayer player) { 95 | final IAttributeInstance attackSpeed = 96 | player.getEntityAttribute(SharedMonsterAttributes.ATTACK_SPEED); 97 | attackSpeed.setBaseValue(RTConfig.Misc.attackSpeed); 98 | 99 | if (RTConfig.Hunger.enabled && !RandomTweaks.APPLECORE_LOADED) { 100 | player.foodStats = new RTFoodStats(player.foodStats); 101 | } 102 | } 103 | 104 | @SubscribeEvent(priority = EventPriority.LOWEST) 105 | public static void onCheckSpawn(LivingSpawnEvent.CheckSpawn event) { 106 | final Entity entity = event.getEntity(); 107 | 108 | if (!(entity instanceof EntityAgeable)) { 109 | return; 110 | } 111 | 112 | if (RTConfig.SheepColorWeights.enabled && !RandomTweaks.COLORFUL_SHEEP_LOADED && 113 | entity.getClass() == EntitySheep.class) { 114 | ColoredSheepHandler.onSheepSpawn((EntitySheep) entity); 115 | } 116 | 117 | if (RTConfig.RandomizedAges.chance != 0.0) { 118 | final EntityAgeable ageable = (EntityAgeable) entity; 119 | 120 | if (ageable.isChild()) { 121 | return; 122 | } 123 | 124 | final EntityEntry entry = EntityRegistry.getEntry(ageable.getClass()); 125 | final boolean found = ArrayUtils.contains(RTConfig.RandomizedAges.animals, entry); 126 | 127 | if (RTConfig.RandomizedAges.animalsWhitelist) { 128 | if (!found) { 129 | return; 130 | } 131 | } else if (found) { 132 | return; 133 | } 134 | 135 | final Random rng = ageable.getRNG(); 136 | 137 | if (rng.nextDouble() < RTConfig.RandomizedAges.chance) { 138 | final int min = RTConfig.RandomizedAges.minimumAge; 139 | final int max = RTConfig.RandomizedAges.maximumAge; 140 | 141 | if (min == max) { 142 | ageable.setGrowingAge(min); 143 | } else { 144 | ageable.setGrowingAge(rng.nextInt(max + 1 - min) + min); 145 | } 146 | } 147 | } 148 | } 149 | 150 | @SubscribeEvent 151 | public static void onLivingUpdate(LivingEvent.LivingUpdateEvent event) { 152 | final EntityLivingBase entity = event.getEntityLiving(); 153 | 154 | if (entity.getEntityWorld().isRemote) { 155 | return; 156 | } 157 | 158 | if (RTConfig.Misc.entityNaNHealthFix && !RandomTweaks.ENTITY_NAN_HEALTH_FIX_LOADED && 159 | Float.isNaN(entity.getHealth())) { 160 | entity.setHealth(0.0F); 161 | return; 162 | } 163 | 164 | if (entity.getClass() == EntitySheep.class) { 165 | ColoredSheepHandler.onSheepTick((EntitySheep) entity); 166 | } 167 | } 168 | 169 | @SubscribeEvent 170 | public static void onLivingHurt(LivingHurtEvent event) { 171 | final EntityLivingBase entity = event.getEntityLiving(); 172 | final DamageSource source = event.getSource(); 173 | final float amount = event.getAmount(); 174 | 175 | if (RTConfig.Misc.entityNaNHealthFix && !RandomTweaks.ENTITY_NAN_HEALTH_FIX_LOADED && 176 | Float.isNaN(amount)) { 177 | RandomTweaks.LOGGER.error("{} was damaged by a NaN value.", entity); 178 | RandomTweaks.LOGGER.error("Immediate source: " + source); 179 | RandomTweaks.LOGGER.error("True source: " + source.getTrueSource()); 180 | RandomTweaks.LOGGER.error( 181 | "This damage will be canceled. Please report this to the relevant mod author." 182 | ); 183 | 184 | event.setResult(Event.Result.DENY); 185 | event.setCanceled(true); 186 | return; 187 | } 188 | 189 | final String gameRule; 190 | 191 | if (source == DamageSource.DROWN) { 192 | gameRule = RTConfig.GameRules.drowningDamageMultiplier; 193 | } else if (source == DamageSource.FALL) { 194 | gameRule = RTConfig.GameRules.fallDamageMultiplier; 195 | } else if (source == DamageSource.IN_FIRE || source == DamageSource.ON_FIRE) { 196 | gameRule = RTConfig.GameRules.fireDamageMultiplier; 197 | } else { 198 | return; 199 | } 200 | 201 | if (gameRule.isEmpty()) { 202 | return; 203 | } 204 | 205 | float multiplier = 0.0F; 206 | 207 | try { 208 | multiplier = Float.parseFloat( 209 | entity.getEntityWorld().getGameRules().getString(gameRule) 210 | ); 211 | } catch (NumberFormatException ignored) {} 212 | 213 | if (multiplier == 0.0F) { 214 | event.setCanceled(true); 215 | } else if (multiplier <= 0.0F) { 216 | event.setCanceled(true); 217 | entity.setHealth(Math.max( 218 | entity.getHealth() + amount * multiplier, 219 | entity.getMaxHealth() 220 | )); 221 | } else { 222 | event.setAmount(amount * multiplier); 223 | } 224 | } 225 | 226 | @SubscribeEvent 227 | public static void onLivingAttack(LivingAttackEvent event) { 228 | final Entity attacker = event.getSource().getTrueSource(); 229 | final EntityLivingBase entity = event.getEntityLiving(); 230 | 231 | if (attacker == null || !(entity instanceof IEntityOwnable)) { 232 | return; 233 | } 234 | 235 | final IEntityOwnable pet = ((IEntityOwnable) entity); 236 | final UUID owner = pet.getOwnerId(); 237 | 238 | if (owner == null) { 239 | return; 240 | } 241 | 242 | final boolean protectFromSneaking = RTConfig.Animals.protectPetsFromSneakingOwners; 243 | 244 | if (RTConfig.Animals.protectPetsFromOwners && owner.equals(attacker.getUniqueID()) && 245 | (protectFromSneaking || (!protectFromSneaking && !attacker.isSneaking()))) { 246 | event.setCanceled(true); 247 | return; 248 | } 249 | 250 | if (RTConfig.Animals.protectPetsFromOtherPets && attacker instanceof IEntityOwnable) { 251 | final IEntityOwnable otherPet = (IEntityOwnable) attacker; 252 | 253 | if (owner.equals(otherPet.getOwnerId())) { 254 | entity.setRevengeTarget(null); 255 | ((EntityLivingBase) attacker).setRevengeTarget(null); 256 | event.setCanceled(true); 257 | } 258 | } 259 | } 260 | 261 | @SubscribeEvent 262 | public static void onLivingDeath(LivingDeathEvent event) { 263 | final EntityLivingBase entity = event.getEntityLiving(); 264 | 265 | if (RTConfig.Misc.mobsDropAllArmorAndEquipment && entity instanceof EntityLiving) { 266 | final EntityLiving living = (EntityLiving) entity; 267 | Arrays.fill(living.inventoryHandsDropChances, 1.0F); 268 | Arrays.fill(living.inventoryArmorDropChances, 1.0F); 269 | } 270 | 271 | if (!RTConfig.Misc.mobsAlwaysDropLoot) { 272 | return; 273 | } 274 | 275 | final World world = entity.getEntityWorld(); 276 | 277 | if (world.isRemote) { 278 | return; 279 | } 280 | 281 | if (entity.recentlyHit == 0) { 282 | entity.recentlyHit = 100; 283 | } 284 | 285 | if (entity.attackingPlayer == null) { 286 | entity.attackingPlayer = FakePlayerFactory.getMinecraft((WorldServer) world); 287 | } 288 | } 289 | 290 | @SubscribeEvent(priority = EventPriority.LOWEST) 291 | public static void onLivingDrops(LivingDropsEvent event) { 292 | if (RandomTweaks.VANILLATWEAKS_LOADED) { 293 | return; 294 | } 295 | 296 | final Entity entity = event.getEntity(); 297 | 298 | if (!entity.getEntityWorld().getGameRules().getBoolean("doMobLoot")) { 299 | return; 300 | } 301 | 302 | if (RTConfig.Animals.batLeatherDropChance != 0.0 && entity instanceof EntityBat && 303 | Math.random() < RTConfig.Animals.batLeatherDropChance) { 304 | entity.dropItem(Items.LEATHER, 1); 305 | } 306 | 307 | if (!RTConfig.Misc.entitiesDropNameTags) { 308 | return; 309 | } 310 | 311 | final String customName = entity.getCustomNameTag(); 312 | 313 | if (customName.isEmpty()) { 314 | return; 315 | } 316 | 317 | final ItemStack nameTag = new ItemStack(Items.NAME_TAG); 318 | nameTag.setStackDisplayName(customName); 319 | entity.entityDropItem(nameTag, 0.0F); 320 | } 321 | 322 | @SubscribeEvent 323 | public static void onPlayerAttackEntity(AttackEntityEvent event) { 324 | if (RandomTweaks.RANDOMCONFIGS_LOADED || 325 | !RTConfig.Misc.disableAttacksDuringAttackCooldown) { 326 | return; 327 | } 328 | 329 | final EntityPlayer player = event.getEntityPlayer(); 330 | 331 | if (!player.getEntityWorld().isRemote && player.getCooledAttackStrength(0.5F) != 1.0F) { 332 | player.resetCooldown(); 333 | event.setCanceled(true); 334 | } 335 | } 336 | 337 | @SubscribeEvent 338 | public static void onPlayerTick(TickEvent.PlayerTickEvent event) { 339 | if (!RTConfig.Misc.updateAllMapsInInventory) { 340 | return; 341 | } 342 | 343 | final EntityPlayer player = event.player; 344 | final World world = player.getEntityWorld(); 345 | 346 | if (world.isRemote) { 347 | return; 348 | } 349 | 350 | //Taken from https://github.com/quat1024/Crowmap/blob/master/src/main/java/quaternary/ 351 | //crowmap/Crowmap.java 352 | 353 | for (int i = 0; i < player.inventory.getSizeInventory(); i++) { 354 | if (i == player.inventory.currentItem) { 355 | //The map is already being held, so there's no need to update it again 356 | return; 357 | } 358 | 359 | final ItemStack stack = player.inventory.getStackInSlot(i); 360 | 361 | if (stack.getItem() == Items.FILLED_MAP) { 362 | Items.FILLED_MAP.updateMapData( 363 | world, player, Items.FILLED_MAP.getMapData(stack, world) 364 | ); 365 | } 366 | } 367 | } 368 | 369 | @SubscribeEvent 370 | public static void onArrowNock(ArrowNockEvent event) { 371 | if (!RTConfig.Misc.bowInfinityFix) { 372 | return; 373 | } 374 | 375 | final ItemStack bow = event.getBow(); 376 | 377 | //Taken from https://github.com/Parker8283/BowInfinityFix/blob/master/src/main/java/net/ 378 | //parker8283/bif/BowInfinityFix.java 379 | if (EnchantmentHelper.getEnchantmentLevel(Enchantments.INFINITY, bow) > 0) { 380 | event.getEntityPlayer().setActiveHand(event.getHand()); 381 | event.setAction(new ActionResult<>(EnumActionResult.SUCCESS, bow)); 382 | } 383 | } 384 | 385 | @SubscribeEvent 386 | public static void onBlockRightClick(PlayerInteractEvent.RightClickBlock event) { 387 | if (!RTConfig.Misc.cakeSoundsAndParticles || RandomTweaks.CAKE_CHOMPS_LOADED) { 388 | return; 389 | } 390 | 391 | final World world = event.getWorld(); 392 | final EntityPlayer player = event.getEntityPlayer(); 393 | final BlockPos pos = event.getPos(); 394 | final IBlockState state = world.getBlockState(pos); 395 | final Block block = state.getBlock(); 396 | 397 | if (!(block instanceof BlockCake) || !player.canEat(false)) { 398 | return; 399 | } 400 | 401 | final Random random = player.getRNG(); 402 | 403 | final ItemStack stack = block.getPickBlock(state, null, world, pos, player); 404 | final int id = Item.getIdFromItem(stack.getItem()); 405 | final int meta = stack.getMetadata(); 406 | 407 | //Taken from EntityLivingBase#updateItemUse 408 | for (int i = 0; i < 5; i++) { 409 | final Vec3d particlePos = new Vec3d( 410 | (random.nextFloat() - 0.5) * 0.3, (-random.nextFloat()) * 0.6 - 0.3, 0.6 411 | ).rotatePitch( 412 | -player.rotationPitch * 0.017453292F 413 | ).rotateYaw( 414 | -player.rotationYaw * 0.017453292F 415 | ).add( 416 | player.posX, player.posY + player.getEyeHeight() + 0.05, player.posZ 417 | ); 418 | 419 | final Vec3d particleSpeed = new Vec3d( 420 | (random.nextFloat() - 0.5) * 0.1, Math.random() * 0.1 + 0.1, 0.0 421 | ).rotatePitch( 422 | -player.rotationPitch * 0.017453292F 423 | ).rotateYaw( 424 | -player.rotationYaw * 0.017453292F 425 | ); 426 | 427 | world.spawnParticle( 428 | EnumParticleTypes.ITEM_CRACK, 429 | particlePos.x, particlePos.y, particlePos.z, 430 | particleSpeed.x, particleSpeed.y, particleSpeed.z, 431 | id, meta 432 | ); 433 | } 434 | 435 | player.playSound( 436 | SoundEvents.ENTITY_GENERIC_EAT, 437 | 0.5F + 0.5F * random.nextInt(2), 438 | (random.nextFloat() - random.nextFloat()) * 0.2F + 1.0F 439 | ); 440 | } 441 | 442 | //EntityPlaceEvent requires Forge 2817+ 443 | @SuppressWarnings("deprecation") 444 | @SubscribeEvent 445 | public static void onBlockPlaced(BlockEvent.PlaceEvent event) { 446 | if (!RTConfig.Misc.wetSpongesDryInNether) { 447 | return; 448 | } 449 | 450 | final World world = event.getWorld(); 451 | 452 | if (world.isRemote) { 453 | return; 454 | } 455 | 456 | final IBlockState state = event.getPlacedBlock(); 457 | 458 | if (state.getBlock() != Blocks.SPONGE || !state.getValue(BlockSponge.WET)) { 459 | return; 460 | } 461 | 462 | final BlockPos pos = event.getPos(); 463 | 464 | if (!BiomeDictionary.getTypes(world.getBiome(pos)).contains(BiomeDictionary.Type.NETHER)) { 465 | return; 466 | } 467 | 468 | world.setBlockState(pos, state.withProperty(BlockSponge.WET, false)); 469 | 470 | world.playSound( 471 | null, pos, SoundEvents.BLOCK_FIRE_EXTINGUISH, SoundCategory.BLOCKS, 0.3F, 472 | 2.6F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.8F 473 | ); 474 | 475 | for (int i = 0; i < 8; i++) { 476 | world.spawnParticle( 477 | EnumParticleTypes.SMOKE_NORMAL, pos.getX() + Math.random(), 478 | pos.getY() + Math.random(), pos.getZ() + Math.random(), 0.0, 0.0, 0.0 479 | ); 480 | } 481 | } 482 | 483 | @SubscribeEvent(priority = EventPriority.LOW) 484 | public static void onEntityInteractSpecific(PlayerInteractEvent.EntityInteractSpecific event) { 485 | if (!RTConfig.Misc.armorStandSwapping) { 486 | return; 487 | } 488 | 489 | final EntityPlayer player = event.getEntityPlayer(); 490 | 491 | if (player.getEntityWorld().isRemote || !player.isSneaking() || player.isSpectator()) { 492 | return; 493 | } 494 | 495 | final Entity target = event.getTarget(); 496 | 497 | if (!(target instanceof EntityArmorStand)) { 498 | return; 499 | } 500 | 501 | event.setCanceled(true); 502 | 503 | final EntityArmorStand armorStand = (EntityArmorStand) target; 504 | final List armorStandInventory = 505 | (List) armorStand.getArmorInventoryList(); 506 | 507 | for (EntityEquipmentSlot slot : EntityUtils.ARMOR_SLOTS) { 508 | final ItemStack playerStack = player.getItemStackFromSlot(slot); 509 | final ItemStack armorStandStack = armorStand.getItemStackFromSlot(slot); 510 | 511 | final int index = slot.getIndex(); 512 | 513 | player.inventory.armorInventory.set(index, armorStandStack); 514 | armorStandInventory.set(index, playerStack); 515 | 516 | final SoundEvent playerEquipSound = ArmorEquipSoundHandler.getSound(armorStandStack); 517 | final SoundEvent armorStandEquipSound = ArmorEquipSoundHandler.getSound(playerStack); 518 | 519 | if (playerEquipSound != null) { 520 | player.playSound(playerEquipSound, 1.0F, 1.0F); 521 | } 522 | 523 | if (armorStandEquipSound != null) { 524 | armorStand.playSound(armorStandEquipSound, 1.0F, 1.0F); 525 | } 526 | } 527 | } 528 | } 529 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/NetherPortalSpawnHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import com.therandomlabs.randomportals.api.event.NetherPortalEvent; 4 | import com.therandomlabs.randomtweaks.config.RTConfig; 5 | import net.minecraft.world.World; 6 | import net.minecraftforge.event.world.BlockEvent; 7 | import net.minecraftforge.fml.common.eventhandler.Event; 8 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 9 | 10 | public final class NetherPortalSpawnHandler { 11 | public static class RandomPortals { 12 | @SubscribeEvent 13 | public static void onPortalActivate(NetherPortalEvent.Activate event) { 14 | handle(event, event.getFrame().getWorld()); 15 | } 16 | } 17 | 18 | public static class Vanilla { 19 | @SubscribeEvent 20 | public static void onPortalSpawn(BlockEvent.PortalSpawnEvent event) { 21 | handle(event, event.getWorld()); 22 | } 23 | } 24 | 25 | private static void handle(Event event, World world) { 26 | final String name = RTConfig.GameRules.disableNetherPortalCreation; 27 | 28 | if(!name.isEmpty() && world.getGameRules().getBoolean(name)) { 29 | event.setCanceled(true); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/PlayerHeadDropHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import com.therandomlabs.randomtweaks.RandomTweaks; 4 | import com.therandomlabs.randomtweaks.config.RTConfig; 5 | import net.minecraft.entity.Entity; 6 | import net.minecraft.entity.monster.EntityCreeper; 7 | import net.minecraft.entity.player.EntityPlayer; 8 | import net.minecraft.init.Items; 9 | import net.minecraft.item.ItemStack; 10 | import net.minecraft.nbt.NBTTagCompound; 11 | import net.minecraft.nbt.NBTUtil; 12 | import net.minecraftforge.event.entity.player.PlayerDropsEvent; 13 | import net.minecraftforge.fml.common.Mod; 14 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 15 | 16 | @Mod.EventBusSubscriber(modid = RandomTweaks.MOD_ID) 17 | public final class PlayerHeadDropHandler { 18 | @SubscribeEvent 19 | public static void onPlayerDrops(PlayerDropsEvent event) { 20 | if(!RTConfig.PlayerHeadDrops.enabled || RandomTweaks.PLAYERS_DROP_HEADS_LOADED || 21 | RandomTweaks.HEADCRUMBS_LOADED) { 22 | return; 23 | } 24 | 25 | final EntityPlayer player = event.getEntityPlayer(); 26 | final Entity source = event.getSource().getTrueSource(); 27 | 28 | if(source instanceof EntityCreeper) { 29 | final EntityCreeper creeper = (EntityCreeper) source; 30 | 31 | if(creeper.getPowered() && creeper.ableToCauseSkullDrop() && 32 | dropSkull(player, RTConfig.PlayerHeadDrops.chanceWhenKilledByChargedCreeper)) { 33 | creeper.incrementDroppedSkulls(); 34 | return; 35 | } 36 | } 37 | 38 | if(source != player && source instanceof EntityPlayer) { 39 | dropSkull(player, RTConfig.PlayerHeadDrops.chanceWhenKilledByPlayer); 40 | return; 41 | } 42 | 43 | dropSkull(player, RTConfig.PlayerHeadDrops.normalChance); 44 | } 45 | 46 | public static boolean dropSkull(EntityPlayer player, double chance) { 47 | if(chance != 1.0 && player.getEntityWorld().rand.nextDouble() >= chance) { 48 | return false; 49 | } 50 | 51 | final ItemStack stack = new ItemStack(Items.SKULL, 1, 3); 52 | stack.setTagCompound(new NBTTagCompound()); 53 | 54 | final NBTTagCompound skullOwner = new NBTTagCompound(); 55 | NBTUtil.writeGameProfile(skullOwner, player.getGameProfile()); 56 | 57 | stack.getTagCompound().setTag("SkullOwner", skullOwner); 58 | 59 | player.dropItem(stack, true, false); 60 | 61 | return true; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/RTFoodStats.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import com.therandomlabs.randomtweaks.config.RTConfig; 4 | import net.minecraft.util.FoodStats; 5 | import net.minecraft.util.Tuple; 6 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 7 | import squeek.applecore.api.food.FoodEvent; 8 | import squeek.applecore.api.hunger.ExhaustionEvent; 9 | 10 | public class RTFoodStats extends FoodStats { 11 | public static class AppleCoreEventHandler { 12 | @SubscribeEvent 13 | public static void onFoodStatsAddition(FoodEvent.FoodStatsAddition event) { 14 | event.setCanceled(true); 15 | 16 | final FoodStats stats = event.player.getFoodStats(); 17 | final Tuple newStats = addStats( 18 | stats.foodLevel, 19 | stats.foodSaturationLevel, 20 | event.foodValuesToBeAdded.hunger, 21 | event.foodValuesToBeAdded.saturationModifier 22 | ); 23 | 24 | stats.foodLevel = newStats.getFirst(); 25 | stats.foodSaturationLevel = newStats.getSecond(); 26 | } 27 | 28 | @SubscribeEvent 29 | public static void onExhaustionAddition(ExhaustionEvent.ExhaustionAddition event) { 30 | event.deltaExhaustion *= RTConfig.Hunger.exhaustionMultiplier; 31 | } 32 | } 33 | 34 | public RTFoodStats(FoodStats stats) { 35 | foodLevel = stats.foodLevel; 36 | foodExhaustionLevel = stats.foodExhaustionLevel; 37 | foodSaturationLevel = stats.foodSaturationLevel; 38 | foodTimer = stats.foodTimer; 39 | } 40 | 41 | @Override 42 | public void addStats(int foodLevel, float foodSaturationModifier) { 43 | final Tuple stats = addStats( 44 | this.foodLevel, 45 | foodSaturationLevel, 46 | foodLevel, 47 | foodSaturationModifier 48 | ); 49 | 50 | this.foodLevel = stats.getFirst(); 51 | foodSaturationLevel = stats.getSecond(); 52 | } 53 | 54 | @Override 55 | public void addExhaustion(float exhaustion) { 56 | super.addExhaustion(exhaustion * (float) RTConfig.Hunger.exhaustionMultiplier); 57 | } 58 | 59 | public static Tuple addStats( 60 | int originalFoodLevel, float originalSaturation, int foodLevel, 61 | float foodSaturationModifier 62 | ) { 63 | int newFoodLevel = originalFoodLevel + foodLevel; 64 | float newSaturation = originalSaturation + foodLevel * foodSaturationModifier * 2.0F; 65 | 66 | if(newFoodLevel > RTConfig.Hunger.maximumHungerLevel) { 67 | if(RTConfig.Hunger.carryExcessHungerToSaturation) { 68 | newSaturation += originalFoodLevel - RTConfig.Hunger.maximumHungerLevel; 69 | } 70 | 71 | newFoodLevel = RTConfig.Hunger.maximumHungerLevel; 72 | } 73 | 74 | float maxSaturationLevel = newFoodLevel + (float) RTConfig.Hunger.saturationLimit; 75 | 76 | //In the unlikely event of overflow 77 | if(maxSaturationLevel == Float.NEGATIVE_INFINITY) { 78 | maxSaturationLevel = Float.MAX_VALUE; 79 | } 80 | 81 | newSaturation = Math.min(newSaturation, maxSaturationLevel); 82 | 83 | return new Tuple<>(newFoodLevel, newSaturation); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/RTLanguageMap.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import com.therandomlabs.randomtweaks.config.RTConfig; 4 | import com.therandomlabs.randomtweaks.util.RomanNumerals; 5 | import net.minecraft.util.text.translation.LanguageMap; 6 | 7 | public class RTLanguageMap extends LanguageMap { 8 | //Use the fully qualified class name so the compiler doesn't throw a warning at us 9 | //https://bugs.openjdk.java.net/browse/JDK-8032211 10 | @SuppressWarnings("deprecation") 11 | public static final RTLanguageMap INSTANCE = 12 | new RTLanguageMap(net.minecraft.util.text.translation.I18n.localizedName); 13 | 14 | private RTLanguageMap(LanguageMap languageMap) { 15 | this.languageList = languageMap.languageList; 16 | } 17 | 18 | @Override 19 | public synchronized String translateKey(String key) { 20 | if(languageList.get(key) != null) { 21 | return languageList.get(key); 22 | } 23 | 24 | //According to OpenEye, key can be null 25 | if(!RTConfig.Misc.moreRomanNumerals || key == null) { 26 | return key; 27 | } 28 | 29 | boolean isLevel = false; 30 | int level = 0; 31 | 32 | if(key.startsWith("enchantment.level.")) { 33 | try { 34 | level = Integer.parseInt(key.substring(18)); 35 | isLevel = true; 36 | } catch(NumberFormatException ignored) {} 37 | } else if(key.startsWith("potion.potency.")) { 38 | try { 39 | level = Integer.parseInt(key.substring(15)); 40 | isLevel = true; 41 | } catch(NumberFormatException ignored) {} 42 | } 43 | 44 | return isLevel ? RomanNumerals.get(level) : key; 45 | } 46 | 47 | @SuppressWarnings("deprecation") 48 | public static void replaceLanguageMaps() { 49 | net.minecraft.util.text.translation.I18n.localizedName = INSTANCE; 50 | LanguageMap.instance = INSTANCE; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/RespawnHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import com.therandomlabs.randomtweaks.RandomTweaks; 4 | import com.therandomlabs.randomtweaks.config.RTConfig; 5 | import net.minecraft.entity.player.EntityPlayer; 6 | import net.minecraft.util.FoodStats; 7 | import net.minecraftforge.event.entity.player.PlayerEvent; 8 | import net.minecraftforge.fml.common.Mod; 9 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 10 | 11 | @Mod.EventBusSubscriber(modid = RandomTweaks.MOD_ID) 12 | public final class RespawnHandler { 13 | public enum HungerResetBehavior { 14 | RESET("reset"), 15 | DONT_RESET("dontReset"), 16 | RESET_UNLESS_KEEP_INVENTORY("resetUnlessKeepInventory"); 17 | 18 | private final String translationKey; 19 | 20 | HungerResetBehavior(String translationKey) { 21 | this.translationKey = 22 | "randomtweaks.config.hunger.respawnResetBehavior." + translationKey; 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return translationKey; 28 | } 29 | } 30 | 31 | public enum DeathPunishmentMode { 32 | ENABLED("enabled"), 33 | ENABLED_IF_KEEP_INVENTORY("enabledIfKeepInventory"), 34 | DISABLED("disabled"); 35 | 36 | private final String translationKey; 37 | 38 | DeathPunishmentMode(String translationKey) { 39 | this.translationKey = "randomtweaks.config.misc.deathPunishmentMode." + translationKey; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | return translationKey; 45 | } 46 | } 47 | 48 | @SubscribeEvent 49 | public static void onRespawn(PlayerEvent.Clone event) { 50 | if (!event.isWasDeath()) { 51 | return; 52 | } 53 | 54 | final EntityPlayer original = event.getOriginal(); 55 | final boolean keepInventory = 56 | original.getEntityWorld().getGameRules().getBoolean("keepInventory"); 57 | 58 | if(resetHungerOnRespawn(original, keepInventory)) { 59 | return; 60 | } 61 | 62 | final EntityPlayer player = event.getEntityPlayer(); 63 | 64 | final FoodStats stats = event.getOriginal().getFoodStats(); 65 | final int oldFoodLevel = stats.getFoodLevel(); 66 | final float oldSaturationLevel = stats.getSaturationLevel(); 67 | 68 | int newFoodLevel = oldFoodLevel; 69 | 70 | final DeathPunishmentMode mode = RTConfig.Misc.deathPunishmentMode; 71 | 72 | if(!player.capabilities.isCreativeMode && 73 | ((keepInventory && mode == DeathPunishmentMode.ENABLED_IF_KEEP_INVENTORY) || 74 | mode == DeathPunishmentMode.ENABLED)) { 75 | newFoodLevel -= 3; 76 | player.experience = 0; 77 | player.experienceLevel = 0; 78 | player.experienceTotal = 0; 79 | } 80 | 81 | final int minimum = RTConfig.Hunger.minimumRespawnHungerLevel; 82 | final FoodStats newStats = player.getFoodStats(); 83 | 84 | newStats.foodLevel = Math.max(newFoodLevel, minimum); 85 | newStats.foodSaturationLevel = oldSaturationLevel; 86 | } 87 | 88 | public static boolean resetHungerOnRespawn(EntityPlayer player, boolean keepInventory) { 89 | if(player.capabilities.isCreativeMode) { 90 | return true; 91 | } 92 | 93 | final DeathPunishmentMode mode = RTConfig.Misc.deathPunishmentMode; 94 | 95 | //deathPunishmentMode overrides respawnResetBehavior 96 | if((keepInventory && mode == DeathPunishmentMode.ENABLED_IF_KEEP_INVENTORY) || 97 | mode == DeathPunishmentMode.ENABLED) { 98 | return false; 99 | } 100 | 101 | switch(RTConfig.Hunger.respawnResetBehavior) { 102 | case RESET: 103 | return true; 104 | case DONT_RESET: 105 | return false; 106 | default: 107 | return keepInventory; 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/SleepHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.List; 5 | import com.therandomlabs.randomlib.TRLUtils; 6 | import com.therandomlabs.randomtweaks.RandomTweaks; 7 | import com.therandomlabs.randomtweaks.config.RTConfig; 8 | import net.minecraft.block.BlockHorizontal; 9 | import net.minecraft.block.state.IBlockState; 10 | import net.minecraft.entity.Entity; 11 | import net.minecraft.entity.monster.EntityMob; 12 | import net.minecraft.entity.player.EntityPlayer; 13 | import net.minecraft.init.MobEffects; 14 | import net.minecraft.potion.PotionEffect; 15 | import net.minecraft.util.EnumFacing; 16 | import net.minecraft.util.ResourceLocation; 17 | import net.minecraft.util.math.AxisAlignedBB; 18 | import net.minecraft.util.math.BlockPos; 19 | import net.minecraft.world.World; 20 | import net.minecraftforge.event.entity.player.PlayerSleepInBedEvent; 21 | import net.minecraftforge.fml.common.Mod; 22 | import net.minecraftforge.fml.common.eventhandler.EventPriority; 23 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 24 | 25 | @Mod.EventBusSubscriber(modid = RandomTweaks.MOD_ID) 26 | public final class SleepHandler { 27 | public static final Method SET_SIZE = TRLUtils.findMethod( 28 | Entity.class, "setSize", "func_70105_a", float.class, float.class 29 | ); 30 | 31 | @SubscribeEvent(priority = EventPriority.LOWEST) 32 | public static void onSleep(PlayerSleepInBedEvent event) { 33 | if(!RTConfig.Sleep.allowSleepNearMobsWithCustomNames && 34 | !RTConfig.Sleep.disableBedProximityRequirement && 35 | RTConfig.Sleep.nearbyMonsterGlowDuration == 0) { 36 | return; 37 | } 38 | 39 | final EntityPlayer.SleepResult result = event.getResultStatus(); 40 | 41 | if(result == EntityPlayer.SleepResult.OTHER_PROBLEM || 42 | result == EntityPlayer.SleepResult.OK) { 43 | return; 44 | } 45 | 46 | final EntityPlayer player = event.getEntityPlayer(); 47 | final World world = player.getEntityWorld(); 48 | 49 | //RandomTweaks does not modify client-sided sleeping behavior 50 | if(world.isRemote) { 51 | return; 52 | } 53 | 54 | final BlockPos pos = event.getPos(); 55 | 56 | IBlockState state; 57 | EnumFacing facing = null; 58 | 59 | try { 60 | state = world.isBlockLoaded(pos) ? world.getBlockState(pos) : null; 61 | 62 | if(state != null) { 63 | final ResourceLocation name = state.getBlock().getRegistryName(); 64 | 65 | if(name != null && name.toString().startsWith("comforts:hammock")) { 66 | return; 67 | } 68 | 69 | facing = state.getValue(BlockHorizontal.FACING); 70 | } 71 | } catch(IllegalArgumentException ex) { 72 | state = null; 73 | facing = null; 74 | } 75 | 76 | if(player.isPlayerSleeping() || !player.isEntityAlive()) { 77 | event.setResult(EntityPlayer.SleepResult.OTHER_PROBLEM); 78 | return; 79 | } 80 | 81 | if(!world.provider.isSurfaceWorld()) { 82 | event.setResult(EntityPlayer.SleepResult.NOT_POSSIBLE_HERE); 83 | return; 84 | } 85 | 86 | if(world.isDaytime()) { 87 | event.setResult(EntityPlayer.SleepResult.NOT_POSSIBLE_NOW); 88 | return; 89 | } 90 | 91 | if(!RTConfig.Sleep.disableBedProximityRequirement && !player.bedInRange(pos, facing)) { 92 | event.setResult(EntityPlayer.SleepResult.TOO_FAR_AWAY); 93 | return; 94 | } 95 | 96 | final List mobsInRange = getMobsInRange(player, world, pos); 97 | 98 | if(!mobsInRange.isEmpty()) { 99 | if(RTConfig.Sleep.nearbyMonsterGlowDuration != 0) { 100 | for(EntityMob mob : mobsInRange) { 101 | mob.addPotionEffect(new PotionEffect( 102 | MobEffects.GLOWING, RTConfig.Sleep.nearbyMonsterGlowDuration, 103 | 0, false, RTConfig.Sleep.nearbyMonsterGlowParticles 104 | )); 105 | } 106 | } 107 | 108 | event.setResult(EntityPlayer.SleepResult.NOT_SAFE); 109 | return; 110 | } 111 | 112 | player.spawnShoulderEntities(); 113 | 114 | if(player.isRiding()) { 115 | player.dismountRidingEntity(); 116 | } 117 | 118 | try { 119 | SET_SIZE.invoke(player, 0.2F, 0.2F); 120 | } catch(Exception ex) { 121 | RandomTweaks.LOGGER.error("Error while setting player size", ex); 122 | } 123 | 124 | if(state != null && state.getBlock().isBed(state, world, pos, player)) { 125 | player.setRenderOffsetForSleep(facing); 126 | 127 | final float x = 0.5F + facing.getXOffset() * 0.4F; 128 | final float z = 0.5F + facing.getZOffset() * 0.4F; 129 | 130 | player.setPosition( 131 | event.getPos().getX() + x, 132 | event.getPos().getY() + 0.6875F, 133 | event.getPos().getZ() + z 134 | ); 135 | } else { 136 | player.setPosition( 137 | event.getPos().getX() + 0.5F, 138 | event.getPos().getY() + 0.6875F, 139 | event.getPos().getZ() + 0.5F 140 | ); 141 | } 142 | 143 | player.sleeping = true; 144 | player.sleepTimer = 0; 145 | player.bedLocation = event.getPos(); 146 | player.motionX = 0.0; 147 | player.motionY = 0.0; 148 | player.motionZ = 0.0; 149 | 150 | world.updateAllPlayersSleepingFlag(); 151 | 152 | event.setResult(EntityPlayer.SleepResult.OK); 153 | } 154 | 155 | public static List getMobsInRange(EntityPlayer player, World world, BlockPos pos) { 156 | return world.getEntitiesWithinAABB( 157 | EntityMob.class, 158 | new AxisAlignedBB( 159 | pos.getX(), pos.getY(), pos.getZ(), pos.getX(), pos.getY(), pos.getZ() 160 | ).grow(8.0, 5.0, 8.0), 161 | mob -> mob.isPreventingPlayerRest(player) && 162 | (!RTConfig.Sleep.allowSleepNearMobsWithCustomNames || !mob.hasCustomName()) 163 | ); 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/SquidHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import com.therandomlabs.randomtweaks.RandomTweaks; 4 | import com.therandomlabs.randomtweaks.config.RTConfig; 5 | import net.minecraft.entity.Entity; 6 | import net.minecraft.entity.passive.EntitySquid; 7 | import net.minecraft.entity.player.EntityPlayer; 8 | import net.minecraft.util.math.AxisAlignedBB; 9 | import net.minecraft.world.World; 10 | import net.minecraft.world.chunk.Chunk; 11 | import net.minecraftforge.event.entity.living.LivingPackSizeEvent; 12 | import net.minecraftforge.event.entity.living.LivingSpawnEvent; 13 | import net.minecraftforge.fml.common.Mod; 14 | import net.minecraftforge.fml.common.eventhandler.Event; 15 | import net.minecraftforge.fml.common.eventhandler.EventPriority; 16 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 17 | 18 | @Mod.EventBusSubscriber(modid = RandomTweaks.MOD_ID) 19 | public final class SquidHandler { 20 | public static final int RADIUS_LIMIT_DISABLED = 0; 21 | public static final int CHUNK_LIMIT_DISABLED = -1; 22 | public static final int SQUID_SPAWNING_DISABLED = 0; 23 | public static final int VANILLA_PACK_SIZE = 0; 24 | 25 | @SubscribeEvent(priority = EventPriority.HIGHEST) 26 | public static void onLivingEntityPackSpawn(LivingPackSizeEvent event) { 27 | final Entity entity = event.getEntity(); 28 | 29 | if(entity.getClass() == EntitySquid.class && 30 | RTConfig.Squids.maxPackSize != VANILLA_PACK_SIZE) { 31 | event.setMaxPackSize(RTConfig.Squids.maxPackSize); 32 | } 33 | } 34 | 35 | @SubscribeEvent 36 | public static void onCheckSpawn(LivingSpawnEvent.CheckSpawn event) { 37 | if(event.getEntity().getClass() == EntitySquid.class && 38 | (!isInRadiusOfPlayer(event) || tooManySquids(event))) { 39 | event.setResult(Event.Result.DENY); 40 | } 41 | } 42 | 43 | public static boolean isInRadiusOfPlayer(LivingSpawnEvent.CheckSpawn event) { 44 | final int radius = RTConfig.Squids.spawnRadiusLimit; 45 | 46 | if(radius == RADIUS_LIMIT_DISABLED) { 47 | return true; 48 | } 49 | 50 | final float x = event.getX(); 51 | final float y = event.getY(); 52 | final float z = event.getZ(); 53 | 54 | final AxisAlignedBB aabb = 55 | new AxisAlignedBB(x, y, z, x, y, z).expand(radius, radius, radius); 56 | 57 | for(EntityPlayer player : event.getWorld().playerEntities) { 58 | if(player.getEntityBoundingBox().intersects(aabb)) { 59 | return true; 60 | } 61 | } 62 | 63 | return false; 64 | } 65 | 66 | public static boolean tooManySquids(LivingSpawnEvent.CheckSpawn event) { 67 | if(RTConfig.Squids.chunkLimit == SQUID_SPAWNING_DISABLED) { 68 | return true; 69 | } 70 | 71 | if(RTConfig.Squids.chunkLimit == CHUNK_LIMIT_DISABLED) { 72 | return false; 73 | } 74 | 75 | final World world = event.getWorld(); 76 | final Chunk chunk = world.getChunk(event.getEntity().getPosition()); 77 | 78 | int squids = 0; 79 | 80 | //Apparently a ConcurrentModificationException can occur here #38 81 | //so we iterate using i instead 82 | for(int i = 0; i < world.loadedEntityList.size(); i++) { 83 | final Entity entity = world.loadedEntityList.get(i); 84 | 85 | if(entity.getClass() != EntitySquid.class || 86 | entity.chunkCoordX != chunk.x || entity.chunkCoordZ != chunk.z) { 87 | continue; 88 | } 89 | 90 | if(++squids >= RTConfig.Squids.chunkLimit) { 91 | return true; 92 | } 93 | } 94 | 95 | return false; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/TorchHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import java.util.function.Predicate; 4 | import com.therandomlabs.randomtweaks.RandomTweaks; 5 | import com.therandomlabs.randomtweaks.config.RTConfig; 6 | import net.minecraft.block.Block; 7 | import net.minecraft.block.BlockTorch; 8 | import net.minecraft.block.state.BlockFaceShape; 9 | import net.minecraft.block.state.IBlockState; 10 | import net.minecraft.entity.player.EntityPlayer; 11 | import net.minecraft.util.EnumFacing; 12 | import net.minecraft.util.math.BlockPos; 13 | import net.minecraft.world.World; 14 | import net.minecraftforge.event.world.BlockEvent; 15 | import net.minecraftforge.fml.common.Mod; 16 | import net.minecraftforge.fml.common.eventhandler.EventPriority; 17 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 18 | 19 | @Mod.EventBusSubscriber(modid = RandomTweaks.MOD_ID) 20 | public final class TorchHandler { 21 | public enum Behavior { 22 | NEVER("never", player -> false), 23 | SNEAKING("sneaking", EntityPlayer::isSneaking), 24 | NOT_SNEAKING("notSneaking", player -> !player.isSneaking()), 25 | ALWAYS("always", player -> true); 26 | 27 | private final String translationKey; 28 | private final Predicate predicate; 29 | 30 | Behavior(String translationKey, Predicate predicate) { 31 | this.translationKey = translationKey; 32 | this.predicate = predicate; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return "randomtweaks.config.misc.torchReorientationBehavior." + translationKey; 38 | } 39 | 40 | public boolean test(EntityPlayer player) { 41 | return predicate.test(player); 42 | } 43 | } 44 | 45 | public enum Orientation { 46 | NORTH(EnumFacing.NORTH), 47 | SOUTH(EnumFacing.SOUTH), 48 | EAST(EnumFacing.EAST), 49 | WEST(EnumFacing.WEST), 50 | UP(EnumFacing.UP); 51 | 52 | private final EnumFacing facing; 53 | 54 | Orientation(EnumFacing facing) { 55 | this.facing = facing; 56 | } 57 | 58 | public EnumFacing get() { 59 | return facing; 60 | } 61 | } 62 | 63 | private static EnumFacing[] TORCH_ORIENTATIONS = 64 | BlockTorch.FACING.getAllowedValues().toArray(new EnumFacing[0]); 65 | 66 | @SubscribeEvent(priority = EventPriority.LOWEST) 67 | public static void onBlockBreak(BlockEvent.BreakEvent event) { 68 | if(!RTConfig.Misc.torchReorientationBehavior.test(event.getPlayer())) { 69 | return; 70 | } 71 | 72 | final World world = event.getWorld(); 73 | final BlockPos pos = event.getPos(); 74 | 75 | for(EnumFacing neighboringSide : TORCH_ORIENTATIONS) { 76 | final BlockPos torchPos = pos.offset(neighboringSide); 77 | final IBlockState torchState = world.getBlockState(torchPos); 78 | final Block block = torchState.getBlock(); 79 | 80 | if(!(block instanceof BlockTorch) || 81 | canPlaceAt(world, pos, torchPos, torchState.getValue(BlockTorch.FACING))) { 82 | continue; 83 | } 84 | 85 | for(EnumFacing orientation : RTConfig.Misc.torchOrientations) { 86 | if(canPlaceAt(world, pos, torchPos, orientation)) { 87 | world.setBlockState( 88 | torchPos, torchState.withProperty(BlockTorch.FACING, orientation) 89 | ); 90 | break; 91 | } 92 | } 93 | } 94 | } 95 | 96 | //Taken and adapted from BlockTorch#canPlaceAt 97 | public static boolean canPlaceAt( 98 | World world, BlockPos brokenPos, BlockPos torchPos, EnumFacing orientation 99 | ) { 100 | final BlockPos attachPos = torchPos.offset(orientation.getOpposite()); 101 | 102 | if(brokenPos.equals(attachPos)) { 103 | return false; 104 | } 105 | 106 | final IBlockState attachState = world.getBlockState(attachPos); 107 | final Block attachBlock = attachState.getBlock(); 108 | final BlockFaceShape attachBlockShape = 109 | attachState.getBlockFaceShape(world, attachPos, orientation); 110 | 111 | //orientation will never be EnumFacing.DOWN so we don't bother checking for it 112 | 113 | if(orientation == EnumFacing.UP) { 114 | return attachBlock.canPlaceTorchOnTop(attachState, world, torchPos); 115 | } 116 | 117 | return !Block.isExceptBlockForAttachWithPiston(attachBlock) && 118 | attachBlockShape == BlockFaceShape.SOLID; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/TrampleHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import com.therandomlabs.randomtweaks.config.RTConfig; 4 | import net.minecraft.block.BlockFarmland; 5 | import net.minecraft.block.state.IBlockState; 6 | import net.minecraft.enchantment.EnchantmentHelper; 7 | import net.minecraft.init.Enchantments; 8 | import net.minecraft.inventory.EntityEquipmentSlot; 9 | import net.minecraft.item.Item; 10 | import net.minecraft.item.ItemArmor; 11 | import net.minecraft.item.ItemStack; 12 | import net.minecraftforge.event.world.BlockEvent; 13 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 14 | 15 | public final class TrampleHandler { 16 | public enum Behavior { 17 | VANILLA("vanilla"), 18 | DONT_TRAMPLE_IF_FEATHER_FALLING("dontTrampleIfFeatherFalling"), 19 | DONT_TRAMPLE_IF_FEATHER_FALLING_OR_WET("dontTrampleIfFeatherFallingOrWet"), 20 | DONT_TRAMPLE_IF_WET("dontTrampleIfWet"), 21 | DONT_TRAMPLE("dontTrample"); 22 | 23 | private final String translationKey; 24 | 25 | Behavior(String translationKey) { 26 | this.translationKey = 27 | "randomtweaks.config.misc.farmlandTrampleBehavior." + translationKey; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return translationKey; 33 | } 34 | } 35 | 36 | @SubscribeEvent 37 | public static void onFarmlandTrample(BlockEvent.FarmlandTrampleEvent event) { 38 | if (RTConfig.Misc.farmlandTrampleBehavior == Behavior.VANILLA) { 39 | return; 40 | } 41 | 42 | if (RTConfig.Misc.farmlandTrampleBehavior == Behavior.DONT_TRAMPLE) { 43 | event.setCanceled(true); 44 | return; 45 | } 46 | 47 | if (RTConfig.Misc.farmlandTrampleBehavior == Behavior.DONT_TRAMPLE_IF_WET || 48 | RTConfig.Misc.farmlandTrampleBehavior == 49 | Behavior.DONT_TRAMPLE_IF_FEATHER_FALLING_OR_WET) { 50 | final IBlockState state = event.getWorld().getBlockState(event.getPos()); 51 | 52 | if (state.getBlock() instanceof BlockFarmland && 53 | state.getValue(BlockFarmland.MOISTURE) == 7) { 54 | event.setCanceled(true); 55 | return; 56 | } else if (RTConfig.Misc.farmlandTrampleBehavior == Behavior.DONT_TRAMPLE_IF_WET) { 57 | return; 58 | } 59 | } 60 | 61 | final Iterable armor = event.getEntity().getArmorInventoryList(); 62 | 63 | for (ItemStack stack : armor) { 64 | final Item item = stack.getItem(); 65 | 66 | if (!(item instanceof ItemArmor && 67 | ((ItemArmor) item).armorType == EntityEquipmentSlot.FEET)) { 68 | continue; 69 | } 70 | 71 | if(EnchantmentHelper.getEnchantmentLevel(Enchantments.FEATHER_FALLING, stack) > 0) { 72 | event.setCanceled(true); 73 | break; 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/ZombieAIHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | import com.therandomlabs.randomtweaks.RandomTweaks; 7 | import com.therandomlabs.randomtweaks.config.RTConfig; 8 | import net.minecraft.entity.EntityLivingBase; 9 | import net.minecraft.entity.ai.EntityAITasks; 10 | import net.minecraft.entity.ai.EntityAIZombieAttack; 11 | import net.minecraft.entity.monster.EntityZombie; 12 | 13 | public final class ZombieAIHandler { 14 | public static final class RTEntityAIZombieAttack extends EntityAIZombieAttack { 15 | public RTEntityAIZombieAttack(EntityZombie zombie, double speed, boolean longMemory) { 16 | super(zombie, speed, longMemory); 17 | } 18 | 19 | @Override 20 | public boolean shouldExecute() { 21 | final EntityLivingBase target = attacker.getAttackTarget(); 22 | 23 | if(target == null || !target.isEntityAlive() || 24 | target.dimension != attacker.dimension) { 25 | return false; 26 | } 27 | 28 | if(--delayCounter <= 0) { 29 | path = attacker.getNavigator().getPathToEntityLiving(target); 30 | 31 | if(path != null) { 32 | return true; 33 | } 34 | 35 | delayCounter = Math.min(30, (int) Math.max( 36 | attacker.getDistanceSq( 37 | target.posX, target.getEntityBoundingBox().minY, target.posZ 38 | ), 39 | 10.0 40 | )); 41 | } 42 | 43 | return false; 44 | } 45 | } 46 | 47 | public static void onZombieJoinWorld(EntityZombie zombie) { 48 | if(!RTConfig.Misc.zombieTargetDetectionImprovements || 49 | RandomTweaks.CALM_DOWN_ZOMBIE_GUY_LOADED) { 50 | return; 51 | } 52 | 53 | final List overrides = new ArrayList<>(); 54 | final Iterator it = zombie.tasks.taskEntries.iterator(); 55 | 56 | while(it.hasNext()) { 57 | final EntityAITasks.EntityAITaskEntry entry = it.next(); 58 | 59 | if(entry.action instanceof EntityAIZombieAttack && 60 | !(entry.action instanceof RTEntityAIZombieAttack)) { 61 | final EntityAIZombieAttack action = (EntityAIZombieAttack) entry.action; 62 | 63 | overrides.add(zombie.tasks.new EntityAITaskEntry( 64 | entry.priority, 65 | new RTEntityAIZombieAttack( 66 | zombie, action.speedTowardsTarget, action.longMemory 67 | ) 68 | )); 69 | 70 | it.remove(); 71 | } 72 | } 73 | 74 | zombie.tasks.taskEntries.addAll(overrides); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/command/CommandDeleteGamerule.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common.command; 2 | 3 | import java.util.List; 4 | import net.minecraft.command.CommandBase; 5 | import net.minecraft.command.CommandException; 6 | import net.minecraft.command.ICommandSender; 7 | import net.minecraft.command.WrongUsageException; 8 | import net.minecraft.server.MinecraftServer; 9 | import net.minecraft.util.math.BlockPos; 10 | import net.minecraft.util.text.TextFormatting; 11 | 12 | public class CommandDeleteGamerule extends CommandBase { 13 | @Override 14 | public String getName() { 15 | return "deletegamerule"; 16 | } 17 | 18 | @Override 19 | public String getUsage(ICommandSender sender) { 20 | return "/deletegamerule "; 21 | } 22 | 23 | @Override 24 | public void execute(MinecraftServer server, ICommandSender sender, String[] args) 25 | throws CommandException { 26 | if(args.length == 0) { 27 | throw new WrongUsageException(getUsage(sender)); 28 | } 29 | 30 | final boolean success = 31 | sender.getEntityWorld().getGameRules().rules.remove(args[0]) != null; 32 | 33 | if(success) { 34 | notifyCommandListener(sender, this, "Gamerule \"%s\" successfully deleted!", args[0]); 35 | } else { 36 | notifyCommandListener( 37 | sender, this, TextFormatting.RED + "No such gamerule exists: %s" + args[0] 38 | ); 39 | } 40 | } 41 | 42 | @Override 43 | public List getTabCompletions( 44 | MinecraftServer server, ICommandSender sender, String[] args, BlockPos targetPos 45 | ) { 46 | return getListOfStringsMatchingLastWord( 47 | args, sender.getEntityWorld().getGameRules().getRules() 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/command/CommandDisconnect.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common.command; 2 | 3 | import com.therandomlabs.randomlib.TRLUtils; 4 | import com.therandomlabs.randompatches.config.RPConfig; 5 | import com.therandomlabs.randomtweaks.RandomTweaks; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.gui.GuiMainMenu; 8 | import net.minecraft.client.gui.GuiMultiplayer; 9 | import net.minecraft.command.CommandBase; 10 | import net.minecraft.command.CommandException; 11 | import net.minecraft.command.ICommandSender; 12 | import net.minecraft.realms.RealmsBridge; 13 | import net.minecraft.server.MinecraftServer; 14 | 15 | public class CommandDisconnect extends CommandBase { 16 | private static final Minecraft mc = Minecraft.getMinecraft(); 17 | 18 | @Override 19 | public String getName() { 20 | return "disconnect"; 21 | } 22 | 23 | @Override 24 | public String getUsage(ICommandSender sender) { 25 | return "commands.disconnect.usage"; 26 | } 27 | 28 | @Override 29 | public void execute(MinecraftServer server, ICommandSender sender, String[] args) 30 | throws CommandException { 31 | final boolean forceTitleScreenOnDisconnect; 32 | 33 | if(RandomTweaks.RANDOMPATCHES_LOADED) { 34 | try { 35 | forceTitleScreenOnDisconnect = RPConfig.Client.forceTitleScreenOnDisconnect; 36 | } catch(Throwable t) { 37 | RandomTweaks.LOGGER.error("Failed to disconnect", t); 38 | throw new CommandException(TRLUtils.localize( 39 | "commands.disconnect.failure", 40 | t.getClass().getName() + ": " + t.getMessage() 41 | )); 42 | } 43 | } else { 44 | forceTitleScreenOnDisconnect = false; 45 | } 46 | 47 | mc.world.sendQuittingDisconnectingPacket(); 48 | mc.loadWorld(null); 49 | 50 | if(forceTitleScreenOnDisconnect || mc.isIntegratedServerRunning()) { 51 | mc.displayGuiScreen(new GuiMainMenu()); 52 | } else if(mc.isConnectedToRealms()) { 53 | new RealmsBridge().switchToRealms(new GuiMainMenu()); 54 | } else { 55 | mc.displayGuiScreen(new GuiMultiplayer(new GuiMainMenu())); 56 | } 57 | } 58 | 59 | @Override 60 | public int getRequiredPermissionLevel() { 61 | return 0; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/command/CommandHunger.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common.command; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | import net.minecraft.command.CommandBase; 6 | import net.minecraft.command.CommandException; 7 | import net.minecraft.command.ICommandSender; 8 | import net.minecraft.command.WrongUsageException; 9 | import net.minecraft.entity.player.EntityPlayer; 10 | import net.minecraft.server.MinecraftServer; 11 | import net.minecraft.util.FoodStats; 12 | import net.minecraft.util.math.BlockPos; 13 | 14 | public class CommandHunger extends CommandBase { 15 | @Override 16 | public String getName() { 17 | return "hunger"; 18 | } 19 | 20 | @Override 21 | public String getUsage(ICommandSender sender) { 22 | return "/hunger [saturation]"; 23 | } 24 | 25 | @Override 26 | public void execute(MinecraftServer server, ICommandSender sender, String[] args) 27 | throws CommandException { 28 | if(args.length < 2) { 29 | throw new WrongUsageException(getUsage(sender)); 30 | } 31 | 32 | final EntityPlayer player = getPlayer(server, sender, args[0]); 33 | final FoodStats stats = player.getFoodStats(); 34 | 35 | stats.foodLevel = parseInt(args[1]); 36 | 37 | if(args.length > 2) { 38 | stats.foodSaturationLevel = (float) parseDouble(args[2]); 39 | } 40 | 41 | notifyCommandListener( 42 | sender, this, "%s's hunger level is %s and saturation level is %s", 43 | player.getDisplayNameString(), stats.foodLevel, stats.foodSaturationLevel 44 | ); 45 | } 46 | 47 | @Override 48 | public List getTabCompletions( 49 | MinecraftServer server, ICommandSender sender, String[] args, BlockPos targetPos 50 | ) { 51 | return args.length == 1 ? 52 | getListOfStringsMatchingLastWord(args, server.getOnlinePlayerNames()) : 53 | Collections.emptyList(); 54 | } 55 | 56 | @Override 57 | public boolean isUsernameIndex(String[] args, int index) { 58 | return index == 0; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/command/CommandRTGive.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common.command; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.Random; 6 | import com.therandomlabs.randomtweaks.RandomTweaks; 7 | import net.minecraft.command.CommandException; 8 | import net.minecraft.command.CommandGive; 9 | import net.minecraft.command.CommandResultStats; 10 | import net.minecraft.command.ICommandSender; 11 | import net.minecraft.command.NumberInvalidException; 12 | import net.minecraft.command.WrongUsageException; 13 | import net.minecraft.entity.item.EntityItem; 14 | import net.minecraft.entity.player.EntityPlayer; 15 | import net.minecraft.init.SoundEvents; 16 | import net.minecraft.item.Item; 17 | import net.minecraft.item.ItemStack; 18 | import net.minecraft.nbt.JsonToNBT; 19 | import net.minecraft.nbt.NBTException; 20 | import net.minecraft.server.MinecraftServer; 21 | import net.minecraft.util.SoundCategory; 22 | import net.minecraft.util.math.BlockPos; 23 | import net.minecraftforge.oredict.OreDictionary; 24 | 25 | public class CommandRTGive extends CommandGive { 26 | @Override 27 | public void execute(MinecraftServer server, ICommandSender sender, String[] args) 28 | throws CommandException { 29 | if(args.length < 2) { 30 | throw new WrongUsageException(getUsage(sender)); 31 | } 32 | 33 | final EntityPlayer player = getPlayer(server, sender, args[0]); 34 | 35 | Item item = null; 36 | int meta = args.length > 3 ? parseInt(args[3]) : 0; 37 | 38 | try { 39 | item = getItemByText(sender, args[1]); 40 | } catch(NumberInvalidException ex) { 41 | if(args[1].startsWith("ore:")) { 42 | final List ores = OreDictionary.getOres(args[1].substring(4)); 43 | 44 | if(!ores.isEmpty()) { 45 | final ItemStack ore = ores.get(0); 46 | 47 | item = ore.getItem(); 48 | meta = ore.getItemDamage(); 49 | } 50 | } else { 51 | try { 52 | item = Item.getItemById(parseInt(args[1], 1)); 53 | } catch(NumberInvalidException ignored) {} 54 | } 55 | } 56 | 57 | if(item == null) { 58 | throw new NumberInvalidException("commands.give.item.notFound", args[1]); 59 | } 60 | 61 | final int amount = args.length > 2 ? parseInt(args[2], 1) : 1; 62 | 63 | final ItemStack stack = new ItemStack(item, amount, meta); 64 | 65 | if(args.length > 4) { 66 | final String tag = buildString(args, 4); 67 | 68 | try { 69 | stack.setTagCompound(JsonToNBT.getTagFromJson(tag)); 70 | } catch(NBTException ex) { 71 | RandomTweaks.LOGGER.error("Failed to parse data tag", ex); 72 | throw new CommandException("commands.give.tagError", ex.getMessage()); 73 | } 74 | } 75 | 76 | final boolean added = player.inventory.addItemStackToInventory(stack); 77 | 78 | if(added) { 79 | final Random rng = player.getRNG(); 80 | final float random1 = rng.nextFloat(); 81 | final float random2 = rng.nextFloat(); 82 | 83 | player.getEntityWorld().playSound( 84 | null, player.posX, player.posY, player.posZ, SoundEvents.ENTITY_ITEM_PICKUP, 85 | SoundCategory.PLAYERS, 0.2F, ((random1 - random2) * 0.7F + 1.0F) * 2.0F 86 | ); 87 | 88 | player.inventoryContainer.detectAndSendChanges(); 89 | 90 | if(stack.isEmpty()) { 91 | stack.setCount(1); 92 | sender.setCommandStat(CommandResultStats.Type.AFFECTED_ITEMS, amount); 93 | 94 | final EntityItem droppedItem = player.dropItem(stack, false); 95 | 96 | if(droppedItem != null) { 97 | droppedItem.makeFakeItem(); 98 | } 99 | } else { 100 | sender.setCommandStat( 101 | CommandResultStats.Type.AFFECTED_ITEMS, 102 | amount - stack.getCount() 103 | ); 104 | 105 | final EntityItem droppedItem = player.dropItem(stack, false); 106 | 107 | if(droppedItem != null) { 108 | droppedItem.setNoPickupDelay(); 109 | droppedItem.setOwner(player.getName()); 110 | } 111 | } 112 | 113 | notifyCommandListener( 114 | sender, this, "commands.give.success", 115 | stack.getTextComponent(), amount, player.getName() 116 | ); 117 | } 118 | } 119 | 120 | @Override 121 | public List getTabCompletions( 122 | MinecraftServer server, ICommandSender sender, String[] args, BlockPos targetPos 123 | ) { 124 | final List tabCompletions = 125 | super.getTabCompletions(server, sender, args, targetPos); 126 | 127 | if(args.length == 2) { 128 | final String[] names = OreDictionary.getOreNames(); 129 | 130 | for(int i = 0; i < names.length; i++) { 131 | names[i] = "ore:" + names[i]; 132 | } 133 | 134 | tabCompletions.addAll(getListOfStringsMatchingLastWord(args, Arrays.asList(names))); 135 | } 136 | 137 | return tabCompletions; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/command/CommandRTHelp.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common.command; 2 | 3 | import java.util.Collection; 4 | import java.util.Comparator; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | import com.therandomlabs.randomtweaks.RandomTweaks; 8 | import net.minecraft.command.CommandBase; 9 | import net.minecraft.command.CommandHelp; 10 | import net.minecraft.command.ICommand; 11 | import net.minecraft.command.ICommandSender; 12 | import net.minecraft.server.MinecraftServer; 13 | import net.minecraftforge.fml.common.FMLCommonHandler; 14 | 15 | //Taken and adapted from https://github.com/matthewprenger/HelpFixer, which is licensed 16 | //under the WTFPL 17 | public class CommandRTHelp extends CommandHelp { 18 | private static class TestCommand extends CommandBase { 19 | private final String name; 20 | 21 | TestCommand(String name) { 22 | this.name = name; 23 | } 24 | 25 | @Override 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | @Override 31 | public String getUsage(ICommandSender sender) { 32 | return null; 33 | } 34 | 35 | @Override 36 | public void execute(MinecraftServer server, ICommandSender sender, String[] args) {} 37 | } 38 | 39 | private static final ICommand testCommand1 = new TestCommand("a"); 40 | private static final ICommand testCommand2 = new TestCommand("z"); 41 | 42 | @Override 43 | protected List getSortedPossibleCommands( 44 | ICommandSender sender, MinecraftServer server 45 | ) { 46 | final List commands = server.getCommandManager().getPossibleCommands(sender); 47 | final Iterator it = commands.iterator(); 48 | 49 | while(it.hasNext()) { 50 | final ICommand command = it.next(); 51 | 52 | try { 53 | if(command.getName() == null) { 54 | RandomTweaks.LOGGER.warn( 55 | "The command {} has a null name! Ignoring...", 56 | command.getClass().getName() 57 | ); 58 | 59 | it.remove(); 60 | } else if(command.getUsage(sender) == null) { 61 | RandomTweaks.LOGGER.warn( 62 | "The command {} has a null usage! Ignoring...", 63 | command.getClass().getName() 64 | ); 65 | 66 | it.remove(); 67 | } 68 | } catch(Exception ex) { 69 | RandomTweaks.LOGGER.warn("Failed to test the command {}!", command, ex); 70 | } 71 | } 72 | 73 | commands.sort(Comparator.comparing(ICommand::getName)); 74 | return commands; 75 | } 76 | 77 | static void serverStarted() { 78 | final Collection commands = FMLCommonHandler.instance(). 79 | getMinecraftServerInstance().getCommandManager().getCommands().values(); 80 | 81 | for(ICommand command : commands) { 82 | if(!isValid(command)) { 83 | RandomTweaks.LOGGER.warn( 84 | "The command {} ({}) incorrectly overrides compareTo!", 85 | command.getName(), command.getClass().getName() 86 | ); 87 | } 88 | } 89 | } 90 | 91 | private static boolean isValid(ICommand command) { 92 | try { 93 | return command.compareTo(testCommand1) != command.compareTo(testCommand2); 94 | } catch(Exception ex) { 95 | RandomTweaks.LOGGER.warn( 96 | "Failed to test the command {} for a valid compareTo!", 97 | command, ex 98 | ); 99 | } 100 | 101 | //We don't know if the implementation is bad, just that it throws an exception 102 | return true; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/command/CommandRegistry.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common.command; 2 | 3 | import com.therandomlabs.randomlib.config.CommandConfigReload; 4 | import com.therandomlabs.randomtweaks.RandomTweaks; 5 | import com.therandomlabs.randomtweaks.config.RTConfig; 6 | import net.minecraftforge.client.ClientCommandHandler; 7 | import net.minecraftforge.fml.common.event.FMLServerStartingEvent; 8 | 9 | public final class CommandRegistry { 10 | public static void register(FMLServerStartingEvent event) { 11 | if(RTConfig.Commands.deletegamerule) { 12 | event.registerServerCommand(new CommandDeleteGamerule()); 13 | } 14 | 15 | if(RTConfig.Commands.hunger) { 16 | event.registerServerCommand(new CommandHunger()); 17 | } 18 | 19 | if(RTConfig.Commands.giveTweaks) { 20 | event.registerServerCommand(new CommandRTGive()); 21 | } 22 | 23 | if(RTConfig.Commands.helpTweaks && !RandomTweaks.HELPFIXER_LOADED) { 24 | event.registerServerCommand(new CommandRTHelp()); 25 | } 26 | 27 | if(RTConfig.Commands.rtreload) { 28 | event.registerServerCommand(CommandConfigReload.server( 29 | "rtreload", "rtreloadclient", RTConfig.class, 30 | "RandomTweaks configuration reloaded!" 31 | )); 32 | } 33 | } 34 | 35 | public static void registerClient() { 36 | if(RTConfig.Commands.rtreloadclient) { 37 | ClientCommandHandler.instance.registerCommand(CommandConfigReload.client( 38 | "rtreloadclient", RTConfig.class 39 | )); 40 | } 41 | 42 | if(RTConfig.Commands.disconnect) { 43 | ClientCommandHandler.instance.registerCommand(new CommandDisconnect()); 44 | } 45 | } 46 | 47 | public static void serverStarted() { 48 | if(RTConfig.Commands.helpTweaks) { 49 | CommandRTHelp.serverStarted(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/world/ChunkGeneratorVoid.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common.world; 2 | 3 | import java.util.Arrays; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.Random; 7 | import com.therandomlabs.randomtweaks.config.RTConfig; 8 | import net.minecraft.entity.EnumCreatureType; 9 | import net.minecraft.util.math.BlockPos; 10 | import net.minecraft.world.World; 11 | import net.minecraft.world.biome.Biome; 12 | import net.minecraft.world.chunk.Chunk; 13 | import net.minecraft.world.gen.IChunkGenerator; 14 | import org.apache.commons.lang3.ArrayUtils; 15 | 16 | public class ChunkGeneratorVoid implements IChunkGenerator { 17 | private final World world; 18 | private final Random random; 19 | 20 | public ChunkGeneratorVoid(World world) { 21 | this.world = world; 22 | random = new Random(world.getSeed()); 23 | } 24 | 25 | @Override 26 | public Chunk generateChunk(int x, int z) { 27 | return createVoidChunk( 28 | world, random, RTConfig.VoidWorld.biome, RTConfig.VoidWorld.randomBiomeBlacklist, 29 | x, z 30 | ); 31 | } 32 | 33 | @Override 34 | public void populate(int x, int z) {} 35 | 36 | @Override 37 | public boolean generateStructures(Chunk chunk, int x, int z) { 38 | return false; 39 | } 40 | 41 | @Override 42 | public List getPossibleCreatures( 43 | EnumCreatureType creatureType, BlockPos pos 44 | ) { 45 | return RTConfig.VoidWorld.mobSpawning ? 46 | world.getBiome(pos).getSpawnableList(creatureType) : Collections.emptyList(); 47 | } 48 | 49 | @Override 50 | public BlockPos getNearestStructurePos( 51 | World world, String structureName, BlockPos pos, boolean findUnexplored 52 | ) { 53 | return null; 54 | } 55 | 56 | @Override 57 | public void recreateStructures(Chunk chunk, int x, int z) {} 58 | 59 | @Override 60 | public boolean isInsideStructure(World world, String structureName, BlockPos pos) { 61 | return false; 62 | } 63 | 64 | public static Chunk createVoidChunk( 65 | World world, Random random, Biome biome, Biome[] biomeBlacklist, int x, int z 66 | ) { 67 | final Chunk chunk = new Chunk(world, x, z); 68 | 69 | if(biome == null) { 70 | biome = world.getBiomeProvider().getBiome(new BlockPos(x * 16 + 8, 0, z * 16 + 8)); 71 | 72 | while(ArrayUtils.contains(biomeBlacklist, biome)) { 73 | biome = Biome.REGISTRY.getRandomObject(random); 74 | } 75 | } 76 | 77 | final byte[] biomeArray = new byte[256]; 78 | Arrays.fill(biomeArray, (byte) Biome.REGISTRY.getIDForObject(biome)); 79 | chunk.setBiomeArray(biomeArray); 80 | 81 | return chunk; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/world/ChunkGeneratorVoidIslands.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common.world; 2 | 3 | import java.util.Random; 4 | import com.therandomlabs.randomtweaks.config.RTConfig; 5 | import net.minecraft.world.World; 6 | import net.minecraft.world.chunk.Chunk; 7 | import net.minecraft.world.gen.ChunkGeneratorOverworld; 8 | 9 | public class ChunkGeneratorVoidIslands extends ChunkGeneratorOverworld { 10 | public static final int ONLY_GENERATE_SPAWN_CHUNK = 1; 11 | 12 | private final World world; 13 | private final Random random; 14 | 15 | public ChunkGeneratorVoidIslands(World world) { 16 | super( 17 | world, 18 | world.getSeed(), 19 | world.getWorldInfo().isMapFeaturesEnabled(), 20 | WorldTypeRealistic.PRESET 21 | ); 22 | 23 | this.world = world; 24 | this.random = new Random(world.getSeed()); 25 | } 26 | 27 | @Override 28 | public Chunk generateChunk(int x, int z) { 29 | //The spawn chunk should always be generated 30 | if(x == 0 && z == 0) { 31 | return super.generateChunk(x, z); 32 | } 33 | 34 | //If the rarity is set to 1, only the spawn chunk should be generated 35 | if(RTConfig.VoidIslandsWorld.chunkRarity != ONLY_GENERATE_SPAWN_CHUNK && 36 | random.nextInt(RTConfig.VoidIslandsWorld.chunkRarity) == 0) { 37 | return super.generateChunk(x, z); 38 | } 39 | 40 | return ChunkGeneratorVoid.createVoidChunk( 41 | world, random, RTConfig.VoidIslandsWorld.voidChunkBiome, 42 | RTConfig.VoidIslandsWorld.voidChunkRandomBiomeBlacklist, x, z 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/world/RTWorldType.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common.world; 2 | 3 | import java.util.Arrays; 4 | import net.minecraft.world.WorldType; 5 | import net.minecraftforge.fml.relauncher.Side; 6 | import net.minecraftforge.fml.relauncher.SideOnly; 7 | import org.apache.commons.lang3.ArrayUtils; 8 | 9 | //A lot of this code is just so the world type options can be toggled in-game 10 | //Worth it? Maybe 11 | public abstract class RTWorldType extends WorldType { 12 | public RTWorldType(String name) { 13 | super(name); 14 | WorldTypeRegistry.worldTypes.add(this); 15 | } 16 | 17 | @SideOnly(Side.CLIENT) 18 | @Override 19 | public boolean hasInfoNotice() { 20 | return true; 21 | } 22 | 23 | public abstract boolean isEnabled(); 24 | 25 | public void enable() { 26 | if(WORLD_TYPES[id] != this) { 27 | if(WORLD_TYPES[id] == null) { 28 | WORLD_TYPES[id] = this; 29 | return; 30 | } 31 | 32 | for(int i = 0; i < WORLD_TYPES.length; i++) { 33 | if(WORLD_TYPES[i] == null) { 34 | WORLD_TYPES[i] = this; 35 | id = i; 36 | return; 37 | } 38 | } 39 | 40 | final int oldLength = WORLD_TYPES.length; 41 | WORLD_TYPES = Arrays.copyOf(WORLD_TYPES, oldLength + 16); 42 | WORLD_TYPES[oldLength] = this; 43 | id = oldLength; 44 | } 45 | } 46 | 47 | public void disable() { 48 | final int index = ArrayUtils.indexOf(WORLD_TYPES, this); 49 | 50 | if(index != ArrayUtils.INDEX_NOT_FOUND) { 51 | WORLD_TYPES[index] = null; 52 | } 53 | } 54 | 55 | public void onConfigReload() { 56 | if(isEnabled()) { 57 | enable(); 58 | } else { 59 | disable(); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/world/WorldGeneratorOceanFloor.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common.world; 2 | 3 | import java.util.Random; 4 | import com.therandomlabs.randomtweaks.config.RTConfig; 5 | import net.minecraft.block.state.pattern.BlockMatcher; 6 | import net.minecraft.init.Blocks; 7 | import net.minecraft.util.math.BlockPos; 8 | import net.minecraft.world.DimensionType; 9 | import net.minecraft.world.World; 10 | import net.minecraft.world.biome.Biome; 11 | import net.minecraft.world.chunk.IChunkProvider; 12 | import net.minecraft.world.gen.IChunkGenerator; 13 | import net.minecraft.world.gen.feature.WorldGenMinable; 14 | import net.minecraft.world.gen.feature.WorldGenerator; 15 | import net.minecraftforge.fml.common.IWorldGenerator; 16 | 17 | public class WorldGeneratorOceanFloor implements IWorldGenerator { 18 | private static final BlockMatcher GRAVEL = BlockMatcher.forBlock(Blocks.GRAVEL); 19 | 20 | private static final WorldGenMinable CLAY = new WorldGenMinable( 21 | Blocks.CLAY.getDefaultState(), 22 | RTConfig.OceanFloor.clayVeinSize, 23 | GRAVEL 24 | ); 25 | 26 | private static final WorldGenMinable SAND = new WorldGenMinable( 27 | Blocks.SAND.getDefaultState(), 28 | RTConfig.OceanFloor.sandVeinSize, 29 | GRAVEL 30 | ); 31 | 32 | private static final WorldGenMinable DIRT = new WorldGenMinable( 33 | Blocks.DIRT.getDefaultState(), 34 | RTConfig.OceanFloor.dirtVeinSize, 35 | GRAVEL 36 | ); 37 | 38 | static { 39 | if(RTConfig.OceanFloor.minY > RTConfig.OceanFloor.maxY) { 40 | throw new IllegalArgumentException( 41 | "oceanFloor.minY must be lesser than or equal to oceanFloor.maxY" 42 | ); 43 | } 44 | } 45 | 46 | @Override 47 | public void generate( 48 | Random random, int chunkX, int chunkZ, World world, IChunkGenerator generator, 49 | IChunkProvider provider 50 | ) { 51 | if(world.provider.getDimensionType() == DimensionType.OVERWORLD) { 52 | generate(CLAY, RTConfig.OceanFloor.clayChance, random, chunkX, chunkZ, world); 53 | generate(SAND, RTConfig.OceanFloor.sandChance, random, chunkX, chunkZ, world); 54 | generate(DIRT, RTConfig.OceanFloor.dirtChance, random, chunkX, chunkZ, world); 55 | } 56 | } 57 | 58 | private void generate( 59 | WorldGenerator generator, int chance, Random random, int chunkX, int chunkZ, 60 | World world 61 | ) { 62 | final int yDifference = RTConfig.OceanFloor.maxY - RTConfig.OceanFloor.minY; 63 | final int x = chunkX * 16; 64 | final int z = chunkZ * 16; 65 | 66 | for(int i = 0; i < chance; i++) { 67 | final BlockPos pos = new BlockPos( 68 | x + random.nextInt(16), 69 | RTConfig.OceanFloor.minY + random.nextInt(yDifference), 70 | z + random.nextInt(16) 71 | ); 72 | 73 | final Biome biome = world.getBiome(pos); 74 | 75 | if(biome.getRegistryName().getPath().contains("ocean")) { 76 | generator.generate(world, random, pos); 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/world/WorldHandler.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common.world; 2 | 3 | import java.util.Random; 4 | import java.util.UUID; 5 | 6 | import com.therandomlabs.randomtweaks.RandomTweaks; 7 | import com.therandomlabs.randomtweaks.config.RTConfig; 8 | import net.minecraft.block.Block; 9 | import net.minecraft.block.BlockBed; 10 | import net.minecraft.block.state.IBlockState; 11 | import net.minecraft.entity.Entity; 12 | import net.minecraft.entity.EntityList; 13 | import net.minecraft.entity.player.EntityPlayer; 14 | import net.minecraft.util.ClassInheritanceMultiMap; 15 | import net.minecraft.util.math.BlockPos; 16 | import net.minecraft.util.math.MathHelper; 17 | import net.minecraft.world.DimensionType; 18 | import net.minecraft.world.GameRules; 19 | import net.minecraft.world.World; 20 | import net.minecraft.world.WorldServer; 21 | import net.minecraft.world.WorldType; 22 | import net.minecraft.world.chunk.Chunk; 23 | import net.minecraftforge.event.entity.player.PlayerEvent; 24 | import net.minecraftforge.event.world.ChunkEvent; 25 | import net.minecraftforge.event.world.WorldEvent; 26 | import net.minecraftforge.fml.common.Mod; 27 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 28 | 29 | @Mod.EventBusSubscriber(modid = RandomTweaks.MOD_ID) 30 | public final class WorldHandler { 31 | private static final Random random = new Random(); 32 | 33 | @SubscribeEvent 34 | public static void onChunkLoad(ChunkEvent.Load event) { 35 | if(!RTConfig.World.fixDuplicateEntityUUIDs) { 36 | return; 37 | } 38 | 39 | final World world = event.getWorld(); 40 | 41 | if(world.isRemote) { 42 | return; 43 | } 44 | 45 | final Chunk chunk = event.getChunk(); 46 | final WorldServer serverWorld = (WorldServer) world; 47 | 48 | //Taken and adapted from: 49 | //https://minecraft.curseforge.com/projects/deuf-duplicate-entity-uuid-fix 50 | 51 | for(ClassInheritanceMultiMap entities : chunk.getEntityLists()) { 52 | for(Entity entity : entities) { 53 | if(entity instanceof EntityPlayer) { 54 | continue; 55 | } 56 | 57 | final UUID uuid = entity.getUniqueID(); 58 | final Entity entityFromUUID = serverWorld.getEntityFromUuid(uuid); 59 | 60 | if(entityFromUUID != null && entityFromUUID != entity) { 61 | UUID newUUID; 62 | 63 | do { 64 | newUUID = MathHelper.getRandomUUID(random); 65 | } while(serverWorld.getEntityFromUuid(newUUID) != null); 66 | 67 | if(RTConfig.World.logEntityUUIDReassignments) { 68 | RandomTweaks.LOGGER.info( 69 | "Changing UUID of entity {} from {} to {}", 70 | EntityList.getKey(entity), uuid, newUUID 71 | ); 72 | } 73 | 74 | entity.setUniqueId(newUUID); 75 | } 76 | } 77 | } 78 | } 79 | 80 | @SubscribeEvent 81 | public static void onWorldLoad(WorldEvent.Load event) { 82 | final World world = event.getWorld(); 83 | 84 | if(world.isRemote) { 85 | return; 86 | } 87 | 88 | final GameRules gameRules = world.getGameRules(); 89 | 90 | final String netherPortalCreation = RTConfig.GameRules.disableNetherPortalCreation; 91 | 92 | if(!netherPortalCreation.isEmpty() && !gameRules.hasRule(netherPortalCreation)) { 93 | gameRules.setOrCreateGameRule(netherPortalCreation, "false"); 94 | } 95 | 96 | final String[] damageMultipliers = { 97 | RTConfig.GameRules.drowningDamageMultiplier, 98 | RTConfig.GameRules.fallDamageMultiplier, 99 | RTConfig.GameRules.fireDamageMultiplier 100 | }; 101 | 102 | for(String gameRule : damageMultipliers) { 103 | if(!gameRule.isEmpty() && !gameRules.hasRule(gameRule)) { 104 | gameRules.setOrCreateGameRule(gameRule, "1.0"); 105 | } 106 | } 107 | } 108 | 109 | @SubscribeEvent 110 | public static void onPlayerRespawn(PlayerEvent.Clone event) { 111 | onPlayerSpawn(event.getEntityPlayer()); 112 | } 113 | 114 | @SubscribeEvent 115 | public static void onPlayerLoad(PlayerEvent.LoadFromFile event) { 116 | onPlayerSpawn(event.getEntityPlayer()); 117 | } 118 | 119 | private static void onPlayerSpawn(EntityPlayer player) { 120 | final World world = player.getEntityWorld(); 121 | 122 | if(world.provider.getDimensionType() != DimensionType.OVERWORLD) { 123 | return; 124 | } 125 | 126 | final WorldType type = world.getWorldType(); 127 | 128 | if(type instanceof WorldTypeVoid) { 129 | onPlayerSpawnInVoidWorld(player, false); 130 | } else if(type instanceof WorldTypeVoidIslands) { 131 | onPlayerSpawnInVoidWorld(player, true); 132 | } 133 | } 134 | 135 | private static void onPlayerSpawnInVoidWorld(EntityPlayer player, boolean voidIslands) { 136 | if(player.capabilities.isFlying) { 137 | return; 138 | } 139 | 140 | final World world = player.getEntityWorld(); 141 | final BlockPos spawnPoint = world.getSpawnPoint(); 142 | 143 | if(isSpawnable(world, world.getTopSolidOrLiquidBlock(spawnPoint))) { 144 | return; 145 | } 146 | 147 | //The player doesn't have a viable spawn point, so we find or create one at (0, 0) 148 | 149 | final int newSpawnY; 150 | 151 | if(voidIslands) { 152 | final BlockPos pos = world.getTopSolidOrLiquidBlock(new BlockPos(0, 0, 0)); 153 | newSpawnY = pos.getY() + 1; 154 | } else { 155 | newSpawnY = RTConfig.VoidWorld.ySpawn; 156 | } 157 | 158 | final BlockPos newSpawn = new BlockPos(0, newSpawnY, 0); 159 | 160 | if (player.getBedLocation() == null) { 161 | player.setPosition(0.5, newSpawnY, 0.5); 162 | player.setSpawnPoint(newSpawn, true); 163 | } 164 | 165 | world.setSpawnPoint(newSpawn); 166 | 167 | if(voidIslands) { 168 | return; 169 | } 170 | 171 | final BlockPos spawnBlock = new BlockPos(0, newSpawnY - 1, 0); 172 | 173 | if(isSpawnable(world, spawnBlock)) { 174 | return; 175 | } 176 | 177 | world.setBlockState(spawnBlock, RTConfig.VoidWorld.spawnBlockState); 178 | } 179 | 180 | private static boolean isSpawnable(World world, BlockPos pos) { 181 | final IBlockState state = world.getBlockState(pos); 182 | final Block block = state.getBlock(); 183 | 184 | if(block instanceof BlockBed) { 185 | return BlockBed.getSafeExitLocation(world, pos, 0) != null; 186 | } 187 | 188 | return state.getMaterial().blocksMovement(); 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/world/WorldTypeRealistic.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common.world; 2 | 3 | import net.minecraft.world.World; 4 | import net.minecraft.world.gen.ChunkGeneratorOverworld; 5 | 6 | public class WorldTypeRealistic extends RTWorldType { 7 | public static final String NAME = "realistic"; 8 | 9 | //Thanks to /u/Soniop 10 | public static final String PRESET = "{\"coordinateScale\":175.0,\"heightScale\":75.0," + 11 | "\"lowerLimitScale\":512.0,\"upperLimitScale\":512.0,\"depthNoiseScaleX\":200.0," + 12 | "\"depthNoiseScaleZ\":200.0,\"depthNoiseScaleExponent\":0.5," + 13 | "\"mainNoiseScaleX\":165.0,\"mainNoiseScaleY\":106.61267,\"mainNoiseScaleZ\":165.0," + 14 | "\"baseSize\":8.267606,\"stretchY\":13.387607,\"biomeDepthWeight\":1.2," + 15 | "\"biomeDepthOffset\":0.2,\"biomeScaleWeight\":3.4084506,\"biomeScaleOffset\":0.0," + 16 | "\"seaLevel\":63,\"useCaves\":true,\"useDungeons\":true,\"dungeonChance\":7," + 17 | "\"useStrongholds\":true,\"useVillages\":true,\"useMineShafts\":true," + 18 | "\"useTemples\":true,\"useMonuments\":true,\"useRavines\":true," + 19 | "\"useWaterLakes\":true,\"waterLakeChance\":49,\"useLavaLakes\":true," + 20 | "\"lavaLakeChance\":80,\"useLavaOceans\":false,\"fixedBiome\":-1,\"biomeSize\":4," + 21 | "\"riverSize\":5,\"dirtSize\":33,\"dirtCount\":10,\"dirtMinHeight\":0," + 22 | "\"dirtMaxHeight\":256,\"gravelSize\":33,\"gravelCount\":8,\"gravelMinHeight\":0," + 23 | "\"gravelMaxHeight\":256,\"graniteSize\":33,\"graniteCount\":10," + 24 | "\"graniteMinHeight\":0,\"graniteMaxHeight\":80,\"dioriteSize\":33," + 25 | "\"dioriteCount\":10,\"dioriteMinHeight\":0,\"dioriteMaxHeight\":80," + 26 | "\"andesiteSize\":33,\"andesiteCount\":10,\"andesiteMinHeight\":0," + 27 | "\"andesiteMaxHeight\":80,\"coalSize\":17,\"coalCount\":20,\"coalMinHeight\":0," + 28 | "\"coalMaxHeight\":128,\"ironSize\":9,\"ironCount\":20,\"ironMinHeight\":0," + 29 | "\"ironMaxHeight\":64,\"goldSize\":9,\"goldCount\":2,\"goldMinHeight\":0," + 30 | "\"goldMaxHeight\":32,\"redstoneSize\":8,\"redstoneCount\":8,\"redstoneMinHeight\":0," + 31 | "\"redstoneMaxHeight\":16,\"diamondSize\":8,\"diamondCount\":1," + 32 | "\"diamondMinHeight\":0,\"diamondMaxHeight\":16,\"lapisSize\":7,\"lapisCount\":1," + 33 | "\"lapisCenterHeight\":16,\"lapisSpread\":16}"; 34 | 35 | public WorldTypeRealistic() { 36 | super(NAME); 37 | } 38 | 39 | @Override 40 | public boolean isEnabled() { 41 | return WorldTypeRegistry.shouldRegisterRealisticWorldType(); 42 | } 43 | 44 | @Override 45 | public ChunkGeneratorOverworld getChunkGenerator(World world, String generatorOptions) { 46 | return new ChunkGeneratorOverworld( 47 | world, world.getSeed(), world.getWorldInfo().isMapFeaturesEnabled(), PRESET 48 | ); 49 | } 50 | 51 | @Override 52 | public float getCloudHeight() { 53 | return 260.0F; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/world/WorldTypeRegistry.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common.world; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import com.therandomlabs.randomtweaks.RandomTweaks; 7 | import com.therandomlabs.randomtweaks.config.RTConfig; 8 | import net.minecraft.world.WorldType; 9 | 10 | public final class WorldTypeRegistry { 11 | static final List worldTypes = new ArrayList<>(); 12 | 13 | public static final WorldTypeRealistic REALISTIC; 14 | public static final WorldTypeVoid VOID; 15 | public static final WorldTypeVoidIslands VOID_ISLANDS; 16 | 17 | static { 18 | //Apparently some mods change the type of WorldType.WORLD_TYPES to force a world type 19 | //(namely Hex Lands) 20 | if(WorldType.WORLD_TYPES.getClass() != WorldType[].class) { 21 | REALISTIC = null; 22 | VOID = null; 23 | VOID_ISLANDS = null; 24 | } else { 25 | REALISTIC = new WorldTypeRealistic(); 26 | VOID = new WorldTypeVoid(); 27 | VOID_ISLANDS = new WorldTypeVoidIslands(); 28 | } 29 | } 30 | 31 | public static void registerWorldTypes() { 32 | worldTypes.forEach(RTWorldType::onConfigReload); 33 | } 34 | 35 | public static boolean shouldRegisterRealisticWorldType() { 36 | if(!RTConfig.World.realisticWorldType) { 37 | return false; 38 | } 39 | 40 | if(!RandomTweaks.QUARK_LOADED) { 41 | return true; 42 | } 43 | 44 | try { 45 | final Class moduleLoader = Class.forName("vazkii.quark.base.module.ModuleLoader"); 46 | 47 | final Method isFeatureEnabled = moduleLoader.getDeclaredMethod( 48 | "isFeatureEnabled", Class.class 49 | ); 50 | 51 | final Class realisticWorldType = 52 | Class.forName("vazkii.quark.world.feature.RealisticWorldType"); 53 | 54 | return !((boolean) isFeatureEnabled.invoke(null, realisticWorldType)); 55 | } catch(Exception ex) { 56 | RandomTweaks.LOGGER.error( 57 | "Failed to check if Quark's realistic world type is enabled", ex 58 | ); 59 | } 60 | 61 | return true; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/world/WorldTypeVoid.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common.world; 2 | 3 | import com.therandomlabs.randomtweaks.config.RTConfig; 4 | import net.minecraft.world.World; 5 | 6 | public class WorldTypeVoid extends RTWorldType { 7 | public static final String NAME = "void"; 8 | 9 | public WorldTypeVoid() { 10 | super(NAME); 11 | } 12 | 13 | @Override 14 | public boolean isEnabled() { 15 | return RTConfig.VoidWorld.enabled; 16 | } 17 | 18 | @Override 19 | public ChunkGeneratorVoid getChunkGenerator(World world, String generatorOptions) { 20 | return new ChunkGeneratorVoid(world); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/common/world/WorldTypeVoidIslands.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.common.world; 2 | 3 | import com.therandomlabs.randomtweaks.config.RTConfig; 4 | import net.minecraft.world.World; 5 | 6 | public class WorldTypeVoidIslands extends RTWorldType { 7 | public static final String NAME = "voidislands"; 8 | 9 | public WorldTypeVoidIslands() { 10 | super(NAME); 11 | } 12 | 13 | @Override 14 | public boolean isEnabled() { 15 | return RTConfig.VoidIslandsWorld.enabled; 16 | } 17 | 18 | @Override 19 | public ChunkGeneratorVoidIslands getChunkGenerator(World world, String generatorOptions) { 20 | return new ChunkGeneratorVoidIslands(world); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/config/RTData.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.config; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.Files; 5 | import java.nio.file.Path; 6 | import java.nio.file.Paths; 7 | import java.util.Collections; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | import com.google.gson.Gson; 11 | import com.google.gson.JsonSyntaxException; 12 | import com.therandomlabs.randomtweaks.RandomTweaks; 13 | import org.apache.commons.lang3.StringUtils; 14 | 15 | public final class RTData { 16 | private static RTData data; 17 | 18 | public Map timeOfDayOverlay; 19 | public boolean stepup; 20 | public boolean fovChanges; 21 | 22 | public static RTData get() { 23 | if(data != null) { 24 | return data; 25 | } 26 | 27 | final Path path = getPath(); 28 | 29 | if(path.toFile().exists()) { 30 | try { 31 | data = new Gson().fromJson(read(path), RTData.class); 32 | } catch(JsonSyntaxException ex) { 33 | RandomTweaks.LOGGER.error( 34 | "Error in the RandomTweaks data JSON. The file will be replaced.", ex 35 | ); 36 | } 37 | } 38 | 39 | if(data == null) { 40 | data = new RTData(); 41 | 42 | data.timeOfDayOverlay = new HashMap<>(); 43 | data.stepup = RTConfig.Client.stepupEnabledByDefault; 44 | data.fovChanges = RTConfig.Keybinds.fovChangesEnabledByDefault; 45 | 46 | save(); 47 | } else if(data.timeOfDayOverlay == null) { 48 | data.timeOfDayOverlay = new HashMap<>(); 49 | save(); 50 | } 51 | 52 | return data; 53 | } 54 | 55 | public static void save() { 56 | //Ensure non-null 57 | get(); 58 | 59 | try { 60 | Files.write(getPath(), Collections.singletonList(new Gson().toJson(data))); 61 | } catch(IOException ex) { 62 | RandomTweaks.LOGGER.error("Error while saving RandomTweaks data", ex); 63 | } 64 | } 65 | 66 | public static Path getPath() { 67 | final Path path; 68 | 69 | if(RTConfig.Client.storeDataInLocal) { 70 | path = Paths.get("local", "client", "rtdata.json"); 71 | } else { 72 | path = Paths.get("config", RandomTweaks.MOD_ID, "data.json"); 73 | } 74 | 75 | final Path parent = path.getParent(); 76 | 77 | try { 78 | if(parent != null) { 79 | if(Files.isRegularFile(parent)) { 80 | Files.delete(parent); 81 | } 82 | 83 | Files.createDirectories(parent); 84 | } 85 | } catch(IOException ex) { 86 | RandomTweaks.LOGGER.error("Failed to create parent: " + path, ex); 87 | } 88 | 89 | return path; 90 | } 91 | 92 | private static String read(Path path) { 93 | try { 94 | return StringUtils.join(Files.readAllLines(path), System.lineSeparator()); 95 | } catch(IOException ex) { 96 | RandomTweaks.LOGGER.error("Failed to read file: " + path, ex); 97 | } 98 | 99 | return "{}"; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/config/RTGuiConfig.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.config; 2 | 3 | import com.therandomlabs.randomlib.config.ConfigManager; 4 | import com.therandomlabs.randomtweaks.RandomTweaks; 5 | import net.minecraft.client.gui.GuiScreen; 6 | import net.minecraftforge.fml.client.config.GuiConfig; 7 | 8 | public class RTGuiConfig extends GuiConfig { 9 | public RTGuiConfig(GuiScreen parentScreen) { 10 | super( 11 | parentScreen, 12 | ConfigManager.getConfigElements(RTConfig.class), 13 | RandomTweaks.MOD_ID, 14 | RandomTweaks.MOD_ID, 15 | false, 16 | false, 17 | ConfigManager.getPathString(RTConfig.class) 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/config/RTGuiConfigFactory.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.config; 2 | 3 | import com.therandomlabs.randomlib.config.TRLGuiConfigFactory; 4 | import net.minecraftforge.fml.client.config.GuiConfig; 5 | 6 | public class RTGuiConfigFactory extends TRLGuiConfigFactory { 7 | @Override 8 | public Class mainConfigGuiClass() { 9 | return RTGuiConfig.class; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/util/Alignment.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.util; 2 | 3 | //Taken and adapted from: 4 | //https://github.com/Lunatrius/InGame-Info-XML/blob/master/src/main/java/com/github/lunatrius/ 5 | //ingameinfo/Alignment.java 6 | //License: https://github.com/Lunatrius/InGame-Info-XML/blob/master/LICENSE 7 | public enum Alignment { 8 | TOP_LEFT("topLeft", 2, 2), 9 | TOP_CENTER("topCenter", 0, 2), 10 | TOP_RIGHT("topRight", -2, 2), 11 | MIDDLE_LEFT("middleLeft", 2, 0), 12 | MIDDLE_CENTER("middleCenter", 0, 0), 13 | MIDDLE_RIGHT("middleRight", -2, 0), 14 | BOTTOM_LEFT("bottomLeft", 2, -2), 15 | BOTTOM_CENTER("bottomCenter", 0, -45), 16 | BOTTOM_RIGHT("bottomRight", -2, -2); 17 | 18 | private static final int MASK_X = 0x0C; 19 | private static final int MASK_Y = 0x03; 20 | 21 | private static final int TOP = 0x01; 22 | private static final int MIDDLE = 0x03; 23 | private static final int BOTTOM = 0x02; 24 | 25 | private static final int LEFT = 0x04; 26 | private static final int CENTER = 0x0C; 27 | private static final int RIGHT = 0x08; 28 | 29 | private final int defaultX; 30 | private final int defaultY; 31 | 32 | private final String translationKey; 33 | 34 | private int alignment; 35 | 36 | static { 37 | TOP_LEFT.alignment = TOP | LEFT; 38 | TOP_CENTER.alignment = TOP | CENTER; 39 | TOP_RIGHT.alignment = TOP | RIGHT; 40 | MIDDLE_LEFT.alignment = MIDDLE | LEFT; 41 | MIDDLE_CENTER.alignment = MIDDLE | CENTER; 42 | MIDDLE_RIGHT.alignment = MIDDLE | RIGHT; 43 | BOTTOM_LEFT.alignment = BOTTOM | LEFT; 44 | BOTTOM_CENTER.alignment = BOTTOM | CENTER; 45 | BOTTOM_RIGHT.alignment = BOTTOM | RIGHT; 46 | } 47 | 48 | Alignment(String translationKey, int x, int y) { 49 | this.translationKey = "randomtweaks.config.client.timeOfDay.alignment." + translationKey; 50 | defaultX = x; 51 | defaultY = y; 52 | } 53 | 54 | @Override 55 | public String toString() { 56 | return translationKey; 57 | } 58 | 59 | @SuppressWarnings("Duplicates") 60 | public int getX(int x, int screenWidth, int textWidth) { 61 | x += defaultX; 62 | 63 | switch(alignment & MASK_X) { 64 | case LEFT: 65 | return x; 66 | case CENTER: 67 | return x + (screenWidth - textWidth) / 2; 68 | case RIGHT: 69 | return x + screenWidth - textWidth; 70 | } 71 | 72 | return 0; 73 | } 74 | 75 | @SuppressWarnings("Duplicates") 76 | public int getY(int y, int screenHeight, int textHeight) { 77 | y += defaultY; 78 | 79 | switch(alignment & MASK_Y) { 80 | case TOP: 81 | return y; 82 | case MIDDLE: 83 | return y + (screenHeight - textHeight) / 2; 84 | case BOTTOM: 85 | return y + screenHeight - textHeight; 86 | } 87 | 88 | return 0; 89 | } 90 | 91 | public int getDefaultX() { 92 | return defaultX; 93 | } 94 | 95 | public int getDefaultY() { 96 | return defaultY; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/com/therandomlabs/randomtweaks/util/RomanNumerals.java: -------------------------------------------------------------------------------- 1 | package com.therandomlabs.randomtweaks.util; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.ConcurrentHashMap; 5 | 6 | public final class RomanNumerals { 7 | private static final String[] ROMAN_NUMERALS = { 8 | "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" 9 | }; 10 | 11 | private static final int[] ROMAN_NUMERAL_VALUES = { 12 | 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 13 | }; 14 | 15 | private static final Map cache = new ConcurrentHashMap<>(); 16 | 17 | private RomanNumerals() {} 18 | 19 | public static String get(int number) { 20 | if(number == 0) { 21 | return "Nulla"; 22 | } 23 | 24 | final String cached = cache.get(number); 25 | 26 | if(cached != null) { 27 | return cached; 28 | } 29 | 30 | final boolean negative = number < 0; 31 | 32 | if(negative) { 33 | number = -number; 34 | } 35 | 36 | final StringBuilder builder = new StringBuilder(); 37 | 38 | for(int i = 0; i < ROMAN_NUMERALS.length; i++) { 39 | while(number >= ROMAN_NUMERAL_VALUES[i]) { 40 | //The largest value that can be represented with Roman numerals without special 41 | //characters 42 | if(number > 3999) { 43 | final String string = String.valueOf(number); 44 | final int nested = 45 | Integer.parseInt(string.substring(0, 1 + (string.length() - 4))); 46 | 47 | //In Roman numerals, brackets mean "multiply by 1000" 48 | builder.append('(').append(get(nested)).append(')'); 49 | number -= nested * 1000; 50 | } else { 51 | builder.append(ROMAN_NUMERALS[i]); 52 | number -= ROMAN_NUMERAL_VALUES[i]; 53 | } 54 | } 55 | } 56 | 57 | String romanNumeral = builder.toString(); 58 | 59 | if(negative) { 60 | romanNumeral = "-" + romanNumeral; 61 | } 62 | 63 | cache.put(number, romanNumeral); 64 | return romanNumeral; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/randomtweaks_at.cfg: -------------------------------------------------------------------------------- 1 | public-f net.minecraft.util.text.translation.I18n field_74839_a # localizedName 2 | public-f net.minecraft.util.text.translation.LanguageMap field_74817_a # instance 3 | public-f net.minecraft.util.text.translation.LanguageMap field_74816_c # languageList 4 | 5 | public net.minecraft.entity.EntityLivingBase field_184633_f # POTION_EFFECTS 6 | 7 | public net.minecraft.client.audio.SoundHandler field_147694_f # sndManager 8 | public net.minecraft.client.audio.SoundManager field_148620_e # sndSystem 9 | 10 | public net.minecraft.entity.ai.EntityAIAttackMelee field_75440_e # speedTowardsTarget 11 | public net.minecraft.entity.ai.EntityAIAttackMelee field_75437_f # longMemory 12 | public net.minecraft.entity.ai.EntityAIAttackMelee field_75438_g # path 13 | public net.minecraft.entity.ai.EntityAIAttackMelee field_75445_i # delayCounter 14 | 15 | public net.minecraft.client.renderer.EntityRenderer func_180438_a(Lnet/minecraft/entity/EntityLivingBase;F)F # getNightVisionBrightness 16 | public net.minecraft.client.resources.SimpleReloadableResourceManager field_110546_b # reloadListeners 17 | 18 | public net.minecraft.entity.EntityLiving field_82174_bp # inventoryHandsDropChances 19 | public net.minecraft.entity.EntityLiving field_184655_bs # inventoryArmorDropChances 20 | public net.minecraft.entity.EntityLivingBase field_70717_bb # attackingPlayer 21 | public net.minecraft.entity.EntityLivingBase field_70718_bc # recentlyHit 22 | 23 | public net.minecraft.block.Block func_193382_c(Lnet/minecraft/block/Block;)Z # isExceptBlockForAttachWithPiston 24 | 25 | public net.minecraft.entity.player.EntityPlayer func_190774_a(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;)Z # bedInRange 26 | # public net.minecraft.entity.Entity func_70105_a(FF)V # setSize - doesn't work for some reason 27 | public net.minecraft.entity.player.EntityPlayer func_192030_dh()V # spawnShoulderEntities 28 | public net.minecraft.entity.player.EntityPlayer func_175139_a(Lnet/minecraft/util/EnumFacing;)V # setRenderOffsetForSleep 29 | public net.minecraft.entity.player.EntityPlayer field_71083_bS # sleeping 30 | public net.minecraft.entity.player.EntityPlayer field_71076_b # sleepTimer 31 | 32 | public net.minecraft.entity.player.EntityPlayer field_71100_bB # foodStats 33 | public net.minecraft.util.FoodStats field_75126_c # foodExhaustionLevel 34 | public net.minecraft.util.FoodStats field_75127_a # foodLevel 35 | public net.minecraft.util.FoodStats field_75125_b # foodSaturationLevel 36 | public net.minecraft.util.FoodStats field_75123_d # foodTimer 37 | 38 | public net.minecraft.world.GameRules field_82771_a # rules 39 | 40 | public-f net.minecraft.world.WorldType field_82748_f # id 41 | 42 | public net.minecraft.client.entity.AbstractClientPlayer func_175155_b()Lnet/minecraft/client/network/NetworkPlayerInfo; # getPlayerInfo 43 | public net.minecraft.client.entity.AbstractClientPlayer field_175157_a # playerInfo 44 | public net.minecraft.client.network.NetworkPlayerInfo field_78829_b # responseTime 45 | public net.minecraft.client.network.NetworkPlayerInfo field_187107_a # playerTextures 46 | 47 | public-f net.minecraft.creativetab.CreativeTabs field_78033_n # index 48 | public net.minecraft.client.gui.inventory.GuiContainerCreative field_147058_w # selectedTabIndex 49 | -------------------------------------------------------------------------------- /src/main/resources/assets/randomtweaks/lang/de_de.lang: -------------------------------------------------------------------------------- 1 | randomtweaks.config.animals=Animals 2 | randomtweaks.config.animals.batLeatherDropChance=Bat leather drop chance 3 | randomtweaks.config.animals.coloredSheep=Colored sheep spawns 4 | randomtweaks.config.animals.leashableVillagers=Leashable villagers 5 | randomtweaks.config.animals.ocelotsCanBeHealed=Enable tamed ocelot healing with fish 6 | randomtweaks.config.animals.parrotsCanBeHealed=Enable tamed parrot healing with seeds 7 | randomtweaks.config.animals.protectPetsFromOtherPets=Protect pets from their owners' other pets 8 | randomtweaks.config.animals.protectPetsFromOwners=Protect pets from their owners 9 | randomtweaks.config.animals.protectPetsFromSneakingOwners=Protect pets from sneaking owners 10 | 11 | randomtweaks.config.animals.randomizedAges=Randomized Ages 12 | randomtweaks.config.animals.randomizedAges.chance=Chance that an animal's age is randomized 13 | randomtweaks.config.animals.randomizedAges.maximumAge=Maximum age 14 | randomtweaks.config.animals.randomizedAges.minimumAge=Minimum age 15 | randomtweaks.config.animals.randomizedAges.animalsWhitelist=Animals whitelist 16 | randomtweaks.config.animals.randomizedAges.animals=Animals 17 | 18 | randomtweaks.config.animals.sheepColorWeights=Sheep Color Weights 19 | randomtweaks.config.animals.sheepColorWeights.enabled=Enable colored sheep spawning 20 | randomtweaks.config.animals.sheepColorWeights.white=§fWhite 21 | randomtweaks.config.animals.sheepColorWeights.orange=§6Orange 22 | randomtweaks.config.animals.sheepColorWeights.magenta=§bMagenta 23 | randomtweaks.config.animals.sheepColorWeights.lightBlue=§9Light blue 24 | randomtweaks.config.animals.sheepColorWeights.yellow=§eYellow 25 | randomtweaks.config.animals.sheepColorWeights.lime=§aLime 26 | randomtweaks.config.animals.sheepColorWeights.pink=§dPink 27 | randomtweaks.config.animals.sheepColorWeights.gray=§8Gray 28 | randomtweaks.config.animals.sheepColorWeights.silver=§7Silver 29 | randomtweaks.config.animals.sheepColorWeights.cyan=§3Cyan 30 | randomtweaks.config.animals.sheepColorWeights.purple=§5Purple 31 | randomtweaks.config.animals.sheepColorWeights.blue=§1Blue 32 | randomtweaks.config.animals.sheepColorWeights.brown=§6Brown 33 | randomtweaks.config.animals.sheepColorWeights.green=§2Green 34 | randomtweaks.config.animals.sheepColorWeights.red=§4Red 35 | randomtweaks.config.animals.sheepColorWeights.black=§0Black 36 | 37 | randomtweaks.config.animals.squids=Squid Spawning Behavior 38 | randomtweaks.config.animals.squids.chunkLimit=Amount of squids allowed in one chunk 39 | randomtweaks.config.animals.squids.maxPackSize=Maximum squid spawn pack size 40 | randomtweaks.config.animals.squids.spawnRadiusLimit=Maximum squid spawn radius from player 41 | 42 | randomtweaks.config.boneMeal=Bone Meal 43 | randomtweaks.config.boneMeal.cacti=Cacti 44 | randomtweaks.config.boneMeal.netherWart=Nether wart 45 | randomtweaks.config.boneMeal.sugarCanes=Sugar canes 46 | 47 | randomtweaks.config.client=Client 48 | randomtweaks.config.client.clearWater=Remove underwater fog 49 | randomtweaks.config.client.contributorCapes=Enable contributor capes 50 | randomtweaks.config.client.disableEnderDragonDeathSound=Disable ender dragon death sound 51 | randomtweaks.config.client.disablePotionIcons=Disable potion icons 52 | randomtweaks.config.client.disablePotionShift=Disable potion effect inventory shift 53 | randomtweaks.config.client.disableWitherSpawnSound=Disable wither spawn sound 54 | randomtweaks.config.client.startOnMultiplayerScreen=Start on the multiplayer screen 55 | randomtweaks.config.client.stepup=Enable stepup 56 | randomtweaks.config.client.jumpBoostAffectsStepup=Jump Boost affects stepup 57 | randomtweaks.config.client.stepupEnabledByDefault=Enable stepup by default 58 | randomtweaks.config.client.togglePotionParticlesKeybind=Toggle Potion Particles keybind 59 | randomtweaks.config.client.potionParticlesEnabledByDefault=Potion particles enabled by default 60 | randomtweaks.config.client.storeDataInLocal=Store data in local 61 | 62 | randomtweaks.config.client.armorEquipSounds=Armor Equip Sounds 63 | randomtweaks.config.client.armorEquipSounds.enabled=Enabled 64 | randomtweaks.config.client.armorEquipSounds.elytraSound=Elytra sound 65 | randomtweaks.config.client.armorEquipSounds.pumpkinSound=Pumpkin sound 66 | randomtweaks.config.client.armorEquipSounds.skullSound=Skull sound 67 | 68 | randomtweaks.config.client.autoThirdPerson=Auto Third Person 69 | randomtweaks.config.client.autoThirdPerson.boat=Boat 70 | randomtweaks.config.client.autoThirdPerson.elytra=Elytra 71 | randomtweaks.config.client.autoThirdPerson.enabled=Enable auto-third person 72 | randomtweaks.config.client.autoThirdPerson.horse=Horse 73 | randomtweaks.config.client.autoThirdPerson.minecart=Minecart 74 | randomtweaks.config.client.autoThirdPerson.pig=Pig 75 | randomtweaks.config.client.autoThirdPerson.wings=Wings 76 | randomtweaks.config.client.autoThirdPerson.wingsFlyingTickDelay=Wings flying tick delay 77 | 78 | randomtweaks.config.client.creativeTabs=Creative Tabs 79 | randomtweaks.config.client.creativeTabs.moveBucketCreativeTab=Move the bucket to the Tools creative tab 80 | randomtweaks.config.client.creativeTabs.noAISpawnEggs=No AI spawn eggs 81 | randomtweaks.config.client.creativeTabs.spawnEggsCreativeTab=Move the spawn eggs to their own creative tab 82 | randomtweaks.config.client.creativeTabs.setCommandBlockCreativeTab=Move the command blocks to the Redstone creative tab 83 | randomtweaks.config.client.creativeTabs.setDragonEggCreativeTab=Add the dragon egg to the Decorations creative tab 84 | 85 | randomtweaks.config.client.ding=Ding 86 | randomtweaks.config.client.ding.ignoreDsurroundMuteWhenBackground=Ignore Dynamic Surroundings' "Mute when Background" feature 87 | randomtweaks.config.client.ding.startupSoundPitch=Startup sound pitch 88 | randomtweaks.config.client.ding.startupSoundVolume=Startup sound volume 89 | randomtweaks.config.client.ding.startupSounds=Startup sounds 90 | randomtweaks.config.client.ding.worldLoadSoundPitch=World load sound pitch 91 | randomtweaks.config.client.ding.worldLoadSoundVolume=World load sound volume 92 | randomtweaks.config.client.ding.worldLoadSounds=World load sounds 93 | 94 | randomtweaks.config.client.keybinds=Keybinds 95 | randomtweaks.config.client.keybinds.fovChangesEnabledByDefault=Enable FoV changes by default 96 | randomtweaks.config.client.keybinds.fovChangesStatusMessage=Enable FoV changes status message 97 | randomtweaks.config.client.keybinds.reloadSoundSystem=Enable Reload Sound System keybind 98 | randomtweaks.config.client.keybinds.toggleFoVChanges=Enable Toggle FoV Changes keybind 99 | randomtweaks.config.client.keybinds.toggleTimeOfDayOverlay=Enable Toggle Time of Day Overlay keybind 100 | 101 | randomtweaks.config.client.nightVision=Night Vision 102 | randomtweaks.config.client.nightVision.enabled=Enabled 103 | randomtweaks.config.client.nightVision.brightness=Brightness 104 | randomtweaks.config.client.nightVision.disableFlashing=Disable flashing 105 | randomtweaks.config.client.nightVision.fadeOut=Fade out 106 | randomtweaks.config.client.nightVision.fadeOutTicks=Fade out ticks 107 | 108 | randomtweaks.config.client.timeOfDay=Time of Day Overlay 109 | randomtweaks.config.client.timeOfDay.alignment=Alignment 110 | randomtweaks.config.client.timeOfDay.alignment.topLeft=Top left 111 | randomtweaks.config.client.timeOfDay.alignment.topCenter=Top center 112 | randomtweaks.config.client.timeOfDay.alignment.topRight=Top right 113 | randomtweaks.config.client.timeOfDay.alignment.middleLeft=Middle left 114 | randomtweaks.config.client.timeOfDay.alignment.middleCenter=Middle center 115 | randomtweaks.config.client.timeOfDay.alignment.middleRight=Middle right 116 | randomtweaks.config.client.timeOfDay.alignment.bottomLeft=Bottom left 117 | randomtweaks.config.client.timeOfDay.alignment.bottomCenter=Bottom center 118 | randomtweaks.config.client.timeOfDay.alignment.bottomRight=Bottom right 119 | randomtweaks.config.client.timeOfDay.disableIfNoDaylightCycle=Disable if doDaylightCycle is false 120 | randomtweaks.config.client.timeOfDay.disableInAdventureMode=Disable in adventure mode 121 | randomtweaks.config.client.timeOfDay.disableInGUIs=Disable in GUIs 122 | randomtweaks.config.client.timeOfDay.enabled=Enable time of day overlay 123 | randomtweaks.config.client.timeOfDay.enabledByDefault=Enable by default 124 | randomtweaks.config.client.timeOfDay.lightOrDark=Light or dark 125 | randomtweaks.config.client.timeOfDay.twentyFourHourTime=Use twenty-four hour time 126 | randomtweaks.config.client.timeOfDay.x=X coordinate 127 | randomtweaks.config.client.timeOfDay.y=Y coordinate 128 | 129 | randomtweaks.config.cobwebBurning=Cobweb Burning 130 | randomtweaks.config.cobwebBurning.enableBurning=Enable burning 131 | randomtweaks.config.cobwebBurning.disableBurningIfSneaking=Disable burning if sneaking 132 | randomtweaks.config.cobwebBurning.items=Items 133 | randomtweaks.config.cobwebBurning.consumeAmount=Consume amount 134 | randomtweaks.config.cobwebBurning.damageAmount=Damage amount 135 | randomtweaks.config.cobwebBurning.burnSound=Burn sound 136 | randomtweaks.config.cobwebBurning.flammableCobwebs=Flammable cobwebs 137 | randomtweaks.config.cobwebBurning.cobwebFireSpreadSpeed=Cobweb fire spread speed 138 | randomtweaks.config.cobwebBurning.cobwebFlammability=Cobweb flammability 139 | 140 | randomtweaks.config.commands=Commands 141 | randomtweaks.config.commands.deletegamerule=/deletegamerule 142 | randomtweaks.config.commands.disconnect=/disconnect 143 | randomtweaks.config.commands.giveTweaks=Tweaks to /give 144 | randomtweaks.config.commands.helpTweaks=Tweaks to /help 145 | randomtweaks.config.commands.hunger=/hunger 146 | randomtweaks.config.commands.rtreload=/rtreload 147 | randomtweaks.config.commands.rtreloadclient=/rtreloadclient 148 | 149 | randomtweaks.config.gameRules=Gamerules 150 | randomtweaks.config.gameRules.disableNetherPortalCreation=disableNetherPortalCreation 151 | randomtweaks.config.gameRules.drowningDamageMultiplier=drowningDamageMultiplier 152 | randomtweaks.config.gameRules.fallDamageMultiplier=fallDamageMultiplier 153 | randomtweaks.config.gameRules.fireDamageMultiplier=fireDamageMultiplier 154 | 155 | randomtweaks.config.hunger=Hunger 156 | randomtweaks.config.hunger.carryExcessHungerToSaturation=Carry excess hunger to saturation 157 | randomtweaks.config.hunger.enabled=Enable all hunger tweaks 158 | randomtweaks.config.hunger.exhaustionMultiplier=Exhaustion multiplier 159 | randomtweaks.config.hunger.maximumHungerLevel=Maximum hunger level 160 | randomtweaks.config.hunger.minimumRespawnHungerLevel=Minimum respawn hunger level 161 | randomtweaks.config.hunger.respawnResetBehavior=Hunger respawn reset behavior 162 | randomtweaks.config.hunger.respawnResetBehavior.reset=Reset 163 | randomtweaks.config.hunger.respawnResetBehavior.dontReset=Don't reset 164 | randomtweaks.config.hunger.respawnResetBehavior.resetUnlessKeepInventory=Reset unless keepInventory 165 | randomtweaks.config.hunger.saturationLimit=Value added to food level for saturation limit 166 | 167 | randomtweaks.config.misc=Miscellaneous 168 | randomtweaks.config.misc.attackSpeed=Attack speed 169 | randomtweaks.config.misc.armorStandSwapping=Armor stand swapping 170 | randomtweaks.config.misc.betterButtonNames=Better button names 171 | randomtweaks.config.misc.bowInfinityFix=Bow Infinity fix 172 | randomtweaks.config.misc.burningArrowsSetBlocksOnFire=Burning arrows set blocks on fire 173 | randomtweaks.config.misc.cakeSoundsAndParticles=Cake sounds and particles 174 | randomtweaks.config.misc.disableAttacksDuringAttackCooldown=Disable attacks during attack cooldown 175 | randomtweaks.config.misc.deathPunishmentMode=Death punishment mode 176 | randomtweaks.config.misc.deathPunishmentMode.enabled=Enabled 177 | randomtweaks.config.misc.deathPunishmentMode.enabledIfKeepInventory=Enabled if keepInventory 178 | randomtweaks.config.misc.deathPunishmentMode.disabled=Disabled 179 | randomtweaks.config.misc.disableCumulativeAnvilCosts=Disable cumulative anvil cost 180 | randomtweaks.config.misc.entitiesDropNameTags=Enable living entities with custom names dropping nametags 181 | randomtweaks.config.misc.entityNaNHealthFix=Entity NaN Health Fix 182 | randomtweaks.config.misc.farmlandTrampleBehavior=Farmland trample behavior 183 | randomtweaks.config.misc.farmlandTrampleBehavior.vanilla=Vanilla 184 | randomtweaks.config.misc.farmlandTrampleBehavior.dontTrampleIfFeatherFalling=Don't trample if Feather Falling 185 | randomtweaks.config.misc.farmlandTrampleBehavior.dontTrampleIfFeatherFallingOrWet=Don't trample if Feather Falling or wet 186 | randomtweaks.config.misc.farmlandTrampleBehavior.dontTrampleIfWet=Don't trample if wet 187 | randomtweaks.config.misc.farmlandTrampleBehavior.dontTrample=Don't trample 188 | randomtweaks.config.misc.localizeEndPortalNames=Localize End portal names 189 | randomtweaks.config.misc.mobsDropAllArmorAndEquipment=Mobs drop all armor and equipment 190 | randomtweaks.config.misc.mobsAlwaysDropLoot=Mobs always drop loot 191 | randomtweaks.config.misc.moreRomanNumerals=More Roman numerals 192 | randomtweaks.config.misc.pickUpSkeletonArrows=Allow arrows shot by skeletons to be picked up 193 | randomtweaks.config.misc.torchReorientationBehavior=Torch reorientation behavior 194 | randomtweaks.config.misc.torchReorientationBehavior.never=Never 195 | randomtweaks.config.misc.torchReorientationBehavior.sneaking=Sneaking 196 | randomtweaks.config.misc.torchReorientationBehavior.notSneaking=Not sneaking 197 | randomtweaks.config.misc.torchReorientationBehavior.always=Always 198 | randomtweaks.config.misc.torchReorientationPriority=Torch reorientation priority 199 | randomtweaks.config.misc.updateAllMapsInInventory=Update all maps in inventory 200 | randomtweaks.config.misc.wetSpongesDryInNether=Wet sponges dry in the Nether 201 | randomtweaks.config.misc.zombieTargetDetectionImprovements=Zombie target detection improvements 202 | 203 | randomtweaks.config.playerHeadDrops=Player Head Drops 204 | randomtweaks.config.playerHeadDrops.enabled=Enable player head drops 205 | randomtweaks.config.playerHeadDrops.chanceWhenKilledByChargedCreeper=Drop chance when killed by a charged creeper 206 | randomtweaks.config.playerHeadDrops.chanceWhenKilledByPlayer=Drop chance when killed by another player 207 | randomtweaks.config.playerHeadDrops.normalChance=Normal drop chance 208 | 209 | randomtweaks.config.sleep=Sleep 210 | randomtweaks.config.sleep.allowSleepNearMobsWithCustomNames=Allow sleep near mobs with custom names 211 | randomtweaks.config.sleep.disableBedProximityRequirement=Disable bed proximity requirement 212 | randomtweaks.config.sleep.nearbyMonsterGlowDuration=Nearby monster glow duration 213 | randomtweaks.config.sleep.nearbyMonsterGlowParticles=Nearby monster glow particles 214 | 215 | randomtweaks.config.world=World 216 | randomtweaks.config.world.cactusSpawnRate=Cactus spawn rate 217 | randomtweaks.config.world.fixDuplicateEntityUUIDs=Fix duplicate entity UUIDs 218 | randomtweaks.config.world.logEntityUUIDReassignments=Log entity UUID reassignments 219 | randomtweaks.config.world.realisticWorldType=Enable Realistic world type 220 | 221 | randomtweaks.config.world.oceanFloor=Ocean Floor Generation 222 | randomtweaks.config.world.oceanFloor.clayChance=Clay spawn chance 223 | randomtweaks.config.world.oceanFloor.clayVeinSize=Clay vein size 224 | randomtweaks.config.world.oceanFloor.dirtChance=Dirt spawn chance 225 | randomtweaks.config.world.oceanFloor.dirtVeinSize=Dirt vein size 226 | randomtweaks.config.world.oceanFloor.enabled=Enable ocean floor generation 227 | randomtweaks.config.world.oceanFloor.maxY=Maximum Y coordinate 228 | randomtweaks.config.world.oceanFloor.minY=Minimum Y coordinate 229 | randomtweaks.config.world.oceanFloor.sandChance=Sand spawn chance 230 | randomtweaks.config.world.oceanFloor.sandVeinSize=Sand vein size 231 | 232 | randomtweaks.config.world.voidWorld=Void World 233 | randomtweaks.config.world.voidWorld.biome=Biome 234 | randomtweaks.config.world.voidWorld.enabled=Enabled 235 | randomtweaks.config.world.voidWorld.mobSpawning=Mob spawning 236 | randomtweaks.config.world.voidWorld.randomBiomeBlacklist=Random biome blacklist 237 | randomtweaks.config.world.voidWorld.spawnBlock=Spawn block 238 | randomtweaks.config.world.voidWorld.spawnBlockMeta=Spawn block meta 239 | randomtweaks.config.world.voidWorld.ySpawn=Y spawn coordinate 240 | 241 | randomtweaks.config.world.voidIslandsWorld=Void Islands World 242 | randomtweaks.config.world.voidIslandsWorld.chunkRarity=Chunk rarity 243 | randomtweaks.config.world.voidIslandsWorld.enabled=Enabled 244 | randomtweaks.config.world.voidIslandsWorld.voidChunkBiome=Void chunk biome 245 | randomtweaks.config.world.voidIslandsWorld.voidChunkRandomBiomeBlacklist=Void chunk random biome blacklist 246 | 247 | timeOfDayOverlay.text=Tag %s, %s:%s%s %s 248 | timeOfDayOverlay.am=AM 249 | timeOfDayOverlay.pm=PM 250 | timeOfDayOverlay.dayTime=(§eTag§r) 251 | timeOfDayOverlay.nightTime=(§8Nacht§r) 252 | timeOfDayOverlay.light=(§eLight§r) 253 | timeOfDayOverlay.dark=(§8Dark§r) 254 | 255 | toggleFoVChanges.enabled=FoV changes enabled 256 | toggleFoVChanges.disabled=FoV changes disabled 257 | 258 | key.categories.randomtweaks=RandomTweaks 259 | key.reloadSoundSystem=Soundsystem Neuladen 260 | key.toggleFoVChanges=Toggle FoV Changes 261 | key.toggleTimeOfDayOverlay=Toggle Time of Day Overlay 262 | key.toggleAutoJump=Toggle Auto Jump 263 | key.togglePotionParticles=Toggle Potion Particles 264 | 265 | reloadSoundSystem.success=§eSoundsystem erfolgreich neugeladen! 266 | 267 | autoJump.disabled=Auto jump disabled 268 | autoJump.enabled=Auto jump enabled 269 | autoJump.enabledStepup=Stepup enabled 270 | 271 | commands.rtreloadclient.usage=/rtreloadclient 272 | commands.rtreloadclient.success=RandomTweaks client-sided configuration reloaded! 273 | 274 | commands.disconnect.usage=/disconnect 275 | commands.disconnect.failure=§cAn error occurred while attempting to disconnect: %s 276 | 277 | generator.realistic=Realistisch 278 | generator.realistic.info=Realistischer Welttyp von u/Soniop 279 | generator.void=Void 280 | generator.void.info=An empty void world with only a block to stand on 281 | generator.voidislands=Void Islands 282 | generator.voidislands.info=Islands in the void 283 | 284 | itemGroup.spawnEggs=Spawn Eggs 285 | 286 | spawnEgg.noAI=§cNo AI 287 | 288 | tile.buttonStone.name=Stone Button 289 | tile.buttonWood.name=Wooden Button 290 | tile.endPortal.name=End Portal 291 | tile.endGateway.name=End Gateway 292 | -------------------------------------------------------------------------------- /src/main/resources/assets/randomtweaks/lang/en_us.lang: -------------------------------------------------------------------------------- 1 | randomtweaks.config.animals=Animals 2 | randomtweaks.config.animals.batLeatherDropChance=Bat leather drop chance 3 | randomtweaks.config.animals.coloredSheep=Colored sheep spawns 4 | randomtweaks.config.animals.leashableVillagers=Leashable villagers 5 | randomtweaks.config.animals.ocelotsCanBeHealed=Enable tamed ocelot healing with fish 6 | randomtweaks.config.animals.parrotsCanBeHealed=Enable tamed parrot healing with seeds 7 | randomtweaks.config.animals.protectPetsFromOtherPets=Protect pets from their owners' other pets 8 | randomtweaks.config.animals.protectPetsFromOwners=Protect pets from their owners 9 | randomtweaks.config.animals.protectPetsFromSneakingOwners=Protect pets from sneaking owners 10 | 11 | randomtweaks.config.animals.randomizedAges=Randomized Ages 12 | randomtweaks.config.animals.randomizedAges.chance=Chance that an animal's age is randomized 13 | randomtweaks.config.animals.randomizedAges.maximumAge=Maximum age 14 | randomtweaks.config.animals.randomizedAges.minimumAge=Minimum age 15 | randomtweaks.config.animals.randomizedAges.animalsWhitelist=Animals whitelist 16 | randomtweaks.config.animals.randomizedAges.animals=Animals 17 | 18 | randomtweaks.config.animals.sheepColorWeights=Sheep Color Weights 19 | randomtweaks.config.animals.sheepColorWeights.enabled=Enable colored sheep spawning 20 | randomtweaks.config.animals.sheepColorWeights.white=§fWhite 21 | randomtweaks.config.animals.sheepColorWeights.orange=§6Orange 22 | randomtweaks.config.animals.sheepColorWeights.magenta=§bMagenta 23 | randomtweaks.config.animals.sheepColorWeights.lightBlue=§9Light blue 24 | randomtweaks.config.animals.sheepColorWeights.yellow=§eYellow 25 | randomtweaks.config.animals.sheepColorWeights.lime=§aLime 26 | randomtweaks.config.animals.sheepColorWeights.pink=§dPink 27 | randomtweaks.config.animals.sheepColorWeights.gray=§8Gray 28 | randomtweaks.config.animals.sheepColorWeights.silver=§7Silver 29 | randomtweaks.config.animals.sheepColorWeights.cyan=§3Cyan 30 | randomtweaks.config.animals.sheepColorWeights.purple=§5Purple 31 | randomtweaks.config.animals.sheepColorWeights.blue=§1Blue 32 | randomtweaks.config.animals.sheepColorWeights.brown=§6Brown 33 | randomtweaks.config.animals.sheepColorWeights.green=§2Green 34 | randomtweaks.config.animals.sheepColorWeights.red=§4Red 35 | randomtweaks.config.animals.sheepColorWeights.black=§0Black 36 | 37 | randomtweaks.config.animals.squids=Squid Spawning Behavior 38 | randomtweaks.config.animals.squids.chunkLimit=Amount of squids allowed in one chunk 39 | randomtweaks.config.animals.squids.maxPackSize=Maximum squid spawn pack size 40 | randomtweaks.config.animals.squids.spawnRadiusLimit=Maximum squid spawn radius from player 41 | 42 | randomtweaks.config.boneMeal=Bone Meal 43 | randomtweaks.config.boneMeal.cacti=Cacti 44 | randomtweaks.config.boneMeal.netherWart=Nether wart 45 | randomtweaks.config.boneMeal.sugarCanes=Sugar canes 46 | 47 | randomtweaks.config.client=Client 48 | randomtweaks.config.client.clearWater=Remove underwater fog 49 | randomtweaks.config.client.contributorCapes=Enable contributor capes 50 | randomtweaks.config.client.disableEnderDragonDeathSound=Disable ender dragon death sound 51 | randomtweaks.config.client.disablePotionIcons=Disable potion icons 52 | randomtweaks.config.client.disablePotionShift=Disable potion effect inventory shift 53 | randomtweaks.config.client.disableWitherSpawnSound=Disable wither spawn sound 54 | randomtweaks.config.client.startOnMultiplayerScreen=Start on the multiplayer screen 55 | randomtweaks.config.client.stepup=Enable stepup 56 | randomtweaks.config.client.jumpBoostAffectsStepup=Jump Boost affects stepup 57 | randomtweaks.config.client.stepupEnabledByDefault=Enable stepup by default 58 | randomtweaks.config.client.togglePotionParticlesKeybind=Toggle Potion Particles keybind 59 | randomtweaks.config.client.potionParticlesEnabledByDefault=Potion particles enabled by default 60 | randomtweaks.config.client.storeDataInLocal=Store data in local 61 | 62 | randomtweaks.config.client.armorEquipSounds=Armor Equip Sounds 63 | randomtweaks.config.client.armorEquipSounds.enabled=Enabled 64 | randomtweaks.config.client.armorEquipSounds.elytraSound=Elytra sound 65 | randomtweaks.config.client.armorEquipSounds.pumpkinSound=Pumpkin sound 66 | randomtweaks.config.client.armorEquipSounds.skullSound=Skull sound 67 | 68 | randomtweaks.config.client.autoThirdPerson=Auto Third Person 69 | randomtweaks.config.client.autoThirdPerson.boat=Boat 70 | randomtweaks.config.client.autoThirdPerson.elytra=Elytra 71 | randomtweaks.config.client.autoThirdPerson.enabled=Enable auto-third person 72 | randomtweaks.config.client.autoThirdPerson.horse=Horse 73 | randomtweaks.config.client.autoThirdPerson.minecart=Minecart 74 | randomtweaks.config.client.autoThirdPerson.pig=Pig 75 | randomtweaks.config.client.autoThirdPerson.wings=Wings 76 | randomtweaks.config.client.autoThirdPerson.wingsFlyingTickDelay=Wings flying tick delay 77 | 78 | randomtweaks.config.client.creativeTabs=Creative Tabs 79 | randomtweaks.config.client.creativeTabs.moveBucketCreativeTab=Move the bucket to the Tools creative tab 80 | randomtweaks.config.client.creativeTabs.noAISpawnEggs=No AI spawn eggs 81 | randomtweaks.config.client.creativeTabs.spawnEggsCreativeTab=Move the spawn eggs to their own creative tab 82 | randomtweaks.config.client.creativeTabs.setCommandBlockCreativeTab=Move the command blocks to the Redstone creative tab 83 | randomtweaks.config.client.creativeTabs.setDragonEggCreativeTab=Add the dragon egg to the Decorations creative tab 84 | 85 | randomtweaks.config.client.ding=Ding 86 | randomtweaks.config.client.ding.ignoreDsurroundMuteWhenBackground=Ignore Dynamic Surroundings' "Mute when Background" feature 87 | randomtweaks.config.client.ding.startupSoundPitch=Startup sound pitch 88 | randomtweaks.config.client.ding.startupSoundVolume=Startup sound volume 89 | randomtweaks.config.client.ding.startupSounds=Startup sounds 90 | randomtweaks.config.client.ding.worldLoadSoundPitch=World load sound pitch 91 | randomtweaks.config.client.ding.worldLoadSoundVolume=World load sound volume 92 | randomtweaks.config.client.ding.worldLoadSounds=World load sounds 93 | 94 | randomtweaks.config.client.keybinds=Keybinds 95 | randomtweaks.config.client.keybinds.fovChangesEnabledByDefault=Enable FoV changes by default 96 | randomtweaks.config.client.keybinds.fovChangesStatusMessage=Enable FoV changes status message 97 | randomtweaks.config.client.keybinds.reloadSoundSystem=Enable Reload Sound System keybind 98 | randomtweaks.config.client.keybinds.toggleFoVChanges=Enable Toggle FoV Changes keybind 99 | randomtweaks.config.client.keybinds.toggleTimeOfDayOverlay=Enable Toggle Time of Day Overlay keybind 100 | 101 | randomtweaks.config.client.nightVision=Night Vision 102 | randomtweaks.config.client.nightVision.enabled=Enabled 103 | randomtweaks.config.client.nightVision.brightness=Brightness 104 | randomtweaks.config.client.nightVision.disableFlashing=Disable flashing 105 | randomtweaks.config.client.nightVision.fadeOut=Fade out 106 | randomtweaks.config.client.nightVision.fadeOutTicks=Fade out ticks 107 | 108 | randomtweaks.config.client.timeOfDay=Time of Day Overlay 109 | randomtweaks.config.client.timeOfDay.alignment=Alignment 110 | randomtweaks.config.client.timeOfDay.alignment.topLeft=Top left 111 | randomtweaks.config.client.timeOfDay.alignment.topCenter=Top center 112 | randomtweaks.config.client.timeOfDay.alignment.topRight=Top right 113 | randomtweaks.config.client.timeOfDay.alignment.middleLeft=Middle left 114 | randomtweaks.config.client.timeOfDay.alignment.middleCenter=Middle center 115 | randomtweaks.config.client.timeOfDay.alignment.middleRight=Middle right 116 | randomtweaks.config.client.timeOfDay.alignment.bottomLeft=Bottom left 117 | randomtweaks.config.client.timeOfDay.alignment.bottomCenter=Bottom center 118 | randomtweaks.config.client.timeOfDay.alignment.bottomRight=Bottom right 119 | randomtweaks.config.client.timeOfDay.disableIfNoDaylightCycle=Disable if doDaylightCycle is false 120 | randomtweaks.config.client.timeOfDay.disableInAdventureMode=Disable in adventure mode 121 | randomtweaks.config.client.timeOfDay.disableInGUIs=Disable in GUIs 122 | randomtweaks.config.client.timeOfDay.enabled=Enable time of day overlay 123 | randomtweaks.config.client.timeOfDay.enabledByDefault=Enable by default 124 | randomtweaks.config.client.timeOfDay.lightOrDark=Light or dark 125 | randomtweaks.config.client.timeOfDay.twentyFourHourTime=Use twenty-four hour time 126 | randomtweaks.config.client.timeOfDay.x=X coordinate 127 | randomtweaks.config.client.timeOfDay.y=Y coordinate 128 | 129 | randomtweaks.config.cobwebBurning=Cobweb Burning 130 | randomtweaks.config.cobwebBurning.enableBurning=Enable burning 131 | randomtweaks.config.cobwebBurning.disableBurningIfSneaking=Disable burning if sneaking 132 | randomtweaks.config.cobwebBurning.items=Items 133 | randomtweaks.config.cobwebBurning.consumeAmount=Consume amount 134 | randomtweaks.config.cobwebBurning.damageAmount=Damage amount 135 | randomtweaks.config.cobwebBurning.burnSound=Burn sound 136 | randomtweaks.config.cobwebBurning.flammableCobwebs=Flammable cobwebs 137 | randomtweaks.config.cobwebBurning.cobwebFireSpreadSpeed=Cobweb fire spread speed 138 | randomtweaks.config.cobwebBurning.cobwebFlammability=Cobweb flammability 139 | 140 | randomtweaks.config.commands=Commands 141 | randomtweaks.config.commands.deletegamerule=/deletegamerule 142 | randomtweaks.config.commands.disconnect=/disconnect 143 | randomtweaks.config.commands.giveTweaks=Tweaks to /give 144 | randomtweaks.config.commands.helpTweaks=Tweaks to /help 145 | randomtweaks.config.commands.hunger=/hunger 146 | randomtweaks.config.commands.rtreload=/rtreload 147 | randomtweaks.config.commands.rtreloadclient=/rtreloadclient 148 | 149 | randomtweaks.config.gameRules=Gamerules 150 | randomtweaks.config.gameRules.disableNetherPortalCreation=disableNetherPortalCreation 151 | randomtweaks.config.gameRules.drowningDamageMultiplier=drowningDamageMultiplier 152 | randomtweaks.config.gameRules.fallDamageMultiplier=fallDamageMultiplier 153 | randomtweaks.config.gameRules.fireDamageMultiplier=fireDamageMultiplier 154 | 155 | randomtweaks.config.hunger=Hunger 156 | randomtweaks.config.hunger.carryExcessHungerToSaturation=Carry excess hunger to saturation 157 | randomtweaks.config.hunger.enabled=Enable all hunger tweaks 158 | randomtweaks.config.hunger.exhaustionMultiplier=Exhaustion multiplier 159 | randomtweaks.config.hunger.maximumHungerLevel=Maximum hunger level 160 | randomtweaks.config.hunger.minimumRespawnHungerLevel=Minimum respawn hunger level 161 | randomtweaks.config.hunger.respawnResetBehavior=Hunger respawn reset behavior 162 | randomtweaks.config.hunger.respawnResetBehavior.reset=Reset 163 | randomtweaks.config.hunger.respawnResetBehavior.dontReset=Don't reset 164 | randomtweaks.config.hunger.respawnResetBehavior.resetUnlessKeepInventory=Reset unless keepInventory 165 | randomtweaks.config.hunger.saturationLimit=Value added to food level for saturation limit 166 | 167 | randomtweaks.config.misc=Miscellaneous 168 | randomtweaks.config.misc.attackSpeed=Attack speed 169 | randomtweaks.config.misc.armorStandSwapping=Armor stand swapping 170 | randomtweaks.config.misc.betterButtonNames=Better button names 171 | randomtweaks.config.misc.bowInfinityFix=Bow Infinity fix 172 | randomtweaks.config.misc.burningArrowsSetBlocksOnFire=Burning arrows set blocks on fire 173 | randomtweaks.config.misc.cakeSoundsAndParticles=Cake sounds and particles 174 | randomtweaks.config.misc.disableAttacksDuringAttackCooldown=Disable attacks during attack cooldown 175 | randomtweaks.config.misc.deathPunishmentMode=Death punishment mode 176 | randomtweaks.config.misc.deathPunishmentMode.enabled=Enabled 177 | randomtweaks.config.misc.deathPunishmentMode.enabledIfKeepInventory=Enabled if keepInventory 178 | randomtweaks.config.misc.deathPunishmentMode.disabled=Disabled 179 | randomtweaks.config.misc.disableCumulativeAnvilCosts=Disable cumulative anvil cost 180 | randomtweaks.config.misc.entitiesDropNameTags=Enable living entities with custom names dropping nametags 181 | randomtweaks.config.misc.entityNaNHealthFix=Entity NaN Health Fix 182 | randomtweaks.config.misc.farmlandTrampleBehavior=Farmland trample behavior 183 | randomtweaks.config.misc.farmlandTrampleBehavior.vanilla=Vanilla 184 | randomtweaks.config.misc.farmlandTrampleBehavior.dontTrampleIfFeatherFalling=Don't trample if Feather Falling 185 | randomtweaks.config.misc.farmlandTrampleBehavior.dontTrampleIfFeatherFallingOrWet=Don't trample if Feather Falling or wet 186 | randomtweaks.config.misc.farmlandTrampleBehavior.dontTrampleIfWet=Don't trample if wet 187 | randomtweaks.config.misc.farmlandTrampleBehavior.dontTrample=Don't trample 188 | randomtweaks.config.misc.localizeEndPortalNames=Localize End portal names 189 | randomtweaks.config.misc.mobsDropAllArmorAndEquipment=Mobs drop all armor and equipment 190 | randomtweaks.config.misc.mobsAlwaysDropLoot=Mobs always drop loot 191 | randomtweaks.config.misc.moreRomanNumerals=More Roman numerals 192 | randomtweaks.config.misc.pickUpSkeletonArrows=Allow arrows shot by skeletons to be picked up 193 | randomtweaks.config.misc.shearableCreepers=Shearable creepers 194 | randomtweaks.config.misc.torchReorientationBehavior=Torch reorientation behavior 195 | randomtweaks.config.misc.torchReorientationBehavior.never=Never 196 | randomtweaks.config.misc.torchReorientationBehavior.sneaking=Sneaking 197 | randomtweaks.config.misc.torchReorientationBehavior.notSneaking=Not sneaking 198 | randomtweaks.config.misc.torchReorientationBehavior.always=Always 199 | randomtweaks.config.misc.torchReorientationPriority=Torch reorientation priority 200 | randomtweaks.config.misc.updateAllMapsInInventory=Update all maps in inventory 201 | randomtweaks.config.misc.wetSpongesDryInNether=Wet sponges dry in the Nether 202 | randomtweaks.config.misc.zombieTargetDetectionImprovements=Zombie target detection improvements 203 | 204 | randomtweaks.config.playerHeadDrops=Player Head Drops 205 | randomtweaks.config.playerHeadDrops.enabled=Enable player head drops 206 | randomtweaks.config.playerHeadDrops.chanceWhenKilledByChargedCreeper=Drop chance when killed by a charged creeper 207 | randomtweaks.config.playerHeadDrops.chanceWhenKilledByPlayer=Drop chance when killed by another player 208 | randomtweaks.config.playerHeadDrops.normalChance=Normal drop chance 209 | 210 | randomtweaks.config.sleep=Sleep 211 | randomtweaks.config.sleep.allowSleepNearMobsWithCustomNames=Allow sleep near mobs with custom names 212 | randomtweaks.config.sleep.disableBedProximityRequirement=Disable bed proximity requirement 213 | randomtweaks.config.sleep.nearbyMonsterGlowDuration=Nearby monster glow duration 214 | randomtweaks.config.sleep.nearbyMonsterGlowParticles=Nearby monster glow particles 215 | 216 | randomtweaks.config.world=World 217 | randomtweaks.config.world.cactusSpawnRate=Cactus spawn rate 218 | randomtweaks.config.world.fixDuplicateEntityUUIDs=Fix duplicate entity UUIDs 219 | randomtweaks.config.world.logEntityUUIDReassignments=Log entity UUID reassignments 220 | randomtweaks.config.world.realisticWorldType=Enable Realistic world type 221 | 222 | randomtweaks.config.world.oceanFloor=Ocean Floor Generation 223 | randomtweaks.config.world.oceanFloor.clayChance=Clay spawn chance 224 | randomtweaks.config.world.oceanFloor.clayVeinSize=Clay vein size 225 | randomtweaks.config.world.oceanFloor.dirtChance=Dirt spawn chance 226 | randomtweaks.config.world.oceanFloor.dirtVeinSize=Dirt vein size 227 | randomtweaks.config.world.oceanFloor.enabled=Enable ocean floor generation 228 | randomtweaks.config.world.oceanFloor.maxY=Maximum Y coordinate 229 | randomtweaks.config.world.oceanFloor.minY=Minimum Y coordinate 230 | randomtweaks.config.world.oceanFloor.sandChance=Sand spawn chance 231 | randomtweaks.config.world.oceanFloor.sandVeinSize=Sand vein size 232 | 233 | randomtweaks.config.world.voidWorld=Void World 234 | randomtweaks.config.world.voidWorld.biome=Biome 235 | randomtweaks.config.world.voidWorld.enabled=Enabled 236 | randomtweaks.config.world.voidWorld.mobSpawning=Mob spawning 237 | randomtweaks.config.world.voidWorld.randomBiomeBlacklist=Random biome blacklist 238 | randomtweaks.config.world.voidWorld.spawnBlock=Spawn block 239 | randomtweaks.config.world.voidWorld.spawnBlockMeta=Spawn block meta 240 | randomtweaks.config.world.voidWorld.ySpawn=Y spawn coordinate 241 | 242 | randomtweaks.config.world.voidIslandsWorld=Void Islands World 243 | randomtweaks.config.world.voidIslandsWorld.chunkRarity=Chunk rarity 244 | randomtweaks.config.world.voidIslandsWorld.enabled=Enabled 245 | randomtweaks.config.world.voidIslandsWorld.voidChunkBiome=Void chunk biome 246 | randomtweaks.config.world.voidIslandsWorld.voidChunkRandomBiomeBlacklist=Void chunk random biome blacklist 247 | 248 | timeOfDayOverlay.text=Day %s, %s:%s%s %s 249 | timeOfDayOverlay.am=AM 250 | timeOfDayOverlay.pm=PM 251 | timeOfDayOverlay.dayTime=(§eDay§r) 252 | timeOfDayOverlay.nightTime=(§8Night§r) 253 | timeOfDayOverlay.light=(§eLight§r) 254 | timeOfDayOverlay.dark=(§8Dark§r) 255 | 256 | toggleFoVChanges.enabled=FoV changes enabled 257 | toggleFoVChanges.disabled=FoV changes disabled 258 | 259 | key.categories.randomtweaks=RandomTweaks 260 | key.reloadSoundSystem=Reload Sound System 261 | key.toggleFoVChanges=Toggle FoV Changes 262 | key.toggleTimeOfDayOverlay=Toggle Time of Day Overlay 263 | key.toggleAutoJump=Toggle Auto Jump 264 | key.togglePotionParticles=Toggle Potion Particles 265 | 266 | reloadSoundSystem.success=§eSound system reloaded! 267 | 268 | autoJump.disabled=Auto jump disabled 269 | autoJump.enabled=Auto jump enabled 270 | autoJump.enabledStepup=Stepup enabled 271 | 272 | commands.rtreloadclient.usage=/rtreloadclient 273 | commands.rtreloadclient.success=RandomTweaks client-sided configuration reloaded! 274 | 275 | commands.disconnect.usage=/disconnect 276 | commands.disconnect.failure=§cAn error occurred while attempting to disconnect: %s 277 | 278 | generator.realistic=Realistic 279 | generator.realistic.info=Realistic world type by u/Soniop 280 | generator.void=Void 281 | generator.void.info=An empty void world with only a block to stand on 282 | generator.voidislands=Void Islands 283 | generator.voidislands.info=Islands in the void 284 | 285 | itemGroup.spawnEggs=Spawn Eggs 286 | 287 | spawnEgg.noAI=§cNo AI 288 | 289 | tile.buttonStone.name=Stone Button 290 | tile.buttonWood.name=Wooden Button 291 | tile.endPortal.name=End Portal 292 | tile.endGateway.name=End Gateway 293 | -------------------------------------------------------------------------------- /src/main/resources/assets/randomtweaks/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheRandomLabs/RandomTweaks/6f940dcbaee165ff99b5cd4b5e22c19f6dc8b30a/src/main/resources/assets/randomtweaks/logo.png -------------------------------------------------------------------------------- /src/main/resources/assets/randomtweaks/textures/cape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheRandomLabs/RandomTweaks/6f940dcbaee165ff99b5cd4b5e22c19f6dc8b30a/src/main/resources/assets/randomtweaks/textures/cape.png -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "modid": "randomtweaks", 4 | "name": "RandomTweaks", 5 | "description": "A bunch of miscellaneous tweaks for Minecraft.", 6 | "version": "${version}", 7 | "mcversion": "${mcversion}", 8 | "url": "https://minecraft.curseforge.com/projects/randomtweaks", 9 | "updateJSON": "https://raw.githubusercontent.com/TheRandomLabs/RandomTweaks/misc/versions.json", 10 | "authorList": [ 11 | "TheRandomLabs" 12 | ], 13 | "credits": "", 14 | "logoFile": "assets/randomtweaks/logo.png", 15 | "screenshots": [], 16 | "dependencies": [] 17 | } 18 | ] 19 | -------------------------------------------------------------------------------- /src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "pack_format": 3, 4 | "description": "Resources used by RandomTweaks" 5 | } 6 | } 7 | --------------------------------------------------------------------------------