diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..dfe07704 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..cef22602 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +# eclipse +bin +*.launch +.settings +.metadata +.classpath +.project + +# idea +out +*.ipr +*.iws +*.iml +.idea + +# gradle +build +.gradle + +# other +eclipse +logs +run diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..fc201981 --- /dev/null +++ b/build.gradle @@ -0,0 +1,86 @@ +buildscript { + repositories { + maven { + url = "https://maven.minecraftforge.net" + } + maven { + name = "Sponge" + url = "https://repo.spongepowered.org/maven" + } + } + dependencies { + classpath("com.anatawa12.forge:ForgeGradle:2.3-1.0.+") { + changing = true + } + classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT' + } +} +apply plugin: 'net.minecraftforge.gradle.forge' +apply plugin: 'org.spongepowered.mixin' + +version = "1.12.2-1.0.0" +group = "mod.acgaming.hkntweaks" +archivesBaseName = "HkNTweaks" + +sourceCompatibility = targetCompatibility = '1.8' +compileJava { + sourceCompatibility = targetCompatibility = '1.8' +} + +minecraft { + version = "1.12.2-14.23.5.2847" + runDir = "run" + mappings = "stable_39" + + def args = ["-Dmixin.debug.export=true", + '-Dmixin.hotSwap=true', + '-Dmixin.checks.interfaces=true'] + + clientJvmArgs.addAll(args) + serverJvmArgs.addAll(args) +} + +jar { + manifest { + attributes 'FMLCorePlugin': 'mod.acgaming.hkntweaks.core.HkNTweaksLoadingPlugin' + attributes 'FMLCorePluginContainsFMLMod': 'true' + attributes 'ForceLoadAsMod': 'true' + } +} + +repositories { + maven { + name = "Curse Maven" + url "https://www.cursemaven.com" + } + maven { + name = "CleanroomMC" + url "https://maven.cleanroommc.com" + } + maven { + name = "Sponge" + url = "https://repo.spongepowered.org/maven" + } +} + +dependencies { + deobfCompile "zone.rong:mixinbooter:5.0" +} + +mixin { + add sourceSets.main, "hkntweaks.refmap.json" +} + +processResources { + inputs.property "version", project.version + inputs.property "mcversion", project.minecraft.version + + from(sourceSets.main.resources.srcDirs) { + include 'mcmod.info' + expand 'version': project.version, 'mcversion': project.minecraft.version + } + + from(sourceSets.main.resources.srcDirs) { + exclude 'mcmod.info' + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..878bf1f7 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,4 @@ +# Sets default memory used for gradle commands. Can be overridden by user or command line properties. +# This is required to provide enough memory for the Minecraft decompilation process. +org.gradle.jvmargs=-Xmx3G +org.gradle.daemon=false \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..30d399d8 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..6b071a78 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Sep 14 12:28:28 PDT 2015 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip diff --git a/gradlew b/gradlew new file mode 100644 index 00000000..91a7e269 --- /dev/null +++ b/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..8a0b282a --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/LICENSE b/src/LICENSE new file mode 100644 index 00000000..0a041280 --- /dev/null +++ b/src/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/src/main/java/mod/acgaming/hkntweaks/HkNTweaks.java b/src/main/java/mod/acgaming/hkntweaks/HkNTweaks.java new file mode 100644 index 00000000..98300c55 --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/HkNTweaks.java @@ -0,0 +1,26 @@ +package mod.acgaming.hkntweaks; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; + +@Mod(modid = HkNTweaks.MODID, + name = HkNTweaks.NAME, + version = HkNTweaks.VERSION, + acceptedMinecraftVersions = "[1.12.2]", + dependencies = HkNTweaks.DEPENDENCIES) +public class HkNTweaks +{ + public static final String MODID = "hkntweaks"; + public static final String NAME = "HkN Tweaks"; + public static final String VERSION = "1.12.2-1.0.0"; + public static final String DEPENDENCIES = "required-after:mixinbooter"; + public static final Logger LOGGER = LogManager.getLogger(); + + @Mod.EventHandler + public void init(FMLInitializationEvent event) + { + LOGGER.info("HkN Tweaks initialized"); + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/bugfixes/HkNBlockOverlay.java b/src/main/java/mod/acgaming/hkntweaks/bugfixes/HkNBlockOverlay.java new file mode 100644 index 00000000..cbabcd3e --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/bugfixes/HkNBlockOverlay.java @@ -0,0 +1,129 @@ +package mod.acgaming.hkntweaks.bugfixes; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; + +import org.lwjgl.opengl.GL11; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.GlStateManager.CullFace; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.util.EnumBlockRenderType; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockPos.MutableBlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.fml.common.Mod; + +import mod.acgaming.hkntweaks.HkNTweaks; + +// Courtesy of Meldexun +@Mod.EventBusSubscriber(modid = HkNTweaks.MODID) +public class HkNBlockOverlay +{ + @SuppressWarnings("deprecation") + public static void renderNearbyBlocks(float partialTicks) + { + Minecraft mc = Minecraft.getMinecraft(); + if (mc.player.isPlayerSleeping()) + { + return; + } + if (mc.player.isSpectator()) + { + return; + } + + double error = 0.175D; + double x = mc.player.lastTickPosX + (mc.player.posX - mc.player.lastTickPosX) * partialTicks; + double y = mc.player.lastTickPosY + (mc.player.posY - mc.player.lastTickPosY) * partialTicks + mc.player.getEyeHeight(); + double z = mc.player.lastTickPosZ + (mc.player.posZ - mc.player.lastTickPosZ) * partialTicks; + AxisAlignedBB aabb = new AxisAlignedBB(x - error, y - error, z - error, x + error, y + error, z + error); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferBuilder = tessellator.getBuffer(); + boolean[] startedBuilding = new boolean[1]; + + forEachNearbyPos(x, y, z, error, pos -> { + IBlockState state = mc.world.getBlockState(pos); + if (state.getRenderType() == EnumBlockRenderType.INVISIBLE) + { + return; + } + if (Arrays.stream(EnumFacing.VALUES).noneMatch(side -> state.doesSideBlockRendering(mc.world, pos, side))) + { + return; + } + + List aabbs = new ArrayList<>(); + state.getBlock().addCollisionBoxToList(state, mc.world, pos, aabb, aabbs, mc.player, true); + Vec3d vec = new Vec3d(x, y, z); + if (aabbs.stream().noneMatch(aabb1 -> aabb1.grow(error).contains(vec))) + { + return; + } + + if (!startedBuilding[0]) + { + startedBuilding[0] = true; + bufferBuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); + bufferBuilder.setTranslation(-x, -(y - mc.player.getEyeHeight()), -z); + } + IBlockState state1 = state.getActualState(mc.world, pos); + mc.getBlockRendererDispatcher().getBlockModelRenderer().renderModel(mc.world, mc.getBlockRendererDispatcher().getModelForState(state1), state1, pos, bufferBuilder, false); + }); + + if (startedBuilding[0]) + { + bufferBuilder.setTranslation(0, 0, 0); + + GlStateManager.cullFace(CullFace.FRONT); + + tessellator.draw(); + bufferBuilder.reset(); + + GlStateManager.cullFace(CullFace.BACK); + + if (OpenGlHelper.useVbo()) + { + GlStateManager.glEnableClientState(GL11.GL_VERTEX_ARRAY); + OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit); + GlStateManager.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY); + OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit); + GlStateManager.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY); + OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit); + GlStateManager.glEnableClientState(GL11.GL_COLOR_ARRAY); + } + } + } + + private static void forEachNearbyPos(double x, double y, double z, double error, Consumer action) + { + int bx = MathHelper.floor(x); + int by = MathHelper.floor(y); + int bz = MathHelper.floor(z); + MutableBlockPos pos = new MutableBlockPos(); + int used = 0; + for (int i = 0; i < 8; i++) + { + double x1 = x + (((i >> 1) & 2) - 1) * error; + double y1 = y + ((i & 2) - 1) * error; + double z1 = z + (((i << 1) & 2) - 1) * error; + pos.setPos(x1, y1, z1); + int mask = 1 << (((pos.getX() + 1 - bx) * 3 + (pos.getY() + 1 - by)) * 3 + (pos.getZ() + 1 - bz)); + if ((used & mask) != 0) + { + continue; + } + used |= mask; + action.accept(pos); + } + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/bugfixes/HkNMaxHealth.java b/src/main/java/mod/acgaming/hkntweaks/bugfixes/HkNMaxHealth.java new file mode 100644 index 00000000..f4615b94 --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/bugfixes/HkNMaxHealth.java @@ -0,0 +1,48 @@ +package mod.acgaming.hkntweaks.bugfixes; + +import java.util.Set; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.PlayerEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import net.minecraftforge.fml.relauncher.Side; + +import mod.acgaming.hkntweaks.HkNTweaks; + +// Courtesy of Laike-Endaril +@Mod.EventBusSubscriber(modid = HkNTweaks.MODID) +public class HkNMaxHealth +{ + @SubscribeEvent + public static void hknPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) + { + event.player.getTags().add("loginhpgo"); + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public static void hknServerTick(TickEvent.PlayerTickEvent event) + { + if (event.side == Side.SERVER && event.phase == TickEvent.Phase.END) + { + EntityPlayer player = event.player; + Set strings = player.getTags(); + for (String s : strings.toArray(new String[0])) + { + if (s.contains("loginhp") && !s.equals("loginhpgo")) + { + if (strings.contains("loginhpgo")) + { + player.setHealth(player.getMaxHealth() * Float.parseFloat(s.replace("loginhp", ""))); + strings.remove("loginhpgo"); + } + strings.remove(s); + break; + } + } + strings.add("loginhp" + String.format("%.2f", player.getHealth() / player.getMaxHealth())); + } + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/bugfixes/HkNMending.java b/src/main/java/mod/acgaming/hkntweaks/bugfixes/HkNMending.java new file mode 100644 index 00000000..dc8776d9 --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/bugfixes/HkNMending.java @@ -0,0 +1,59 @@ +package mod.acgaming.hkntweaks.bugfixes; + +import java.util.List; + +import com.google.common.collect.Lists; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.item.EntityXPOrb; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Enchantments; +import net.minecraft.item.ItemStack; +import net.minecraftforge.event.entity.player.PlayerPickupXpEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +import mod.acgaming.hkntweaks.HkNTweaks; + +// Courtesy of FloorIsJava +@Mod.EventBusSubscriber(modid = HkNTweaks.MODID) +public class HkNMending +{ + public static final int DURABILITY_PER_XP = 2; + + public static ItemStack getDamagedEnchantedItem(final Enchantment ench, final EntityPlayer player) + { + final List valid = ench.getEntityEquipment(player); + if (valid.isEmpty()) return ItemStack.EMPTY; + else + { + final List choices = Lists.newArrayList(); + for (final ItemStack itemstack : valid) if (!itemstack.isEmpty() && itemstack.isItemDamaged() && EnchantmentHelper.getEnchantmentLevel(ench, itemstack) > 0) choices.add(itemstack); + if (choices.isEmpty()) return ItemStack.EMPTY; + return choices.get(player.getRNG().nextInt(choices.size())); + } + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public static void hknPickupXP(final PlayerPickupXpEvent event) + { + event.setCanceled(true); + final EntityPlayer player = event.getEntityPlayer(); + final EntityXPOrb xp = event.getOrb(); + ItemStack item = getDamagedEnchantedItem(Enchantments.MENDING, player); + player.xpCooldown = 2; + player.onItemPickup(xp, 1); + int repairPower = xp.xpValue * DURABILITY_PER_XP; + while (!item.isEmpty() && repairPower > 0) + { + final int realRepair = Math.min(repairPower, item.getItemDamage()); + repairPower -= realRepair; + item.setItemDamage(item.getItemDamage() - realRepair); + item = getDamagedEnchantedItem(Enchantments.MENDING, player); + } + xp.xpValue = repairPower / DURABILITY_PER_XP; + if (xp.xpValue > 0) player.addExperience(xp.xpValue); + xp.setDead(); + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNBlockOverlayMixin.java b/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNBlockOverlayMixin.java new file mode 100644 index 00000000..3de83dda --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNBlockOverlayMixin.java @@ -0,0 +1,25 @@ +package mod.acgaming.hkntweaks.bugfixes.mixin; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.RenderGlobal; +import net.minecraft.util.BlockRenderLayer; + +import mod.acgaming.hkntweaks.bugfixes.HkNBlockOverlay; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +// Courtesy of Meldexun +@Mixin(RenderGlobal.class) +public class HkNBlockOverlayMixin +{ + @Inject(method = "renderBlockLayer(Lnet/minecraft/util/BlockRenderLayer;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/ChunkRenderContainer;renderChunkLayer(Lnet/minecraft/util/BlockRenderLayer;)V")) + public void hknBlockOverlay(BlockRenderLayer blockLayerIn, CallbackInfo info) + { + if (blockLayerIn == BlockRenderLayer.SOLID) + { + HkNBlockOverlay.renderNearbyBlocks(Minecraft.getMinecraft().getRenderPartialTicks()); + } + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNDimensionChangeMixin.java b/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNDimensionChangeMixin.java new file mode 100644 index 00000000..404640b0 --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNDimensionChangeMixin.java @@ -0,0 +1,46 @@ +package mod.acgaming.hkntweaks.bugfixes.mixin; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.NetHandlerPlayServer; +import net.minecraft.network.play.server.SPacketEntityEffect; +import net.minecraft.network.play.server.SPacketPlayerAbilities; +import net.minecraft.network.play.server.SPacketSetExperience; +import net.minecraft.network.play.server.SPacketUpdateHealth; +import net.minecraft.potion.PotionEffect; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ITeleporter; + +import com.mojang.authlib.GameProfile; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +// MC-124177 +// https://bugs.mojang.com/browse/MC-124177 +@Mixin(EntityPlayerMP.class) +public abstract class HkNDimensionChangeMixin extends EntityPlayer +{ + @Shadow + public NetHandlerPlayServer connection; + + public HkNDimensionChangeMixin(World worldIn, GameProfile gameProfileIn) + { + super(worldIn, gameProfileIn); + } + + @Inject(method = "changeDimension", at = @At(value = "HEAD"), remap = false) + public void hknChangeDimension(int dimensionIn, ITeleporter teleporter, CallbackInfoReturnable cir) + { + this.connection.sendPacket(new SPacketUpdateHealth(this.getHealth(), this.foodStats.getFoodLevel(), this.foodStats.getSaturationLevel())); + this.connection.sendPacket(new SPacketSetExperience(this.experience, this.experienceTotal, this.experienceLevel)); + this.connection.sendPacket(new SPacketPlayerAbilities(this.capabilities)); + for (PotionEffect effect : getActivePotionEffects()) + { + this.connection.sendPacket(new SPacketEntityEffect(this.getEntityId(), effect)); + } + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNEntityAABBMixin.java b/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNEntityAABBMixin.java new file mode 100644 index 00000000..87357f22 --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNEntityAABBMixin.java @@ -0,0 +1,46 @@ +package mod.acgaming.hkntweaks.bugfixes.mixin; + +import net.minecraft.entity.Entity; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraftforge.common.util.Constants; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +// MC-2025 +// https://bugs.mojang.com/browse/MC-2025 +@Mixin(Entity.class) +public abstract class HkNEntityAABBMixin +{ + @Shadow + public abstract AxisAlignedBB getEntityBoundingBox(); + + @Shadow + public abstract void setEntityBoundingBox(AxisAlignedBB bb); + + @Inject(method = "writeToNBT", at = @At(value = "INVOKE", target = "Lnet/minecraft/nbt/NBTTagCompound;setTag(Ljava/lang/String;Lnet/minecraft/nbt/NBTBase;)V", ordinal = 2)) + public void hknWriteAABBToNBT(NBTTagCompound compound, CallbackInfoReturnable cir) + { + AxisAlignedBB aabb = this.getEntityBoundingBox(); + if (aabb != null) compound.setTag("AABB", newDoubleNBTList(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ)); + } + + @Inject(method = "readFromNBT", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;setRotation(FF)V")) + public void hknReadAABBFromNBT(NBTTagCompound compound, CallbackInfo ci) + { + if (compound.hasKey("AABB")) + { + NBTTagList aabbNbt = compound.getTagList("AABB", Constants.NBT.TAG_DOUBLE); + this.setEntityBoundingBox(new AxisAlignedBB(aabbNbt.getDoubleAt(0), aabbNbt.getDoubleAt(1), aabbNbt.getDoubleAt(2), aabbNbt.getDoubleAt(3), aabbNbt.getDoubleAt(4), aabbNbt.getDoubleAt(5))); + } + } + + @Shadow + protected abstract NBTTagList newDoubleNBTList(double... numbers); +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNLadderFlyingMixin.java b/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNLadderFlyingMixin.java new file mode 100644 index 00000000..4eb11d55 --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNLadderFlyingMixin.java @@ -0,0 +1,19 @@ +package mod.acgaming.hkntweaks.bugfixes.mixin; + +import net.minecraft.entity.EntityLivingBase; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import zone.rong.mixinextras.injector.ModifyExpressionValue; + +// MC-12829 +// https://bugs.mojang.com/browse/MC-12829 +@Mixin(EntityLivingBase.class) +public class HkNLadderFlyingMixin +{ + @ModifyExpressionValue(method = "isOnLadder", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/EntityPlayer;isSpectator()Z")) + public boolean hknIsNotClimbing(boolean isSpectator) + { + return isSpectator; + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNLadderFlyingPlayerMixin.java b/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNLadderFlyingPlayerMixin.java new file mode 100644 index 00000000..00801033 --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNLadderFlyingPlayerMixin.java @@ -0,0 +1,22 @@ +package mod.acgaming.hkntweaks.bugfixes.mixin; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerCapabilities; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +// MC-12829 +// https://bugs.mojang.com/browse/MC-12829 +@Mixin(EntityPlayer.class) +public class HkNLadderFlyingPlayerMixin extends HkNLadderFlyingMixin +{ + @Shadow + public PlayerCapabilities capabilities; + + @Override + public boolean hknIsNotClimbing(boolean isSpectator) + { + return isSpectator || (capabilities.isFlying); + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNPistonChunkMixin.java b/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNPistonChunkMixin.java new file mode 100644 index 00000000..04335663 --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNPistonChunkMixin.java @@ -0,0 +1,25 @@ +package mod.acgaming.hkntweaks.bugfixes.mixin; + +import java.util.HashMap; +import java.util.LinkedHashMap; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.Chunk; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import zone.rong.mixinextras.injector.ModifyExpressionValue; + +// MC-89146 +// https://bugs.mojang.com/browse/MC-89146 +// Courtesy of Xcom6000 +@Mixin(Chunk.class) +public class HkNPistonChunkMixin +{ + @ModifyExpressionValue(method = "", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/Maps;newHashMap()Ljava/util/HashMap;")) + public HashMap hknWrapLinkedHashMap(HashMap hashMap) + { + return new LinkedHashMap<>(hashMap); + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNPistonTileMixin.java b/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNPistonTileMixin.java new file mode 100644 index 00000000..04bb9aac --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNPistonTileMixin.java @@ -0,0 +1,71 @@ +package mod.acgaming.hkntweaks.bugfixes.mixin; + +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityPiston; +import net.minecraft.util.EnumFacing; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +// MC-89146 +// https://bugs.mojang.com/browse/MC-89146 +// Courtesy of Xcom6000 +@Mixin(TileEntityPiston.class) +public class HkNPistonTileMixin extends TileEntity +{ + @Shadow + private IBlockState pistonState; + + @Shadow + private EnumFacing pistonFacing; + + @Shadow + private float progress; + + @Shadow + private float lastProgress; + + @Shadow + private boolean extending; + + @Shadow + private boolean shouldHeadBeRendered; + + /** + * @author ACGaming + * @reason Fix piston progress + */ + @Overwrite + public void readFromNBT(NBTTagCompound compound) + { + super.readFromNBT(compound); + this.pistonState = Block.getBlockById(compound.getInteger("blockId")).getStateFromMeta(compound.getInteger("blockData")); + this.pistonFacing = EnumFacing.byIndex(compound.getInteger("facing")); + this.progress = compound.getFloat("progress"); + this.lastProgress = compound.getFloat("lastProgress"); + this.extending = compound.getBoolean("extending"); + this.shouldHeadBeRendered = compound.getBoolean("source"); + } + + /** + * @author ACGaming + * @reason Fix piston progress + */ + @Overwrite + public NBTTagCompound writeToNBT(NBTTagCompound compound) + { + super.writeToNBT(compound); + compound.setInteger("blockId", Block.getIdFromBlock(this.pistonState.getBlock())); + compound.setInteger("blockData", this.pistonState.getBlock().getMetaFromState(this.pistonState)); + compound.setInteger("facing", this.pistonFacing.getIndex()); + compound.setFloat("progress", this.progress); + compound.setFloat("lastProgress", this.lastProgress); + compound.setBoolean("extending", this.extending); + compound.setBoolean("source", this.shouldHeadBeRendered); + return compound; + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNSkeletonAimMixin.java b/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNSkeletonAimMixin.java new file mode 100644 index 00000000..b699661d --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/bugfixes/mixin/HkNSkeletonAimMixin.java @@ -0,0 +1,30 @@ +package mod.acgaming.hkntweaks.bugfixes.mixin; + +import net.minecraft.entity.IRangedAttackMob; +import net.minecraft.entity.ai.EntityAIAttackRangedBow; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.monster.EntityMob; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +// MC-121706 +// https://bugs.mojang.com/browse/MC-121706 +@Mixin(EntityAIAttackRangedBow.class) +public abstract class HkNSkeletonAimMixin extends EntityAIBase +{ + @Shadow + @Final + private T entity; + + @SuppressWarnings("ConstantConditions") + @Inject(method = "updateTask", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/ai/EntityLookHelper;setLookPositionWithEntity(Lnet/minecraft/entity/Entity;FF)V", shift = At.Shift.AFTER)) + public void hknLookAtTarget(CallbackInfo ci) + { + this.entity.getLookHelper().setLookPositionWithEntity(this.entity.getAttackTarget(), 30.0F, 30.0F); + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/config/HkNTweaksConfig.java b/src/main/java/mod/acgaming/hkntweaks/config/HkNTweaksConfig.java new file mode 100644 index 00000000..552f96a0 --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/config/HkNTweaksConfig.java @@ -0,0 +1,69 @@ +package mod.acgaming.hkntweaks.config; + +import net.minecraftforge.common.config.Config; +import net.minecraftforge.common.config.ConfigManager; +import net.minecraftforge.fml.client.event.ConfigChangedEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +import mod.acgaming.hkntweaks.HkNTweaks; + +@Config(modid = HkNTweaks.MODID, name = "HkNTweaks") +public class HkNTweaksConfig +{ + @Config.Name("Bugfixes") + public static BugfixesCategory bugfixes = new BugfixesCategory(); + + @Config.Name("Tweaks") + public static TweaksCategory tweaks = new TweaksCategory(); + + public static class BugfixesCategory + { + + } + + public static class TweaksCategory + { + @Config.Name("Auto Jump Toggle") + @Config.Comment("") + public boolean hknAutoJumpToggle = true; + + @Config.Name("Bed Obstruction Toggle") + @Config.Comment("") + public boolean hknBedObstructionToggle = true; + + @Config.Name("Bow Infinity Toggle") + @Config.Comment("") + public boolean hknBowInfinityToggle = true; + + @Config.Name("Water Fall Damage Toggle") + @Config.Comment("") + public boolean hknFallDamageToggle = false; + + @Config.Name("Water Fall Damage Reduction") + @Config.Comment("How much fall damage gets reduced by water per tick") + public float hknFallDamageSubtrahend = 2F; + + @Config.Name("Mob Despawn Toggle") + @Config.Comment("") + public boolean hknMobDespawnToggle = true; + + @Config.Name("Offhand Toggle") + @Config.Comment("") + public boolean hknOffhandToggle = true; + } + + @Mod.EventBusSubscriber(modid = HkNTweaks.MODID) + public static class EventHandler + { + @SubscribeEvent + public static void onConfigChanged(final ConfigChangedEvent.OnConfigChangedEvent event) + { + if (event.getModID().equals(HkNTweaks.MODID)) + { + ConfigManager.sync(HkNTweaks.MODID, Config.Type.INSTANCE); + HkNTweaks.LOGGER.info("HkN Tweaks config reloaded"); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/core/HkNTweaksContainer.java b/src/main/java/mod/acgaming/hkntweaks/core/HkNTweaksContainer.java new file mode 100644 index 00000000..0bf33336 --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/core/HkNTweaksContainer.java @@ -0,0 +1,27 @@ +package mod.acgaming.hkntweaks.core; + +import com.google.common.eventbus.EventBus; +import net.minecraftforge.fml.common.DummyModContainer; +import net.minecraftforge.fml.common.LoadController; +import net.minecraftforge.fml.common.ModMetadata; + +public class HkNTweaksContainer extends DummyModContainer +{ + public HkNTweaksContainer() + { + super(new ModMetadata()); + ModMetadata meta = this.getMetadata(); + meta.modId = "hkntweakscore"; + meta.name = "HkN Tweaks Core"; + meta.description = "Core functionality of HkN Tweaks"; + meta.version = "1.12.2-1.0.0"; + meta.authorList.add("ACGaming"); + } + + @Override + public boolean registerBus(EventBus bus, LoadController controller) + { + bus.register(this); + return true; + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/core/HkNTweaksLoadingPlugin.java b/src/main/java/mod/acgaming/hkntweaks/core/HkNTweaksLoadingPlugin.java new file mode 100644 index 00000000..4d4136f3 --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/core/HkNTweaksLoadingPlugin.java @@ -0,0 +1,97 @@ +package mod.acgaming.hkntweaks.core; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import javax.annotation.Nullable; + +import net.minecraftforge.common.ForgeVersion; +import net.minecraftforge.fml.relauncher.FMLLaunchHandler; +import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin; +import net.minecraftforge.fml.relauncher.Side; + +import mod.acgaming.hkntweaks.HkNTweaks; +import mod.acgaming.hkntweaks.config.HkNTweaksConfig; +import zone.rong.mixinbooter.IEarlyMixinLoader; + +@IFMLLoadingPlugin.Name("HkNTweaksCore") +@IFMLLoadingPlugin.MCVersion(ForgeVersion.mcVersion) +@IFMLLoadingPlugin.SortingIndex(Integer.MIN_VALUE) +public class HkNTweaksLoadingPlugin implements IFMLLoadingPlugin, IEarlyMixinLoader +{ + public static final boolean isClient = FMLLaunchHandler.side() == Side.CLIENT; + + static + { + HkNTweaks.LOGGER.info("HkN Tweaks Core initializing..."); + } + + @Override + public String[] getASMTransformerClass() + { + return new String[0]; + } + + @Override + public String getModContainerClass() + { + return HkNTweaksContainer.class.getName(); + } + + @Nullable + @Override + public String getSetupClass() + { + return null; + } + + @Override + public void injectData(Map data) + { + + } + + @Override + public String getAccessTransformerClass() + { + return null; + } + + @Override + public List getMixinConfigs() + { + return isClient ? Collections.singletonList( + "mixins.tweaks.autojump.json" + ) : Arrays.asList( + "mixins.bugfixes.json", + "mixins.tweaks.bedobstruction.json", + "mixins.tweaks.falldamage.json", + "mixins.tweaks.mobdespawn.json" + ); + } + + @Override + public boolean shouldMixinConfigQueue(String mixinConfig) + { + if (isClient) + { + if ("mixins.tweaks.autojump.json".equals(mixinConfig)) + { + return HkNTweaksConfig.tweaks.hknAutoJumpToggle; + } + } + switch (mixinConfig) + { + case "mixins.bugfixes.json": + return true; + case "mixins.tweaks.bedobstruction.json": + return HkNTweaksConfig.tweaks.hknBedObstructionToggle; + case "mixins.tweaks.falldamage.json": + return HkNTweaksConfig.tweaks.hknFallDamageToggle; + case "mixins.tweaks.mobdespawn.json": + return HkNTweaksConfig.tweaks.hknMobDespawnToggle; + } + return true; + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/tweaks/HkNBowInfinity.java b/src/main/java/mod/acgaming/hkntweaks/tweaks/HkNBowInfinity.java new file mode 100644 index 00000000..cd99c3a1 --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/tweaks/HkNBowInfinity.java @@ -0,0 +1,32 @@ +package mod.acgaming.hkntweaks.tweaks; + +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraftforge.event.entity.player.ArrowNockEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.registry.GameRegistry; + +import mod.acgaming.hkntweaks.HkNTweaks; +import mod.acgaming.hkntweaks.config.HkNTweaksConfig; + +// Courtesy of Parker8283 +@Mod.EventBusSubscriber(modid = HkNTweaks.MODID) +public class HkNBowInfinity +{ + @GameRegistry.ObjectHolder("minecraft:infinity") + public static final Enchantment INFINITY = null; + + @SubscribeEvent + public static void hknBowInfinity(ArrowNockEvent event) + { + if (!HkNTweaksConfig.tweaks.hknBowInfinityToggle) return; + if (EnchantmentHelper.getEnchantmentLevel(INFINITY, event.getBow()) > 0) + { + event.getEntityPlayer().setActiveHand(event.getHand()); + event.setAction(new ActionResult<>(EnumActionResult.SUCCESS, event.getBow())); + } + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/tweaks/HkNOffhand.java b/src/main/java/mod/acgaming/hkntweaks/tweaks/HkNOffhand.java new file mode 100644 index 00000000..84f0abd9 --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/tweaks/HkNOffhand.java @@ -0,0 +1,31 @@ +package mod.acgaming.hkntweaks.tweaks; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemFood; +import net.minecraft.util.EnumHand; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.Event; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +import mod.acgaming.hkntweaks.HkNTweaks; +import mod.acgaming.hkntweaks.config.HkNTweaksConfig; + +@Mod.EventBusSubscriber(modid = HkNTweaks.MODID) +public class HkNOffhand +{ + @SubscribeEvent + public static void hknOffhand(PlayerInteractEvent.RightClickBlock event) + { + if (!HkNTweaksConfig.tweaks.hknOffhandToggle) return; + EntityPlayer player = event.getEntityPlayer(); + Item heldItemMainhand = player.getHeldItemMainhand().getItem(); + Item heldItemOffhand = player.getHeldItemOffhand().getItem(); + if (event.getHand() == EnumHand.OFF_HAND + && heldItemOffhand instanceof ItemBlock + && (heldItemMainhand instanceof ItemBlock || heldItemMainhand instanceof ItemFood)) + event.setUseItem(Event.Result.DENY); + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/tweaks/mixin/HkNAutoJumpMixin.java b/src/main/java/mod/acgaming/hkntweaks/tweaks/mixin/HkNAutoJumpMixin.java new file mode 100644 index 00000000..6ff491ae --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/tweaks/mixin/HkNAutoJumpMixin.java @@ -0,0 +1,22 @@ +package mod.acgaming.hkntweaks.tweaks.mixin; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +// Courtesy of Aroma1997 +@Mixin(EntityPlayerSP.class) +public class HkNAutoJumpMixin +{ + @Inject(method = "isAutoJumpEnabled", at = @At("RETURN"), cancellable = true) + public void hkNAutoJump(CallbackInfoReturnable cir) + { + if (Minecraft.getMinecraft().gameSettings.autoJump && !Minecraft.getMinecraft().player.isSneaking()) Minecraft.getMinecraft().player.stepHeight = 1.2f; + else Minecraft.getMinecraft().player.stepHeight = 0.6f; + cir.setReturnValue(false); + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/tweaks/mixin/HkNBedObstructionMixin.java b/src/main/java/mod/acgaming/hkntweaks/tweaks/mixin/HkNBedObstructionMixin.java new file mode 100644 index 00000000..31e93f59 --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/tweaks/mixin/HkNBedObstructionMixin.java @@ -0,0 +1,79 @@ +package mod.acgaming.hkntweaks.tweaks.mixin; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockHorizontal; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +// Courtesy of fonnymunkey +@Mixin(EntityPlayer.class) +public class HkNBedObstructionMixin +{ + @Inject(at = @At("HEAD"), method = "getBedSpawnLocation(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Z)Lnet/minecraft/util/math/BlockPos;", cancellable = true) + private static void hknBedSpawnLocation(World worldIn, BlockPos bedLocation, boolean forceSpawn, CallbackInfoReturnable callback) + { + IBlockState state = worldIn.getBlockState(bedLocation); + Block block = state.getBlock(); + if (!block.isBed(state, worldIn, bedLocation, null)) + { + if (!forceSpawn) callback.setReturnValue(null); + else callback.setReturnValue(iterateSpawnPoint(worldIn, bedLocation)); + } + else callback.setReturnValue(iterateBedPoint(worldIn, bedLocation)); + } + + private static BlockPos iterateSpawnPoint(World world, BlockPos pos) + { + if (isValidSpawnPos(world, pos, false)) return pos; + int x = pos.getX(); + int y = pos.getY(); + int z = pos.getZ(); + for (int xIter = x - 1; xIter <= x + 1; ++xIter) + { + for (int zIter = z - 1; zIter <= z + 1; ++zIter) + { + BlockPos blockPos = new BlockPos(xIter, y, zIter); + if (isValidSpawnPos(world, blockPos, false)) return blockPos; + } + } + return null; + } + + private static BlockPos iterateBedPoint(World world, BlockPos pos) + { + EnumFacing enumfacing = world.getBlockState(pos).getValue(BlockHorizontal.FACING); + int x = pos.getX(); + int y = pos.getY(); + int z = pos.getZ(); + for (int yOffset = 0; yOffset <= 1; ++yOffset) + { + for (int facingOffset = 0; facingOffset <= 1; ++facingOffset) + { + int xOffset = x - enumfacing.getXOffset() * facingOffset; + int zOffset = z - enumfacing.getZOffset() * facingOffset; + for (int xIter = xOffset - 1; xIter <= xOffset + 1; ++xIter) + { + for (int zIter = zOffset - 1; zIter <= zOffset + 1; ++zIter) + { + BlockPos blockPos = new BlockPos(xIter, y + yOffset, zIter); + if (isValidSpawnPos(world, blockPos, true)) return blockPos; + } + } + } + } + return null; + } + + private static boolean isValidSpawnPos(World worldIn, BlockPos blockPos, boolean requireFloor) + { + return (worldIn.getBlockState(blockPos.down()).getMaterial().isSolid() || !requireFloor) && worldIn.getBlockState(blockPos).getBlock().canSpawnInBlock() && worldIn.getBlockState(blockPos.up()).getBlock().canSpawnInBlock(); + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/tweaks/mixin/HkNFallDamageMixin.java b/src/main/java/mod/acgaming/hkntweaks/tweaks/mixin/HkNFallDamageMixin.java new file mode 100644 index 00000000..34fdc0da --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/tweaks/mixin/HkNFallDamageMixin.java @@ -0,0 +1,32 @@ +package mod.acgaming.hkntweaks.tweaks.mixin; + +import net.minecraft.entity.Entity; + +import mod.acgaming.hkntweaks.config.HkNTweaksConfig; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(Entity.class) +public class HkNFallDamageMixin +{ + @Shadow + public float fallDistance; + @Unique + public float hknFallDistance; + + @Inject(method = "handleWaterMovement", at = @At("HEAD")) + public void hknStoreFallDistance(CallbackInfoReturnable cir) + { + hknFallDistance = this.fallDistance; + } + + @Inject(method = "handleWaterMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;extinguish()V")) + public void hknLoadFallDistance(CallbackInfoReturnable cir) + { + this.fallDistance = hknFallDistance - HkNTweaksConfig.tweaks.hknFallDamageSubtrahend; + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/hkntweaks/tweaks/mixin/HkNMobDespawnMixin.java b/src/main/java/mod/acgaming/hkntweaks/tweaks/mixin/HkNMobDespawnMixin.java new file mode 100644 index 00000000..0fdbfd50 --- /dev/null +++ b/src/main/java/mod/acgaming/hkntweaks/tweaks/mixin/HkNMobDespawnMixin.java @@ -0,0 +1,52 @@ +package mod.acgaming.hkntweaks.tweaks.mixin; + +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +// Courtesy of frikinjay +@Mixin(EntityLiving.class) +public abstract class HkNMobDespawnMixin extends EntityLivingBase +{ + public boolean pickedItems = false; + @Shadow + private boolean persistenceRequired; + + public HkNMobDespawnMixin(World worldIn) + { + super(worldIn); + } + + @Inject(at = @At("TAIL"), method = "updateEquipmentIfNeeded") + public void hknUpdateEquipmentIfNeeded(CallbackInfo info) + { + this.pickedItems = true; + this.persistenceRequired = this.hasCustomName(); + } + + @Redirect(method = "despawnEntity", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/EntityLiving;setDead()V")) + public void hknDespawnEntity(EntityLiving instance) + { + if (this.pickedItems) this.dropEquipmentOnDespawn(); + this.setDead(); + } + + public void dropEquipmentOnDespawn() + { + for (EntityEquipmentSlot entityequipmentslot : EntityEquipmentSlot.values()) + { + ItemStack itemstack = this.getItemStackFromSlot(entityequipmentslot); + if (!itemstack.isEmpty() && !EnchantmentHelper.hasVanishingCurse(itemstack)) this.entityDropItem(itemstack, 0.0F); + } + } +} \ No newline at end of file diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info new file mode 100644 index 00000000..40307861 --- /dev/null +++ b/src/main/resources/mcmod.info @@ -0,0 +1,16 @@ +[ + { + "modid": "hkntweaks", + "name": "HkN Tweaks", + "description": "ACGaming's assorted collection of bugfixes and tweaks", + "version": "${version}", + "mcversion": "${mcversion}", + "url": "", + "authorList": [ + "ACGaming" + ], + "dependencies": [ + "mixinbooter" + ] + } +] \ No newline at end of file diff --git a/src/main/resources/mixins.bugfixes.json b/src/main/resources/mixins.bugfixes.json new file mode 100644 index 00000000..2f7ddc79 --- /dev/null +++ b/src/main/resources/mixins.bugfixes.json @@ -0,0 +1,8 @@ +{ + "package": "mod.acgaming.hkntweaks.bugfixes.mixin", + "refmap": "hkntweaks.refmap.json", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": ["HkNDimensionChangeMixin", "HkNEntityAABBMixin", "HkNLadderFlyingMixin", "HkNLadderFlyingPlayerMixin", "HkNPistonChunkMixin", "HkNPistonTileMixin", "HkNSkeletonAimMixin"], + "client": ["HkNBlockOverlayMixin"] +} \ No newline at end of file diff --git a/src/main/resources/mixins.tweaks.autojump.json b/src/main/resources/mixins.tweaks.autojump.json new file mode 100644 index 00000000..554b3b24 --- /dev/null +++ b/src/main/resources/mixins.tweaks.autojump.json @@ -0,0 +1,7 @@ +{ + "package": "mod.acgaming.hkntweaks.tweaks.mixin", + "refmap": "hkntweaks.refmap.json", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "client": ["HkNAutoJumpMixin"] +} \ No newline at end of file diff --git a/src/main/resources/mixins.tweaks.bedobstruction.json b/src/main/resources/mixins.tweaks.bedobstruction.json new file mode 100644 index 00000000..3173021b --- /dev/null +++ b/src/main/resources/mixins.tweaks.bedobstruction.json @@ -0,0 +1,7 @@ +{ + "package": "mod.acgaming.hkntweaks.tweaks.mixin", + "refmap": "hkntweaks.refmap.json", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": ["HkNBedObstructionMixin"] +} \ No newline at end of file diff --git a/src/main/resources/mixins.tweaks.falldamage.json b/src/main/resources/mixins.tweaks.falldamage.json new file mode 100644 index 00000000..daae708e --- /dev/null +++ b/src/main/resources/mixins.tweaks.falldamage.json @@ -0,0 +1,7 @@ +{ + "package": "mod.acgaming.hkntweaks.tweaks.mixin", + "refmap": "hkntweaks.refmap.json", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": ["HkNFallDamageMixin"] +} \ No newline at end of file diff --git a/src/main/resources/mixins.tweaks.mobdespawn.json b/src/main/resources/mixins.tweaks.mobdespawn.json new file mode 100644 index 00000000..9d9e206d --- /dev/null +++ b/src/main/resources/mixins.tweaks.mobdespawn.json @@ -0,0 +1,7 @@ +{ + "package": "mod.acgaming.hkntweaks.tweaks.mixin", + "refmap": "hkntweaks.refmap.json", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": ["HkNMobDespawnMixin"] +} \ No newline at end of file diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta new file mode 100644 index 00000000..c4a0db37 --- /dev/null +++ b/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "pack_format": 3, + "description": "HkN Tweaks assets" + } +} \ No newline at end of file