From c3de306086a1faca41fc6bce1a2cff25b85bfac3 Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Fri, 29 Oct 2021 04:20:12 +0200 Subject: [PATCH] project: Mixins --- .../java/net/runelite/mixins/CameraMixin.java | 12 ++- .../net/runelite/mixins/RSClientMixin.java | 99 ++++++++++++++++++- .../net/runelite/mixins/RSNanoClockMixin.java | 73 ++++++++++++++ .../net/runelite/mixins/ScriptVMMixin.java | 12 +++ .../java/net/runelite/rs/api/RSClient.java | 9 ++ .../java/net/runelite/rs/api/RSNanoClock.java | 11 ++- 6 files changed, 209 insertions(+), 7 deletions(-) create mode 100644 runelite-mixins/src/main/java/net/runelite/mixins/RSNanoClockMixin.java diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/CameraMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/CameraMixin.java index ee8c0e1bed..b5dae452e7 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/CameraMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/CameraMixin.java @@ -33,8 +33,9 @@ import net.runelite.rs.api.RSClient; @Mixin(RSClient.class) public abstract class CameraMixin implements RSClient { - private static final int STANDARD_PITCH_MAX = 383; - private static final int NEW_PITCH_MAX = 512; + public static final int STANDARD_PITCH_MIN = 128; + public static final int STANDARD_PITCH_MAX = 383; + public static final int NEW_PITCH_MAX = 512; @Shadow("client") static RSClient client; @@ -48,6 +49,13 @@ public abstract class CameraMixin implements RSClient @Inject static int lastPitchTarget = 128; + @Inject + @Override + public boolean getCameraPitchRelaxerEnabled() + { + return pitchRelaxEnabled; + } + @Inject public void setCameraPitchRelaxerEnabled(boolean enabled) { diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index 03fa001d20..7f2e1c3be8 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -27,6 +27,7 @@ package net.runelite.mixins; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; +import com.google.common.primitives.Doubles; import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; @@ -71,6 +72,7 @@ import net.runelite.api.NameableContainer; import net.runelite.api.Node; import net.runelite.api.NodeCache; import net.runelite.api.ObjectComposition; +import net.runelite.api.Perspective; import static net.runelite.api.Perspective.LOCAL_TILE_SIZE; import net.runelite.api.Player; import net.runelite.api.Point; @@ -134,6 +136,9 @@ import net.runelite.api.widgets.WidgetConfig; import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetItem; import net.runelite.api.widgets.WidgetType; +import static net.runelite.mixins.CameraMixin.NEW_PITCH_MAX; +import static net.runelite.mixins.CameraMixin.STANDARD_PITCH_MAX; +import static net.runelite.mixins.CameraMixin.STANDARD_PITCH_MIN; import net.runelite.rs.api.RSAbstractArchive; import net.runelite.rs.api.RSArchive; import net.runelite.rs.api.RSChatChannel; @@ -262,6 +267,21 @@ public abstract class RSClientMixin implements RSClient @Inject private Integer comparingAppearance = 0; + @Inject + private static boolean hdMinimapEnabled; + + @Inject + public static boolean unlockedFps; + + @Inject + public static double tmpCamAngleY; + + @Inject + public static double tmpCamAngleX; + + @Inject + public long lastNanoTime; + @Inject private List outdatedScripts = new ArrayList<>(); @@ -332,9 +352,6 @@ public abstract class RSClientMixin implements RSClient { } - @Inject - private static boolean hdMinimapEnabled; - @Inject @Override public String getBuildID() @@ -1581,6 +1598,7 @@ public abstract class RSClientMixin implements RSClient public void draw(boolean var1) { callbacks.clientMainLoop(); + updateCamera(); } @MethodHook("drawInterface") @@ -2356,7 +2374,6 @@ public abstract class RSClientMixin implements RSClient } - @Inject public static RSArchive[] archives = new RSArchive[21]; @@ -2407,5 +2424,79 @@ public abstract class RSClientMixin implements RSClient { return client.getSequenceDefinition(id); } + + @Inject + @Override + public boolean isUnlockedFps() + { + return unlockedFps; + } + + @Inject + public void setUnlockedFps(boolean unlocked) + { + unlockedFps = unlocked; + + if (unlocked) + { + posToCameraAngle(client.getMapAngle(), client.getCameraPitch()); + } + } + + @Inject + public void updateCamera() + { + if (unlockedFps) + { + long nanoTime = System.nanoTime(); + long diff = nanoTime - this.lastNanoTime; + this.lastNanoTime = nanoTime; + + if (this.getGameState() == GameState.LOGGED_IN) + { + this.interpolateCamera(diff); + } + } + } + + @Inject + public void interpolateCamera(long var1) + { + double angleDX = diffToDangle(client.getCamAngleDY(), var1); + double angleDY = diffToDangle(client.getCamAngleDX(), var1); + + tmpCamAngleY += angleDX / 2; + tmpCamAngleX += angleDY / 2; + tmpCamAngleX = Doubles.constrainToRange(tmpCamAngleX, Perspective.UNIT * STANDARD_PITCH_MIN, client.getCameraPitchRelaxerEnabled() ? Perspective.UNIT * NEW_PITCH_MAX : Perspective.UNIT * STANDARD_PITCH_MAX); + + int yaw = toCameraPos(tmpCamAngleY); + int pitch = toCameraPos(tmpCamAngleX); + + client.setCameraYawTarget(yaw); + client.setCameraPitchTarget(pitch); + } + + @Inject + public static double diffToDangle(int var0, long var1) + { + double var2 = var0 * Perspective.UNIT; + double var3 = (double) var1 / 2.0E7D; + + return var2 * var3; + } + + @Inject + @Override + public void posToCameraAngle(int var0, int var1) + { + tmpCamAngleY = var0 * Perspective.UNIT; + tmpCamAngleX = var1 * Perspective.UNIT; + } + + @Inject + public static int toCameraPos(double var0) + { + return (int) (var0 / Perspective.UNIT) & 2047; + } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSNanoClockMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSNanoClockMixin.java new file mode 100644 index 0000000000..2d71583b6a --- /dev/null +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSNanoClockMixin.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016-2017, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.mixins; + +import net.runelite.api.mixins.Copy; +import net.runelite.api.mixins.Mixin; +import net.runelite.api.mixins.Replace; +import net.runelite.api.mixins.Shadow; +import net.runelite.rs.api.RSClient; +import net.runelite.rs.api.RSNanoClock; + +@Mixin(RSNanoClock.class) +public abstract class RSNanoClockMixin implements RSNanoClock +{ + @Shadow("client") + private static RSClient client; + + @Copy("wait") + @Replace("wait") + public int copy$wait(int cycleDurationMillis, int var2) + { + if (!client.isUnlockedFps()) + { + return copy$wait(cycleDurationMillis, var2); + } + else + { + long nanoTime = System.nanoTime(); + if (nanoTime < getLastTimeNano()) + { + setLastTimeNano(nanoTime); + return 1; + } + else + { + long cycleDuration = (long) cycleDurationMillis * 1000000L; + long diff = nanoTime - getLastTimeNano(); + int cycles = (int) (diff / cycleDuration); + + setLastTimeNano(getLastTimeNano() + (long) cycles * cycleDuration); + + if (cycles > 10) + { + cycles = 10; + } + + return cycles; + } + } + } +} diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/ScriptVMMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/ScriptVMMixin.java index a2d58406c3..b9b0b1ac6f 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/ScriptVMMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/ScriptVMMixin.java @@ -36,6 +36,7 @@ import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Replace; import net.runelite.api.mixins.Shadow; import net.runelite.api.widgets.JavaScriptCallback; +import static net.runelite.cache.script.Opcodes.CAM_FORCEANGLE; import static net.runelite.cache.script.Opcodes.INVOKE; import static net.runelite.cache.script.Opcodes.RETURN; import static net.runelite.cache.script.RuneLiteOpcodes.RUNELITE_EXECUTE; @@ -134,6 +135,17 @@ public abstract class ScriptVMMixin implements RSClient return false; case RETURN: client.getCallbacks().post(new ScriptPostFired((int) currentScript.getHash())); + return false; + case CAM_FORCEANGLE: + int[] intStack = client.getIntStack(); + int intStackSize = client.getIntStackSize(); + int var4 = intStack[intStackSize - 1]; + int var3 = intStack[intStackSize - 2]; + if (!client.isCameraLocked()) + { + client.posToCameraAngle(var4, var3); + } + return false; } return false; diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java index 5f3b07342f..b43890618f 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java @@ -1459,4 +1459,13 @@ public interface RSClient extends RSGameEngine, Client @Import("ModelData_get") RSModelData getModelData(RSAbstractArchive var0, int var1, int var2); + + @Import("isCameraLocked") + boolean isCameraLocked(); + + boolean getCameraPitchRelaxerEnabled(); + + boolean isUnlockedFps(); + + void posToCameraAngle(int var0, int var1); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSNanoClock.java b/runescape-api/src/main/java/net/runelite/rs/api/RSNanoClock.java index 477ed51730..9e74ff279e 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSNanoClock.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSNanoClock.java @@ -1,3 +1,12 @@ package net.runelite.rs.api; -public interface RSNanoClock {} +import net.runelite.mapping.Import; + +public interface RSNanoClock +{ + @Import("lastTimeNano") + long getLastTimeNano(); + + @Import("lastTimeNano") + void setLastTimeNano(long lastNanoTime); +}