diff --git a/src/client/java/wtf/hak/survivalfabric/SurvivalFabricClient.java b/src/client/java/wtf/hak/survivalfabric/SurvivalFabricClient.java index 099d664..26fc1e5 100644 --- a/src/client/java/wtf/hak/survivalfabric/SurvivalFabricClient.java +++ b/src/client/java/wtf/hak/survivalfabric/SurvivalFabricClient.java @@ -5,6 +5,7 @@ import wtf.hak.survivalfabric.config.client.ClientConfigManager; import wtf.hak.survivalfabric.features.AngleViewer; import wtf.hak.survivalfabric.features.RemoveDarknessEffect; import wtf.hak.survivalfabric.features.SFKeyBindings; +import wtf.hak.survivalfabric.features.Zoom; public class SurvivalFabricClient implements ClientModInitializer { @@ -18,6 +19,6 @@ public class SurvivalFabricClient implements ClientModInitializer { AngleViewer.register(); RemoveDarknessEffect.register(); SFKeyBindings.register(); - + Zoom.register(); } } \ No newline at end of file diff --git a/src/client/java/wtf/hak/survivalfabric/features/Zoom.java b/src/client/java/wtf/hak/survivalfabric/features/Zoom.java new file mode 100644 index 0000000..23b907c --- /dev/null +++ b/src/client/java/wtf/hak/survivalfabric/features/Zoom.java @@ -0,0 +1,52 @@ +package wtf.hak.survivalfabric.features; + +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.option.KeyBinding; +import net.minecraft.client.util.InputUtil; +import net.minecraft.text.Text; +import org.lwjgl.glfw.GLFW; +import wtf.hak.survivalfabric.utils.MathUtils; + +public class Zoom { + + private static final KeyBinding ZOOM_BIND = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.survivalfabric.zoom", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_C, "category.survivalfabric.survivalfabric")); + private static final float INITIAL_ZOOM = 20f; + + private static boolean SHOULD_ZOOM = false; + private static float ZOOM_STEP_VALUE = 2.5f; + private static int ZOOM_STEP = 0; + + public static void register() { + ClientTickEvents.END_CLIENT_TICK.register(client -> { + if(ZOOM_BIND.isPressed()) + SHOULD_ZOOM = true; + else { + SHOULD_ZOOM = false; + ZOOM_STEP = 0; + } + }); + } + + public static boolean isZooming() { + return SHOULD_ZOOM; + } + + public static float getZoomFov() { + return INITIAL_ZOOM - -ZOOM_STEP * ZOOM_STEP_VALUE; + } + + public static void modifyStep(int step) { + ZOOM_STEP += step; + + // Clamp the zoom level so the FOV stays within [1, 110] + float zoomFov = getZoomFov(); + if (zoomFov < 1) { + ZOOM_STEP = Math.round((1 - INITIAL_ZOOM) / ZOOM_STEP_VALUE)+1; + } else if (zoomFov > 110) { + ZOOM_STEP = Math.round((110 - INITIAL_ZOOM) / ZOOM_STEP_VALUE); + } + MinecraftClient.getInstance().player.sendMessage(Text.literal(ZOOM_STEP + ""), true); + } +} diff --git a/src/client/java/wtf/hak/survivalfabric/mixin/client/GameRendererMixin.java b/src/client/java/wtf/hak/survivalfabric/mixin/client/GameRendererMixin.java new file mode 100644 index 0000000..9106213 --- /dev/null +++ b/src/client/java/wtf/hak/survivalfabric/mixin/client/GameRendererMixin.java @@ -0,0 +1,21 @@ +package wtf.hak.survivalfabric.mixin.client; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import com.llamalad7.mixinextras.sugar.Local; +import net.minecraft.client.render.GameRenderer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import wtf.hak.survivalfabric.features.Zoom; + +@Mixin(GameRenderer.class) +public abstract class GameRendererMixin { + + /** + * Modify Zoom FOV + */ + @ModifyReturnValue(method = "getFov", at = @At("RETURN")) + private float modifyFovWithZoom(float fov, @Local(argsOnly = true) float tickDelta) { + return Zoom.isZooming() ? Zoom.getZoomFov() : fov; + } + +} diff --git a/src/client/java/wtf/hak/survivalfabric/mixin/client/MouseMixin.java b/src/client/java/wtf/hak/survivalfabric/mixin/client/MouseMixin.java new file mode 100644 index 0000000..6f80828 --- /dev/null +++ b/src/client/java/wtf/hak/survivalfabric/mixin/client/MouseMixin.java @@ -0,0 +1,31 @@ +package wtf.hak.survivalfabric.mixin.client; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.Mouse; +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 wtf.hak.survivalfabric.features.Zoom; + +@Mixin(Mouse.class) +public class MouseMixin { + + /** + * Scrolling listener for zooming + */ + @Inject(method = "onMouseScroll", at = @At("HEAD"), cancellable = true) + private void onMouseScroll(long window, double horizontal, double vertical, CallbackInfo ci) { + if(Zoom.isZooming()) { + if(MinecraftClient.getInstance().player != null) { + if(vertical>0) + Zoom.modifyStep(-1); + else + Zoom.modifyStep(1); + } + ci.cancel(); + } + } + + +} diff --git a/src/client/resources/survivalfabric.client.mixins.json b/src/client/resources/survivalfabric.client.mixins.json index b5906b0..109f1b8 100644 --- a/src/client/resources/survivalfabric.client.mixins.json +++ b/src/client/resources/survivalfabric.client.mixins.json @@ -5,7 +5,9 @@ "client": [ "BackgroundRendererMixin", "BlockEntityRendererMixin", - "EntityMixin" + "EntityMixin", + "GameRendererMixin", + "MouseMixin" ], "injectors": { "defaultRequire": 1 diff --git a/src/main/java/wtf/hak/survivalfabric/utils/MathUtils.java b/src/main/java/wtf/hak/survivalfabric/utils/MathUtils.java index b8018c6..d5abf0e 100644 --- a/src/main/java/wtf/hak/survivalfabric/utils/MathUtils.java +++ b/src/main/java/wtf/hak/survivalfabric/utils/MathUtils.java @@ -3,6 +3,18 @@ package wtf.hak.survivalfabric.utils; public class MathUtils { + public static double clamp(double value, double min, double max) { + return Math.max(min, Math.min(max, value)); + } + + public static float clamp(float value, float min, float max) { + return Math.max(min, Math.min(max, value)); + } + + public static int clamp(int value, int min, int max) { + return Math.max(min, Math.min(max, value)); + } + public static boolean hasSupportedOperator(String msg) { return msg.contains("+") || msg.contains("-") || msg.contains("*") || msg.contains("/"); } diff --git a/src/main/resources/assets/survivalfabric/lang/en_us.json b/src/main/resources/assets/survivalfabric/lang/en_us.json index 92e23d7..03f83b6 100644 --- a/src/main/resources/assets/survivalfabric/lang/en_us.json +++ b/src/main/resources/assets/survivalfabric/lang/en_us.json @@ -17,5 +17,6 @@ "key.survivalfabric.angle14": "204.98 / -41.68", "key.survivalfabric.angle15": "244.97 / -41.71", "category.survivalfabric.survivalfabric": "Survival Fabric", - "key.survivalfabric.camera": "/camera" + "key.survivalfabric.camera": "/camera", + "key.survivalfabric.zoom": "Zoom" } \ No newline at end of file