From d12d06bdb37ad2cc7ce5f44ef029428cbe9cd7cf Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Wed, 13 Dec 2023 21:27:12 +0000 Subject: [PATCH 1/8] Refactor disableNextTick --- common/src/main/java/net/xolt/freecam/Freecam.java | 12 ++++-------- .../net/xolt/freecam/mixins/LivingEntityMixin.java | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/common/src/main/java/net/xolt/freecam/Freecam.java b/common/src/main/java/net/xolt/freecam/Freecam.java index c4ebd537..19f35d7b 100644 --- a/common/src/main/java/net/xolt/freecam/Freecam.java +++ b/common/src/main/java/net/xolt/freecam/Freecam.java @@ -37,9 +37,8 @@ public class Freecam { public static void preTick(Minecraft mc) { if (isEnabled()) { // Disable if the previous tick asked us to - if (disableNextTick()) { + if (disableNextTick) { toggle(); - disableNextTick = false; } // Prevent player from being controlled when freecam is enabled @@ -51,6 +50,7 @@ public static void preTick(Minecraft mc) { mc.gameRenderer.setRenderHand(ModConfig.INSTANCE.visual.showHand); } + disableNextTick = false; } public static void postTick(Minecraft mc) { @@ -282,12 +282,8 @@ public static HashMap getTripodsForDimension() { return result; } - public static boolean disableNextTick() { - return disableNextTick; - } - - public static void setDisableNextTick(boolean damage) { - disableNextTick = damage; + public static void disableNextTick() { + disableNextTick = true; } public static boolean isEnabled() { diff --git a/common/src/main/java/net/xolt/freecam/mixins/LivingEntityMixin.java b/common/src/main/java/net/xolt/freecam/mixins/LivingEntityMixin.java index 0ad4834d..3cd4187c 100644 --- a/common/src/main/java/net/xolt/freecam/mixins/LivingEntityMixin.java +++ b/common/src/main/java/net/xolt/freecam/mixins/LivingEntityMixin.java @@ -32,7 +32,7 @@ private void onGetMovementSpeed(CallbackInfoReturnable cir) { private void onSetHealth(float health, CallbackInfo ci) { if (Freecam.isEnabled() && ModConfig.INSTANCE.utility.disableOnDamage && this.equals(MC.player)) { if (!MC.player.isCreative() && getHealth() > health) { - Freecam.setDisableNextTick(true); + Freecam.disableNextTick(); } } } From fe3e3794255b0e02e04a945a10d2738fe7228b70 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Wed, 13 Dec 2023 18:38:13 +0000 Subject: [PATCH 2/8] Cleanup & improve keypress handling - General cleanup of keybind code. - Allow toggle bind to be held while waiting for tripod combos. - Only toggle when bind is released & no tripods were activated. - Only toggle when bind wasn't held _too_ long. Also: - Added a `reset` method to `ModBinding`. - Updated "wrapper" methods to Mojang mappings. --- .../main/java/net/xolt/freecam/Freecam.java | 46 +++++++++++++------ .../net/xolt/freecam/config/ModBindings.java | 23 +++++++--- .../xolt/freecam/mixins/MinecraftMixin.java | 2 +- 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/common/src/main/java/net/xolt/freecam/Freecam.java b/common/src/main/java/net/xolt/freecam/Freecam.java index 19f35d7b..e53b01e9 100644 --- a/common/src/main/java/net/xolt/freecam/Freecam.java +++ b/common/src/main/java/net/xolt/freecam/Freecam.java @@ -22,11 +22,14 @@ public class Freecam { public static final Minecraft MC = Minecraft.getInstance(); public static final String MOD_ID = "freecam"; + private static final long TOGGLE_KEY_MAX_TICKS = 10; private static boolean freecamEnabled = false; private static boolean tripodEnabled = false; private static boolean playerControlEnabled = false; private static boolean disableNextTick = false; + private static boolean toggleKeyUsedWhileHeld = false; + private static long toggleKeyHeldTicks = 0; private static Integer activeTripod = null; private static FreeCamera freeCamera; private static HashMap overworld_tripods = new HashMap<>(); @@ -54,32 +57,45 @@ public static void preTick(Minecraft mc) { } public static void postTick(Minecraft mc) { - if (KEY_TRIPOD_RESET.isPressed()) { - for (KeyMapping hotbarKey : mc.options.keyHotbarSlots) { - while (hotbarKey.consumeClick()) { - resetCamera(hotbarKey.getDefaultKey().getValue()); - while (KEY_TRIPOD_RESET.wasPressed()) {} + if (KEY_TOGGLE.isDown()) { + // Count held ticks, so we can toggle on release + toggleKeyHeldTicks++; + KEY_TOGGLE.reset(); + + // Handle + combos + for (KeyMapping combo : mc.options.keyHotbarSlots) { + while (combo.consumeClick()) { + toggleTripod(combo.getDefaultKey().getValue()); + toggleKeyUsedWhileHeld = true; } } } + // Check if toggle was pressed, and is now released + else if (KEY_TOGGLE.consumeClick() || toggleKeyHeldTicks > 0) { + // Only toggle if the key wasn't used (or held too long) + if (!toggleKeyUsedWhileHeld && toggleKeyHeldTicks < TOGGLE_KEY_MAX_TICKS) { + toggle(); + } + // Reset state + KEY_TOGGLE.reset(); + toggleKeyHeldTicks = 0; + toggleKeyUsedWhileHeld = false; + } - if (KEY_TOGGLE.isPressed()) { - for (KeyMapping hotbarKey : mc.options.keyHotbarSlots) { - while (hotbarKey.consumeClick()) { - toggleTripod(hotbarKey.getDefaultKey().getValue()); - while (KEY_TOGGLE.wasPressed()) {} + // Handle + combos + if (KEY_TRIPOD_RESET.isDown()) { + for (KeyMapping key : mc.options.keyHotbarSlots) { + while (key.consumeClick()) { + resetCamera(key.getDefaultKey().getValue()); } } - } else if (KEY_TOGGLE.wasPressed()) { - toggle(); - while (KEY_TOGGLE.wasPressed()) {} } - while (KEY_PLAYER_CONTROL.wasPressed()) { + while (KEY_PLAYER_CONTROL.consumeClick()) { switchControls(); } - while (KEY_CONFIG_GUI.wasPressed()) { + while (KEY_CONFIG_GUI.consumeClick()) { mc.setScreen(AutoConfig.getConfigScreen(ModConfig.class, mc.screen).get()); } } diff --git a/common/src/main/java/net/xolt/freecam/config/ModBindings.java b/common/src/main/java/net/xolt/freecam/config/ModBindings.java index 5694c8a3..c7cafba4 100644 --- a/common/src/main/java/net/xolt/freecam/config/ModBindings.java +++ b/common/src/main/java/net/xolt/freecam/config/ModBindings.java @@ -3,6 +3,7 @@ import com.google.common.base.Supplier; import com.google.common.base.Suppliers; import com.mojang.blaze3d.platform.InputConstants; +import net.minecraft.client.KeyMapping; import org.jetbrains.annotations.NotNull; import java.util.Arrays; @@ -10,7 +11,6 @@ import java.util.Objects; import java.util.Spliterator; import java.util.function.Consumer; -import net.minecraft.client.KeyMapping; import static org.lwjgl.glfw.GLFW.GLFW_KEY_F4; import static org.lwjgl.glfw.GLFW.GLFW_KEY_UNKNOWN; @@ -22,7 +22,7 @@ public enum ModBindings { KEY_TRIPOD_RESET("tripodReset"), KEY_CONFIG_GUI("configGui"); - private final Supplier lazyBinding; + private final Supplier lazyMapping; ModBindings(String translationKey) { this(translationKey, InputConstants.Type.KEYSYM, GLFW_KEY_UNKNOWN); @@ -37,7 +37,7 @@ public enum ModBindings { } ModBindings(String translationKey, InputConstants.Type type, int code) { - this.lazyBinding = Suppliers.memoize(() -> + this.lazyMapping = Suppliers.memoize(() -> new KeyMapping("key.freecam." + translationKey, type, code, "category.freecam.freecam")); } @@ -45,7 +45,7 @@ public enum ModBindings { * @return the result of calling {@link KeyMapping#isDown()} on the represented {@link KeyMapping}. * @see KeyMapping#isDown() */ - public boolean isPressed() { + public boolean isDown() { return get().isDown(); } @@ -53,10 +53,21 @@ public boolean isPressed() { * @return the result of calling {@link KeyMapping#consumeClick()} on the represented {@link KeyMapping}. * @see KeyMapping#consumeClick() */ - public boolean wasPressed() { + public boolean consumeClick() { return get().consumeClick(); } + /** + * Reset whether the key was pressed. + *

+ * Note: Cannot use {@link KeyMapping#release()} because it doesn't work as expected. + */ + @SuppressWarnings("StatementWithEmptyBody") + public void reset() { + final KeyMapping key = get(); + while (key.consumeClick()) {} + } + /** * Lazily get the actual {@link KeyMapping} represented by this enum value. *

@@ -65,7 +76,7 @@ public boolean wasPressed() { * @return the actual {@link KeyMapping}. */ public KeyMapping get() { - return lazyBinding.get(); + return lazyMapping.get(); } /** diff --git a/common/src/main/java/net/xolt/freecam/mixins/MinecraftMixin.java b/common/src/main/java/net/xolt/freecam/mixins/MinecraftMixin.java index 5cabbb2a..24934309 100644 --- a/common/src/main/java/net/xolt/freecam/mixins/MinecraftMixin.java +++ b/common/src/main/java/net/xolt/freecam/mixins/MinecraftMixin.java @@ -45,7 +45,7 @@ private void onHandleBlockBreaking(CallbackInfo ci) { // Prevents hotbar keys from changing selected slot when freecam key is held @Inject(method = "handleKeybinds", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/KeyMapping;consumeClick()Z", ordinal = 2), cancellable = true) private void onHandleInputEvents(CallbackInfo ci) { - if (KEY_TOGGLE.isPressed() || KEY_TRIPOD_RESET.isPressed()) { + if (KEY_TOGGLE.isDown() || KEY_TRIPOD_RESET.isDown()) { ci.cancel(); } } From 61b781182f03cad673a71215e1f624b5cf2fb35c Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Wed, 13 Dec 2023 18:56:19 +0000 Subject: [PATCH 3/8] Refactor tripod storage, support modded dimensions - Use format string for tripod notification translations - Move tripod storage to `TripodRegistry` - Support modded dimensions by using a `HashMap` of `DimensionType`s - Store tripod slots efficiently using an `EnumMap` (i.e. an array) --- .../main/java/net/xolt/freecam/Freecam.java | 77 +++++++------------ .../xolt/freecam/tripod/TripodRegistry.java | 53 +++++++++++++ .../net/xolt/freecam/tripod/TripodSlot.java | 35 +++++++++ .../resources/assets/freecam/lang/en_us.json | 6 +- .../resources/assets/freecam/lang/it_it.json | 6 +- .../resources/assets/freecam/lang/zh_cn.json | 6 +- 6 files changed, 123 insertions(+), 60 deletions(-) create mode 100644 common/src/main/java/net/xolt/freecam/tripod/TripodRegistry.java create mode 100644 common/src/main/java/net/xolt/freecam/tripod/TripodSlot.java diff --git a/common/src/main/java/net/xolt/freecam/Freecam.java b/common/src/main/java/net/xolt/freecam/Freecam.java index e53b01e9..b127e679 100644 --- a/common/src/main/java/net/xolt/freecam/Freecam.java +++ b/common/src/main/java/net/xolt/freecam/Freecam.java @@ -9,12 +9,11 @@ import net.minecraft.network.chat.Component; import net.minecraft.world.level.ChunkPos; import net.xolt.freecam.config.ModConfig; +import net.xolt.freecam.tripod.TripodRegistry; +import net.xolt.freecam.tripod.TripodSlot; import net.xolt.freecam.util.FreeCamera; import net.xolt.freecam.util.FreecamPosition; import net.xolt.freecam.variant.api.BuildVariant; -import org.lwjgl.glfw.GLFW; - -import java.util.HashMap; import static net.xolt.freecam.config.ModBindings.*; @@ -30,11 +29,9 @@ public class Freecam { private static boolean disableNextTick = false; private static boolean toggleKeyUsedWhileHeld = false; private static long toggleKeyHeldTicks = 0; - private static Integer activeTripod = null; + private static final TripodRegistry tripods = new TripodRegistry(); + private static TripodSlot activeTripod = TripodSlot.NONE; private static FreeCamera freeCamera; - private static HashMap overworld_tripods = new HashMap<>(); - private static HashMap nether_tripods = new HashMap<>(); - private static HashMap end_tripods = new HashMap<>(); private static CameraType rememberedF5 = null; public static void preTick(Minecraft mc) { @@ -65,7 +62,7 @@ public static void postTick(Minecraft mc) { // Handle + combos for (KeyMapping combo : mc.options.keyHotbarSlots) { while (combo.consumeClick()) { - toggleTripod(combo.getDefaultKey().getValue()); + toggleTripod(TripodSlot.ofKeyCode(combo.getDefaultKey().getValue())); toggleKeyUsedWhileHeld = true; } } @@ -86,7 +83,7 @@ else if (KEY_TOGGLE.consumeClick() || toggleKeyHeldTicks > 0) { if (KEY_TRIPOD_RESET.isDown()) { for (KeyMapping key : mc.options.keyHotbarSlots) { while (key.consumeClick()) { - resetCamera(key.getDefaultKey().getValue()); + resetCamera(TripodSlot.ofKeyCode(key.getDefaultKey().getValue())); } } } @@ -104,7 +101,7 @@ public static void onDisconnect() { if (isEnabled()) { toggle(); } - clearTripods(); + tripods.clear(); } public static void toggle() { @@ -124,24 +121,24 @@ public static void toggle() { } } - private static void toggleTripod(Integer keyCode) { - if (keyCode == null) { + private static void toggleTripod(TripodSlot tripod) { + if (tripod == TripodSlot.NONE) { return; } if (tripodEnabled) { - if (activeTripod.equals(keyCode)) { + if (activeTripod == tripod) { onDisableTripod(); tripodEnabled = false; } else { onDisableTripod(); - onEnableTripod(keyCode); + onEnableTripod(tripod); } } else { if (freecamEnabled) { toggle(); } - onEnableTripod(keyCode); + onEnableTripod(tripod); tripodEnabled = true; } if (!tripodEnabled) { @@ -163,10 +160,10 @@ public static void switchControls() { playerControlEnabled = !playerControlEnabled; } - private static void onEnableTripod(int keyCode) { + private static void onEnableTripod(TripodSlot tripod) { onEnable(); - FreecamPosition position = getTripodsForDimension().get(keyCode); + FreecamPosition position = tripods.get(tripod); boolean chunkLoaded = false; if (position != null) { ChunkPos chunkPos = position.getChunkPos(); @@ -174,35 +171,35 @@ private static void onEnableTripod(int keyCode) { } if (!chunkLoaded) { - resetCamera(keyCode); + resetCamera(tripod); position = null; } if (position == null) { - freeCamera = new FreeCamera(-420 - (keyCode % GLFW.GLFW_KEY_0)); + freeCamera = new FreeCamera(-420 - tripod.ordinal()); } else { - freeCamera = new FreeCamera(-420 - (keyCode % GLFW.GLFW_KEY_0), position); + freeCamera = new FreeCamera(-420 - tripod.ordinal(), position); } freeCamera.spawn(); MC.setCameraEntity(freeCamera); - activeTripod = keyCode; + activeTripod = tripod; if (ModConfig.INSTANCE.notification.notifyTripod) { - MC.player.displayClientMessage(Component.translatable("msg.freecam.openTripod").append("" + activeTripod % GLFW.GLFW_KEY_0), true); + MC.player.displayClientMessage(Component.translatable("msg.freecam.openTripod", tripod), true); } } private static void onDisableTripod() { - getTripodsForDimension().put(activeTripod, new FreecamPosition(freeCamera)); + tripods.put(activeTripod, new FreecamPosition(freeCamera)); onDisable(); if (MC.player != null) { if (ModConfig.INSTANCE.notification.notifyTripod) { - MC.player.displayClientMessage(Component.translatable("msg.freecam.closeTripod").append("" + activeTripod % GLFW.GLFW_KEY_0), true); + MC.player.displayClientMessage(Component.translatable("msg.freecam.closeTripod", activeTripod), true); } } - activeTripod = null; + activeTripod = TripodSlot.NONE; } private static void onEnableFreecam() { @@ -260,44 +257,22 @@ private static void onDisabled() { } } - private static void resetCamera(int keyCode) { - if (tripodEnabled && activeTripod != null && activeTripod == keyCode && freeCamera != null) { + private static void resetCamera(TripodSlot tripod) { + if (tripodEnabled && activeTripod != TripodSlot.NONE && activeTripod == tripod && freeCamera != null) { freeCamera.copyPosition(MC.player); } else { - getTripodsForDimension().put(keyCode, null); + tripods.put(tripod, null); } if (ModConfig.INSTANCE.notification.notifyTripod) { - MC.player.displayClientMessage(Component.translatable("msg.freecam.tripodReset").append("" + keyCode % GLFW.GLFW_KEY_0), true); + MC.player.displayClientMessage(Component.translatable("msg.freecam.tripodReset", tripod), true); } } - public static void clearTripods() { - overworld_tripods = new HashMap<>(); - nether_tripods = new HashMap<>(); - end_tripods = new HashMap<>(); - } - public static FreeCamera getFreeCamera() { return freeCamera; } - public static HashMap getTripodsForDimension() { - HashMap result; - switch (MC.level.dimensionTypeId().location().getPath()) { - case "the_nether": - result = nether_tripods; - break; - case "the_end": - result = end_tripods; - break; - default: - result = overworld_tripods; - break; - } - return result; - } - public static void disableNextTick() { disableNextTick = true; } diff --git a/common/src/main/java/net/xolt/freecam/tripod/TripodRegistry.java b/common/src/main/java/net/xolt/freecam/tripod/TripodRegistry.java new file mode 100644 index 00000000..3995ad87 --- /dev/null +++ b/common/src/main/java/net/xolt/freecam/tripod/TripodRegistry.java @@ -0,0 +1,53 @@ +package net.xolt.freecam.tripod; + +import net.minecraft.world.level.dimension.DimensionType; +import net.xolt.freecam.util.FreecamPosition; +import org.jetbrains.annotations.Nullable; + +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import static net.xolt.freecam.Freecam.MC; + +public class TripodRegistry { + private final Map> tripods = new HashMap<>(); + + public @Nullable FreecamPosition get(TripodSlot tripod) { + return get(dimension(), tripod); + } + + public @Nullable FreecamPosition get(DimensionType dimension, TripodSlot tripod) { + return Optional.ofNullable(tripods.get(dimension)) + .map(positions -> positions.get(tripod)) + .orElse(null); + } + + public void put(TripodSlot tripod, @Nullable FreecamPosition position) { + put(dimension(), tripod, position); + } + + public void put(DimensionType dimension, TripodSlot tripod, @Nullable FreecamPosition position) { + tripods.computeIfAbsent(dimension, TripodRegistry::newEntry) + .put(tripod, position); + + } + + /** + * Clear all tripods for all dimensions. + */ + public void clear() { + tripods.clear(); + } + + // Get the current dimension + private static DimensionType dimension() { + return MC.level.dimensionType(); + } + + // Construct a new dimension entry + private static Map newEntry(DimensionType dimension) { + return new EnumMap<>(TripodSlot.class); + } +} diff --git a/common/src/main/java/net/xolt/freecam/tripod/TripodSlot.java b/common/src/main/java/net/xolt/freecam/tripod/TripodSlot.java new file mode 100644 index 00000000..fd05bfc9 --- /dev/null +++ b/common/src/main/java/net/xolt/freecam/tripod/TripodSlot.java @@ -0,0 +1,35 @@ +package net.xolt.freecam.tripod; + +import static org.lwjgl.glfw.GLFW.GLFW_KEY_0; + +public enum TripodSlot { + NONE, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE; + + public static final int MIN = 1; + public static final int MAX = values().length - 1; + + @Override + public String toString() { + return this == NONE ? "None" : "#%d".formatted(ordinal()); + } + + public static boolean inRange(int number) { + return number >= MIN && number <= MAX; + } + + public static TripodSlot valueOf(int number) throws IndexOutOfBoundsException { + if (inRange(number)) { + throw new IndexOutOfBoundsException("Cannot get TripodSlot for number %d: must be %d-%d.".formatted(number, MIN, MAX)); + } + return valueOfUnsafe(number); + } + + public static TripodSlot ofKeyCode(int keyCode) { + int number = keyCode - GLFW_KEY_0; + return inRange(number) ? valueOfUnsafe(number) : NONE; + } + + private static TripodSlot valueOfUnsafe(int number) { + return values()[number]; + } +} diff --git a/common/src/main/resources/assets/freecam/lang/en_us.json b/common/src/main/resources/assets/freecam/lang/en_us.json index a6234c1f..2c8460c0 100644 --- a/common/src/main/resources/assets/freecam/lang/en_us.json +++ b/common/src/main/resources/assets/freecam/lang/en_us.json @@ -6,9 +6,9 @@ "key.freecam.configGui": "Config GUI", "msg.freecam.enable": "Freecam has been enabled.", "msg.freecam.disable": "Freecam has been disabled.", - "msg.freecam.openTripod": "Opening camera #", - "msg.freecam.closeTripod": "Closing camera #", - "msg.freecam.tripodReset": "Reset camera #", + "msg.freecam.openTripod": "Opening camera %s", + "msg.freecam.closeTripod": "Closing camera %s", + "msg.freecam.tripodReset": "Reset camera %s", "text.autoconfig.freecam.title": "Freecam Options", "text.autoconfig.freecam.option.movement": "Movement Options", "text.autoconfig.freecam.option.movement.@Tooltip": "How the camera moves.", diff --git a/common/src/main/resources/assets/freecam/lang/it_it.json b/common/src/main/resources/assets/freecam/lang/it_it.json index 35763c8f..87d6e66d 100644 --- a/common/src/main/resources/assets/freecam/lang/it_it.json +++ b/common/src/main/resources/assets/freecam/lang/it_it.json @@ -6,9 +6,9 @@ "key.freecam.configGui": "GUI di configurazione", "msg.freecam.enable": "la Camera libera è stata abilitata.", "msg.freecam.disable": "la Camera libera è stata disattivata.", - "msg.freecam.openTripod": "Apri la Camera #", - "msg.freecam.closeTripod": "Chiudi la Camera #", - "msg.freecam.tripodReset": "Reseta la Camera #", + "msg.freecam.openTripod": "Apri la Camera %s", + "msg.freecam.closeTripod": "Chiudi la Camera %s", + "msg.freecam.tripodReset": "Reseta la Camera %s", "text.autoconfig.freecam.title": "Opzioni Camera libera", "text.autoconfig.freecam.option.movement": "Opzioni di Movimento", "text.autoconfig.freecam.option.movement.@Tooltip": "Come si muove la telecamera.", diff --git a/common/src/main/resources/assets/freecam/lang/zh_cn.json b/common/src/main/resources/assets/freecam/lang/zh_cn.json index 8b7f01dc..c3f567a5 100644 --- a/common/src/main/resources/assets/freecam/lang/zh_cn.json +++ b/common/src/main/resources/assets/freecam/lang/zh_cn.json @@ -6,9 +6,9 @@ "key.freecam.configGui": "打开GUI", "msg.freecam.enable": "自由视角已经启用。", "msg.freecam.disable": "自由视角已经禁用。", - "msg.freecam.openTripod": "启用视角 #", - "msg.freecam.closeTripod": "禁用视角 #", - "msg.freecam.tripodReset": "重置视角 #", + "msg.freecam.openTripod": "启用视角 %s", + "msg.freecam.closeTripod": "禁用视角 %s", + "msg.freecam.tripodReset": "重置视角 %s", "text.autoconfig.freecam.title": "自由视角(Freecam)选项", "text.autoconfig.freecam.option.movement": "移动选项", "text.autoconfig.freecam.option.movement.@Tooltip": "视角如何移动。", From eb2859556f3685cab58d2f89f7e8d5cfd912cbc0 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Wed, 13 Dec 2023 21:56:27 +0000 Subject: [PATCH 4/8] Simplify FreecamPosition by assuming SWIMMING We can safely assume that we _always_ want the swimming height and that `FreeCamera` will always be swimming. --- .../net/xolt/freecam/util/FreeCamera.java | 4 ++-- .../xolt/freecam/util/FreecamPosition.java | 23 +++++++------------ 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/common/src/main/java/net/xolt/freecam/util/FreeCamera.java b/common/src/main/java/net/xolt/freecam/util/FreeCamera.java index 09b929bf..ff93e767 100644 --- a/common/src/main/java/net/xolt/freecam/util/FreeCamera.java +++ b/common/src/main/java/net/xolt/freecam/util/FreeCamera.java @@ -41,20 +41,20 @@ public void send(Packet packet) { }; public FreeCamera(int id) { - this(id, FreecamPosition.getSwimmingPosition(MC.player)); + this(id, new FreecamPosition(MC.player)); } public FreeCamera(int id, FreecamPosition position) { super(MC, MC.level, NETWORK_HANDLER, MC.player.getStats(), MC.player.getRecipeBook(), false, false); setId(id); + setPose(Pose.SWIMMING); applyPosition(position); getAbilities().flying = true; input = new KeyboardInput(MC.options); } public void applyPosition(FreecamPosition position) { - super.setPose(position.pose); moveTo(position.x, position.y, position.z, position.yaw, position.pitch); xBob = getXRot(); yBob = getYRot(); diff --git a/common/src/main/java/net/xolt/freecam/util/FreecamPosition.java b/common/src/main/java/net/xolt/freecam/util/FreecamPosition.java index 535bc3aa..f306ca6a 100644 --- a/common/src/main/java/net/xolt/freecam/util/FreecamPosition.java +++ b/common/src/main/java/net/xolt/freecam/util/FreecamPosition.java @@ -12,7 +12,6 @@ public class FreecamPosition { public double z; public float pitch; public float yaw; - public Pose pose; private final Quaternionf rotation = new Quaternionf(0.0F, 0.0F, 0.0F, 1.0F); private final Vector3f verticalPlane = new Vector3f(0.0F, 1.0F, 0.0F); @@ -21,9 +20,8 @@ public class FreecamPosition { public FreecamPosition(Entity entity) { x = entity.getX(); - y = entity.getY(); + y = getSwimmingY(entity); z = entity.getZ(); - pose = entity.getPose(); setRotation(entity.getYRot(), entity.getXRot()); } @@ -64,19 +62,14 @@ public void move(double fwd, double up, double right) { + (double) diagonalPlane.z() * right; } - public static FreecamPosition getSwimmingPosition(Entity entity) { - FreecamPosition position = new FreecamPosition(entity); - - // Set pose to swimming, adjusting y position so eye-height doesn't change - if (position.pose != Pose.SWIMMING) { - position.y += entity.getEyeHeight(position.pose) - entity.getEyeHeight(Pose.SWIMMING); - position.pose = Pose.SWIMMING; - } - - return position; - } - public ChunkPos getChunkPos() { return new ChunkPos((int) (x / 16), (int) (z / 16)); } + + private static double getSwimmingY(Entity entity) { + if (entity.getPose() == Pose.SWIMMING) { + return entity.getY(); + } + return entity.getY() - entity.getEyeHeight(Pose.SWIMMING) + entity.getEyeHeight(entity.getPose()); + } } From 18786217d69b23101415bae3674bae8012007608 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Thu, 14 Dec 2023 00:22:40 +0000 Subject: [PATCH 5/8] FreeCamera.copyPosition use SWIMMING pose Fixes `resetCamera` moving freecam to the player's feet. --- common/src/main/java/net/xolt/freecam/util/FreeCamera.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/common/src/main/java/net/xolt/freecam/util/FreeCamera.java b/common/src/main/java/net/xolt/freecam/util/FreeCamera.java index ff93e767..bb475e85 100644 --- a/common/src/main/java/net/xolt/freecam/util/FreeCamera.java +++ b/common/src/main/java/net/xolt/freecam/util/FreeCamera.java @@ -54,6 +54,11 @@ public FreeCamera(int id, FreecamPosition position) { input = new KeyboardInput(MC.options); } + @Override + public void copyPosition(Entity entity) { + applyPosition(new FreecamPosition(entity)); + } + public void applyPosition(FreecamPosition position) { moveTo(position.x, position.y, position.z, position.yaw, position.pitch); xBob = getXRot(); From d177f6db322744b2c55621774e17b81936003887 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Wed, 13 Dec 2023 21:45:15 +0000 Subject: [PATCH 6/8] Remove 2-arg FreeCamera constructor --- common/src/main/java/net/xolt/freecam/Freecam.java | 11 +++++------ .../main/java/net/xolt/freecam/util/FreeCamera.java | 5 ----- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/common/src/main/java/net/xolt/freecam/Freecam.java b/common/src/main/java/net/xolt/freecam/Freecam.java index b127e679..24a17ef4 100644 --- a/common/src/main/java/net/xolt/freecam/Freecam.java +++ b/common/src/main/java/net/xolt/freecam/Freecam.java @@ -15,6 +15,8 @@ import net.xolt.freecam.util.FreecamPosition; import net.xolt.freecam.variant.api.BuildVariant; +import java.util.Objects; + import static net.xolt.freecam.config.ModBindings.*; public class Freecam { @@ -175,12 +177,8 @@ private static void onEnableTripod(TripodSlot tripod) { position = null; } - if (position == null) { - freeCamera = new FreeCamera(-420 - tripod.ordinal()); - } else { - freeCamera = new FreeCamera(-420 - tripod.ordinal(), position); - } - + freeCamera = new FreeCamera(-420 - tripod.ordinal()); + freeCamera.applyPosition(Objects.requireNonNullElseGet(position, () -> new FreecamPosition(MC.player))); freeCamera.spawn(); MC.setCameraEntity(freeCamera); activeTripod = tripod; @@ -205,6 +203,7 @@ private static void onDisableTripod() { private static void onEnableFreecam() { onEnable(); freeCamera = new FreeCamera(-420); + freeCamera.applyPosition(new FreecamPosition(MC.player)); freeCamera.applyPerspective( ModConfig.INSTANCE.visual.perspective, ModConfig.INSTANCE.collision.alwaysCheck || !(ModConfig.INSTANCE.collision.ignoreAll && BuildVariant.getInstance().cheatsPermitted()) diff --git a/common/src/main/java/net/xolt/freecam/util/FreeCamera.java b/common/src/main/java/net/xolt/freecam/util/FreeCamera.java index bb475e85..01af8e47 100644 --- a/common/src/main/java/net/xolt/freecam/util/FreeCamera.java +++ b/common/src/main/java/net/xolt/freecam/util/FreeCamera.java @@ -41,15 +41,10 @@ public void send(Packet packet) { }; public FreeCamera(int id) { - this(id, new FreecamPosition(MC.player)); - } - - public FreeCamera(int id, FreecamPosition position) { super(MC, MC.level, NETWORK_HANDLER, MC.player.getStats(), MC.player.getRecipeBook(), false, false); setId(id); setPose(Pose.SWIMMING); - applyPosition(position); getAbilities().flying = true; input = new KeyboardInput(MC.options); } From 3dd10567bf08f5caf6120502665b8a200bff2744 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Thu, 14 Dec 2023 00:20:54 +0000 Subject: [PATCH 7/8] Refactor position setting --- .../main/java/net/xolt/freecam/Freecam.java | 52 +++++++++++++++---- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/common/src/main/java/net/xolt/freecam/Freecam.java b/common/src/main/java/net/xolt/freecam/Freecam.java index 24a17ef4..a8779b3e 100644 --- a/common/src/main/java/net/xolt/freecam/Freecam.java +++ b/common/src/main/java/net/xolt/freecam/Freecam.java @@ -7,6 +7,7 @@ import net.minecraft.client.player.Input; import net.minecraft.client.player.KeyboardInput; import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.Entity; import net.minecraft.world.level.ChunkPos; import net.xolt.freecam.config.ModConfig; import net.xolt.freecam.tripod.TripodRegistry; @@ -14,8 +15,7 @@ import net.xolt.freecam.util.FreeCamera; import net.xolt.freecam.util.FreecamPosition; import net.xolt.freecam.variant.api.BuildVariant; - -import java.util.Objects; +import org.jetbrains.annotations.Nullable; import static net.xolt.freecam.config.ModBindings.*; @@ -178,7 +178,12 @@ private static void onEnableTripod(TripodSlot tripod) { } freeCamera = new FreeCamera(-420 - tripod.ordinal()); - freeCamera.applyPosition(Objects.requireNonNullElseGet(position, () -> new FreecamPosition(MC.player))); + if (position == null) { + moveToPlayer(); + } else { + moveToPosition(position); + } + freeCamera.spawn(); MC.setCameraEntity(freeCamera); activeTripod = tripod; @@ -203,11 +208,7 @@ private static void onDisableTripod() { private static void onEnableFreecam() { onEnable(); freeCamera = new FreeCamera(-420); - freeCamera.applyPosition(new FreecamPosition(MC.player)); - freeCamera.applyPerspective( - ModConfig.INSTANCE.visual.perspective, - ModConfig.INSTANCE.collision.alwaysCheck || !(ModConfig.INSTANCE.collision.ignoreAll && BuildVariant.getInstance().cheatsPermitted()) - ); + moveToPlayer(); freeCamera.spawn(); MC.setCameraEntity(freeCamera); @@ -258,7 +259,7 @@ private static void onDisabled() { private static void resetCamera(TripodSlot tripod) { if (tripodEnabled && activeTripod != TripodSlot.NONE && activeTripod == tripod && freeCamera != null) { - freeCamera.copyPosition(MC.player); + moveToPlayer(); } else { tripods.put(tripod, null); } @@ -268,6 +269,39 @@ private static void resetCamera(TripodSlot tripod) { } } + public static void moveToEntity(@Nullable Entity entity) { + if (freeCamera == null) { + return; + } + if (entity == null) { + moveToPlayer(); + return; + } + freeCamera.copyPosition(entity); + } + + public static void moveToPosition(@Nullable FreecamPosition position) { + if (freeCamera == null) { + return; + } + if (position == null) { + moveToPlayer(); + return; + } + freeCamera.applyPosition(position); + } + + public static void moveToPlayer() { + if (freeCamera == null) { + return; + } + freeCamera.copyPosition(MC.player); + freeCamera.applyPerspective( + ModConfig.INSTANCE.visual.perspective, + ModConfig.INSTANCE.collision.alwaysCheck || !(ModConfig.INSTANCE.collision.ignoreAll && BuildVariant.getInstance().cheatsPermitted()) + ); + } + public static FreeCamera getFreeCamera() { return freeCamera; } From b9c1b3351fe9d9259f1aa3b062ca232c60aa5592 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Tue, 19 Dec 2023 16:48:27 +0000 Subject: [PATCH 8/8] Add usage note to AccessWidener --- common/src/main/resources/freecam.accesswidener | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/src/main/resources/freecam.accesswidener b/common/src/main/resources/freecam.accesswidener index a7ddc5a6..a8472364 100644 --- a/common/src/main/resources/freecam.accesswidener +++ b/common/src/main/resources/freecam.accesswidener @@ -1,3 +1,4 @@ accessWidener v2 named -accessible field net/minecraft/client/renderer/entity/EntityRenderDispatcher shouldRenderShadow Z +#Used by EntityRendererMixin +accessible field net/minecraft/client/renderer/entity/EntityRenderDispatcher shouldRenderShadow Z \ No newline at end of file