diff --git a/src/main/java/com/alrex/parcool/ParCool.java b/src/main/java/com/alrex/parcool/ParCool.java index 2297a9e7..b8724296 100644 --- a/src/main/java/com/alrex/parcool/ParCool.java +++ b/src/main/java/com/alrex/parcool/ParCool.java @@ -4,6 +4,7 @@ import com.alrex.parcool.api.Effects; import com.alrex.parcool.api.SoundEvents; import com.alrex.parcool.client.input.KeyBindings; +import com.alrex.parcool.client.input.KeyRecorder; import com.alrex.parcool.client.renderer.Renderers; import com.alrex.parcool.common.block.Blocks; import com.alrex.parcool.common.block.TileEntities; @@ -27,6 +28,7 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.event.RegisterCommandsEvent; +import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.ModLoadingContext; @@ -79,6 +81,7 @@ public ParCool() { MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.addListener(Limitations::init); MinecraftForge.EVENT_BUS.addListener(Limitations::save); + MinecraftForge.EVENT_BUS.addListener(EventPriority.LOW, KeyRecorder::onInputs); Blocks.register(FMLJavaModLoadingContext.get().getModEventBus()); Items.register(FMLJavaModLoadingContext.get().getModEventBus()); diff --git a/src/main/java/com/alrex/parcool/client/input/KeyRecorder.java b/src/main/java/com/alrex/parcool/client/input/KeyRecorder.java index 33e74740..3e68adb9 100644 --- a/src/main/java/com/alrex/parcool/client/input/KeyRecorder.java +++ b/src/main/java/com/alrex/parcool/client/input/KeyRecorder.java @@ -1,10 +1,17 @@ package com.alrex.parcool.client.input; import javax.annotation.Nullable; +import com.alrex.parcool.utilities.CameraUtil; +import com.alrex.parcool.utilities.VectorUtil; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.settings.KeyBinding; +import net.minecraft.util.MovementInput; +import net.minecraft.util.math.vector.Vector2f; import net.minecraft.util.math.vector.Vector3d; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.client.event.InputUpdateEvent; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -27,7 +34,8 @@ public class KeyRecorder { public static final KeyState keyQuickTurn = new KeyState(); public static final KeyState keyFlipping = new KeyState(); public static final KeyState keyBindGrabWall = new KeyState(); - public static Vector3d lastDirection = null; + private static Vector3d keyboardDirection = null; + private static Vector3d lastDirection = null; @SubscribeEvent public static void onClientTick(TickEvent.ClientTickEvent event) { @@ -50,12 +58,13 @@ public static void onClientTick(TickEvent.ClientTickEvent event) { record(KeyBindings.getKeyQuickTurn(), keyQuickTurn); record(KeyBindings.getKeyFlipping(), keyFlipping); record(KeyBindings.getKeyGrabWall(), keyBindGrabWall); - recordMovingVector(KeyBindings.isAnyMovingKeyDown()); } @Nullable public static Vector3d getLastMoveVector() { - return lastDirection; + Vector3d vector = lastDirection; + if (vector == null) return null; + return CameraUtil.alignVectorToCamera(vector); } private static void record(Boolean isDown, KeyState state) { @@ -78,8 +87,12 @@ private static void record(KeyBinding keyBinding, KeyState state) { record(keyBinding.isDown(), state); } - private static void recordMovingVector(boolean isMoving) { - if (isMoving) lastDirection = KeyBindings.getCurrentMoveVector(); + public static void recordKeyboardMovingVector(MovementInput moving) { + Vector2f vector = moving.getMoveVector(); + if (!VectorUtil.isZero(vector)) { + Vector3d newDirection = new Vector3d(vector.x, 0, vector.y); + keyboardDirection = newDirection; + } } public static class KeyState { @@ -114,4 +127,19 @@ public int getPreviousTickNotKeyDown() { return previousTickNotKeyDown; } } + + public static void onInputs(InputUpdateEvent event) { + ClientPlayerEntity player = Minecraft.getInstance().player; + if (player == null) return; + if (keyboardDirection != null) { + lastDirection = keyboardDirection; + keyboardDirection = null; + return; + } + Vector2f vector = player.input.getMoveVector(); + if (!VectorUtil.isZero(vector)) { + Vector3d newDirection = new Vector3d(vector.x, 0, vector.y); + lastDirection = newDirection; + } + } } diff --git a/src/main/java/com/alrex/parcool/common/action/impl/Dodge.java b/src/main/java/com/alrex/parcool/common/action/impl/Dodge.java index 7a7daaa0..b4f4a1ed 100644 --- a/src/main/java/com/alrex/parcool/common/action/impl/Dodge.java +++ b/src/main/java/com/alrex/parcool/common/action/impl/Dodge.java @@ -14,6 +14,7 @@ import com.alrex.parcool.common.info.ActionInfo; import com.alrex.parcool.config.ParCoolConfig; import com.alrex.parcool.extern.AdditionalMods; +import com.alrex.parcool.utilities.CameraUtil; import com.alrex.parcool.utilities.EntityUtil; import com.alrex.parcool.utilities.VectorUtil; @@ -131,7 +132,6 @@ public double getSpeedModifier(ActionInfo info) { public boolean canStart(PlayerEntity player, Parkourability parkourability, IStamina stamina, ByteBuffer startInfo) { boolean enabledDoubleTap = ParCoolConfig.Client.Booleans.EnableDoubleTappingForDodge.get(); DodgeDirection direction = null; - Vector3d dodgeVec = KeyRecorder.getLastMoveVector(); if (enabledDoubleTap) { if (KeyRecorder.keyBack.isDoubleTapped()) direction = DodgeDirection.Back; if (KeyRecorder.keyLeft.isDoubleTapped()) direction = DodgeDirection.Left; @@ -142,14 +142,15 @@ public boolean canStart(PlayerEntity player, Parkourability parkourability, ISta if (KeyBindings.isKeyForwardDown()) direction = DodgeDirection.Front; if (KeyBindings.isKeyLeftDown()) direction = DodgeDirection.Left; if (KeyBindings.isKeyRightDown()) direction = DodgeDirection.Right; - if (direction != null) dodgeVec = KeyBindings.getCurrentMoveVector(); } - if (direction == null || dodgeVec == null) return false; + if (direction == null) return false; + Vector3d dodgeVec = KeyRecorder.getLastMoveVector(); + if (dodgeVec == null) return false; direction = AdditionalMods.betterThirdPerson().handleCustomCameraRotationForDodge(direction); direction = AdditionalMods.shoulderSurfingManager().handleCustomCameraRotationForDodge(direction); startInfo.putInt(direction.ordinal()); - startInfo.putDouble(dodgeVec.x); - startInfo.putDouble(dodgeVec.z); + startInfo.putDouble(dodgeVec.x()); + startInfo.putDouble(dodgeVec.z()); return ((parkourability.getAdditionalProperties().getLandingTick() > 5 || parkourability.getAdditionalProperties().getPreviousNotLandingTick() < 2) && player.isOnGround() && !isInSuccessiveCoolDown(parkourability.getActionInfo()) @@ -179,8 +180,8 @@ public boolean canContinue(PlayerEntity player, Parkourability parkourability, I @Override public void onStartInLocalClient(PlayerEntity player, Parkourability parkourability, IStamina stamina, ByteBuffer startData) { dodgeDirection = DodgeDirection.values()[startData.getInt()]; - Vector3d dodgeVec = new Vector3d(startData.getDouble(), 0, startData.getDouble()); coolTime = getMaxCoolTime(parkourability.getActionInfo()); + Vector3d dodgeVec = new Vector3d(startData.getDouble(), 0, startData.getDouble()); if (successivelyCount < getMaxSuccessiveDodge(parkourability.getActionInfo())) { successivelyCount++; } @@ -190,10 +191,8 @@ public void onStartInLocalClient(PlayerEntity player, Parkourability parkourabil successivelyCoolTick = getSuccessiveCoolTime(parkourability.getActionInfo()); if (!player.isOnGround()) return; - float cameraYRot = Minecraft.getInstance().getCameraEntity().yRot; - dodgeVec = VectorUtil.rotateYDegrees(dodgeVec, cameraYRot); dodgeVec = dodgeVec.scale(0.9 * getSpeedModifier(parkourability.getActionInfo())); - if (AdditionalMods.isCameraDecoupled()) { + if (CameraUtil.isCameraDecoupled()) { EntityUtil.setYRot(player, VectorUtil.toYaw(dodgeVec)); } player.setDeltaMovement(dodgeVec); diff --git a/src/main/java/com/alrex/parcool/extern/AdditionalMods.java b/src/main/java/com/alrex/parcool/extern/AdditionalMods.java index 871715f5..90cf0dc8 100644 --- a/src/main/java/com/alrex/parcool/extern/AdditionalMods.java +++ b/src/main/java/com/alrex/parcool/extern/AdditionalMods.java @@ -2,7 +2,6 @@ import com.alrex.parcool.extern.betterthirdperson.BetterThirdPersonManager; import com.alrex.parcool.extern.shouldersurfing.ShoulderSurfingManager; - import java.util.Arrays; import java.util.function.Supplier; @@ -30,8 +29,4 @@ public ModManager get() { public static void init() { Arrays.stream(values()).map(AdditionalMods::get).forEach(ModManager::init); } - - public static boolean isCameraDecoupled() { - return shoulderSurfingManager().isCameraDecoupled() || betterThirdPerson().isCameraDecoupled(); - } } diff --git a/src/main/java/com/alrex/parcool/extern/betterthirdperson/BetterThirdPersonManager.java b/src/main/java/com/alrex/parcool/extern/betterthirdperson/BetterThirdPersonManager.java index bb4035e5..7a3b00d6 100644 --- a/src/main/java/com/alrex/parcool/extern/betterthirdperson/BetterThirdPersonManager.java +++ b/src/main/java/com/alrex/parcool/extern/betterthirdperson/BetterThirdPersonManager.java @@ -1,7 +1,6 @@ package com.alrex.parcool.extern.betterthirdperson; import com.alrex.parcool.common.action.impl.Dodge; -import com.alrex.parcool.extern.AdditionalMods; import com.alrex.parcool.extern.ModManager; import io.socol.betterthirdperson.BetterThirdPerson; import net.minecraft.client.Minecraft; @@ -20,4 +19,9 @@ public boolean isCameraDecoupled() { && !Minecraft.getInstance().options.getCameraType().isFirstPerson() && BetterThirdPerson.getCameraManager().hasCustomCamera(); } + + public Float getCameraYaw() { + if (!isCameraDecoupled()) return null; + return BetterThirdPerson.getCameraManager().getCustomCamera().getYaw(); + } } diff --git a/src/main/java/com/alrex/parcool/extern/shouldersurfing/ShoulderSurfingManager.java b/src/main/java/com/alrex/parcool/extern/shouldersurfing/ShoulderSurfingManager.java index ed47bd6d..0b2b1fb3 100644 --- a/src/main/java/com/alrex/parcool/extern/shouldersurfing/ShoulderSurfingManager.java +++ b/src/main/java/com/alrex/parcool/extern/shouldersurfing/ShoulderSurfingManager.java @@ -22,4 +22,9 @@ public Boolean isCameraDecoupled() { && ShoulderSurfing.getInstance().isShoulderSurfing() && Config.CLIENT.isCameraDecoupled(); } + + public Float getCameraYaw() { + if (!isCameraDecoupled()) return null; + return ShoulderSurfing.getInstance().getCamera().getYRot(); + } } diff --git a/src/main/java/com/alrex/parcool/mixin/client/MovementInputMixin.java b/src/main/java/com/alrex/parcool/mixin/client/MovementInputMixin.java new file mode 100644 index 00000000..ce02ad6c --- /dev/null +++ b/src/main/java/com/alrex/parcool/mixin/client/MovementInputMixin.java @@ -0,0 +1,23 @@ +package com.alrex.parcool.mixin.client; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.At; +import com.alrex.parcool.client.input.KeyRecorder; +import net.minecraft.util.MovementInputFromOptions; + +@Mixin({MovementInputFromOptions.class}) +public class MovementInputMixin { + @Inject( + method = {"tick"}, + at = @At( + value = "FIELD", + target = "Lnet/minecraft/util/MovementInputFromOptions;shiftKeyDown:Z", + shift = At.Shift.AFTER // Execute after the field assignment + ) + ) + public void tickHook(boolean moveSlowly, CallbackInfo ci) { + KeyRecorder.recordKeyboardMovingVector((MovementInputFromOptions)(Object)this); + } +} \ No newline at end of file diff --git a/src/main/java/com/alrex/parcool/utilities/CameraUtil.java b/src/main/java/com/alrex/parcool/utilities/CameraUtil.java new file mode 100644 index 00000000..891d4716 --- /dev/null +++ b/src/main/java/com/alrex/parcool/utilities/CameraUtil.java @@ -0,0 +1,28 @@ +package com.alrex.parcool.utilities; + +import javax.annotation.Nullable; +import com.alrex.parcool.extern.AdditionalMods; +import net.minecraft.client.Minecraft; +import net.minecraft.util.math.vector.Vector3d; + +public class CameraUtil { + public static boolean isCameraDecoupled() { + return AdditionalMods.shoulderSurfingManager().isCameraDecoupled() || AdditionalMods.betterThirdPerson().isCameraDecoupled(); + } + + public static float getCameraYaw() { + @Nullable Float yaw = AdditionalMods.shoulderSurfingManager().getCameraYaw(); + if (yaw != null) return yaw; + yaw = AdditionalMods.betterThirdPerson().getCameraYaw(); + if (yaw != null) return yaw; + return Minecraft.getInstance().cameraEntity.yRot; + } + + public static Vector3d alignVectorToCamera(Vector3d vector) { + if (vector == null) return null; + Minecraft mc = Minecraft.getInstance(); + if (mc.player == null) return vector; + Float cameraYaw = getCameraYaw(); + return VectorUtil.rotateYDegrees(vector, cameraYaw); + } +} diff --git a/src/main/resources/parcool.mixins.json b/src/main/resources/parcool.mixins.json index d7da227e..197303c1 100644 --- a/src/main/resources/parcool.mixins.json +++ b/src/main/resources/parcool.mixins.json @@ -11,7 +11,8 @@ "client.GameSettingsMixin", "client.LivingRendererMixin", "client.PlayerModelMixin", - "client.PlayerRendererMixin" + "client.PlayerRendererMixin", + "client.MovementInputMixin" ], "injectors": { "defaultRequire": 1