Files
common/src/main/java/org/saturnclient/mod/mods/ZoomMod.java
T
selimaj-devandclaude 85c7057ba1 Preview easing curves beside curve dropdowns
CurveProperty holds the easing curves in the order Animation.getCurve
takes them, replacing three copies of the list in zoom, freelook and the
animation config; it's saved the same way. Its dropdown opens a
CurveOptions popup: a CurvePreview graph beside the list, with a dot
running along the hovered curve, or the current one.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 18:19:18 +02:00

124 lines
4.5 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package org.saturnclient.mod.mods;
import java.util.function.Function;
import org.saturnclient.common.provider.GLFWProvider;
import org.saturnclient.config.property.BoolProperty;
import org.saturnclient.config.property.CurveProperty;
import org.saturnclient.config.property.FloatProperty;
import org.saturnclient.config.property.IntProperty;
import org.saturnclient.config.property.KeybindingProperty;
import org.saturnclient.config.property.Property;
import org.saturnclient.mod.Mod;
import org.saturnclient.mod.ModSpec;
import org.saturnclient.ui.anim.Animation;
public class ZoomMod extends Mod {
private static final BoolProperty enabled = Property.bool(false);
private static final BoolProperty toggle = Property.bool(false);
public static final KeybindingProperty zoomKey = Property.keybinding(GLFWProvider.GLFW_KEY_C);
public static final FloatProperty zoomLevel = Property.floatProp(3.0f).range(1f, 10f, 0.5f).unit("×");
public static final IntProperty zoomInDuration = Property.integer(700).range(0, 2000, 50).unit("ms");
public static final IntProperty zoomOutDuration = Property.integer(300).range(0, 2000, 50).unit("ms");
public static final CurveProperty curve = Property.curve(1);
public ZoomMod() {
super(
new ModSpec("Zoom", "zoom")
.description("Zoom in for a closer view")
.tags("Camera", "Utility")
.version("v0.2.0"),
enabled.named("Enabled"),
toggle.named("Toggle zoom").description("Press the key once instead of holding it"),
zoomKey.named("Zoom Keybinding").description("The key that zooms in"),
zoomLevel.named("Zoom Level").description("How far the camera zooms in"),
zoomInDuration.named("Zoom In Duration").description("How long zooming in takes"),
zoomOutDuration.named("Zoom Out Duration").description("How long zooming back out takes"),
curve.named("Curve").description("Easing of the zoom"));
}
// ---------------------------------------------------------------
// Mod fields
// ---------------------------------------------------------------
/** Zooming state */
public static boolean isZooming = false;
/** Animation state */
private static float progress = 0f; // 0 → 1
private static long lastTime = System.currentTimeMillis();
private static boolean lastTarget = false; // remember previous zoom state
// ---------------------------------------------------------------
// Mod contract
// ---------------------------------------------------------------
@Override
public void tick() {
// Update target zoom state
if (toggle.value) {
if (zoomKey.wasKeyPressed()) {
isZooming = !isZooming;
}
} else {
isZooming = zoomKey.isKeyPressed();
}
}
@Override
public void onEnabled(boolean e) {
enabled.value = e;
if (!e)
isZooming = false;
}
@Override
public boolean isEnabled() {
return enabled.value;
}
// ---------------------------------------------------------------
// Mixin query API
// ---------------------------------------------------------------
/** Returns {@code true} when the FOV override should be applied. */
public static boolean shouldZoom() {
return enabled.value && (isZooming || progress > 0f);
}
public static int getZoomDuration() {
if (isZooming) {
return zoomInDuration.value;
} else {
return zoomOutDuration.value;
}
}
/** Returns the zoom divisor (e.g. 3.0 → one-third of normal FOV). */
public static float getZoomLevel() {
// Detect target change and reset timer
if (isZooming != lastTarget) {
lastTime = System.currentTimeMillis();
lastTarget = isZooming;
}
long now = System.currentTimeMillis();
float delta = (now - lastTime) / (float) getZoomDuration();
lastTime = now;
// Animate progress toward target
if (isZooming) {
progress = Math.min(1f, progress + delta);
} else {
progress = Math.max(0f, progress - delta);
}
// Apply curve
Function<Double, Double> curveFn = Animation.getCurve(curve.value);
double curved = curveFn.apply((double) progress);
// Map to zoom level
return 1.0f + (float) curved * (zoomLevel.value - 1f);
}
}