From a66fbdfab71ece98223d257f3a6da7ab0339ee1f Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Fri, 9 Oct 2026 13:13:59 -0400 Subject: Bunch of wip stuff Signed-off-by: Andrew Opalach --- Plugin.cs | 1296 +++++++++++++++++++++++++++---------------------------------- 1 file changed, 565 insertions(+), 731 deletions(-) (limited to 'Plugin.cs') diff --git a/Plugin.cs b/Plugin.cs index d49ab19..3a022d4 100755 --- a/Plugin.cs +++ b/Plugin.cs @@ -1,12 +1,9 @@ //#define ENABLE_ASSERTS //#define HOOK_ORDER_ASSERTS //#define LOG_DEBUG_MESSAGES -#define MOUSE_AND_KEYBOARD_LAYER -//#define INTEROP_FEATURE +#define INTEROP_FEATURE using System.Numerics; -using System.Runtime.InteropServices; -using System.Text.RegularExpressions; #if ENABLE_ASSERTS using System.Diagnostics; #endif @@ -19,8 +16,8 @@ using SharpPluginLoader.Core.IO; using SharpPluginLoader.Core.View; using SharpPluginLoader.Core.Memory; using SharpPluginLoader.Core.Actions; -using SharpPluginLoader.Core.Components; using SharpPluginLoader.Core.Configuration; +using SharpPluginLoader.Core.Rendering; // Tentative List of Actions: // - Toggle Free Camera @@ -169,7 +166,7 @@ namespace NewCamera } } - public unsafe class Plugin : IPlugin + public class Plugin : IPlugin { public string Name => "New Camera"; public string Author => "Akon City Software"; @@ -184,8 +181,6 @@ namespace NewCamera #endif } - public static nint lton(long l) { unchecked { return (nint)l; } } - public static byte ByteFlag(bool f) { return f ? (byte)0x1 : (byte)0x0; } private static readonly MtObject sMain = SingletonManager.GetSingleton("sMhMain")!; @@ -217,7 +212,7 @@ namespace NewCamera private bool freeCamera = false; private bool freeCameraFromViewMode = false; private bool freeCameraFallback = false; - private bool freeCameraNoMenu = false; + private bool freeCameraIgnoreMenu = false; private Camera? vCamera = null; private int vCameraViewportIndex = -1; private float? restoreFov = null; @@ -229,7 +224,7 @@ namespace NewCamera private bool unlockMovementHeld = false; private bool unlockMovementToggled = false; private bool unlockMovementPause = false; - private bool playerMovementLocked => !(unlockMovementHeld || unlockMovementToggled) || unlockMovementPause; + private bool playerMovementUnlocked => !unlockMovementPause && (unlockMovementHeld || unlockMovementToggled); private bool lockVerticalToggled = false; private NativeFunction getViewParamOffset; @@ -245,9 +240,8 @@ namespace NewCamera private bool enableOffsetPerspective = false; private bool offsetPerspective = false; - private Player? lastPlayer = null; - private Camera? pCamera = null; - private int pCameraViewportIndex = -1; + private static Camera? pCamera = null; + private static int pCameraViewportIndex = -1; private bool applyPerspective = false; private float previousFov = -1.0f; private int previousCameraAnimState = 0; @@ -255,40 +249,24 @@ namespace NewCamera private bool enableCombo = false; private Button[]? freeCameraCombo = null; - private bool disableComboButton1 = false; + private bool blockComboButton1 = false; private bool comboButton1Down = false; - private static readonly MtObject sMhController = SingletonManager.GetSingleton("sMhSteamController")!; - private nint primaryPad = 0x0; - private int PadLx, PadLy; - private int PadRx, PadRy; - - private uint lastPadDown = 0u; - private uint? prevPadDown = null; private bool unlockInputToggled = false; private bool unlockInputForMenu = false; private bool unlockInputHideMenu = false; - private bool buttonWasDown(Button button) - { - return (lastPadDown & (uint)button) == (uint)button; - } - private bool buttonWasPressed(Button button) - { - return (lastPadDown & (uint)button) == (uint)button && (prevPadDown & (uint)button) != (uint)button; - } - private bool buttonWasReleased(Button button) - { - return (lastPadDown & (uint)button) != (uint)button && (prevPadDown & (uint)button) == (uint)button; - } -#if MOUSE_AND_KEYBOARD_LAYER + private static readonly MtObject sMhController = SingletonManager.GetSingleton("sMhSteamController")!; + private int PadLx, PadLy; + private int PadRx, PadRy; + private static readonly MtObject sMhMouse = SingletonManager.GetSingleton("sMhMouse")!; - private static readonly MtObject sMhKeyboard = SingletonManager.GetSingleton("sMhKeyboard")!; private bool mouseEnabled = false; private float mouseSensitivity; + + private static readonly MtObject sMhKeyboard = SingletonManager.GetSingleton("sMhKeyboard")!; private bool keyboardEnabled = false; private int keyboardLookValue; -#endif private float plusRight = 0.0f; private float plusForward = 0.0f; @@ -296,11 +274,6 @@ namespace NewCamera private bool sortMonsters = true; private bool sortAnimals = true; - private string modelFilter = ""; - private bool modelFilterIsRegex = false; - private Regex? modelRegex = null; - public static bool modelOnlyAddressLod0 = false; - private delegate void ProcessCameraDelegate(nint cameraPointer); private Hook? setCameraHook; private Hook? calculateCameraHook; @@ -333,9 +306,6 @@ namespace NewCamera private Hook? calculateViewHook; */ - private delegate void WritePadInputDelegate(nint unknownPtr, nint unknownPtr2, nint unknownPtr3); - private Hook? writePadInputHook; - private delegate float CheckMovementDelegate(int stickValue, float alwaysZero); private Hook? checkMovementHook; @@ -414,13 +384,12 @@ namespace NewCamera enableCombo = binds.EnableCombo; freeCameraCombo = Config.ParseCombo(binds.FreeCameraCombo); typedCombo = binds.FreeCameraCombo.Replace(",", "+"); - disableComboButton1 = binds.DisableComboButton1UnlessButton2Held; -#if MOUSE_AND_KEYBOARD_LAYER + blockComboButton1 = binds.ComboButton1BlocksUnlessButton2Held; + mouseEnabled = binds.EnableMouse; mouseSensitivity = binds.MouseSensitivity; keyboardEnabled = binds.EnableKeyboard; keyboardLookValue = binds.KeyboardLookSensitivity; -#endif Config.Settings camera = config.Camera; cameraSpeed = camera.Speed; @@ -435,7 +404,7 @@ namespace NewCamera stickDeadzone = camera.StickDeadzone; alternateNearClip = camera.AlternateNearClip; - enableOffsetPerspective = config.PerspectiveCameraEnabled; + enableOffsetPerspective = config.CameraOffsetEnabled; ConfigManager.SaveConfig(this); @@ -450,6 +419,8 @@ namespace NewCamera PlayerExt.Initialize(); + Poser.Initialize(); + getViewParamOffset = new NativeFunction(0x14136E6C0); // Asserts based on version 15.23.00. @@ -524,10 +495,6 @@ namespace NewCamera calculateViewHook = Hook.Create(addr, CalculateViewHook); */ - addr = PatternScanner.FindFirst(Pattern.FromString("48 89 5C 24 08 57 44 8B 9A 60 01 00 00 48 8B DA 41 0F BF 40 08 4D 8B D0 89 82 80 01 00 00 BF 00 10 00 00 41 0F BF 40 0A 89 82 84 01 00 00 41 0F BF 40 0C 89 82 78 01 00 00 41 0F BF 40 0E 89 82 7C 01 00 00")); - Assert(addr == 0x1422A1280); // nint, nint, nint - writePadInputHook = Hook.Create(addr, WritePadInputHook); - // Place where we can change the analog stick value the game uses for player movement. addr = PatternScanner.FindFirst(Pattern.FromString("66 0F 6E C1 0F 5B C0 85 C9 78 11")); Assert(addr == 0x142107CB0); // int, float @@ -551,12 +518,12 @@ namespace NewCamera noopCharacterFade.Enable(); } - underwaterCamera1 = new Patch(lton(0x1412AD54D), [0x90, 0x90, 0x90, 0x90, 0x90, 0x90]); // Nop "Is diving" check. - underwaterCamera2 = new Patch(lton(0x1412AD571), [0xB1, 0x01, 0x28, 0xC1, 0x90, 0x90, 0x90]); // Make cl the inverse of al. - underwaterCamera3 = new Patch(lton(0x141FA5A7E), [0x90, 0x90]); // Nop check. - underwaterCamera4 = new Patch(lton(0x141FA5BA0), [0x40, 0x84, 0xF6, 0x90, 0x74]); // jae -> je. - underwaterCamera5 = new Patch(lton(0x141FA5A74), [0x0F, 0x57, 0xF6, 0x31, 0xD2, 0x48, 0x8D, 0x4D, 0x80, 0xE8, 0x9E, 0x41, 0x38, 0xFE, 0xC1, 0xE8, 0x14, 0x66, 0x25, 0xD8, 0x03, 0xFF, 0xC8, 0x66, 0x3D, 0x48, 0x00, 0x77]); - nullifyDofCoc = new Patch(lton(0x1424236DD), [0x0F, 0x57, 0xF6, 0x90, 0x90, 0x90, 0x90]); + underwaterCamera1 = new Patch(0x1412AD54D, [0x90, 0x90, 0x90, 0x90, 0x90, 0x90]); // Nop "Is diving" check. + underwaterCamera2 = new Patch(0x1412AD571, [0xB1, 0x01, 0x28, 0xC1, 0x90, 0x90, 0x90]); // Make cl the inverse of al. + underwaterCamera3 = new Patch(0x141FA5A7E, [0x90, 0x90]); // Nop check. + underwaterCamera4 = new Patch(0x141FA5BA0, [0x40, 0x84, 0xF6, 0x90, 0x74]); // jae -> je. + underwaterCamera5 = new Patch(0x141FA5A74, [0x0F, 0x57, 0xF6, 0x31, 0xD2, 0x48, 0x8D, 0x4D, 0x80, 0xE8, 0x9E, 0x41, 0x38, 0xFE, 0xC1, 0xE8, 0x14, 0x66, 0x25, 0xD8, 0x03, 0xFF, 0xC8, 0x66, 0x3D, 0x48, 0x00, 0x77]); + nullifyDofCoc = new Patch(0x1424236DD, [0x0F, 0x57, 0xF6, 0x90, 0x90, 0x90, 0x90]); underwaterCheckHook = Hook.Create(0x1412AD500, UnderwaterCheckHook); // nint return data; @@ -636,12 +603,15 @@ namespace NewCamera public void OnLoad() { - PlayerExt.sPlayer = SingletonManager.GetSingleton("sPlayer")!; + PlayerExt.OnLoad(); + Config config = loadConfig(); + if (enableOffsetPerspective && config.Selected != "") { setPerspectivePreset(config.Presets[config.Selected]); } + #if INTEROP_FEATURE if (config.TuningToolInterop) { @@ -657,141 +627,28 @@ namespace NewCamera #endif } - private void toggleUi() - { - uiToggled = !uiToggled; - if (uiToggled) - { - jmpOverUi.Enable(); - } - else - { - jmpOverUi.Disable(); - } - if (unlockInputForMenu) - { - unlockInputHideMenu = uiToggled; - } - } - - private Player? checkPlayerChange() - { - Player? player = PlayerExt.getPlayer(); - if (player != lastPlayer) - { - pCamera = null; - pCameraViewportIndex = -1; - lastPlayer = player; - } - return player; - } - - private int getVisibleCamera() - { - for (int i = 0; i < 8; i++) - { - Viewport vp = CameraSystem.GetViewport(i); - // A viewport can be visible with a null camera. - if (vp.Visible && vp.Camera != null) - { - return i; - } - } - return -1; - } - - private void checkCurrentVisibleCamera(Player? player) - { - int prevIndex = vCameraViewportIndex; - vCameraViewportIndex = getVisibleCamera(); - if (vCameraViewportIndex >= 0) - { - Camera camera = CameraSystem.GetViewport(vCameraViewportIndex).Camera!; - // Evaluate potential free camera target change. - if (freeCamera) - { - if (vCamera != camera) - { - if (player != null) - { - // Try to position the camera behind the player. - cameraPosition = player.Position; - cameraPosition.X -= player.Forward.X * 250.0f; - cameraPosition.Y += 200.0f; - cameraPosition.Z -= player.Forward.Z * 250.0f; - cameraTarget = player.Position; - cameraTarget.Y += 150.0f; - } - else - { - cameraPosition = camera.Position; - cameraTarget = camera.Target; - } - Quaternion forward = Quaternion.Normalize(getForward(cameraPosition, cameraTarget)); - cameraYaw = Single.RadiansToDegrees(MathF.Atan2(forward.Z, forward.X)); - cameraPitch = Single.RadiansToDegrees(MathF.Asin(forward.Y)); - } - } - vCamera = camera; - // Assume that after a player is set the visible camera is the player camera. - if (pCamera == null && player != null) - { - pCamera = vCamera; - pCameraViewportIndex = vCameraViewportIndex; - } - } - else - { - vCamera = null; - pCamera = null; - pCameraViewportIndex = -1; - } - } - - private void checkCameraAnimState() - { - if (pCamera != null) - { - previousCameraAnimState = MemoryUtil.Read(pCamera.Instance + 0x240); - if (previousCameraAnimState == 5) - { - ActionInfo currentActionInfo = lastPlayer!.ActionController.CurrentAction; - // 1:314 = Wingdrake landing on area enter. - // 1:319 = Disoriented wingdrake landing next to monster. - if (currentActionInfo.ActionSet == 1 && (currentActionInfo.ActionId == 314 || currentActionInfo.ActionId == 319)) - { - // Temporarily disable evaluation of cameraAnimState != 5. - ignoreAnimState = true; - } - } - else if (ignoreAnimState) - { - // Once cameraAnimState is no longer 5, resume default logic. - ignoreAnimState = false; - } - } - else - { - previousCameraAnimState = 0; - } - } - - private void resetStatePerFrame() - { - primaryPad = 0x0; - - // Zero pad input in case no controllers are connected. - PadLx = 0; PadLy = 0; - PadRx = 0; PadRy = 0; - - cameraOffset = Vector3.Zero; - } - public void OnUpdate(float deltaTime) { if (updateTick == int.MaxValue) updateTick = 0; else updateTick++; + /* + if (Input.IsDown(Mouse.Right)) Log.Info("Down"); + if (Input.IsPressed(Mouse.Left)) Log.Info("Pressed"); + if (Input.IsReleased(Mouse.Left)) Log.Info("Released"); + if (Input.IsChanged(Mouse.Left)) Log.Info("Changed"); + + if (Input.IsDown(Button.Triangle)) Log.Info("Down"); + if (Input.IsPressed(Button.Triangle)) Log.Info("Pressed"); + if (Input.IsReleased(Button.Triangle)) Log.Info("Released"); + if (Input.IsChanged(Button.Triangle)) Log.Info("Changed"); + + if (Input.IsDown(Key.H)) Log.Info("Down"); + if (Input.IsPressed(Key.H)) Log.Info("Pressed"); + if (Input.IsReleased(Key.H)) Log.Info("Released"); + if (Input.IsChanged(Key.H)) Log.Info("Changed"); + */ + debugLog($"OnUpdate() @ {updateTick}"); #if HOOK_ORDER_ASSERTS @@ -799,36 +656,10 @@ namespace NewCamera hookOrder = 0; #endif -#if MOUSE_AND_KEYBOARD_LAYER - if (keyboardEnabled) - { - if (Input.IsPressed(Key.NumPad0)) - { - enableFreeCamera = !enableFreeCamera; - } - if (Input.IsPressed(Key.NumPadPeriod)) - { - toggleUi(); - } - if (Input.IsPressed(Key.NumPadSlash)) - { - if (disableNearDofOverride != 0) - { - TuningToolInterop.RemoveOverride(disableNearDofOverride); - disableNearDofOverride = 0; - } - else - { - disableNearDofOverride = TuningToolInterop.AddOverride("Dof Near Enable", new Vector4(), 0); - } - } - } -#endif - Player? player = null; if (freeCameraFallback) { - player = checkPlayerChange(); + player = PlayerExt.getPlayer(); checkCurrentVisibleCamera(player); // Ensure vCamera is valid. if (vCamera != null) { @@ -854,7 +685,7 @@ namespace NewCamera } } freeCameraFallback = true; - freeCameraNoMenu = false; + freeCameraIgnoreMenu = false; ref float gameSpeed = ref MemoryUtil.GetRef(sMain.Instance + 0xA4); if (freezeGame && gameSpeed != 0.0f) @@ -868,8 +699,6 @@ namespace NewCamera } PlayerExt.OnUpdate(); - - resetStatePerFrame(); } private static Quaternion getForward(Vector3 pos, Vector3 target) @@ -1044,37 +873,46 @@ namespace NewCamera deltaTime = MemoryUtil.Read(sMain.Instance + 0x94); } - bool lockVerticalAndModifySpeed = buttonWasDown(Button.L2) || lockVerticalToggled; + Player? player = PlayerExt.getLastPlayer(); + if (player == null) + { + player = PlayerExt.getPlayerFromSaveSlot(); + } + + bool lockVerticalAndModifySpeed = (!Input.PadCaptured && Input.IsDown(Button.L2)) || lockVerticalToggled; float adjustedSpeed = cameraSpeed * deltaTime * (lockVerticalAndModifySpeed ? cameraSpeedModifier : 1.0f); bool lockCameraLook = false; - if (Math.Abs(PadLy) < stickDeadzone) PadLy = 0; - if (Math.Abs(PadLx) < stickDeadzone) PadLx = 0; - if (Math.Abs(PadRx) < stickDeadzone) PadRx = 0; - if (Math.Abs(PadRy) < stickDeadzone) PadRy = 0; - cameraFrame = Vector3.Zero; - Player? player = lastPlayer; - if (player == null) + PadRx = 0; PadRy = 0; + PadLx = 0; PadLy = 0; + + if (!Input.PadCaptured) { - player = PlayerExt.getPlayerFromSaveSlot(); + if (Math.Abs(Input.GetPadRx()) >= stickDeadzone) + { + PadRx = Input.GetPadRx(); + } + if (Math.Abs(Input.GetPadRy()) >= stickDeadzone) + { + PadRy = Input.GetPadRy(); + } + if (Math.Abs(Input.GetPadLx()) >= stickDeadzone) + { + PadLx = Input.GetPadLx(); + } + if (Math.Abs(Input.GetPadLy()) >= stickDeadzone) + { + PadLy = Input.GetPadLy(); + } } - /* - // PadLx/y is read in WritePadInputHook(). - if ((buttonWasDown(Button.L2) && buttonWasDown(Button.R2)) || toggleAttachToChest) - { - if (player != null && attachToChest && chestBone1 != 0x0 && chestBone2 != 0x0) - { - Quaternion rotation = new Quaternion(player.Rotation.X, player.Rotation.Y, player.Rotation.Z, player.Rotation.W); - Vector3 up = Vector3.Transform(new Vector3(0.0f, 1.0f, 0.0f), rotation); - Vector3 right = Vector3.Transform(new Vector3(1.0f, 0.0f, 0.0f), rotation); - ref Vector3 jiggle1 = ref MemoryUtil.GetRef((swapChestSides ? chestBone2 : chestBone1) + 0xD0); - ref Vector3 jiggle2 = ref MemoryUtil.GetRef((swapChestSides ? chestBone1 : chestBone2) + 0xD0); - float scale = (Int16.MaxValue / adjustedSpeed / chestMoveScale); - jiggle1 -= (right * (PadRx / scale)) + (up * (PadRy / scale)); - jiggle2 -= (right * (PadLx / scale)) + (up * (PadLy / scale)); + if ((!Input.PadCaptured && Input.IsDown(Button.L2) && Input.IsDown(Button.R2)) || PlayerExt.Attach.Toggle) + { + if (player != null && PlayerExt.Attach.Available()) + { + PlayerExt.Attach.Apply(player, deltaTime, PadRx, PadRy, PadLx, PadLy); lockCameraLook = true; } else // Left stick zoom. @@ -1083,24 +921,34 @@ namespace NewCamera cameraFov = Math.Clamp(cameraFov - Ly, 1.0f, 179.0f); } } - */ - if (playerMovementLocked || orbitPlayer) // Move camera. + else if (!playerMovementUnlocked || orbitPlayer) // Move camera. { -#if MOUSE_AND_KEYBOARD_LAYER - if (keyboardEnabled) + if (keyboardEnabled && !Input.KeyboardCaptured) { - if (Input.IsDown(Key.Up)) PadLy += Int16.MaxValue; - if (Input.IsDown(Key.Down)) PadLy -= Int16.MaxValue; - if (Input.IsDown(Key.Left)) PadLx -= Int16.MaxValue; - if (Input.IsDown(Key.Right)) PadLx += Int16.MaxValue; + if (Input.IsDown(Key.Up)) + { + PadLy += Int16.MaxValue; + } + if (Input.IsDown(Key.Down)) + { + PadLy -= Int16.MaxValue; + } + if (Input.IsDown(Key.Left)) + { + PadLx -= Int16.MaxValue; + } + if (Input.IsDown(Key.Right)) + { + PadLx += Int16.MaxValue; + } } -#endif + float Ly = PadLy / (Int16.MaxValue / adjustedSpeed); float Lx = PadLx / (Int16.MaxValue / adjustedSpeed); if (orbitPlayer) { - if (playerMovementLocked) + if (!playerMovementUnlocked) { if (lockVerticalAndModifySpeed) { @@ -1121,7 +969,14 @@ namespace NewCamera } else { - orbitMovementRotation += Lx / 5.0f; + if (PadLy < 0) + { + orbitMovementRotation -= Lx / 3.0f; + } + else + { + orbitMovementRotation += Lx / 3.0f; + } } if (orbitMovementRotation >= 180.0f) { @@ -1165,22 +1020,22 @@ namespace NewCamera } } - if (!unlockInputToggled && !comboButton1Down) + if (!unlockInputToggled && !comboButton1Down && !Input.PadCaptured) { - if (buttonWasDown(Button.Share)) + if (Input.IsDown(Button.Share)) { - if (buttonWasPressed(Button.Square)) + if (Input.IsPressed(Button.Square)) { setNearClip(camera, !guessAltNearClipSet(camera)); } } - if (buttonWasDown(Button.R1)) + if (Input.IsDown(Button.R1)) { - if (buttonWasPressed(Button.Right)) + if (Input.IsPressed(Button.Right)) { cameraRoll = (restoreRoll != null) ? (float)restoreRoll : 0.0f; } - if (buttonWasPressed(Button.Up)) + if (Input.IsPressed(Button.Up)) { if (restoreFov != null) { @@ -1194,27 +1049,26 @@ namespace NewCamera } else if (!unlockInputForMenu || unlockInputHideMenu) { - if (buttonWasDown(Button.Up)) + if (Input.IsDown(Button.Up)) { cameraFrame.Y += adjustedSpeed / 2.0f; } - if (buttonWasDown(Button.Down)) + if (Input.IsDown(Button.Down)) { cameraFrame.Y -= adjustedSpeed / 2.0f; } - if (buttonWasDown(Button.Left)) + if (Input.IsDown(Button.Left)) { cameraRoll -= adjustedSpeed / 4.0f; } - if (buttonWasDown(Button.Right)) + if (Input.IsDown(Button.Right)) { cameraRoll += adjustedSpeed / 4.0f; } } } -#if MOUSE_AND_KEYBOARD_LAYER - if (keyboardEnabled) + if (keyboardEnabled && !Input.KeyboardCaptured) { if (Input.IsDown(Key.NumPadMinus)) { @@ -1255,30 +1109,35 @@ namespace NewCamera { cameraRoll -= adjustedSpeed / 4.0f; } + if (Input.IsDown(Key.NumPad8)) + { + PadRy += keyboardLookValue; + } + if (Input.IsDown(Key.NumPad2)) + { + PadRy -= keyboardLookValue; + } + if (Input.IsDown(Key.NumPad4)) + { + PadRx -= keyboardLookValue; + } + if (Input.IsDown(Key.NumPad6)) + { + PadRx += keyboardLookValue; + } } -#endif - // Camera look. PadRx/y is read in WritePadInputHook(). if (!lockCameraLook) { -#if MOUSE_AND_KEYBOARD_LAYER - if (keyboardEnabled) - { - if (Input.IsDown(Key.NumPad8)) PadRy += keyboardLookValue; - if (Input.IsDown(Key.NumPad2)) PadRy -= keyboardLookValue; - if (Input.IsDown(Key.NumPad4)) PadRx -= keyboardLookValue; - if (Input.IsDown(Key.NumPad6)) PadRx += keyboardLookValue; - } -#endif float adjustedSensitivity = cameraSensitivity * deltaTime * cameraFov; float Rx = PadRx / (Int16.MaxValue / adjustedSensitivity); float Ry = PadRy / (Int16.MaxValue / adjustedSensitivity); -#if MOUSE_AND_KEYBOARD_LAYER - if (mouseEnabled && !playerInMenu()) + if (mouseEnabled && !Input.MouseCaptured && !inMenu()) { - Rx += MemoryUtil.GetRef(sMhMouse.Instance + 0xFC) * mouseSensitivity; - Ry -= MemoryUtil.GetRef(sMhMouse.Instance + 0x100) * mouseSensitivity; - ref int scrollY = ref MemoryUtil.GetRef(sMhMouse.Instance + 0x17C); + // Update mouse _after_ factoring in deltaTime. + Rx += Input.GetMouseDeltaX() * mouseSensitivity; + Ry -= Input.GetMouseDeltaY() * mouseSensitivity; + int scrollY = Input.GetScrollDeltaY(); if (orbitPlayer) { orbitDistance -= scrollY * cameraZoomSpeed * 2.0f; @@ -1292,7 +1151,6 @@ namespace NewCamera cameraFov = Math.Clamp(cameraFov - scrollY * cameraZoomSpeed, 1.0f, 179.0f); } } -#endif cameraYaw += Rx; if (plusRight != 0.0f && !orbitPlayer) { @@ -1355,10 +1213,10 @@ namespace NewCamera { Quaternion rotation; Vector3 target; - bool targetJoint = orbitJoint >= 0 && orbitJoint < PlayerExt.bodyJoints.Count; + bool targetJoint = orbitJoint >= 0 && orbitJoint < Poser.bodyJoints.Count; if (targetJoint) { - nint jointAddr = PlayerExt.bodyJoints[orbitJoint]; + nint jointAddr = Poser.bodyJoints[orbitJoint]; target = MemoryUtil.GetRef(jointAddr + 0x50); rotation = new Quaternion(player.Rotation.X, player.Rotation.Y, player.Rotation.Z, player.Rotation.W); rotation *= MemoryUtil.GetRef(jointAddr + 0x70); @@ -1418,6 +1276,102 @@ namespace NewCamera camera.FieldOfView = cameraFov; } + public static void OnPlayerChange() + { + pCamera = null; + pCameraViewportIndex = -1; + } + + private int getVisibleCamera() + { + for (int i = 0; i < 8; i++) + { + Viewport vp = CameraSystem.GetViewport(i); + // A viewport can be visible with a null camera. + if (vp.Visible && vp.Camera != null) + { + return i; + } + } + return -1; + } + + private void checkCurrentVisibleCamera(Player? player) + { + int prevIndex = vCameraViewportIndex; + vCameraViewportIndex = getVisibleCamera(); + if (vCameraViewportIndex >= 0) + { + Camera camera = CameraSystem.GetViewport(vCameraViewportIndex).Camera!; + // Evaluate potential free camera target change. + if (freeCamera) + { + if (vCamera != camera) + { + if (player != null) + { + // Try to position the camera behind the player. + cameraPosition = player.Position; + cameraPosition.X -= player.Forward.X * 250.0f; + cameraPosition.Y += 200.0f; + cameraPosition.Z -= player.Forward.Z * 250.0f; + cameraTarget = player.Position; + cameraTarget.Y += 150.0f; + } + else + { + cameraPosition = camera.Position; + cameraTarget = camera.Target; + } + Quaternion forward = Quaternion.Normalize(getForward(cameraPosition, cameraTarget)); + cameraYaw = Single.RadiansToDegrees(MathF.Atan2(forward.Z, forward.X)); + cameraPitch = Single.RadiansToDegrees(MathF.Asin(forward.Y)); + } + } + vCamera = camera; + // Assume that after a player is set the visible camera is the player camera. + if (pCamera == null && player != null) + { + pCamera = vCamera; + pCameraViewportIndex = vCameraViewportIndex; + } + } + else + { + vCamera = null; + pCamera = null; + pCameraViewportIndex = -1; + } + } + + private void checkCameraAnimState() + { + if (pCamera != null) + { + previousCameraAnimState = MemoryUtil.Read(pCamera.Instance + 0x240); + if (previousCameraAnimState == 5) + { + ActionInfo currentActionInfo = PlayerExt.getLastPlayer()!.ActionController.CurrentAction; + // 1:314 = Wingdrake landing on area enter. + // 1:319 = Disoriented wingdrake landing next to monster. + if (currentActionInfo.ActionSet == 1 && (currentActionInfo.ActionId == 314 || currentActionInfo.ActionId == 319)) + { + // Temporarily disable evaluation of cameraAnimState != 5. + ignoreAnimState = true; + } + } + else if (ignoreAnimState) + { + // Once cameraAnimState is no longer 5, resume default logic. + ignoreAnimState = false; + } + } + else + { + previousCameraAnimState = 0; + } + } + private void SetCameraHook(nint cameraPointer) { debugLog($"SetCameraHook(0x{cameraPointer:X}) @ {updateTick}"); @@ -1427,7 +1381,7 @@ namespace NewCamera hookOrder = 1; #endif - Player? player = checkPlayerChange(); + Player? player = PlayerExt.getPlayer(); checkCurrentVisibleCamera(player); checkCameraAnimState(); @@ -1552,11 +1506,8 @@ namespace NewCamera if (vCamera != null && freeCamera) { updateFreeCamera(vCamera); - MemoryUtil.GetRef(psuedoViewModeObject + 0xE0) = cameraFrame; - processViewMode.Invoke(psuedoViewModeObject); - cameraPosition = MemoryUtil.GetRef(psuedoViewModeObject + 0x90); } */ @@ -1576,11 +1527,15 @@ namespace NewCamera enableFreeCamera = true; freeCameraFromViewMode = true; } + else + { + startViewModeHook!.Original(viewModeObject); + } } + // The order of this hook between SetCameraHook() and CalculateCameraHook() is inconsistent. private void SetCameraTentHook(nint unknownPtr) { - // The order of this hook between SetCameraHook() and CalculateCameraHook() is inconsistent. debugLog($"SetCameraTentHook(0x{unknownPtr:X}) @ {updateTick}"); if (freeCamera && vCamera != null) @@ -1599,6 +1554,7 @@ namespace NewCamera } freeCameraFallback = false; + freeCameraIgnoreMenu = true; } private void SetCameraCutsceneHook(nint unknownPtr) @@ -1616,7 +1572,7 @@ namespace NewCamera } freeCameraFallback = false; - freeCameraNoMenu = true; + freeCameraIgnoreMenu = true; } /* @@ -1655,311 +1611,258 @@ namespace NewCamera MemoryUtil.GetRef(sMain.Instance + 0xA4) = freezeGame ? 0.0f : resumeSpeed; } - private bool playerInMenu() + private bool inMenu() { - // This doesn't align with in-game mouse controls. This can be observed when closing the pause - // menu where there is a brief moment the camera moves -> freezes again -> then starts normally. - return !freeCameraNoMenu && MemoryUtil.GetRef(Gui.SingletonInstance.Instance + 0x147A8) == 0x1; + return !freeCameraIgnoreMenu && MemoryUtil.GetRef(Gui.SingletonInstance.Instance + 0x147AC) > 0x3; } - // This can undoubtedly be simplified. - private void WritePadInputHook(nint unknownPtr, nint unknownPtr2, nint unknownPtr3) + private void offsetSelectedPreset(int n) { - debugLog($"WritePadInputHook(0x{unknownPtr:X}, 0x{unknownPtr2:X}, 0x{unknownPtr3:X}) @ {updateTick}"); + Config config = ConfigManager.GetConfig(this); + Dictionary.KeyCollection presetKeys = config.Presets.Keys; + if (presetKeys.Count > 0) + { + if (config.Selected != "") + { + int selectedIndex; + for (selectedIndex = 0; selectedIndex < presetKeys.Count; selectedIndex++) + { + string presetKey = presetKeys.ElementAt(selectedIndex); + if (presetKey == config.Selected) + { + break; + } + } + selectedIndex += n; + if (selectedIndex >= presetKeys.Count) + { + selectedIndex -= presetKeys.Count; + } + else if (selectedIndex < 0) + { + selectedIndex += presetKeys.Count; + } + config.Selected = presetKeys.ElementAt(selectedIndex); + } + else + { + config.Selected = presetKeys.ElementAt((n == 1) ? 0 : presetKeys.Count - 1); + } + setPerspectivePreset(config.Presets[config.Selected]); + ConfigManager.SaveConfig(this); + } + } - // Assume the primary pad always comes first. - if (primaryPad == 0x0) primaryPad = unknownPtr2; - if (unknownPtr2 != primaryPad) + private void toggleUi() + { + uiToggled = !uiToggled; + if (uiToggled) { - writePadInputHook!.Original(unknownPtr, unknownPtr2, unknownPtr3); - return; + jmpOverUi.Enable(); } + else + { + jmpOverUi.Disable(); + } + if (unlockInputForMenu) + { + unlockInputHideMenu = uiToggled; + } + } - Button b1 = 0u, b2 = 0u; - uint b1u = 0u; - if (enableCombo && freeCameraCombo != null) + public void toggleNearDof() + { + if (disableNearDofOverride != 0) { - b1 = freeCameraCombo[0]; - b2 = freeCameraCombo[1]; - b1u = (uint)b1; - if (disableComboButton1 && comboButton1Down) - { - MemoryUtil.GetRef(sMhController.Instance + 0x198) |= b1u; - } + TuningToolInterop.RemoveOverride(disableNearDofOverride); + disableNearDofOverride = 0; + } + else + { + disableNearDofOverride = TuningToolInterop.AddOverride("Dof Near Enable", new Vector4(), 0); } + } - writePadInputHook!.Original(unknownPtr, unknownPtr2, unknownPtr3); + private unsafe void openGestureMenu(bool poses) + { + // MonsterHunterWorld.exe+1ADA26A - mov rax,[rbx+00014018] + // Poses: MonsterHunterWorld.exe+1EC8000 + // Gestures: MonsterHunterWorld.exe+1EC7D10 + nint baseAddr = MemoryUtil.Read(0x1451C4640); + nint gesturesAddr = MemoryUtil.Read(baseAddr + 0x14018); + setupGestureMenu.Invoke(gesturesAddr, 0x0, poses ? 0x1 : 0x0); // Poses. + showGestureMenu.Invoke(gesturesAddr); + } - uint PadDown = MemoryUtil.Read(sMhController.Instance + 0x198); - uint PadRel = MemoryUtil.Read(sMhController.Instance + 0x1A4); - prevPadDown = (prevPadDown == null) ? PadDown : lastPadDown; - lastPadDown = PadDown; + private static bool bindsDisabled = false; - PadLx = MemoryUtil.Read(sMhController.Instance + 0x1B8); - PadLy = MemoryUtil.Read(sMhController.Instance + 0x1BC); - PadRx = MemoryUtil.Read(sMhController.Instance + 0x1B0); - PadRy = MemoryUtil.Read(sMhController.Instance + 0x1B4); + public void OnPadUpdate() + { + if (Input.PadCaptured) return; + Button b1 = 0u, b2 = 0u; if (enableCombo && freeCameraCombo != null) { - if (disableComboButton1) + b1 = freeCameraCombo[0]; + b2 = freeCameraCombo[1]; + if (!bindsDisabled && (Input.IsDown(b1) || Input.IsReleased(b1))) { - if (comboButton1Down || enableFreeCamera || !buttonWasDown(b2)) + if (Input.IsPressed(b2)) { - if ((PadDown & b1u) == b1u) - { - comboButton1Down = true; - } - MemoryUtil.GetRef(sMhController.Instance + 0x198) &= ~b1u; + enableFreeCamera = !enableFreeCamera; + } + if (Input.IsPressed(Button.Share)) + { + toggleUi(); + } + if (Input.IsPressed(Button.R1)) + { + Renderer.ToggleMenu(); + } + if (Input.IsPressed(Button.L1)) + { + unlockInputToggled = !unlockInputToggled; + } + int presetSelect = (Input.IsPressed(Button.Up) ? -1 : 0) + (Input.IsPressed(Button.Down) ? 1 : 0); + if (presetSelect != 0 && enableOffsetPerspective) + { + offsetSelectedPreset(presetSelect); } - - if (comboButton1Down) + if (blockComboButton1) { - if (((PadRel & b1u) == b1u)) - { - comboButton1Down = false; - } - MemoryUtil.GetRef(sMhController.Instance + 0x1A0) &= ~b1u; - MemoryUtil.GetRef(sMhController.Instance + 0x1A4) &= ~b1u; - MemoryUtil.GetRef(sMhController.Instance + 0x1A8) &= ~b1u; + Input.BlockPadButtons(); } } - } - - if ((comboButton1Down || (!disableComboButton1 && buttonWasDown(b1)))) - { - if (buttonWasPressed(b2)) - { - enableFreeCamera = !enableFreeCamera; - } - if (buttonWasPressed(Button.Share)) - { - toggleUi(); - } - if (buttonWasPressed(Button.L1)) - { - unlockInputToggled = !unlockInputToggled; - } - int presetSelect = (buttonWasPressed(Button.Up) ? -1 : 0) + (buttonWasPressed(Button.Down) ? 1 : 0); - if (presetSelect != 0) + else { - Config config = ConfigManager.GetConfig(this); - Dictionary.KeyCollection presetKeys = config.Presets.Keys; - if (presetKeys.Count > 0) + if (Input.IsPressed(b2)) { - if (config.Selected != "") - { - int selectedIndex; - for (selectedIndex = 0; selectedIndex < presetKeys.Count; selectedIndex++) - { - string presetKey = presetKeys.ElementAt(selectedIndex); - if (presetKey == config.Selected) - { - break; - } - } - selectedIndex += presetSelect; - if (selectedIndex >= presetKeys.Count) - { - selectedIndex -= presetKeys.Count; - } - else if (selectedIndex < 0) - { - selectedIndex += presetKeys.Count; - } - config.Selected = presetKeys.ElementAt(selectedIndex); - } - else - { - config.Selected = presetKeys.ElementAt((presetSelect == 1) ? 0 : presetKeys.Count - 1); - } - setPerspectivePreset(config.Presets[config.Selected]); - ConfigManager.SaveConfig(this); + bindsDisabled = true; + } + else if (Input.IsReleased(b2)) + { + bindsDisabled = false; } } } - if (unlockMovementHeld && buttonWasReleased(Button.R2)) + if (unlockMovementHeld && Input.IsReleased(Button.R2)) { unlockMovementHeld = false; unlockMovementPause = false; } - bool blockInput = comboButton1Down || (enableFreeCamera && !unlockInputToggled); + if (unlockInputForMenu && !inMenu()) + { + unlockInputForMenu = false; + } - if (blockInput) + if (enableFreeCamera) { - uint Mask = 0u; - uint StartSelectMask = (uint)Button.Options | (uint)Button.Share; - uint DPadMask = (uint)Button.Up | (uint)Button.Down | (uint)Button.Left | (uint)Button.Right; - uint BumperMask = (uint)Button.L1 | (uint)Button.R1; - uint StickMask = (uint)Button.LsUp | (uint)Button.LsDown | (uint)Button.LsLeft | (uint)Button.LsRight | - (uint)Button.RsUp | (uint)Button.RsDown | (uint)Button.RsLeft | (uint)Button.RsRight; - // @TODO: This is broken if you mix keyboard/mouse and controller input. - if (unlockInputForMenu) + bool blockInput = !unlockInputToggled && (!unlockInputForMenu || unlockInputHideMenu); + + if (blockInput) { - // Idealy we wouldn't block Y or X here but triggering Rearrange or Edit Shoutout in - // the gesture menu can desync our primitive "still in menu" handling when B is pressed. - uint FaceButtonMask = (uint)Button.Triangle | (uint)Button.Square; - Mask = FaceButtonMask | StartSelectMask; - if (unlockInputHideMenu) - { - Mask |= (uint)Button.Circle; // Still allow A/Cross. - Mask |= DPadMask | BumperMask | StickMask; - } - else if (buttonWasReleased(Button.Circle)) - { - unlockInputForMenu = false; - unlockInputHideMenu = false; - } + Input.BlockPadButtons(); + Input.BlockPadRx(); + Input.BlockPadRy(); + Input.BlockPadRz(); + Input.BlockPadLz(); } - else + + if (!playerMovementUnlocked || orbitIgnoreCamera) { - uint FaceButtonMask = (uint)Button.Cross | (uint)Button.Circle | (uint)Button.Square | (uint)Button.Triangle; - Mask = FaceButtonMask | StartSelectMask | DPadMask | BumperMask | StickMask; + Input.BlockPadLx(); } - if (enableCombo && freeCameraCombo != null) + + if (!playerMovementUnlocked) { - Mask &= ~(b1u | (uint)b2); + Input.BlockPadLy(); } - MemoryUtil.GetRef(sMhController.Instance + 0x198) &= ~Mask; - MemoryUtil.GetRef(sMhController.Instance + 0x1A0) &= ~Mask; - MemoryUtil.GetRef(sMhController.Instance + 0x1A8) &= ~Mask; - MemoryUtil.GetRef(sMhController.Instance + 0x1AC) &= ~Mask; - MemoryUtil.GetRef(sMhController.Instance + 0x1C0) = 0; // Left trigger. - MemoryUtil.GetRef(sMhController.Instance + 0x1C1) = 0; // Right trigger. - MemoryUtil.GetRef(sMhController.Instance + 0x1B0) = 0; // Rx. - MemoryUtil.GetRef(sMhController.Instance + 0x1B4) = 0; // Ry. - } - if (enableFreeCamera) - { - if (playerMovementLocked) + if (orbitIgnoreCamera) { - MemoryUtil.GetRef(sMhController.Instance + 0x1B8) = 0; // Lx. - MemoryUtil.GetRef(sMhController.Instance + 0x1BC) = 0; // Ly. + if (PadLy < 0) + { + PadLy -= Math.Abs(PadLx); + } + else + { + PadLy += Math.Abs(PadLx); + } + Input.SetPadLy(PadLy); } if (orbitPlayer) { - if (plusRight != 0.0f && !playerMovementLocked && !orbitIgnoreCamera) + if (plusRight != 0.0f && playerMovementUnlocked && !orbitIgnoreCamera) { - int Lx = (int)(Int16.MaxValue * Math.Clamp(plusRight, -1.0f, 1.0f)); - MemoryUtil.GetRef(sMhController.Instance + 0x1B8) = Lx; + Input.SetPadLx((int)(Math.Clamp(plusRight, -1.0f, 1.0f) * Int16.MaxValue)); } if (plusForward != 0.0f) { - int Ly = (int)(Int16.MaxValue * Math.Clamp(plusForward, -1.0f, 1.0f)); - MemoryUtil.GetRef(sMhController.Instance + 0x1BC) = Ly; + Input.SetPadLy((int)(Math.Clamp(plusForward, -1.0f, 1.0f) * Int16.MaxValue)); } } - if (!unlockMovementHeld && buttonWasPressed(Button.R2)) + if (!unlockMovementHeld && Input.IsPressed(Button.R2)) { unlockMovementHeld = true; } if (unlockMovementHeld) { - if (buttonWasPressed(Button.L1)) + if (Input.IsPressed(Button.L1)) { unlockMovementToggled = !unlockMovementToggled; } - // Temporarily disable for zoom mode. - if (buttonWasDown(Button.L2)) + if (Input.IsDown(Button.L2)) { - unlockMovementPause = true; + unlockMovementPause = true; // For zoom mode. } - else if (buttonWasReleased(Button.L2)) + else if (Input.IsReleased(Button.L2)) { unlockMovementPause = false; } } - if (buttonWasDown(Button.L2) && buttonWasPressed(Button.L1)) + if (Input.IsDown(Button.L2) && Input.IsPressed(Button.L1)) { lockVerticalToggled = !lockVerticalToggled; } if (blockInput) { - if (buttonWasDown(Button.R1)) + if (Input.IsDown(Button.R1) && Input.IsPressed(Button.Down)) { - if (buttonWasPressed(Button.Down)) - { - Player? player = PlayerExt.getPlayer(); - if (player != null) - { - // Y - 150 to approximately align the players head with the camera. - player.Position = new Vector3(cameraPosition.X, cameraPosition.Y - 150.0f, cameraPosition.Z); - } - } - - if (buttonWasPressed(Button.Left)) + Player? player = PlayerExt.getPlayer(); + if (player != null) { - toggleFreezeGame(); + player.Position = new Vector3(cameraPosition.X, cameraPosition.Y - 150.0f, cameraPosition.Z); } } - if (buttonWasDown(Button.Share)) + if (Input.IsDown(Button.R1) && Input.IsPressed(Button.Left)) { - if (buttonWasPressed(Button.Cross)) - { - } - if (buttonWasPressed(Button.Circle)) - { - if (disableNearDofOverride != 0) - { - TuningToolInterop.RemoveOverride(disableNearDofOverride); - disableNearDofOverride = 0; - } - else - { - disableNearDofOverride = TuningToolInterop.AddOverride("Dof Near Enable", new Vector4(), 0); - } - } + toggleFreezeGame(); } - else if (freeCameraFromViewMode && !unlockInputForMenu && buttonWasPressed(Button.Circle)) + + if (Input.IsDown(Button.Share) && Input.IsPressed(Button.Circle)) { - enableFreeCamera = false; + toggleNearDof(); } - if (buttonWasPressed(Button.Options) && (plusRight != 0.0f || plusForward != 0.0f)) + if (freeCameraFromViewMode && !Input.IsDown(Button.Share) && Input.IsPressed(Button.Circle)) { - if (buttonWasDown(Button.Share)) - { - plusRight = 0.0f; - plusForward = 0.0f; - } - else - { - if (plusRight != 0.0f) - { - plusRight = -plusRight; - } - if (plusForward != 0.0f) - { - plusForward = -plusForward; - } - } + enableFreeCamera = false; } - if (!unlockInputForMenu && buttonWasPressed(Button.Triangle)) + + if (!unlockInputForMenu && !freeCameraIgnoreMenu && Input.IsPressed(Button.Triangle)) { Player? player = PlayerExt.getPlayer(); if (player != null) { - nint baseAddr = MemoryUtil.Read(0x1451C4640); - // MonsterHunterWorld.exe+1ADA26A - mov rax,[rbx+00014018] - nint gesturesAddr = MemoryUtil.Read(baseAddr + 0x14018); - if (buttonWasDown(Button.Share)) // MonsterHunterWorld.exe+1EC8000 - { - setupGestureMenu.Invoke(gesturesAddr, 0x0, 0x1); // Poses. - } - else // MonsterHunterWorld.exe+1EC7D10 - { - setupGestureMenu.Invoke(gesturesAddr, 0x0, 0x0); // Gestures. - } - showGestureMenu.Invoke(gesturesAddr); + openGestureMenu(Input.IsDown(Button.Share)); unlockInputForMenu = true; } } @@ -1967,6 +1870,49 @@ namespace NewCamera } } + public void OnMouseUpdate() + { + if (mouseEnabled && !Input.MouseCaptured) + { + if (freeCamera) + { + if (freeCameraFromViewMode && Input.IsPressed(Key.Escape)) + { + enableFreeCamera = false; + } + } + } + } + + public void OnKeyboardUpdate() + { + if (keyboardEnabled && !Input.KeyboardCaptured) + { + if (Input.IsPressed(Key.NumPad0)) + { + enableFreeCamera = !enableFreeCamera; + } + + if (Input.IsPressed(Key.NumPadPeriod)) + { + toggleUi(); + } + + if (freeCamera) + { + Input.Block(Key.Up); + Input.Block(Key.Down); + Input.Block(Key.Left); + Input.Block(Key.Right); + + if (Input.IsPressed(Key.NumPadSlash)) + { + toggleNearDof(); + } + } + } + } + private float CheckMovementHook(int stickValue, float alwaysZero) { debugLog($"CheckMovementHook({stickValue:X}, {alwaysZero}) @ {updateTick}"); @@ -1981,7 +1927,7 @@ namespace NewCamera vCamera.Target.Y = cameraPosition.Y; vCamera.Target.Z = cameraPosition.Z + dist * MathF.Sin(Single.DegreesToRadians(orbitMovementRotation)); } - if (playerMovementLocked && (plusRight == 0.0f && plusForward == 0.0f)) + if (!playerMovementUnlocked && (plusRight == 0.0f && plusForward == 0.0f)) { stickValue = 0; } @@ -2053,7 +1999,7 @@ namespace NewCamera } } - private void drawViewportInfo(int i, float width, Config config, bool debug) + private unsafe void drawViewportInfo(int i, float width, Config config, bool debug) { ImGui.PushItemWidth(width * 0.75f); Viewport vp = CameraSystem.GetViewport(i); @@ -2157,7 +2103,8 @@ namespace NewCamera continue; } string positionKey = positionKeys.ElementAt(j - 1); - if (ImGui.Selectable(positionKey)) + bool isSelected = positionKey == selectedPositionName; + if (ImGui.Selectable(positionKey, isSelected)) { Config.Position pos = config.Positions[positionKey]; selectedPositionName = positionKey; @@ -2171,6 +2118,7 @@ namespace NewCamera camera.Position = cameraPosition; camera.Target = cameraTarget; } + if (isSelected) ImGui.SetItemDefaultFocus(); } ImGui.EndCombo(); } @@ -2206,7 +2154,7 @@ namespace NewCamera } if (camera == pCamera) { - Player? player = checkPlayerChange(); + Player? player = PlayerExt.getPlayer(); if (!debug && player != null) { ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(0.0f, 6.0f)); @@ -2318,79 +2266,9 @@ namespace NewCamera ImGui.PopItemWidth(); } - public static void drawAnimationInfo(Entity entity, float width, bool debug) + public void OnRender() { - ActionController actionController = entity.ActionController; - ActionInfo currentActionInfo = actionController.CurrentAction; - SharpPluginLoader.Core.Actions.Action? currentAction = null; - if (currentActionInfo.ActionSet >= 0 && currentActionInfo.ActionSet <= 3) - { - ActionList actionList = actionController.GetActionList(currentActionInfo.ActionSet); - if (currentActionInfo.ActionId >= 0 && currentActionInfo.ActionId < actionList.Count) - { - currentAction = actionList[currentActionInfo.ActionId]; - } - } - if (debug) - { - ImGui.Text($"ActionController: 0x{actionController.Instance:X}"); - ImGui.Text($" Current: {currentAction} {currentActionInfo}"); - if (currentAction != null) - { - - ImGui.Text($" Active Time: {currentAction.ActiveTime}"); - ImGui.Text($" Delta Sec: {currentAction.DeltaSec}"); - } - } - AnimationId currentAnimation = entity.CurrentAnimation; - AnimationLayerComponent? animationLayer = entity.AnimationLayer; - if (animationLayer != null) - { - ImGui.Text(debug ? $"AnimationLayer: 0x{animationLayer.Instance:X}" : "Animation"); - if (debug) - { - ImGui.Text($" Current: {currentAnimation}"); - ImGui.Text($" Frame: {animationLayer.CurrentFrame:0.000}/{animationLayer.MaxFrame:0.000}"); - return; - } - else - { - ImGui.Text($" Current: {currentAnimation.Lmt}.{currentAnimation.Id}, {(currentAction != null ? currentAction.Name : "None")}"); - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("{Lmt}.{Id}, {Action}"); - ImGui.EndTooltip(); - } - ImGui.SetNextItemWidth(width * 0.8f); - ImGui.SliderFloat("Frame", ref animationLayer.CurrentFrame, 0.0f, animationLayer.MaxFrame, "%.3f"); - } - bool animationPaused = animationLayer.Paused; - if (ImGui.Checkbox("Paused", ref animationPaused)) - { - animationLayer.Paused = animationPaused; - } - ImGui.SameLine(); - float? lockedSpeed = animationLayer.LockedSpeed; - float speed = lockedSpeed ?? animationLayer.Speed; - bool animationLocked = lockedSpeed != null; - if (ImGui.Checkbox("Set", ref animationLocked)) - { - if (animationLocked) - { - animationLayer.LockSpeed(speed); - } - else - { - animationLayer.UnlockSpeed(); - } - } - ImGui.SameLine(); - ImGui.SetNextItemWidth(width * 0.35f); - if (ImGui.DragFloat($"Speed", ref speed, 0.01f, 0.0f, 0.0f, "%.3f")) - { - if (animationLocked) animationLayer.LockSpeed(speed); - } - } + Poser.OnRender(); } public void OnImGuiRender() @@ -2403,13 +2281,11 @@ namespace NewCamera Config config = ConfigManager.GetConfig(this); // If we use vCamera or pCamera here, we need to ensure they're not invalid. - Player? player = checkPlayerChange(); + Player? player = PlayerExt.getPlayer(); checkCurrentVisibleCamera(player); - ImGui.Separator(); - ImGui.PushItemWidth(width * 0.475f); - ImGui.Checkbox("Free Camera", ref enableFreeCamera); + ImGui.Checkbox("Enable Free Camera", ref enableFreeCamera); ImGui.PushID("Settings"); ImGui.DragFloat("Camera Speed", ref cameraSpeed, 0.01f, 0.0f, 0.0f, "%.4f"); if (ImGui.BeginItemTooltip()) @@ -2471,9 +2347,9 @@ namespace NewCamera ImGui.Separator(); - if (ImGui.Checkbox("Perspective Camera", ref enableOffsetPerspective)) + if (ImGui.Checkbox("Enable Camera Offset", ref enableOffsetPerspective)) { - config.PerspectiveCameraEnabled = enableOffsetPerspective; + config.CameraOffsetEnabled = enableOffsetPerspective; if (enableOffsetPerspective) { if (config.Selected != "") @@ -2697,8 +2573,8 @@ namespace NewCamera ImGui.Separator(); - ImGui.PushID("Binds"); - if (ImGui.CollapsingHeader("Binds")) + ImGui.PushID("Controller"); + if (ImGui.CollapsingHeader("Controller")) { if (ImGui.Checkbox("Toggle Free Camera", ref enableCombo)) { @@ -2742,49 +2618,55 @@ namespace NewCamera } } ImGui.SameLine(); - if (ImGui.Checkbox("Disable Button1 Unless Button2 is Held", ref disableComboButton1)) + if (ImGui.Checkbox("Button1 Blocks Input Unless Button2 is Held", ref blockComboButton1)) { comboButton1Down = false; Config.Settings.Binds binds = config.Binds; - binds.DisableComboButton1UnlessButton2Held = disableComboButton1; + binds.ComboButton1BlocksUnlessButton2Held = blockComboButton1; config.Binds = binds; ConfigManager.SaveConfig(this); } if (ImGui.BeginItemTooltip()) { - ImGui.Text("For example, if bound to RStick+LT, right stick presses will ignored by the game unless you're holding the left trigger.\nIn that case, it can let you avoid switching the targeted monster when toggling free camera."); + ImGui.Text("This allows Global binds to not interrupt the game."); ImGui.EndTooltip(); } ImGui.Text("Global"); - if (ImGui.BeginItemTooltip()) + if (!enableCombo) { - ImGui.Text("Button1 refers to the first button of the Toggle Free Camera bind."); - ImGui.EndTooltip(); + ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f); } if (ImGui.BeginTable("Global Binds", 2, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Borders)) { ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); - ImGui.Text("Hold Button1 + Press Select"); + ImGui.Text("Hold Button1"); + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Button1 refers to the first button of the Toggle Free Camera bind."); + ImGui.EndTooltip(); + } + ImGui.TableSetColumnIndex(1); + ImGui.Text(""); + + ImGui.Indent(6.0f); + + ImGui.TableNextRow(); + ImGui.TableSetColumnIndex(0); + ImGui.Text("Select"); ImGui.TableSetColumnIndex(1); ImGui.Text("Toggle UI"); ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); - ImGui.Text("Hold Button1 + Press D-Pad Up/Down"); + ImGui.Text("D-Pad Up/Down"); ImGui.TableSetColumnIndex(1); - ImGui.Text("Select Perspective Camera Preset"); - - ImGui.EndTable(); - } + ImGui.Text("Select Camera Offset Preset"); - ImGui.Text("While in Free Camera | ( ) = Toggle"); - if (ImGui.BeginTable("Binds", 2, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Borders)) - { ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); - ImGui.Text("Hold Button1 + Press LB"); + ImGui.Text("LB"); ImGui.TableSetColumnIndex(1); ImGui.Text("Toggle Unlock Input"); if (ImGui.BeginItemTooltip()) @@ -2793,22 +2675,34 @@ namespace NewCamera ImGui.EndTooltip(); } + ImGui.Unindent(6.0f); + + ImGui.EndTable(); + } + if (!enableCombo) + { + ImGui.PopStyleVar(); + } + + ImGui.Text("While in Free Camera | ( ) = Toggle"); + if (ImGui.BeginTable("Binds", 2, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Borders)) + { ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); - ImGui.Text("Hold RT (+ Press LB)"); + ImGui.Text("Hold RT (LB)"); ImGui.TableSetColumnIndex(1); ImGui.Text("Unlock Player Movement and Freeze Camera Movement"); ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); - ImGui.Text("Hold LT (+ Press LB)"); + ImGui.Text("Hold LT (LB)"); ImGui.TableSetColumnIndex(1); ImGui.Text("Lock Vertical Camera Movement and Apply Speed Modifier"); ImGui.EndTable(); } - ImGui.Text("Disabled While Input to the Game is Unlocked"); + ImGui.Text("Disabled While Input is Unlocked"); if (ImGui.BeginTable("More Binds", 2, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Borders)) { ImGui.TableNextRow(); @@ -2825,7 +2719,7 @@ namespace NewCamera ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); - ImGui.Text("Hold LT + RT"); + ImGui.Text("Hold LT & RT"); ImGui.TableSetColumnIndex(1); ImGui.Text("Zoom with Left Stick Up/Down"); if (ImGui.BeginItemTooltip()) @@ -2836,7 +2730,7 @@ namespace NewCamera ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); - ImGui.Text("Press Y"); + ImGui.Text("Y"); ImGui.TableSetColumnIndex(1); ImGui.Text("Open Gestures Menu"); @@ -2846,48 +2740,67 @@ namespace NewCamera ImGui.TableSetColumnIndex(1); ImGui.Text(""); + ImGui.Indent(6.0f); + ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); - ImGui.Text(" + Press Y"); + ImGui.Text("Y"); ImGui.TableSetColumnIndex(1); ImGui.Text("Open Poses Menu"); ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); - ImGui.Text(" + Press X"); + ImGui.Text("B"); + ImGui.TableSetColumnIndex(1); + ImGui.Text("Toggle Depth of Field Near"); + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Requires World Tuning Tool."); + ImGui.EndTooltip(); + } + + ImGui.TableNextRow(); + ImGui.TableSetColumnIndex(0); + ImGui.Text("X"); ImGui.TableSetColumnIndex(1); ImGui.Text("Toggle Alternate Near Clip"); + ImGui.Unindent(6.0f); + ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); ImGui.Text("Hold RB"); ImGui.TableSetColumnIndex(1); ImGui.Text(""); + ImGui.Indent(6.0f); + ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); - ImGui.Text(" + Press D-Pad Right"); + ImGui.Text("D-Pad Right"); ImGui.TableSetColumnIndex(1); ImGui.Text("Reset Roll"); ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); - ImGui.Text(" + Press D-Pad Up"); + ImGui.Text("D-Pad Up"); ImGui.TableSetColumnIndex(1); ImGui.Text("Reset Zoom"); ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); - ImGui.Text(" + Press D-Pad Left"); + ImGui.Text("D-Pad Left"); ImGui.TableSetColumnIndex(1); ImGui.Text("Toggle Freeze Game"); ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); - ImGui.Text(" + Press D-Pad Down"); + ImGui.Text("D-Pad Down"); ImGui.TableSetColumnIndex(1); ImGui.Text("Teleport Player to Camera Position"); + ImGui.Unindent(6.0f); + ImGui.EndTable(); } @@ -2895,7 +2808,6 @@ namespace NewCamera } ImGui.PopID(); -#if MOUSE_AND_KEYBOARD_LAYER ImGui.PushID("Mouse/Keyboard"); if (ImGui.CollapsingHeader("Mouse & Keyboard")) { @@ -2908,6 +2820,8 @@ namespace NewCamera ConfigManager.SaveConfig(this); } ImGui.SameLine(); + float widthDiff = ImGui.CalcTextSize("Enable Keyboard").X - ImGui.CalcTextSize("Enable Mouse").X; + ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(widthDiff, 0.0f)); if (ImGui.DragFloat("Mouse Sensitivity", ref mouseSensitivity, 0.001f, 0.0f, 0.0f, "%.4f")) { Config.Settings.Binds binds = config.Binds; @@ -3000,13 +2914,19 @@ namespace NewCamera ImGui.Separator(); } ImGui.PopID(); -#endif ImGui.PushID("Viewport"); - if (ImGui.CollapsingHeader("Viewport") && vCameraViewportIndex >= 0) + if (ImGui.CollapsingHeader("Viewport")) { - drawViewportInfo(vCameraViewportIndex, width, config, false); - ImGui.Separator(); + if (vCameraViewportIndex >= 0) + { + drawViewportInfo(vCameraViewportIndex, width, config, false); + ImGui.Separator(); + } + else + { + ImGui.Text("No viewports"); + } } ImGui.PopID(); @@ -3020,12 +2940,21 @@ namespace NewCamera { if (player != null) { - PlayerExt.drawPlayerInfo(player, width); + PlayerExt.DrawPlayerInfo(player, width); ImGui.Separator(); } + else + { + ImGui.Text("Player not found"); + } } ImGui.PopID(); + if (Poser.overlayJoints) + { + Renderer.RequestMouseCapture(); + } + ImGui.PushID("World"); if (ImGui.CollapsingHeader("World")) { @@ -3152,7 +3081,7 @@ namespace NewCamera ImGui.Text($"Address: 0x{player.Instance:X}"); ImGui.Text($"Settings: 0x{PlayerExt.getPlayerSettings():X}"); - drawAnimationInfo(player, width, true); + Models.drawAnimationInfo(player, width, true); bool move = player.Move; if (ImGui.Checkbox("Move", ref move)) @@ -3202,14 +3131,11 @@ namespace NewCamera ImGui.DragFloat3("Position", ref monster.Position, 0.5f); Vector4 rotation = new Vector4(monster.Rotation.X, monster.Rotation.Y, monster.Rotation.Z, monster.Rotation.W); ImGui.SliderFloat4("Rotation", ref rotation, -1.0f, 1.0f); - Vector3 rotationOffset = new Vector3(); - if (ImGui.DragFloat3("Rotation Offset", ref rotationOffset, 0.0025f)) + if (Models.DrawRotate("Rotate", rotation, out Vector4 result)) { - Quaternion qRotation = new Quaternion(rotation.X, rotation.Y, rotation.Z, rotation.W); - qRotation *= Quaternion.CreateFromYawPitchRoll(rotationOffset.X, rotationOffset.Y, rotationOffset.Z); - monster.Rotation = new MtQuaternion(qRotation.X, qRotation.Y, qRotation.Z, qRotation.W); + monster.Rotation = new MtQuaternion(result.X, result.Y, result.Z, result.W); } - drawAnimationInfo(monster, width, true); + Models.drawAnimationInfo(monster, width, true); ImGui.PopID(); ImGui.Separator(); } @@ -3238,7 +3164,12 @@ namespace NewCamera ImGui.Text($"{animal.Id:X} ({animal.OtherId:X}):"); ImGui.Text($" Address: 0x{animal.Instance:X}"); ImGui.DragFloat3("Position", ref animal.Position, 0.5f); - // Freeze: +0x1AFC = 0xFFFFFFFC + Vector4 rotation = new Vector4(animal.Rotation.X, animal.Rotation.Y, animal.Rotation.Z, animal.Rotation.W); + ImGui.SliderFloat4("Rotation", ref rotation, -1.0f, 1.0f); + if (Models.DrawRotate("Rotate", rotation, out Vector4 result)) + { + animal.Rotation = new MtQuaternion(result.X, result.Y, result.Z, result.W); + } if (ImGui.Button("Remove")) { MemoryUtil.GetRef(animal.Instance + 0x928) = 0xFFFFFFFF; @@ -3250,124 +3181,27 @@ namespace NewCamera ImGui.Separator(); - ImGui.Checkbox("Only Toggle LOD 0", ref modelOnlyAddressLod0); + Models.DrawModelsList(width, (player != null) ? player.Instance : 0x0); + + bool expand = ImGui.CollapsingHeader("Objects"); if (ImGui.BeginItemTooltip()) { - ImGui.Text($"This can be used to check if a given model is showing LOD 0 or not.\nApplies when a part is toggled, meaning you should probably toggle all parts on before enabling this."); + ImGui.Text("This reads from the list of objects to be updated.\nTherefore, at any given moment it could be empty."); ImGui.EndTooltip(); } - if (ImGui.CollapsingHeader("Loaded Models") && player != null) + if (expand) { - ImGui.Text("Filter"); - bool updateRegex = false; - ImGui.SetNextItemWidth(width * 0.5f); - bool invalidRegex = modelFilterIsRegex && modelFilter != "" && modelRegex == null; - if (invalidRegex) - { - ImGui.PushStyleColor(ImGuiCol.Text, 0xFF0000FF); - } - if (ImGui.InputText("##Filter", ref modelFilter, 256)) - { - if (modelFilterIsRegex) - { - updateRegex = true; - } - } - if (invalidRegex) - { - ImGui.PopStyleColor(); - } - ImGui.SameLine(); - if (ImGui.Button("Clear")) - { - modelFilter = ""; - if (modelFilterIsRegex) - { - updateRegex = true; - } - } - ImGui.SameLine(); - if (ImGui.Checkbox("Regex", ref modelFilterIsRegex)) - { - if (modelFilterIsRegex) - { - updateRegex = true; - } - } - if (updateRegex) - { - if (String.IsNullOrEmpty(modelFilter)) - { - modelRegex = null; - } - else - { - try - { - modelRegex = new Regex(modelFilter); - } - catch (ArgumentException) - { - modelRegex = null; - } - } - } - nint bodyArmorParts = MemoryUtil.Read(player.Instance + 0x2A0); - if (bodyArmorParts != 0x0) - { - nint next = bodyArmorParts - 0x40; - nint head = next; - nint prev = MemoryUtil.Read(next + 0x10); - for (;next != 0x0;) - { - ImGui.PushID(next); - nint partsAddr = next + 0x40; - nint vTable = MemoryUtil.Read(partsAddr); - if (vTable == 0x143507A18) - { - string fullString = Marshal.PtrToStringAnsi(partsAddr + 0xC)!; - bool filterMatch = false; - if (modelFilterIsRegex) - { - filterMatch = modelRegex == null || modelRegex.Match(fullString).Success; - } - else - { - filterMatch = String.IsNullOrEmpty(modelFilter) || fullString.StartsWith(modelFilter); - } - if (filterMatch) - { - PlayerExt.drawModelParts(0x0, partsAddr); - } - } - ImGui.PopID(); - if (head == prev) - { - next = MemoryUtil.Read(next + 0x10); - } - else - { - next = MemoryUtil.Read(next + 0x18); - if (next == 0x0) - { - head = prev; - next = prev; - } - } - } - } + Models.DrawObjectList(width, player!); } ImGui.Separator(); -#if MOUSE_AND_KEYBOARD_LAYER ImGui.PushID("Mouse/Keyboard"); ImGui.Text("Mouse"); ImGui.Text($"Address: 0x{sMhMouse.Instance:X}"); ImGui.Text("Keyboard"); ImGui.Text($"Address: 0x{sMhKeyboard.Instance:X}"); ImGui.PopID(); -#endif ImGui.PushID("Pad"); ImGui.Text("Pad"); -- cgit v1.2.3-101-g0448