From a8786bcbca400ce4afa6594c4b594b6cbf380e0b Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 27 May 2025 22:08:44 +0200 Subject: [PATCH 1/3] [VirtualInput] Rewrite camera clearing on load --- .../tasmod/handlers/LoadingScreenHandler.java | 21 +++++++++++++++++-- .../playbackhooks/MixinEntityRenderer.java | 3 ++- .../tasmod/virtual/VirtualInput.java | 5 ++++- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java b/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java index 3cc890c9..c5a02e99 100644 --- a/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java @@ -6,21 +6,24 @@ import com.minecrafttas.mctcommon.events.EventClient.EventDoneLoadingPlayer; import com.minecrafttas.mctcommon.events.EventClient.EventDoneLoadingWorld; import com.minecrafttas.mctcommon.events.EventClient.EventLaunchIntegratedServer; +import com.minecrafttas.mctcommon.events.EventClient.EventPlayerLeaveClientSide; import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.TASmodClient; import com.minecrafttas.tasmod.mixin.playbackhooks.MixinEntityRenderer; import com.minecrafttas.tasmod.playback.PlaybackControllerClient; import com.minecrafttas.tasmod.util.LoggerMarkers; import com.minecrafttas.tasmod.virtual.VirtualInput; +import com.minecrafttas.tasmod.virtual.VirtualInput.VirtualCameraAngleInput; import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; /** * Handles logic during a loading screen to transition between states. * * @author Scribble */ -public class LoadingScreenHandler implements EventLaunchIntegratedServer, EventClientGameLoop, EventDoneLoadingWorld, EventDoneLoadingPlayer { +public class LoadingScreenHandler implements EventLaunchIntegratedServer, EventClientGameLoop, EventDoneLoadingWorld, EventDoneLoadingPlayer, EventPlayerLeaveClientSide { private boolean waszero; private boolean isLoading; @@ -90,7 +93,21 @@ public boolean isLoading() { @Override public void onDoneLoadingPlayer() { LOGGER.debug(LoggerMarkers.Event, "Finished loading the player position on the client"); - TASmodClient.virtual.clear(); + VirtualCameraAngleInput cameraAngle = TASmodClient.virtual.CAMERA_ANGLE; + if (cameraAngle.getCurrentPitch() == null || cameraAngle.getCurrentYaw() == null) { + LOGGER.debug("Setting the initial pitch and yaw"); + Minecraft mc = Minecraft.getMinecraft(); + EntityPlayerSP player = mc.player; + cameraAngle.setCamera(player.rotationPitch, player.rotationYaw); + TASmodClient.virtual.clear(); + } + } + + @Override + public void onPlayerLeaveClientSide(EntityPlayerSP player) { + LOGGER.debug(LoggerMarkers.Event, "Finished leaving on the on the client side"); + LOGGER.debug("Resetting pitch and yaw"); + TASmodClient.virtual.CAMERA_ANGLE.clear(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java index 4ad6feb8..b0f58f5d 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java @@ -118,7 +118,8 @@ public void runUpdate(float partialTicks) { // set nextCameraAngle to the current absolute camera coordinates. // This ensures that the camera position is loaded correctly if (newPitch == null || newYaw == null) { - TASmodClient.virtual.CAMERA_ANGLE.setCamera(prevPitch, prevYaw); +// TASmod.LOGGER.warn("Pitch and Yaw is null! This is not good!"); +// TASmodClient.virtual.CAMERA_ANGLE.setCamera(prevPitch, prevYaw); return; } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 440074af..3099197c 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -137,7 +137,6 @@ public boolean willKeyBeDown(int keycode) { public void clear() { KEYBOARD.nextKeyboard.clear(); MOUSE.nextMouse.clear(); - CAMERA_ANGLE.nextCameraAngle.clear(); } public void preloadInput(VirtualKeyboard keyboardToPreload, VirtualMouse mouseToPreload, VirtualCameraAngle angleToPreload) { @@ -710,5 +709,9 @@ public Triple getInterpolatedState(float partialTick, float } return Triple.of(interpolatedPitch, interpolatedYaw, 0f); } + + public void clear() { + nextCameraAngle.clear(); + } } } From 0915358c10872f0732df0e06a009fba7264b0ed9 Mon Sep 17 00:00:00 2001 From: Scribble Date: Wed, 28 May 2025 10:38:00 +0200 Subject: [PATCH 2/3] [VirtualInput] Clean up camera changes - Adjusted documentation - Move VirtualInput#clear from onDoneLoadingPlayer to onPlayerJoinedClientSide - Renamed VirtualInput#clear to VirtualInput#clearKeys for clarity - Added clearNext methods to Keyboard and Mouse to be able to clear individual input methods. Also to be consistent with the camera angle --- .../mctcommon/events/EventClient.java | 8 +++- .../tasmod/handlers/LoadingScreenHandler.java | 39 ++++++++++--------- .../playback/PlaybackControllerClient.java | 6 +-- .../savestates/SavestateHandlerClient.java | 4 +- .../tasmod/virtual/VirtualInput.java | 24 ++++++++++-- 5 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/minecrafttas/mctcommon/events/EventClient.java b/src/main/java/com/minecrafttas/mctcommon/events/EventClient.java index 5eb11628..3a265f92 100644 --- a/src/main/java/com/minecrafttas/mctcommon/events/EventClient.java +++ b/src/main/java/com/minecrafttas/mctcommon/events/EventClient.java @@ -62,7 +62,9 @@ public static interface EventDoneLoadingWorld extends EventBase { } /** - * Fired when the player is done loading, after the position has been loaded from the server side + * Fired when the player is done loading, after the position has been loaded from the server side.
+ * This also fires every time the player switches dimensions. + * * @author Scribble * @see NetHandlerPlayClient#handlePlayerPosLook(net.minecraft.network.play.server.SPacketPlayerPosLook) */ @@ -70,7 +72,9 @@ public static interface EventDoneLoadingWorld extends EventBase { public static interface EventDoneLoadingPlayer extends EventBase { /** - * Fired when the player is done loading, after the position has been loaded from the server side + * Fired when the player is done loading, after the position has been loaded from the server side.
+ * This also fires every time the player switches dimensions. + * * @see NetHandlerPlayClient#handlePlayerPosLook(net.minecraft.network.play.server.SPacketPlayerPosLook) */ public void onDoneLoadingPlayer(); diff --git a/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java b/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java index c5a02e99..0e174bd1 100644 --- a/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java @@ -6,13 +6,12 @@ import com.minecrafttas.mctcommon.events.EventClient.EventDoneLoadingPlayer; import com.minecrafttas.mctcommon.events.EventClient.EventDoneLoadingWorld; import com.minecrafttas.mctcommon.events.EventClient.EventLaunchIntegratedServer; +import com.minecrafttas.mctcommon.events.EventClient.EventPlayerJoinedClientSide; import com.minecrafttas.mctcommon.events.EventClient.EventPlayerLeaveClientSide; import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.TASmodClient; -import com.minecrafttas.tasmod.mixin.playbackhooks.MixinEntityRenderer; import com.minecrafttas.tasmod.playback.PlaybackControllerClient; import com.minecrafttas.tasmod.util.LoggerMarkers; -import com.minecrafttas.tasmod.virtual.VirtualInput; import com.minecrafttas.tasmod.virtual.VirtualInput.VirtualCameraAngleInput; import net.minecraft.client.Minecraft; @@ -23,7 +22,7 @@ * * @author Scribble */ -public class LoadingScreenHandler implements EventLaunchIntegratedServer, EventClientGameLoop, EventDoneLoadingWorld, EventDoneLoadingPlayer, EventPlayerLeaveClientSide { +public class LoadingScreenHandler implements EventLaunchIntegratedServer, EventClientGameLoop, EventDoneLoadingWorld, EventDoneLoadingPlayer, EventPlayerJoinedClientSide, EventPlayerLeaveClientSide { private boolean waszero; private boolean isLoading; @@ -78,17 +77,7 @@ public boolean isLoading() { /** * {@inheritDoc} * - *

Fixes an issue, where the look position of the player is reset to 0 -180,
- * As well as removing any keyboard inputs present in the main menu - * - *

{@link MixinEntityRenderer#runUpdate(float)} rewrites the camera input,
- * So that it can be used with interpolation.
- * However, when you start the game, this camera input needs to be initialised with the current look position from the server.
- * So a special condition is set, that if the {@link VirtualInput#CAMERA_ANGLE} is null,
- * it intialises the {@link VirtualInput#CAMERA_ANGLE CAMERA_ANGLE} with the current player camera angle. - * - *

So {@link VirtualInput#clear()} has to be called at the right moment in the player initialisation
- * to set the correct values. Before that, the playerRotation defaults to 0 -180 + *

Initializes the virtual camera to be in line with the vanilla camera. */ @Override public void onDoneLoadingPlayer() { @@ -99,15 +88,29 @@ public void onDoneLoadingPlayer() { Minecraft mc = Minecraft.getMinecraft(); EntityPlayerSP player = mc.player; cameraAngle.setCamera(player.rotationPitch, player.rotationYaw); - TASmodClient.virtual.clear(); } } + /** + * {@inheritDoc} + * + *

Fixes stuck keys when loading the world + */ + @Override + public void onPlayerJoinedClientSide(EntityPlayerSP player) { + TASmodClient.virtual.clearKeys(); + } + + /** + * {@inheritDoc} + * + *

Resets the camera angle when leaving the world. + *

If you later rejoin the world {@link #onDoneLoadingPlayer()} will re-initialise the camera angle + */ @Override public void onPlayerLeaveClientSide(EntityPlayerSP player) { LOGGER.debug(LoggerMarkers.Event, "Finished leaving on the on the client side"); - LOGGER.debug("Resetting pitch and yaw"); - TASmodClient.virtual.CAMERA_ANGLE.clear(); + LOGGER.debug("Resetting the camera angle on leaving the world"); + TASmodClient.virtual.CAMERA_ANGLE.clearNext(); } - } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index 43d35534..b275a921 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -245,7 +245,7 @@ public String setTASStateClient(TASstate stateIn, boolean verbose) { LOGGER.debug(LoggerMarkers.Playback, "Pausing a playback"); state = TASstate.PAUSED; stateAfterPause = TASstate.PLAYBACK; - TASmodClient.virtual.clear(); + TASmodClient.virtual.clearKeys(); return verbose ? TextFormatting.GREEN + "Pausing a playback" : ""; case NONE: stopPlayback(true); @@ -291,7 +291,7 @@ private void startRecording() { private void stopRecording() { LOGGER.debug(LoggerMarkers.Playback, "Stopping a recording"); - TASmodClient.virtual.clear(); + TASmodClient.virtual.clearKeys(); } private void startPlayback() { @@ -305,7 +305,7 @@ private void stopPlayback(boolean clearInputs) { LOGGER.debug(LoggerMarkers.Playback, "Stopping a playback"); Minecraft.getMinecraft().gameSettings.chatLinks = true; if (clearInputs) { - TASmodClient.virtual.clear(); + TASmodClient.virtual.clearKeys(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerClient.java b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerClient.java index 63703a1a..b27baa51 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerClient.java @@ -203,7 +203,7 @@ public static void loadstate(String nameOfSavestate) throws Exception { preload(savestateContainerList, index); controller.setInputs(savestateContainerList, index); - TASmodClient.virtual.clear(); + TASmodClient.virtual.clearKeys(); } /* * When loading a savestate during a playback 2 different scenarios can happen. @@ -237,7 +237,7 @@ else if (state == TASstate.PLAYBACK) { preload(controller.getInputs(), index); controller.setIndex(index); - TASmodClient.virtual.clear(); + TASmodClient.virtual.clearKeys(); } /* * Scenario 2: diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 3099197c..ff615b56 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -134,9 +134,9 @@ public boolean willKeyBeDown(int keycode) { /** * Unpresses all keys in {@link VirtualKeyboardInput#nextKeyboard} and {@link VirtualMouseInput#nextMouse} */ - public void clear() { - KEYBOARD.nextKeyboard.clear(); - MOUSE.nextMouse.clear(); + public void clearKeys() { + KEYBOARD.clearNext(); + MOUSE.clearNext(); } public void preloadInput(VirtualKeyboard keyboardToPreload, VirtualMouse mouseToPreload, VirtualCameraAngle angleToPreload) { @@ -339,6 +339,13 @@ public boolean isKeyDown(int keycode) { public boolean willKeyBeDown(int keycode) { return nextKeyboard.isKeyDown(keycode); } + + /** + * Clears the {@link #nextKeyboard} + */ + public void clearNext() { + nextKeyboard.clear(); + } } /** @@ -530,6 +537,12 @@ public boolean willKeyBeDown(int keycode) { return nextMouse.isKeyDown(keycode); } + /** + * Clears the {@link #nextMouse} + */ + public void clearNext() { + nextMouse.clear(); + } } /** @@ -710,7 +723,10 @@ public Triple getInterpolatedState(float partialTick, float return Triple.of(interpolatedPitch, interpolatedYaw, 0f); } - public void clear() { + /** + * Clears the {@link #nextCameraAngle} + */ + public void clearNext() { nextCameraAngle.clear(); } } From aff8f6180c16c3afc5f7bb39782d7a89aedbdfb7 Mon Sep 17 00:00:00 2001 From: Scribble Date: Wed, 28 May 2025 11:10:30 +0200 Subject: [PATCH 3/3] [VirtualInput] Documentation and method naming fixes - Fixed documentation in MixinEntityRenderer and renamed mixin methods to better describe the area --- .../mixin/events/MixinEntityRenderer.java | 35 ---------------- .../playbackhooks/MixinEntityRenderer.java | 41 +++++++++++++++---- src/main/resources/tasmod.mixin.json | 1 - 3 files changed, 34 insertions(+), 43 deletions(-) delete mode 100644 src/main/java/com/minecrafttas/tasmod/mixin/events/MixinEntityRenderer.java diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/events/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/events/MixinEntityRenderer.java deleted file mode 100644 index f61e3de6..00000000 --- a/src/main/java/com/minecrafttas/tasmod/mixin/events/MixinEntityRenderer.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.minecrafttas.tasmod.mixin.events; - -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 com.minecrafttas.mctcommon.events.EventListenerRegistry; -import com.minecrafttas.tasmod.events.EventClient.EventDrawHotbarAlways; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.ScaledResolution; -import net.minecraft.client.renderer.EntityRenderer; -import net.minecraft.client.renderer.GlStateManager; - -@Mixin(EntityRenderer.class) -public class MixinEntityRenderer { - - @Shadow - private Minecraft mc; - - @Inject(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V")) - public void inject_onRenderGameOverlay(CallbackInfo ci) { - ScaledResolution scaledResolution = new ScaledResolution(this.mc); - GlStateManager.clear(256); - GlStateManager.matrixMode(5889); - GlStateManager.loadIdentity(); - GlStateManager.ortho(0.0, scaledResolution.getScaledWidth_double(), scaledResolution.getScaledHeight_double(), 0.0, 1000.0, 3000.0); - GlStateManager.matrixMode(5888); - GlStateManager.loadIdentity(); - GlStateManager.translate(0.0F, 0.0F, -2000.0F); - EventListenerRegistry.fireEvent(EventDrawHotbarAlways.class); - } -} diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java index b0f58f5d..daf1f405 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java @@ -11,12 +11,15 @@ import com.llamalad7.mixinextras.sugar.Share; import com.llamalad7.mixinextras.sugar.ref.LocalFloatRef; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; import com.minecrafttas.tasmod.TASmodClient; +import com.minecrafttas.tasmod.events.EventClient.EventDrawHotbarAlways; import com.minecrafttas.tasmod.util.Ducks.SubtickDuck; import com.minecrafttas.tasmod.virtual.VirtualInput; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.EntityRenderer; import net.minecraft.client.renderer.GlStateManager; @@ -114,11 +117,18 @@ public void runUpdate(float partialTicks) { Float newPitch = TASmodClient.virtual.CAMERA_ANGLE.getCurrentPitch(); Float newYaw = TASmodClient.virtual.CAMERA_ANGLE.getCurrentYaw(); - // If the pitch or yaw is null (usually on initialize or when the player joins the world), - // set nextCameraAngle to the current absolute camera coordinates. - // This ensures that the camera position is loaded correctly + /* + * If the pitch or yaw is null, + * usually on initialize or when the player joins the world), + * do not update the camera angle. + * + * This is called during the loading screen for 2 game loops, + * at which point the player is not initialized, + * hence we do not have the correct camera angle yet. + * + * The angle is instead initialized in LoadingScreenHandler#onDoneLoadingPlayer. + */ if (newPitch == null || newYaw == null) { -// TASmod.LOGGER.warn("Pitch and Yaw is null! This is not good!"); // TASmodClient.virtual.CAMERA_ANGLE.setCamera(prevPitch, prevYaw); return; } @@ -139,7 +149,7 @@ public void runUpdate(float partialTicks) { * @return 0f for disabeling this method */ @ModifyArg(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;rotate(FFFF)V", ordinal = 8), index = 0) - public float redirect_orientCameraPitch(float pitch, @Share("pitch") LocalFloatRef sharedPitch) { + public float playback_orientCameraPitch(float pitch, @Share("pitch") LocalFloatRef sharedPitch) { sharedPitch.set(pitch); return 0f; } @@ -151,7 +161,7 @@ public float redirect_orientCameraPitch(float pitch, @Share("pitch") LocalFloatR * @return The redirected yaw */ @ModifyArg(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;rotate(FFFF)V", ordinal = 9), index = 0) - public float redirect_orientCameraYawAnimal(float yawAnimal, @Share("pitch") LocalFloatRef sharedPitch) { + public float playback_orientCameraYawAnimal(float yawAnimal, @Share("pitch") LocalFloatRef sharedPitch) { return redirectCam(sharedPitch.get(), yawAnimal); } @@ -162,10 +172,27 @@ public float redirect_orientCameraYawAnimal(float yawAnimal, @Share("pitch") Loc * @return The redirected yaw */ @ModifyArg(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;rotate(FFFF)V", ordinal = 10), index = 0) - public float redirect_orientCameraYaw(float yaw, @Share("pitch") LocalFloatRef sharedPitch) { + public float playback_orientCameraYaw(float yaw, @Share("pitch") LocalFloatRef sharedPitch) { return redirectCam(sharedPitch.get(), yaw); } + /** + * Updates the game overlay and adds an event + * @param ci CallBackInfo + */ + @Inject(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V")) + public void playback_updateOverlay(CallbackInfo ci) { + ScaledResolution scaledResolution = new ScaledResolution(this.mc); + GlStateManager.clear(256); + GlStateManager.matrixMode(5889); + GlStateManager.loadIdentity(); + GlStateManager.ortho(0.0, scaledResolution.getScaledWidth_double(), scaledResolution.getScaledHeight_double(), 0.0, 1000.0, 3000.0); + GlStateManager.matrixMode(5888); + GlStateManager.loadIdentity(); + GlStateManager.translate(0.0F, 0.0F, -2000.0F); + EventListenerRegistry.fireEvent(EventDrawHotbarAlways.class); + } + /** * Turns the camera via GLStateManager * @param pitch The pi diff --git a/src/main/resources/tasmod.mixin.json b/src/main/resources/tasmod.mixin.json index bf57b5be..6f004f1d 100644 --- a/src/main/resources/tasmod.mixin.json +++ b/src/main/resources/tasmod.mixin.json @@ -41,7 +41,6 @@ // Events "events.MixinGuiIngame", - "events.MixinEntityRenderer", "events.MixinNetHandlerPlayClient", "clientcommands.MixinEntityPlayerSP",