WIP port to Fabric

Water movement is still broken
This commit is contained in:
Ryan Liptak 2019-09-15 13:51:13 -07:00
parent 076e4c0a8f
commit 0da195ebb5
26 changed files with 797 additions and 742 deletions

View File

@ -1,49 +1,50 @@
buildscript {
repositories {
jcenter()
maven {
name = "forge"
url = "http://files.minecraftforge.net/maven"
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
}
plugins {
id 'fabric-loom' version '0.2.5-SNAPSHOT'
}
apply plugin: 'net.minecraftforge.gradle.forge'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
archivesBaseName = project.archives_base_name
group = project.maven_group
minecraft {
version = "14.23.0.2486"
mappings = "snapshot_20170625"
runDir = "run"
coreMod = "squeek.quakemovement.ASMPlugin"
replace "\${version}", project.version
replaceIn "ModInfo.java"
}
group = project.projectDir.name.toLowerCase()
archivesBaseName = project.projectDir.name + "-mc" + project.minecraft.version
sourceSets.main.java.srcDirs += 'java'
sourceSets.main.resources.srcDirs += 'resources'
jar {
manifest {
attributes 'FMLCorePlugin': 'squeek.quakemovement.ASMPlugin'
attributes 'FMLCorePluginContainsFMLMod': 'true'
}
dependencies {
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}"
modCompile "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api-base:+"
include "net.fabricmc.fabric-api:fabric-api-base:+"
modImplementation "net.fabricmc.fabric-api:fabric-keybindings-v0:+"
include "net.fabricmc.fabric-api:fabric-keybindings-v0:+"
}
processResources {
inputs.property "vars", project.version + project.minecraft.version
from(sourceSets.main.resources.srcDirs) {
include '**/*.info'
expand 'version':project.version, 'mcversion':project.minecraft.version
}
from(sourceSets.main.resources.srcDirs) {
exclude '**/*.info'
}
}
inputs.property "vars", project.version
from(sourceSets.main.resources.srcDirs) {
include '**/fabric.mod.json'
expand 'version':project.version
}
from(sourceSets.main.resources.srcDirs) {
exclude '**/fabric.mod.json'
}
}
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = "sources"
from sourceSets.main.allSource
}
jar {
from "LICENSE"
}

12
gradle.properties Normal file
View File

@ -0,0 +1,12 @@
# Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx1G
# Fabric Properties
# check these on https://fabricmc.net/use
minecraft_version=1.14.4
yarn_mappings=1.14.4+build.5
loader_version=0.4.8+build.159
# Mod Properties
maven_group = squeek.quakemovement
archives_base_name = squake

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,6 @@
#Mon Aug 22 17:36:22 EDT 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip

169
gradlew vendored Normal file
View File

@ -0,0 +1,169 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# 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\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# 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
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
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" -a "$nonstop" = "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"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# 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"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

84
gradlew.bat vendored Normal file
View File

@ -0,0 +1,84 @@
@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
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@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=
@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 Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_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=%*
: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

View File

@ -1,234 +0,0 @@
package squeek.quakemovement;
import net.minecraft.launchwrapper.IClassTransformer;
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.*;
import java.util.Map;
@IFMLLoadingPlugin.MCVersion("1.12.2")
public class ASMPlugin implements IFMLLoadingPlugin, IClassTransformer
{
public static boolean isObfuscated = false;
private static String CLASS_ENTITY_PLAYER = "net.minecraft.entity.player.EntityPlayer";
private static String CLASS_ENTITY = "net.minecraft.entity.Entity";
private static String CLASS_QUAKE_CLIENT_PLAYER = "squeek.quakemovement.QuakeClientPlayer";
private static String CLASS_QUAKE_SERVER_PLAYER = "squeek.quakemovement.QuakeServerPlayer";
@Override
public byte[] transform(String name, String transformedName, byte[] bytes)
{
if (transformedName.equals(CLASS_ENTITY_PLAYER))
{
ClassNode classNode = readClassFromBytes(bytes);
MethodNode method;
method = findMethodNodeOfClass(classNode, isObfuscated ? "a" : "travel", "(FFF)V");
if (method == null)
throw new RuntimeException("could not find EntityPlayer.travel");
InsnList loadParameters = new InsnList();
loadParameters.add(new VarInsnNode(Opcodes.ALOAD, 0));
loadParameters.add(new VarInsnNode(Opcodes.FLOAD, 1));
loadParameters.add(new VarInsnNode(Opcodes.FLOAD, 2));
loadParameters.add(new VarInsnNode(Opcodes.FLOAD, 3));
injectStandardHook(method, findFirstInstruction(method), CLASS_QUAKE_CLIENT_PLAYER, "moveEntityWithHeading", toMethodDescriptor("Z", CLASS_ENTITY_PLAYER, "F", "F", "F"), loadParameters);
method = findMethodNodeOfClass(classNode, isObfuscated ? "n" : "onLivingUpdate", "()V");
if (method == null)
throw new RuntimeException("could not find EntityPlayer.onLivingUpdate");
loadParameters.clear();
loadParameters.add(new VarInsnNode(Opcodes.ALOAD, 0));
injectSimpleHook(method, findFirstInstruction(method), CLASS_QUAKE_CLIENT_PLAYER, "beforeOnLivingUpdate", toMethodDescriptor("V", CLASS_ENTITY_PLAYER), loadParameters);
method = findMethodNodeOfClass(classNode, isObfuscated ? "cu" : "jump", "()V");
if (method == null)
throw new RuntimeException("could not find EntityPlayer.jump");
loadParameters.clear();
loadParameters.add(new VarInsnNode(Opcodes.ALOAD, 0));
injectSimpleHook(method, findLastInstructionWithOpcode(method, Opcodes.RETURN), CLASS_QUAKE_CLIENT_PLAYER, "afterJump", toMethodDescriptor("V", CLASS_ENTITY_PLAYER), loadParameters);
method = findMethodNodeOfClass(classNode, isObfuscated ? "e" : "fall", "(FF)V");
if (method == null)
throw new RuntimeException("could not find EntityPlayer.fall");
loadParameters.clear();
loadParameters.add(new VarInsnNode(Opcodes.ALOAD, 0));
loadParameters.add(new VarInsnNode(Opcodes.FLOAD, 1));
loadParameters.add(new VarInsnNode(Opcodes.FLOAD, 1));
injectSimpleHook(method, findFirstInstruction(method), CLASS_QUAKE_SERVER_PLAYER, "beforeFall", toMethodDescriptor("V", CLASS_ENTITY_PLAYER, "F", "F"), loadParameters);
loadParameters.clear();
loadParameters.add(new VarInsnNode(Opcodes.ALOAD, 0));
loadParameters.add(new VarInsnNode(Opcodes.FLOAD, 1));
loadParameters.add(new VarInsnNode(Opcodes.FLOAD, 1));
injectSimpleHook(method, findLastInstructionWithOpcode(method, Opcodes.RETURN), CLASS_QUAKE_SERVER_PLAYER, "afterFall", toMethodDescriptor("V", CLASS_ENTITY_PLAYER, "F", "F"), loadParameters);
return writeClassToBytes(classNode);
}
else if (transformedName.equals(CLASS_ENTITY))
{
ClassNode classNode = readClassFromBytes(bytes);
MethodNode method;
method = findMethodNodeOfClass(classNode, isObfuscated ? "b" : "moveRelative", "(FFFF)V");
if (method == null)
throw new RuntimeException("could not find Entity.moveRelative");
InsnList loadParameters = new InsnList();
loadParameters.add(new VarInsnNode(Opcodes.ALOAD, 0));
loadParameters.add(new VarInsnNode(Opcodes.FLOAD, 1));
loadParameters.add(new VarInsnNode(Opcodes.FLOAD, 2));
loadParameters.add(new VarInsnNode(Opcodes.FLOAD, 3));
loadParameters.add(new VarInsnNode(Opcodes.FLOAD, 4));
injectStandardHook(method, findFirstInstruction(method), CLASS_QUAKE_CLIENT_PLAYER, "moveRelativeBase", toMethodDescriptor("Z", CLASS_ENTITY, "F", "F", "F", "F"), loadParameters);
return writeClassToBytes(classNode);
}
return bytes;
}
private void injectStandardHook(MethodNode method, AbstractInsnNode node, String hookClassName, String hookMethodName, String hookMethodDescriptor, InsnList loadParameters)
{
InsnList toInject = new InsnList();
LabelNode ifNotCanceled = new LabelNode();
toInject.add(loadParameters);
toInject.add(new MethodInsnNode(Opcodes.INVOKESTATIC, toInternalClassName(hookClassName), hookMethodName, hookMethodDescriptor, false));
toInject.add(new JumpInsnNode(Opcodes.IFEQ, ifNotCanceled));
toInject.add(new InsnNode(Opcodes.RETURN));
toInject.add(ifNotCanceled);
method.instructions.insertBefore(node, toInject);
}
private void injectSimpleHook(MethodNode method, AbstractInsnNode node, String hookClassName, String hookMethodName, String hookMethodDescriptor, InsnList loadParameters)
{
InsnList toInject = new InsnList();
toInject.add(loadParameters);
toInject.add(new MethodInsnNode(Opcodes.INVOKESTATIC, toInternalClassName(hookClassName), hookMethodName, hookMethodDescriptor, false));
method.instructions.insertBefore(node, toInject);
}
@Override
public String[] getASMTransformerClass()
{
return new String[]{this.getClass().getName()};
}
@Override
public String getModContainerClass()
{
return null;
}
@Override
public String getSetupClass()
{
return null;
}
@Override
public void injectData(Map<String, Object> data)
{
isObfuscated = (Boolean) data.get("runtimeDeobfuscationEnabled");
}
@Override
public String getAccessTransformerClass()
{
return null;
}
private ClassNode readClassFromBytes(byte[] bytes)
{
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(bytes);
classReader.accept(classNode, 0);
return classNode;
}
private byte[] writeClassToBytes(ClassNode classNode)
{
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
classNode.accept(writer);
return writer.toByteArray();
}
private MethodNode findMethodNodeOfClass(ClassNode classNode, String methodName, String methodDesc)
{
for (MethodNode method : classNode.methods)
{
if (method.name.equals(methodName) && method.desc.equals(methodDesc))
{
return method;
}
}
return null;
}
private static String toInternalClassName(String className)
{
return className.replace('.', '/');
}
private static boolean isDescriptor(String descriptor)
{
return descriptor.length() == 1 || (descriptor.startsWith("L") && descriptor.endsWith(";"));
}
private static String toDescriptor(String className)
{
return isDescriptor(className) ? className : "L" + toInternalClassName(className) + ";";
}
private static String toMethodDescriptor(String returnType, String... paramTypes)
{
StringBuilder paramDescriptors = new StringBuilder();
for (String paramType : paramTypes)
paramDescriptors.append(toDescriptor(paramType));
return "(" + paramDescriptors.toString() + ")" + toDescriptor(returnType);
}
private static boolean isLabelOrLineNumber(AbstractInsnNode insn)
{
return insn.getType() == AbstractInsnNode.LABEL || insn.getType() == AbstractInsnNode.LINE;
}
private static AbstractInsnNode getOrFindInstruction(AbstractInsnNode firstInsnToCheck, boolean reverseDirection)
{
for (AbstractInsnNode instruction = firstInsnToCheck; instruction != null; instruction = reverseDirection ? instruction.getPrevious() : instruction.getNext())
{
if (!isLabelOrLineNumber(instruction))
return instruction;
}
return null;
}
private static AbstractInsnNode findFirstInstruction(MethodNode method)
{
return getOrFindInstruction(method.instructions.getFirst(), false);
}
public static AbstractInsnNode getOrFindInstructionWithOpcode(AbstractInsnNode firstInsnToCheck, int opcode, boolean reverseDirection)
{
for (AbstractInsnNode instruction = firstInsnToCheck; instruction != null; instruction = reverseDirection ? instruction.getPrevious() : instruction.getNext())
{
if (instruction.getOpcode() == opcode)
return instruction;
}
return null;
}
public static AbstractInsnNode findLastInstructionWithOpcode(MethodNode method, int opcode)
{
return getOrFindInstructionWithOpcode(method.instructions.getLast(), opcode, true);
}
}

View File

@ -0,0 +1,32 @@
package squeek.quakemovement;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding;
import net.fabricmc.fabric.api.client.keybinding.KeyBindingRegistry;
import net.minecraft.client.util.InputUtil;
import net.minecraft.util.Identifier;
import org.lwjgl.glfw.GLFW;
@Environment(EnvType.CLIENT)
public class KeyBindInitializer implements ClientModInitializer
{
public static FabricKeyBinding ENABLE;
public static String CATEGORY = "fabric.mods." + ModInfo.MODID;
@Override
public void onInitializeClient()
{
KeyBindingRegistry.INSTANCE.addCategory(CATEGORY);
ENABLE = registerKey("enable", GLFW.GLFW_KEY_UNKNOWN, CATEGORY);
}
public static FabricKeyBinding registerKey(String name, Integer code, String category)
{
FabricKeyBinding key = FabricKeyBinding.Builder.create(new Identifier(ModInfo.MODID, name), InputUtil.Type.KEYSYM, code, category).build();
KeyBindingRegistry.INSTANCE.register(key);
return key;
}
}

View File

@ -1,130 +1,61 @@
package squeek.quakemovement;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
import net.minecraftforge.fml.client.event.ConfigChangedEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.io.File;
public class ModConfig
{
public static final String CATEGORY_MOVEMENT = "movement";
public static float TRIMP_MULTIPLIER;
private static final String TRIMP_MULTIPLIER_NAME = "trimpMultiplier";
private static final double TRIMP_MULTIPLIER_DEFAULT = 1.4D;
public static float TRIMP_MULTIPLIER = (float)TRIMP_MULTIPLIER_DEFAULT;
private static final String TRIMP_MULTIPLIER_NAME = "trimpMultiplier";
public static float HARD_CAP;
private static final String HARD_CAP_NAME = "hardCapThreshold";
private static final double HARD_CAP_DEFAULT = 2.0D;
public static float HARD_CAP = (float)HARD_CAP_DEFAULT;
private static final String HARD_CAP_NAME = "hardCapThreshold";
public static float SOFT_CAP;
private static final String SOFT_CAP_NAME = "softCapThreshold";
private static final double SOFT_CAP_DEFAULT = 1.4D;
public static float SOFT_CAP = (float)SOFT_CAP_DEFAULT;
private static final String SOFT_CAP_NAME = "softCapThreshold";
public static float SOFT_CAP_DEGEN;
private static final String SOFT_CAP_DEGEN_NAME = "softCapDegen";
private static final double SOFT_CAP_DEGEN_DEFAULT = 0.65D; // 0.65
public static boolean SHARKING_ENABLED;
private static final String SHARKING_ENABLED_NAME = "sharkingEnabled";
private static final boolean SHARKING_ENABLED_DEFAULT = true;
public static boolean SHARKING_ENABLED = SHARKING_ENABLED_DEFAULT;
private static final String SHARKING_ENABLED_NAME = "sharkingEnabled";
public static double SHARKING_SURFACE_TENSION;
private static final String SHARKING_SURFACE_TENSION_NAME = "sharkingSurfaceTension";
private static final double SHARKING_SURFACE_TENSION_DEFAULT = 0.2D;
public static double SHARKING_SURFACE_TENSION = SHARKING_SURFACE_TENSION_DEFAULT;
private static final String SHARKING_SURFACE_TENSION_NAME = "sharkingSurfaceTension";
public static double SHARKING_WATER_FRICTION;
private static final String SHARKING_WATER_FRICTION_NAME = "sharkingWaterFriction";
private static final double SHARKING_WATER_FRICTION_DEFAULT = 0.1D;
public static double SHARKING_WATER_FRICTION = SHARKING_WATER_FRICTION_DEFAULT;
private static final String SHARKING_WATER_FRICTION_NAME = "sharkingWaterFriction";
public static double ACCELERATE;
private static final String ACCELERATE_NAME = "groundAccelerate";
private static final double ACCELERATE_DEFAULT = 10.0D;
public static double ACCELERATE = ACCELERATE_DEFAULT;
private static final String ACCELERATE_NAME = "groundAccelerate";
public static double AIR_ACCELERATE;
private static final String AIR_ACCELERATE_NAME = "airAccelerate";
private static final double AIR_ACCELERATE_DEFAULT = 14.0D;
public static double AIR_ACCELERATE = AIR_ACCELERATE_DEFAULT;
private static final String AIR_ACCELERATE_NAME = "airAccelerate";
public static boolean UNCAPPED_BUNNYHOP_ENABLED;
private static final String UNCAPPED_BUNNYHOP_ENABLED_NAME = "uncappedBunnyhopEnabled";
private static final boolean UNCAPPED_BUNNYHOP_ENABLED_DEFAULT = true;
public static boolean UNCAPPED_BUNNYHOP_ENABLED = UNCAPPED_BUNNYHOP_ENABLED_DEFAULT;
private static final String UNCAPPED_BUNNYHOP_ENABLED_NAME = "uncappedBunnyhopEnabled";
public static boolean TRIMPING_ENABLED;
private static final String TRIMPING_ENABLED_NAME = "trimpEnabled";
private static final boolean TRIMPING_ENABLED_DEFAULT = true;
public static boolean TRIMPING_ENABLED = TRIMPING_ENABLED_DEFAULT;
private static final String TRIMPING_ENABLED_NAME = "trimpEnabled";
public static double INCREASED_FALL_DISTANCE;
private static final String INCREASED_FALL_DISTANCE_NAME = "fallDistanceThresholdIncrease";
private static final double INCREASED_FALL_DISTANCE_DEFAULT = 0.0D;
public static double INCREASED_FALL_DISTANCE = INCREASED_FALL_DISTANCE_DEFAULT;
private static final String INCREASED_FALL_DISTANCE_NAME = "fallDistanceThresholdIncrease";
public static double MAX_AIR_ACCEL_PER_TICK;
private static final String MAX_AIR_ACCEL_PER_TICK_NAME = "maxAirAccelerationPerTick";
private static final double MAX_AIR_ACCEL_PER_TICK_DEFAULT = 0.045D;
public static double MAX_AIR_ACCEL_PER_TICK = MAX_AIR_ACCEL_PER_TICK_DEFAULT;
private static final String MAX_AIR_ACCEL_PER_TICK_NAME = "maxAirAccelerationPerTick";
public static boolean ENABLED;
private static Property ENABLED_PROPERTY;
private static final String ENABLED_NAME = "enabled";
private static final boolean ENABLED_DEFAULT = true;
public static Configuration config;
public static void init(File file)
{
if (config == null)
{
config = new Configuration(file);
load();
}
}
public static void load()
{
UNCAPPED_BUNNYHOP_ENABLED = config.get(CATEGORY_MOVEMENT, UNCAPPED_BUNNYHOP_ENABLED_NAME, UNCAPPED_BUNNYHOP_ENABLED_DEFAULT, "if enabled, the soft and hard caps will not be applied at all").getBoolean(UNCAPPED_BUNNYHOP_ENABLED_DEFAULT);
AIR_ACCELERATE = config.get(CATEGORY_MOVEMENT, AIR_ACCELERATE_NAME, AIR_ACCELERATE_DEFAULT, "a higher value means you can turn more sharply in the air without losing speed").getDouble(AIR_ACCELERATE_DEFAULT);
MAX_AIR_ACCEL_PER_TICK = config.get(CATEGORY_MOVEMENT, MAX_AIR_ACCEL_PER_TICK_NAME, MAX_AIR_ACCEL_PER_TICK_DEFAULT, "a higher value means faster air acceleration").getDouble(MAX_AIR_ACCEL_PER_TICK_DEFAULT);
ACCELERATE = config.get(CATEGORY_MOVEMENT, ACCELERATE_NAME, ACCELERATE_DEFAULT, "a higher value means you accelerate faster on the ground").getDouble(ACCELERATE_DEFAULT);
HARD_CAP = (float) (config.get(CATEGORY_MOVEMENT, HARD_CAP_NAME, HARD_CAP_DEFAULT, "see " + UNCAPPED_BUNNYHOP_ENABLED_NAME + "; if you ever jump while above the hard cap speed (moveSpeed*hardCapThreshold), your speed is set to the hard cap speed").getDouble(HARD_CAP_DEFAULT));
SOFT_CAP = (float) (config.get(CATEGORY_MOVEMENT, SOFT_CAP_NAME, SOFT_CAP_DEFAULT, "see " + UNCAPPED_BUNNYHOP_ENABLED_NAME + " and " + SOFT_CAP_DEGEN_NAME + "; soft cap speed = (moveSpeed*softCapThreshold)").getDouble(SOFT_CAP_DEFAULT));
SOFT_CAP_DEGEN = (float) (config.get(CATEGORY_MOVEMENT, SOFT_CAP_DEGEN_NAME, SOFT_CAP_DEGEN_DEFAULT, "the modifier used to calculate speed lost when jumping above the soft cap").getDouble(SOFT_CAP_DEGEN_DEFAULT));
SHARKING_ENABLED = config.get(CATEGORY_MOVEMENT, SHARKING_ENABLED_NAME, SHARKING_ENABLED_DEFAULT, "if enabled, holding jump while swimming at the surface of water allows you to glide").getBoolean(SHARKING_ENABLED_DEFAULT);
SHARKING_WATER_FRICTION = 1.0D - config.get(CATEGORY_MOVEMENT, SHARKING_WATER_FRICTION_NAME, SHARKING_WATER_FRICTION_DEFAULT, "amount of friction while sharking (between 0 and 1)").getDouble(SHARKING_WATER_FRICTION_DEFAULT) * 0.05D;
SHARKING_SURFACE_TENSION = 1.0D - config.get(CATEGORY_MOVEMENT, SHARKING_SURFACE_TENSION_NAME, SHARKING_SURFACE_TENSION_DEFAULT, "amount of downward momentum you lose while entering water, a higher value means that you are able to shark after hitting the water from higher up").getDouble(SHARKING_SURFACE_TENSION_DEFAULT);
TRIMPING_ENABLED = config.get(CATEGORY_MOVEMENT, TRIMPING_ENABLED_NAME, TRIMPING_ENABLED_DEFAULT, "if enabled, holding sneak while jumping will convert your horizontal speed into vertical speed").getBoolean(TRIMPING_ENABLED_DEFAULT);
TRIMP_MULTIPLIER = (float) (config.get(CATEGORY_MOVEMENT, TRIMP_MULTIPLIER_NAME, TRIMP_MULTIPLIER_DEFAULT, "a lower value means less horizontal speed converted to vertical speed and vice versa").getDouble(TRIMP_MULTIPLIER_DEFAULT));
INCREASED_FALL_DISTANCE = (float) (config.get(CATEGORY_MOVEMENT, INCREASED_FALL_DISTANCE_NAME, INCREASED_FALL_DISTANCE_DEFAULT, "increases the distance needed to fall in order to take fall damage; this is a server-side setting").getDouble(INCREASED_FALL_DISTANCE_DEFAULT));
ENABLED_PROPERTY = config.get(CATEGORY_MOVEMENT, ENABLED_NAME, ENABLED_DEFAULT, "turns off/on the quake-style movement for the client (essentially the saved value of the ingame toggle keybind)");
ENABLED = ENABLED_PROPERTY.getBoolean(ENABLED_DEFAULT);
save();
}
public static void setEnabled(boolean enabled)
{
ModConfig.ENABLED = enabled;
ENABLED_PROPERTY.set(enabled);
save();
}
public static void save()
{
if (config.hasChanged())
{
config.save();
}
}
@SubscribeEvent
public void onConfigurationChangedEvent(ConfigChangedEvent.OnConfigChangedEvent event)
{
if (event.getModID().equalsIgnoreCase(ModInfo.MODID))
{
load();
}
}
public static boolean ENABLED = ENABLED_DEFAULT;
}

View File

@ -1,20 +0,0 @@
package squeek.quakemovement;
import net.minecraft.client.gui.GuiScreen;
import net.minecraftforge.common.config.ConfigElement;
import net.minecraftforge.fml.client.DefaultGuiFactory;
import net.minecraftforge.fml.client.config.GuiConfig;
public class ModConfigGuiFactory extends DefaultGuiFactory
{
public ModConfigGuiFactory()
{
super(ModInfo.MODID, GuiConfig.getAbridgedConfigPath(ModConfig.config.toString()));
}
@Override
public GuiScreen createConfigGui(GuiScreen parentScreen)
{
return new GuiConfig(parentScreen, new ConfigElement(ModConfig.config.getCategory(ModConfig.CATEGORY_MOVEMENT)).getChildElements(), modid, false, false, title);
}
}

View File

@ -3,6 +3,4 @@ package squeek.quakemovement;
public final class ModInfo
{
public static final String MODID = "squake";
public static final String VERSION = "${version}";
public static final String CONFIG_GUI_FACTORY_CLASS = "squeek.quakemovement.ModConfigGuiFactory";
}

View File

@ -1,49 +1,33 @@
package squeek.quakemovement;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.living.LivingFallEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.Mod.Instance;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import com.mojang.blaze3d.platform.GlStateManager;
import net.fabricmc.api.ModInitializer;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.MathHelper;
@Mod(modid = ModInfo.MODID, version = ModInfo.VERSION, name="Squake", acceptedMinecraftVersions="[1.12.2]", dependencies = "after:squeedometer", guiFactory = ModInfo.CONFIG_GUI_FACTORY_CLASS)
public class ModQuakeMovement
public class ModQuakeMovement implements ModInitializer
{
// The instance of your mod that Forge uses.
@Instance(value = ModInfo.MODID)
public static ModQuakeMovement instance;
@EventHandler
public void preInit(FMLPreInitializationEvent event)
{
ModConfig.init(event.getSuggestedConfigurationFile());
MinecraftForge.EVENT_BUS.register(new ModConfig());
MinecraftForge.EVENT_BUS.register(this);
if (event.getSide() == Side.CLIENT)
{
MinecraftForge.EVENT_BUS.register(new ToggleKeyHandler());
}
}
@EventHandler
public void postInit(FMLPostInitializationEvent event)
@Override
public void onInitialize()
{
}
@SubscribeEvent
public void onLivingFall(LivingFallEvent event)
public static float getFriction()
{
if (!(event.getEntityLiving() instanceof EntityPlayer))
return;
if (ModConfig.INCREASED_FALL_DISTANCE != 0.0D)
{
event.setDistance((float) (event.getDistance() - ModConfig.INCREASED_FALL_DISTANCE));
}
return 0.6f;
}
}
public static void drawSpeedometer()
{
GlStateManager.pushMatrix();
MinecraftClient mc = MinecraftClient.getInstance();
PlayerEntity player = mc.player;
double deltaX = player.x - player.prevX;
double deltaZ = player.z - player.prevZ;
double speed = MathHelper.sqrt(deltaX * deltaX + deltaZ * deltaZ);
String speedString = String.format("%.02f", speed);
mc.textRenderer.drawWithShadow(speedString, 10, mc.window.getScaledHeight() - mc.textRenderer.fontHeight - 10, 0xFFDDDDDD);
GlStateManager.popMatrix();
}
}

View File

@ -1,142 +1,97 @@
package squeek.quakemovement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.MoverType;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.FoodStats;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.entity.MovementType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.particle.BlockStateParticleEffect;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.relauncher.ReflectionHelper;
import net.minecraft.util.math.Vec3d;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class QuakeClientPlayer
{
private static Random random = new Random();
private static List<double[]> baseVelocities = new ArrayList<double[]>();
private static boolean didJumpThisTick = false;
private static List<float[]> baseVelocities = new ArrayList<float[]>();
private static Method setDidJumpThisTick = null;
private static Method setIsJumping = null;
static
public static boolean travel(PlayerEntity player, Vec3d movementInput)
{
try
{
if (Loader.isModLoaded("squeedometer"))
{
Class<?> hudSpeedometer = Class.forName("squeek.speedometer.HudSpeedometer");
setDidJumpThisTick = hudSpeedometer.getDeclaredMethod("setDidJumpThisTick", boolean.class);
setIsJumping = hudSpeedometer.getDeclaredMethod("setIsJumping", boolean.class);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static boolean moveEntityWithHeading(EntityPlayer player, float sidemove, float upmove, float forwardmove)
{
if (!player.world.isRemote)
if (!player.world.isClient)
return false;
if (!ModConfig.ENABLED)
return false;
boolean didQuakeMovement;
double d0 = player.posX;
double d1 = player.posY;
double d2 = player.posZ;
double d0 = player.x;
double d1 = player.y;
double d2 = player.z;
if ((player.capabilities.isFlying || player.isElytraFlying()) && player.getRidingEntity() == null)
if ((player.abilities.flying || player.isFallFlying()) && !player.hasVehicle())
return false;
else
didQuakeMovement = quake_moveEntityWithHeading(player, sidemove, upmove, forwardmove);
didQuakeMovement = quake_travel(player, movementInput);
if (didQuakeMovement)
player.addMovementStat(player.posX - d0, player.posY - d1, player.posZ - d2);
player.method_7282(player.x - d0, player.y - d1, player.z - d2);
return didQuakeMovement;
}
public static void beforeOnLivingUpdate(EntityPlayer player)
public static void beforeOnLivingUpdate(PlayerEntity player)
{
if (!player.world.isRemote)
if (!player.world.isClient)
return;
didJumpThisTick = false;
if (setDidJumpThisTick != null)
{
try
{
setDidJumpThisTick.invoke(null, false);
}
catch (Exception e)
{
}
}
if (!baseVelocities.isEmpty())
{
baseVelocities.clear();
}
if (setIsJumping != null)
{
try
{
setIsJumping.invoke(null, isJumping(player));
}
catch (Exception e)
{
}
}
}
public static boolean moveRelativeBase(Entity entity, float sidemove, float upmove, float forwardmove, float friction)
public static boolean updateVelocity(Entity entity, Vec3d movementInput, float movementSpeed)
{
if (!(entity instanceof EntityPlayer))
if (!(entity instanceof PlayerEntity))
return false;
return moveRelative((EntityPlayer)entity, sidemove, forwardmove, upmove, friction);
return updateVelocityPlayer((PlayerEntity) entity, movementInput, movementSpeed);
}
public static boolean moveRelative(EntityPlayer player, float sidemove, float upmove, float forwardmove, float friction)
public static boolean updateVelocityPlayer(PlayerEntity player, Vec3d movementInput, float movementSpeed)
{
if (!player.world.isRemote)
if (!player.world.isClient)
return false;
if (!ModConfig.ENABLED)
return false;
if ((player.capabilities.isFlying && player.getRidingEntity() == null) || player.isInWater() || player.isInLava() || player.isOnLadder())
if ((player.abilities.flying && !player.hasVehicle()) || player.isInsideWater() || player.isInLava() || !player.abilities.flying)
{
return false;
}
// this is probably wrong, but its what was there in 1.10.2
float wishspeed = friction;
float wishspeed = movementSpeed;
wishspeed *= 2.15f;
float[] wishdir = getMovementDirection(player, sidemove, forwardmove);
float[] wishvel = new float[]{wishdir[0] * wishspeed, wishdir[1] * wishspeed};
double[] wishdir = getMovementDirection(player, movementInput.x, movementInput.z);
double[] wishvel = new double[]{wishdir[0] * wishspeed, wishdir[1] * wishspeed};
baseVelocities.add(wishvel);
return true;
}
public static void afterJump(EntityPlayer player)
public static void afterJump(PlayerEntity player)
{
if (!player.world.isRemote)
if (!player.world.isClient)
return;
if (!ModConfig.ENABLED)
@ -145,24 +100,12 @@ public class QuakeClientPlayer
// undo this dumb thing
if (player.isSprinting())
{
float f = player.rotationYaw * 0.017453292F;
player.motionX += MathHelper.sin(f) * 0.2F;
player.motionZ -= MathHelper.cos(f) * 0.2F;
float f = player.yaw * 0.017453292F;
Vec3d deltaVelocity = new Vec3d(MathHelper.sin(f) * 0.2F, 0, -(MathHelper.cos(f) * 0.2F));
player.setVelocity(player.getVelocity().add(deltaVelocity));
}
quake_Jump(player);
didJumpThisTick = true;
if (setDidJumpThisTick != null)
{
try
{
setDidJumpThisTick.invoke(null, true);
}
catch (Exception e)
{
}
}
}
/* =================================================
@ -170,52 +113,53 @@ public class QuakeClientPlayer
* =================================================
*/
private static double getSpeed(EntityPlayer player)
private static double getSpeed(PlayerEntity player)
{
return MathHelper.sqrt(player.motionX * player.motionX + player.motionZ * player.motionZ);
Vec3d velocity = player.getVelocity();
return MathHelper.sqrt(velocity.x * velocity.x + velocity.z * velocity.z);
}
private static float getSurfaceFriction(EntityPlayer player)
private static float getSurfaceFriction(PlayerEntity player)
{
float f2 = 1.0F;
if (player.onGround)
{
BlockPos groundPos = new BlockPos(MathHelper.floor(player.posX), MathHelper.floor(player.getEntityBoundingBox().minY) - 1, MathHelper.floor(player.posZ));
BlockPos groundPos = new BlockPos(MathHelper.floor(player.x), MathHelper.floor(player.getBoundingBox().minY) - 1, MathHelper.floor(player.z));
Block ground = player.world.getBlockState(groundPos).getBlock();
f2 = 1.0F - ground.slipperiness;
f2 = 1.0F - ground.getSlipperiness();
}
return f2;
}
private static float getSlipperiness(EntityPlayer player)
private static float getSlipperiness(PlayerEntity player)
{
float f2 = 0.91F;
if (player.onGround)
{
f2 = 0.54600006F;
BlockPos groundPos = new BlockPos(MathHelper.floor(player.posX), MathHelper.floor(player.getEntityBoundingBox().minY) - 1, MathHelper.floor(player.posZ));
BlockPos groundPos = new BlockPos(MathHelper.floor(player.x), MathHelper.floor(player.getBoundingBox().minY) - 1, MathHelper.floor(player.z));
Block ground = player.world.getBlockState(groundPos).getBlock();
f2 = ground.slipperiness * 0.91F;
f2 = ground.getSlipperiness() * 0.91F;
}
return f2;
}
private static float minecraft_getMoveSpeed(EntityPlayer player)
private static float minecraft_getMoveSpeed(PlayerEntity player)
{
float f2 = getSlipperiness(player);
float f3 = 0.16277136F / (f2 * f2 * f2);
return player.getAIMoveSpeed() * f3;
return player.getMovementSpeed() * f3;
}
private static float[] getMovementDirection(EntityPlayer player, float sidemove, float forwardmove)
private static double[] getMovementDirection(PlayerEntity player, double sidemove, double forwardmove)
{
float f3 = sidemove * sidemove + forwardmove * forwardmove;
float[] dir = {0.0F, 0.0F};
double f3 = sidemove * sidemove + forwardmove * forwardmove;
double[] dir = {0.0F, 0.0F};
if (f3 >= 1.0E-4F)
{
@ -229,8 +173,8 @@ public class QuakeClientPlayer
f3 = 1.0F / f3;
sidemove *= f3;
forwardmove *= f3;
float f4 = MathHelper.sin(player.rotationYaw * (float) Math.PI / 180.0F);
float f5 = MathHelper.cos(player.rotationYaw * (float) Math.PI / 180.0F);
double f4 = MathHelper.sin(player.yaw * (float) Math.PI / 180.0F);
double f5 = MathHelper.cos(player.yaw * (float) Math.PI / 180.0F);
dir[0] = (sidemove * f5 - forwardmove * f4);
dir[1] = (forwardmove * f5 + sidemove * f4);
}
@ -238,47 +182,43 @@ public class QuakeClientPlayer
return dir;
}
private static float quake_getMoveSpeed(EntityPlayer player)
private static float quake_getMoveSpeed(PlayerEntity player)
{
float baseSpeed = player.getAIMoveSpeed();
float baseSpeed = player.getMovementSpeed();
return !player.isSneaking() ? baseSpeed * 2.15F : baseSpeed * 1.11F;
}
private static float quake_getMaxMoveSpeed(EntityPlayer player)
private static float quake_getMaxMoveSpeed(PlayerEntity player)
{
float baseSpeed = player.getAIMoveSpeed();
float baseSpeed = player.getMovementSpeed();
return baseSpeed * 2.15F;
}
private static void spawnBunnyhopParticles(EntityPlayer player, int numParticles)
private static void spawnBunnyhopParticles(PlayerEntity player, int numParticles)
{
// taken from sprint
int j = MathHelper.floor(player.posX);
int i = MathHelper.floor(player.posY - 0.20000000298023224D - player.getYOffset());
int k = MathHelper.floor(player.posZ);
IBlockState blockState = player.world.getBlockState(new BlockPos(j, i, k));
int j = MathHelper.floor(player.x);
int i = MathHelper.floor(player.y - 0.20000000298023224D - player.getHeightOffset());
int k = MathHelper.floor(player.z);
BlockState blockState = player.world.getBlockState(new BlockPos(j, i, k));
if (blockState.getRenderType() != EnumBlockRenderType.INVISIBLE)
if (blockState.getRenderType() != BlockRenderType.INVISIBLE)
{
for (int iParticle = 0; iParticle < numParticles; iParticle++)
{
player.world.spawnParticle(EnumParticleTypes.BLOCK_CRACK, player.posX + (random.nextFloat() - 0.5D) * player.width, player.getEntityBoundingBox().minY + 0.1D, player.posZ + (random.nextFloat() - 0.5D) * player.width, -player.motionX * 4.0D, 1.5D, -player.motionZ * 4.0D, Block.getStateId(blockState));
player.world.addParticle(new BlockStateParticleEffect(ParticleTypes.BLOCK, blockState), player.x + (random.nextFloat() - 0.5D) * player.getWidth(), player.y + 0.1D, player.z + (random.nextFloat() - 0.5D) * player.getWidth(), -player.getVelocity().x * 4.0D, 1.5D, -player.getVelocity().z * 4.0D);
}
}
}
private static final Field isJumping = ReflectionHelper.findField(EntityLivingBase.class, "isJumping", "field_70703_bu", "bd");
private static boolean isJumping(EntityPlayer player)
public static interface IsJumpingGetter
{
try
{
return isJumping.getBoolean(player);
}
catch(Exception e)
{
return false;
}
boolean isJumping();
}
private static boolean isJumping(PlayerEntity player)
{
return ((IsJumpingGetter) player).isJumping();
}
/* =================================================
@ -291,90 +231,94 @@ public class QuakeClientPlayer
* =================================================
*/
private static void minecraft_ApplyGravity(EntityPlayer player)
private static void minecraft_ApplyGravity(PlayerEntity player)
{
if (player.world.isRemote && (!player.world.isBlockLoaded(new BlockPos((int)player.posX, (int)player.posY, (int)player.posZ)) || !player.world.getChunkFromBlockCoords(new BlockPos((int) player.posX, (int) player.posY, (int) player.posZ)).isLoaded()))
BlockPos pos = new BlockPos((int) player.x, (int) player.y, (int) player.z);
double velocityY = player.getVelocity().y;
if (player.world.isClient && !player.world.isBlockLoaded(pos))
{
if (player.posY > 0.0D)
if (player.y > 0.0D)
{
player.motionY = -0.1D;
velocityY = -0.1D;
}
else
{
player.motionY = 0.0D;
velocityY = 0.0D;
}
}
else
{
// gravity
player.motionY -= 0.08D;
velocityY -= 0.08D;
}
// air resistance
player.motionY *= 0.9800000190734863D;
velocityY *= 0.9800000190734863D;
player.setVelocity(player.getVelocity().x, velocityY, player.getVelocity().z);
}
private static void minecraft_ApplyFriction(EntityPlayer player, float momentumRetention)
private static void minecraft_ApplyFriction(PlayerEntity player, float momentumRetention)
{
player.motionX *= momentumRetention;
player.motionZ *= momentumRetention;
player.setVelocity(player.getVelocity().multiply(momentumRetention, 1, momentumRetention));
}
private static void minecraft_ApplyLadderPhysics(EntityPlayer player)
/*
private static void minecraft_ApplyLadderPhysics(PlayerEntity player)
{
if (player.isOnLadder())
if (player.canClimb())
{
float f5 = 0.15F;
if (player.motionX < (-f5))
if (player.velocityX < (-f5))
{
player.motionX = (-f5);
player.velocityX = (-f5);
}
if (player.motionX > f5)
if (player.velocityX > f5)
{
player.motionX = f5;
player.velocityX = f5;
}
if (player.motionZ < (-f5))
if (player.velocityZ < (-f5))
{
player.motionZ = (-f5);
player.velocityZ = (-f5);
}
if (player.motionZ > f5)
if (player.velocityZ > f5)
{
player.motionZ = f5;
player.velocityZ = f5;
}
player.fallDistance = 0.0F;
if (player.motionY < -0.15D)
if (player.velocityY < -0.15D)
{
player.motionY = -0.15D;
player.velocityY = -0.15D;
}
boolean flag = player.isSneaking();
if (flag && player.motionY < 0.0D)
if (flag && player.velocityY < 0.0D)
{
player.motionY = 0.0D;
player.velocityY = 0.0D;
}
}
}
private static void minecraft_ClimbLadder(EntityPlayer player)
private static void minecraft_ClimbLadder(PlayerEntity player)
{
if (player.isCollidedHorizontally && player.isOnLadder())
if (player.horizontalCollision && player.canClimb())
{
player.motionY = 0.2D;
player.velocityY = 0.2D;
}
}
*/
private static void minecraft_SwingLimbsBasedOnMovement(EntityPlayer player)
private static void minecraft_SwingLimbsBasedOnMovement(PlayerEntity player)
{
player.prevLimbSwingAmount = player.limbSwingAmount;
double d0 = player.posX - player.prevPosX;
double d1 = player.posZ - player.prevPosZ;
player.lastLimbDistance = player.limbDistance;
double d0 = player.x - player.prevX;
double d1 = player.z - player.prevZ;
float f6 = MathHelper.sqrt(d0 * d0 + d1 * d1) * 4.0F;
if (f6 > 1.0F)
@ -382,31 +326,30 @@ public class QuakeClientPlayer
f6 = 1.0F;
}
player.limbSwingAmount += (f6 - player.limbSwingAmount) * 0.4F;
player.limbSwing += player.limbSwingAmount;
player.limbDistance += (f6 - player.limbDistance) * 0.4F;
player.limbAngle += player.limbDistance;
}
private static void minecraft_WaterMove(EntityPlayer player, float sidemove, float upmove, float forwardmove)
private static void minecraft_WaterMove(PlayerEntity player, Vec3d movementInput)
{
double d0 = player.posY;
player.moveRelative(sidemove, upmove, forwardmove, 0.04F);
player.move(MoverType.SELF, player.motionX, player.motionY, player.motionZ);
player.motionX *= 0.800000011920929D;
player.motionY *= 0.800000011920929D;
player.motionZ *= 0.800000011920929D;
player.motionY -= 0.02D;
if (player.isCollidedHorizontally && player.isOffsetPositionInLiquid(player.motionX, player.motionY + 0.6000000238418579D - player.posY + d0, player.motionZ))
{
player.motionY = 0.30000001192092896D;
}
// double d0 = player.y;
// player.updateVelocity(0.04F, movementInput);
// player.move(MovementType.SELF, player.getVelocity());
// Vec3d velocity = player.getVelocity().multiply(0.800000011920929D).add(0, 0.02D, 0);
// player.setVelocity(velocity);
//
// if (player.horizontalCollision && player.method_5654(velocity.x, velocity.y + 0.6000000238418579D - player.y + d0, velocity.z))
// {
// player.setVelocity(velocity.x, 0.30000001192092896D, velocity.z);
// }
}
public static void minecraft_moveEntityWithHeading(EntityPlayer player, float sidemove, float upmove, float forwardmove)
/*
public static void minecraft_moveEntityWithHeading(PlayerEntity player, float sidemove, float upmove, float forwardmove)
{
// take care of water and lava movement using default code
if ((player.isInWater() && !player.capabilities.isFlying)
|| (player.isInLava() && !player.capabilities.isFlying))
if ((player.isInWater() && !player.abilities.flying)
|| (player.isTouchingLava() && !player.abilities.flying))
{
player.travel(sidemove, upmove, forwardmove);
}
@ -422,7 +365,7 @@ public class QuakeClientPlayer
minecraft_ApplyLadderPhysics(player);
// do the movement
player.move(MoverType.SELF, player.motionX, player.motionY, player.motionZ);
player.move(MovementType.field_6308, player.velocityX, player.velocityY, player.velocityZ);
// climb ladder here for some reason
minecraft_ClimbLadder(player);
@ -435,6 +378,7 @@ public class QuakeClientPlayer
minecraft_SwingLimbsBasedOnMovement(player);
}
}
*/
/* =================================================
* END MINECRAFT PHYSICS
@ -449,32 +393,32 @@ public class QuakeClientPlayer
/**
* Moves the entity based on the specified heading. Args: strafe, forward
*/
public static boolean quake_moveEntityWithHeading(EntityPlayer player, float sidemove, float upmove, float forwardmove)
public static boolean quake_travel(PlayerEntity player, Vec3d movementInput)
{
// take care of ladder movement using default code
if (player.isOnLadder())
if (player.isClimbing())
{
return false;
}
// take care of lava movement using default code
else if ((player.isInLava() && !player.capabilities.isFlying))
else if ((player.isInLava() && !player.abilities.flying))
{
return false;
}
else if (player.isInWater() && !player.capabilities.isFlying)
else if (player.isInsideWater() && !player.abilities.flying)
{
if (ModConfig.SHARKING_ENABLED)
quake_WaterMove(player, sidemove, upmove, forwardmove);
else
{
return false;
}
// if (ModConfig.SHARKING_ENABLED)
// quake_WaterMove(player, (float) movementInput.x, (float) movementInput.y, (float) movementInput.z);
// else
// {
return false;
// }
}
else
{
// get all relevant movement values
float wishspeed = (sidemove != 0.0F || forwardmove != 0.0F) ? quake_getMoveSpeed(player) : 0.0F;
float[] wishdir = getMovementDirection(player, sidemove, forwardmove);
float wishspeed = (movementInput.x != 0.0D || movementInput.z != 0.0D) ? quake_getMoveSpeed(player) : 0.0F;
double[] wishdir = getMovementDirection(player, movementInput.x, movementInput.z);
boolean onGroundForReal = player.onGround && !isJumping(player);
float momentumRetention = getSlipperiness(player);
@ -499,10 +443,9 @@ public class QuakeClientPlayer
{
float speedMod = wishspeed / quake_getMaxMoveSpeed(player);
// add in base velocities
for (float[] baseVel : baseVelocities)
for (double[] baseVel : baseVelocities)
{
player.motionX += baseVel[0] * speedMod;
player.motionZ += baseVel[1] * speedMod;
player.setVelocity(player.getVelocity().add(baseVel[0] * speedMod, 0, baseVel[1] * speedMod));
}
}
}
@ -512,18 +455,18 @@ public class QuakeClientPlayer
double sv_airaccelerate = ModConfig.AIR_ACCELERATE;
quake_AirAccelerate(player, wishspeed, wishdir[0], wishdir[1], sv_airaccelerate);
if (ModConfig.SHARKING_ENABLED && ModConfig.SHARKING_SURFACE_TENSION > 0.0D && isJumping(player) && player.motionY < 0.0F)
if (ModConfig.SHARKING_ENABLED && ModConfig.SHARKING_SURFACE_TENSION > 0.0D && isJumping(player) && player.getVelocity().y < 0.0F)
{
AxisAlignedBB axisalignedbb = player.getEntityBoundingBox().offset(player.motionX, player.motionY, player.motionZ);
boolean isFallingIntoWater = player.world.containsAnyLiquid(axisalignedbb);
Box axisalignedbb = player.getBoundingBox().offset(player.getVelocity());
boolean isFallingIntoWater = player.world.containsBlockWithMaterial(axisalignedbb, Material.WATER);
if (isFallingIntoWater)
player.motionY *= ModConfig.SHARKING_SURFACE_TENSION;
player.setVelocity(player.getVelocity().multiply(1.0D, ModConfig.SHARKING_SURFACE_TENSION, 1.0D));
}
}
// apply velocity
player.move(MoverType.SELF, player.motionX, player.motionY, player.motionZ);
player.move(MovementType.SELF, player.getVelocity());
// HL2 code applies half gravity before acceleration and half after acceleration, but this seems to work fine
minecraft_ApplyGravity(player);
@ -535,7 +478,7 @@ public class QuakeClientPlayer
return true;
}
private static void quake_Jump(EntityPlayer player)
private static void quake_Jump(PlayerEntity player)
{
quake_ApplySoftCap(player, quake_getMaxMoveSpeed(player));
@ -547,7 +490,7 @@ public class QuakeClientPlayer
}
}
private static boolean quake_DoTrimp(EntityPlayer player)
private static boolean quake_DoTrimp(PlayerEntity player)
{
if (ModConfig.TRIMPING_ENABLED && player.isSneaking())
{
@ -559,13 +502,12 @@ public class QuakeClientPlayer
if (speedbonus > 1.0F)
speedbonus = 1.0F;
player.motionY += speedbonus * curspeed * ModConfig.TRIMP_MULTIPLIER;
player.setVelocity(player.getVelocity().add(0, speedbonus * curspeed * ModConfig.TRIMP_MULTIPLIER, 0));
if (ModConfig.TRIMP_MULTIPLIER > 0)
{
float mult = 1.0f / ModConfig.TRIMP_MULTIPLIER;
player.motionX *= mult;
player.motionZ *= mult;
player.setVelocity(player.getVelocity().multiply(mult, 1, mult));
}
spawnBunnyhopParticles(player, 30);
@ -577,11 +519,9 @@ public class QuakeClientPlayer
return false;
}
private static void quake_ApplyWaterFriction(EntityPlayer player, double friction)
private static void quake_ApplyWaterFriction(PlayerEntity player, double friction)
{
player.motionX *= friction;
player.motionY *= friction;
player.motionZ *= friction;
player.setVelocity(player.getVelocity().multiply(friction));
/*
float speed = (float)(player.getSpeed());
@ -591,9 +531,9 @@ public class QuakeClientPlayer
newspeed = speed - 0.05F * speed * friction; //* player->m_surfaceFriction;
float mult = newspeed/speed;
player.motionX *= mult;
player.motionY *= mult;
player.motionZ *= mult;
player.velocityX *= mult;
player.velocityY *= mult;
player.velocityZ *= mult;
}
return newspeed;
@ -601,14 +541,14 @@ public class QuakeClientPlayer
/*
// slow in water
player.motionX *= 0.800000011920929D;
player.motionY *= 0.800000011920929D;
player.motionZ *= 0.800000011920929D;
player.velocityX *= 0.800000011920929D;
player.velocityY *= 0.800000011920929D;
player.velocityZ *= 0.800000011920929D;
*/
}
@SuppressWarnings("unused")
private static void quake_WaterAccelerate(EntityPlayer player, float wishspeed, float speed, double wishX, double wishZ, double accel)
private static void quake_WaterAccelerate(PlayerEntity player, float wishspeed, float speed, double wishX, double wishZ, double accel)
{
float addspeed = wishspeed - speed;
if (addspeed > 0)
@ -619,24 +559,25 @@ public class QuakeClientPlayer
accelspeed = addspeed;
}
player.motionX += accelspeed * wishX;
player.motionZ += accelspeed * wishZ;
Vec3d newVelocity = player.getVelocity().add(accelspeed * wishX, 0, accelspeed * wishZ);
player.setVelocity(newVelocity);
}
}
private static void quake_WaterMove(EntityPlayer player, float sidemove, float upmove, float forwardmove)
private static void quake_WaterMove(PlayerEntity player, float sidemove, float upmove, float forwardmove)
{
double lastPosY = player.posY;
double lastPosY = player.y;
// get all relevant movement values
float wishspeed = (sidemove != 0.0F || forwardmove != 0.0F) ? quake_getMaxMoveSpeed(player) : 0.0F;
float[] wishdir = getMovementDirection(player, sidemove, forwardmove);
boolean isSharking = isJumping(player) && player.isOffsetPositionInLiquid(0.0D, 1.0D, 0.0D);
double[] wishdir = getMovementDirection(player, sidemove, forwardmove);
boolean isOffsetInLiquid = player.world.getBlockState(new BlockPos(player.x, player.y + 1.0D, player.z)).getFluidState().isEmpty();
boolean isSharking = isJumping(player) && isOffsetInLiquid;
double curspeed = getSpeed(player);
if (!isSharking || curspeed < 0.078F)
{
minecraft_WaterMove(player, sidemove, upmove, forwardmove);
minecraft_WaterMove(player, new Vec3d(sidemove, upmove, forwardmove));
}
else
{
@ -648,36 +589,35 @@ public class QuakeClientPlayer
else
quake_Accelerate(player, .0980F, wishdir[0], wishdir[1], ModConfig.ACCELERATE);
player.move(MoverType.SELF, player.motionX, player.motionY, player.motionZ);
player.move(MovementType.SELF, player.getVelocity());
player.motionY = 0.0D;
player.setVelocity(player.getVelocity().x, 0, player.getVelocity().z);
}
// water jump
if (player.isCollidedHorizontally && player.isOffsetPositionInLiquid(player.motionX, player.motionY + 0.6000000238418579D - player.posY + lastPosY, player.motionZ))
if (player.horizontalCollision && player.doesNotCollide(player.getVelocity().x, player.getVelocity().y + 0.6000000238418579D - player.y + lastPosY, player.getVelocity().z))
{
player.motionY = 0.30000001192092896D;
player.setVelocity(player.getVelocity().x, 0.30000001192092896D, player.getVelocity().z);
}
if (!baseVelocities.isEmpty())
{
float speedMod = wishspeed / quake_getMaxMoveSpeed(player);
// add in base velocities
for (float[] baseVel : baseVelocities)
for (double[] baseVel : baseVelocities)
{
player.motionX += baseVel[0] * speedMod;
player.motionZ += baseVel[1] * speedMod;
player.setVelocity(player.getVelocity().add(baseVel[0] * speedMod, 0, baseVel[1] * speedMod));
}
}
}
private static void quake_Accelerate(EntityPlayer player, float wishspeed, double wishX, double wishZ, double accel)
private static void quake_Accelerate(PlayerEntity player, float wishspeed, double wishX, double wishZ, double accel)
{
double addspeed, accelspeed, currentspeed;
// Determine veer amount
// this is a dot product
currentspeed = player.motionX * wishX + player.motionZ * wishZ;
currentspeed = player.getVelocity().x * wishX + player.getVelocity().z * wishZ;
// See how much to add
addspeed = wishspeed - currentspeed;
@ -694,11 +634,10 @@ public class QuakeClientPlayer
accelspeed = addspeed;
// Adjust pmove vel.
player.motionX += accelspeed * wishX;
player.motionZ += accelspeed * wishZ;
player.setVelocity(player.getVelocity().add(accelspeed * wishX, 0, accelspeed * wishZ));
}
private static void quake_AirAccelerate(EntityPlayer player, float wishspeed, double wishX, double wishZ, double accel)
private static void quake_AirAccelerate(PlayerEntity player, float wishspeed, double wishX, double wishZ, double accel)
{
double addspeed, accelspeed, currentspeed;
@ -710,7 +649,7 @@ public class QuakeClientPlayer
// Determine veer amount
// this is a dot product
currentspeed = player.motionX * wishX + player.motionZ * wishZ;
currentspeed = player.getVelocity().x * wishX + player.getVelocity().z * wishZ;
// See how much to add
addspeed = wishspd - currentspeed;
@ -727,12 +666,11 @@ public class QuakeClientPlayer
accelspeed = addspeed;
// Adjust pmove vel.
player.motionX += accelspeed * wishX;
player.motionZ += accelspeed * wishZ;
player.setVelocity(player.getVelocity().add(accelspeed * wishX, 0, accelspeed * wishZ));
}
@SuppressWarnings("unused")
private static void quake_Friction(EntityPlayer player)
private static void quake_Friction(PlayerEntity player)
{
double speed, newspeed, control;
float friction;
@ -773,12 +711,12 @@ public class QuakeClientPlayer
// Determine proportion of old speed we are using.
newspeed /= speed;
// Adjust velocity according to proportion.
player.motionX *= newspeed;
player.motionZ *= newspeed;
player.setVelocity(player.getVelocity().multiply(newspeed, 1, newspeed));
}
}
private static void quake_ApplySoftCap(EntityPlayer player, float movespeed)
private static void quake_ApplySoftCap(PlayerEntity player, float movespeed)
{
float softCapPercent = ModConfig.SOFT_CAP;
float softCapDegen = ModConfig.SOFT_CAP_DEGEN;
@ -799,15 +737,14 @@ public class QuakeClientPlayer
{
float applied_cap = (speed - softCap) * softCapDegen + softCap;
float multi = applied_cap / speed;
player.motionX *= multi;
player.motionZ *= multi;
player.setVelocity(player.getVelocity().multiply(multi, 1, multi));
}
spawnBunnyhopParticles(player, 10);
}
}
private static void quake_ApplyHardCap(EntityPlayer player, float movespeed)
private static void quake_ApplyHardCap(PlayerEntity player, float movespeed)
{
if (ModConfig.UNCAPPED_BUNNYHOP_ENABLED)
return;
@ -820,19 +757,12 @@ public class QuakeClientPlayer
if (speed > hardCap && hardCap != 0.0F)
{
float multi = hardCap / speed;
player.motionX *= multi;
player.motionZ *= multi;
player.setVelocity(player.getVelocity().multiply(multi, 1, multi));
spawnBunnyhopParticles(player, 30);
}
}
@SuppressWarnings("unused")
private static void quake_OnLivingUpdate()
{
didJumpThisTick = false;
}
/* =================================================
* END QUAKE PHYSICS
* =================================================

View File

@ -1,6 +1,6 @@
package squeek.quakemovement;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.PlayerEntity;
public class QuakeServerPlayer
{
@ -8,19 +8,19 @@ public class QuakeServerPlayer
// because we only care about the state before it has any possibility of changing
private static boolean wasVelocityChangedBeforeFall = false;
public static void beforeFall(EntityPlayer player, float fallDistance, float damageMultiplier)
public static void beforeFall(PlayerEntity player, float fallDistance, float damageMultiplier)
{
if (player.world.isRemote)
if (player.world.isClient)
return;
wasVelocityChangedBeforeFall = player.velocityChanged;
wasVelocityChangedBeforeFall = player.velocityModified;
}
public static void afterFall(EntityPlayer player, float fallDistance, float damageMultiplier)
public static void afterFall(PlayerEntity player, float fallDistance, float damageMultiplier)
{
if (player.world.isRemote)
if (player.world.isClient)
return;
player.velocityChanged = wasVelocityChangedBeforeFall;
player.velocityModified = wasVelocityChangedBeforeFall;
}
}

View File

@ -1,37 +0,0 @@
package squeek.quakemovement;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.text.TextComponentString;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.input.Keyboard;
@SideOnly(Side.CLIENT)
public class ToggleKeyHandler
{
private static final KeyBinding TOGGLE_KEY = new KeyBinding("squake.key.toggle", Keyboard.CHAR_NONE, ModInfo.MODID);
static
{
ClientRegistry.registerKeyBinding(TOGGLE_KEY);
}
@SubscribeEvent
public void onKeyEvent(InputEvent.KeyInputEvent event)
{
if (TOGGLE_KEY.isPressed())
{
ModConfig.setEnabled(!ModConfig.ENABLED);
EntityPlayer player = FMLClientHandler.instance().getClientPlayerEntity();
String feedback = ModConfig.ENABLED ? I18n.format("squake.key.toggle.enabled") : I18n.format("squake.key.toggle.disabled");
player.sendMessage(new TextComponentString("[" + ModInfo.MODID + "] " + feedback));
}
}
}

View File

@ -0,0 +1,24 @@
package squeek.quakemovement.mixin;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.Vec3d;
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;
import squeek.quakemovement.ModConfig;
import squeek.quakemovement.QuakeClientPlayer;
@Mixin(Entity.class)
public abstract class EntityMixin
{
@Inject(at = @At("HEAD"), method = "updateVelocity(FLnet/minecraft/util/math/Vec3d;)V", cancellable = true)
private void updateVelocity(float movementSpeed, Vec3d movementInput, CallbackInfo info)
{
if (!ModConfig.ENABLED)
return;
if (QuakeClientPlayer.updateVelocity((Entity) (Object) this, movementInput, movementSpeed))
info.cancel();
}
}

View File

@ -0,0 +1,27 @@
package squeek.quakemovement.mixin;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.resource.language.I18n;
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;
import squeek.quakemovement.KeyBindInitializer;
import squeek.quakemovement.ModConfig;
import squeek.quakemovement.ModInfo;
@Mixin(MinecraftClient.class)
public class KeyPressMixin
{
@Inject(method = "handleInputEvents", at=@At("HEAD"))
public void handleInputEvents(CallbackInfo info)
{
if (KeyBindInitializer.ENABLE.wasPressed())
{
ModConfig.ENABLED = !ModConfig.ENABLED;
String feedback = ModConfig.ENABLED ? I18n.translate("squake.key.toggle.enabled") : I18n.translate("squake.key.toggle.disabled");
MinecraftClient.getInstance().player.sendChatMessage("[" + ModInfo.MODID + "] " + feedback);
}
}
}

View File

@ -0,0 +1,19 @@
package squeek.quakemovement.mixin;
import net.minecraft.entity.LivingEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import squeek.quakemovement.QuakeClientPlayer;
@Mixin(LivingEntity.class)
public class LivingEntityMixin implements QuakeClientPlayer.IsJumpingGetter
{
@Shadow
boolean jumping;
@Override
public boolean isJumping()
{
return this.jumping;
}
}

View File

@ -0,0 +1,49 @@
package squeek.quakemovement.mixin;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.Vec3d;
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;
import squeek.quakemovement.ModConfig;
import squeek.quakemovement.QuakeClientPlayer;
import squeek.quakemovement.QuakeServerPlayer;
@Mixin(PlayerEntity.class)
public abstract class PlayerEntityMixin
{
@Inject(at = @At("HEAD"), method = "travel(Lnet/minecraft/util/math/Vec3d;)V", cancellable = true)
private void travel(Vec3d movementInput, CallbackInfo info)
{
if (!ModConfig.ENABLED)
return;
if (QuakeClientPlayer.travel((PlayerEntity) (Object) this, movementInput))
info.cancel();
}
@Inject(at = @At("HEAD"), method = "tick()V")
private void beforeUpdate(CallbackInfo info)
{
QuakeClientPlayer.beforeOnLivingUpdate((PlayerEntity) (Object) this);
}
@Inject(at = @At("TAIL"), method = "jump()V")
private void afterJump(CallbackInfo info)
{
QuakeClientPlayer.afterJump((PlayerEntity) (Object) this);
}
@Inject(at = @At("HEAD"), method = "handleFallDamage(FF)V")
private void beforeFall(float fallDistance, float damageMultiplier, CallbackInfo info)
{
QuakeServerPlayer.beforeFall((PlayerEntity) (Object) this, fallDistance, damageMultiplier);
}
@Inject(at = @At("TAIL"), method = "handleFallDamage(FF)V")
private void afterFall(float fallDistance, float damageMultiplier, CallbackInfo info)
{
QuakeServerPlayer.afterFall((PlayerEntity) (Object) this, fallDistance, damageMultiplier);
}
}

View File

@ -0,0 +1,15 @@
package squeek.quakemovement.mixin;
import net.minecraft.block.Block;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import squeek.quakemovement.ModQuakeMovement;
@Mixin(Block.class)
public abstract class TestBlockMixin
{
// @Overwrite
// public float getSlipperiness() {
// return ModQuakeMovement.getFriction();
// }
}

View File

@ -0,0 +1,19 @@
package squeek.quakemovement.mixin;
import net.minecraft.client.gui.hud.InGameHud;
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;
import squeek.quakemovement.ModQuakeMovement;
@Mixin(InGameHud.class)
public class TestSpeedometerMixin
{
@Inject(at = @At("HEAD"), method = "renderStatusEffectOverlay()V")
private void renderStatusEffectOverlay(CallbackInfo info)
{
ModQuakeMovement.drawSpeedometer();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

34
resources/fabric.mod.json Normal file
View File

@ -0,0 +1,34 @@
{
"schemaVersion": 1,
"id": "squake",
"version": "${version}",
"name": "Squake",
"description": "Quake-style movement (bunnyhopping, etc) in Minecraft",
"authors": [
"squeek502"
],
"contact": {
"sources": "https://github.com/squeek502/Squake"
},
"license": "Unlicense",
"icon": "assets/squake/icon.png",
"environment": "*",
"entrypoints": {
"main": [
"squeek.quakemovement.ModQuakeMovement"
],
"client": [
"squeek.quakemovement.KeyBindInitializer"
]
},
"mixins": [
"squake.mixins.json"
],
"depends": {
"fabricloader": ">=0.4.0"
}
}

View File

@ -1,16 +0,0 @@
[
{
"modid": "squake",
"name": "Squake",
"description": "Quake-style movement in Minecraft.",
"version": "${version}",
"mcversion": "${mcversion}",
"url": "",
"updateUrl": "",
"authorList": ["squeek"],
"credits": "",
"logoFile": "",
"screenshots": [],
"dependencies": []
}
]

View File

@ -0,0 +1,18 @@
{
"required": true,
"package": "squeek.quakemovement.mixin",
"compatibilityLevel": "JAVA_8",
"mixins": [
"PlayerEntityMixin",
"TestBlockMixin"
],
"client": [
"LivingEntityMixin",
"EntityMixin",
"KeyPressMixin",
"TestSpeedometerMixin"
],
"injectors": {
"defaultRequire": 1
}
}

10
settings.gradle Normal file
View File

@ -0,0 +1,10 @@
pluginManagement {
repositories {
jcenter()
maven {
name = 'Fabric'
url = 'http://maven.fabricmc.net/'
}
gradlePluginPortal()
}
}