summaryrefslogtreecommitdiff
path: root/Plugin.cs
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2026-06-02 22:23:53 -0400
committerAndrew Opalach <andrew@akon.city> 2026-06-02 22:23:53 -0400
commitd40ec05f3e61b51be0b6a7797fc11e0b626d238b (patch)
tree1a7469336b6bb93e848a44eba1ed0c3dadb575d5 /Plugin.cs
parent513f05695545b8eceec1085f741862ec3a7bf3b5 (diff)
downloadNewCamera-d40ec05f3e61b51be0b6a7797fc11e0b626d238b.tar.gz
NewCamera-d40ec05f3e61b51be0b6a7797fc11e0b626d238b.tar.bz2
NewCamera-d40ec05f3e61b51be0b6a7797fc11e0b626d238b.zip
Organize joints, cleanup for new release
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'Plugin.cs')
-rwxr-xr-xPlugin.cs1723
1 files changed, 1255 insertions, 468 deletions
diff --git a/Plugin.cs b/Plugin.cs
index 01f7ab7..9220b3b 100755
--- a/Plugin.cs
+++ b/Plugin.cs
@@ -1,11 +1,12 @@
-#define ENABLE_ASSERTS
+//#define ENABLE_ASSERTS
//#define HOOK_ORDER_ASSERTS
//#define LOG_DEBUG_MESSAGES
#define MOUSE_AND_KEYBOARD_LAYER
-#define QUARANTINED_FEATURES
+//#define QUARANTINED_FEATURES
using System.Numerics;
using System.Runtime.InteropServices;
+using System.Text.RegularExpressions;
#if ENABLE_ASSERTS
using System.Diagnostics;
#endif
@@ -20,7 +21,6 @@ using SharpPluginLoader.Core.Memory;
using SharpPluginLoader.Core.Actions;
using SharpPluginLoader.Core.Components;
using SharpPluginLoader.Core.Configuration;
-using WorldTuningTool;
// Tentative List of Actions:
// - Toggle Free Camera
@@ -48,16 +48,14 @@ using WorldTuningTool;
// - Open Poses Menu
// @TODO:
-// - Collect armor parts logic.
-// - Map joints to parts.
+// - Pass on ImGui flicker.
+// - Cleanup math.
// - pCamera refactor.
-// - Structured tuning tool interop.
// - Attempt to document all test cases I can think of.
-// - Wasd for ignore camera direction.
-// - Make audio like waterfall follow camera position instead of player position.
-// - Audio high/lowpass?
// - Centralize all bindings to get a better idea of how to structure custom binds.
-// - Use GetRef<>.
+// - WASD for ignore camera direction.
+// - Make audio like waterfall follow camera position instead of player position.
+// - Audio high/lowpass possible?
// - Save toggle state to config file.
// - Include Hide Weapon.
// - Hunter effects:
@@ -138,6 +136,37 @@ using WorldTuningTool;
namespace NewCamera
{
+ public static class TuningToolInterop
+ {
+ public static string PluginName = "World Tuning Tool";
+ public static dynamic? Instance = null;
+
+ public static bool InitFromLoadedInstance()
+ {
+#if QUARANTINED_FEATURES
+ Instance = IPlugin.GetInstance(PluginName);
+#endif
+ return Instance != null;
+ }
+
+ public static int AddOverride(string name, Vector4 v4, int i1)
+ {
+ if (Instance != null)
+ {
+ return Instance.AddOverride(name, v4, i1);
+ }
+ return 0;
+ }
+
+ public static void RemoveOverride(int id)
+ {
+ if (Instance != null)
+ {
+ Instance.RemoveOverride(id);
+ }
+ }
+ }
+
public unsafe class Plugin : IPlugin
{
public string Name => "New Camera";
@@ -157,8 +186,6 @@ namespace NewCamera
private bool disableMod = false;
- private WorldTuningTool.Interop tuningTool = new WorldTuningTool.Interop();
-
private static readonly MtObject sMain = SingletonManager.GetSingleton("sMhMain")!;
private bool freezeGame = false;
private bool decoupleDtFromGameTime = false;
@@ -211,6 +238,7 @@ namespace NewCamera
private float orbitDistance = 350.0f;
private float orbitY = 150.0f;
private float orbitRight = 0.0f;
+ private int orbitJoint = -1;
private bool enableOffsetPerspective = false;
private bool offsetPerspective = false;
@@ -262,6 +290,13 @@ namespace NewCamera
private float plusRight = 0.0f;
private float plusForward = 0.0f;
+ private bool sortMonsters = true;
+ private bool sortAnimals = true;
+
+ private string modelFilter = "";
+ private bool modelFilterIsRegex = false;
+ private Regex? modelRegex = null;
+
private delegate void ProcessCameraDelegate(nint cameraPointer);
private Hook<ProcessCameraDelegate>? setCameraHook;
private Hook<ProcessCameraDelegate>? calculateCameraHook;
@@ -368,100 +403,142 @@ namespace NewCamera
private bool hideKnife = false;
private bool hideSlinger = false;
- // List of Joints:
- // Hip (1_0)
- // Right Leg (2_0)
- // Left Leg (2_1)
- // Lower Back (2_2)
- // Left Knee (3_1)
- // Right Knee (3_2)
- // Upper Back (3_4)
- // Lower Neck (4_0)
- // Right Ankle (4_1)
- // Left Ankle (4_5)
- // Left Shoulder (4_7)
- // Right Shoulder (4_8)
- // Left Toes (5_2)
- // Right Shoulder2 (5_3)
- // Upper Neck (5_4)
- // Left Shoulder2 (5_5)
- // Right Toes (5_6)
- // Right Elbow (6_4)
- // Left Elbow (6_5)
- // Left Wrist (7_1)
- // Right Wrist (7_4)
- // Left Palm (8_0)
- // Left Middle (8_2)
- // Left Index (8_3)
- // Right Palm (8_4)
- // Left Thumb (8_5)
- // Right Thumb (8_7)
- // Right Index (8_11)
- // Right Middle (8_12)
- // Right Index T (9_0)
- // Left Pinky T (9_1)
- // Left Thumb T (9_2)
- // Left Index T (9_3)
- // Left Middle T (9_4)
- // Left Ring T (9_5)
- // Right Middle T (9_6)
- // Right Thumb T (9_7)
- // Right Ring T (9_8)
- // Right Pinky T (9_9)
- // Right Index P (A_0)
- // Right Thumb P (A_1)
- // Left Pinky P (A_2)
- // Left Ring P (A_3)
- // Left Middle P (A_4)
- // Right Ring P (A_5)
- // Left Index P (A_6)
- // Left Thumb P (A_7)
- // Right Middle P (A_8)
- // Right Pinky P (A_9)
- // Left Pinky D (B_0)
- // Right Pinky D (B_1)
- // Left Ring D (B_2)
- // Right Ring D (B_3)
+ private static class Armor
+ {
+ public const byte Body = 0;
+ public const byte Helmet = 1;
+ public const byte Arm = 2;
+ public const byte Waist = 3;
+ public const byte Leg = 4;
+ public const byte Face = 5;
+ public const byte EyeLens = 6;
+ public const byte Hair = 7;
+ }
- private struct Armor
+ private static class Joint
{
- public const int Body = 0;
- public const int Helmet = 1;
- public const int Arm = 2;
- public const int Waist = 3;
- public const int Leg = 4;
- public const int Face = 5;
- };
+ public const byte Root = 0;
+ public const byte Root2 = 1; // Animations use this root.
+ public const byte LowerBack = 2;
+ public const byte UpperBack = 3;
+ public const byte LowerNeck = 4;
+ public const byte LowerNeckNull = 5;
+ public const byte UpperNeck = 6;
+ public const byte LeftCollarbone = 7;
+ public const byte LeftShoulderNull = 8;
+ public const byte LeftShoulder = 9;
+ public const byte LeftElbow = 10;
+ public const byte LeftWrist = 11;
+ public const byte LeftWristNull = 12;
+ public const byte LeftThumbLow = 13;
+ public const byte LeftThumbMid = 14;
+ public const byte LeftThumbHigh = 15;
+ public const byte LeftIndexLow = 16;
+ public const byte LeftIndexMid = 17;
+ public const byte LeftIndexHigh = 18;
+ public const byte LeftMiddleLow = 19;
+ public const byte LeftMiddleMid = 20;
+ public const byte LeftMiddleHigh = 21;
+ public const byte LeftPalm = 22;
+ public const byte LeftRingLow = 23;
+ public const byte LeftRingMid = 24;
+ public const byte LeftRingHigh = 25;
+ public const byte LeftPinkyLow = 26;
+ public const byte LeftPinkyMid = 27;
+ public const byte LeftPinkyHigh = 28;
+ public const byte LeftArmUnk1 = 29;
+ public const byte LeftArmUnk2 = 30;
+ public const byte LeftArmUnk3 = 31;
+ public const byte LeftArmUnk4 = 32;
+ public const byte LeftArmUnk5 = 33;
+ public const byte LeftArmUnk6 = 34;
+ public const byte LeftArmUnk7 = 35;
+ public const byte RightCollarbone = 36;
+ public const byte RightShoulder = 37;
+ public const byte RightElbow = 38;
+ public const byte RightWrist = 39;
+ public const byte RightWristNull = 40;
+ public const byte RightThumbLow = 41;
+ public const byte RightThumbMid = 42;
+ public const byte RightThumbHigh = 43;
+ public const byte RightIndexLow = 44;
+ public const byte RightIndexMid = 45;
+ public const byte RightIndexHigh = 46;
+ public const byte RightMiddleLow = 47;
+ public const byte RightMiddleMid = 48;
+ public const byte RightMiddleHigh = 49;
+ public const byte RightPalm = 50;
+ public const byte RightRingLow = 51;
+ public const byte RightRingMid = 52;
+ public const byte RightRingHigh = 53;
+ public const byte RightPinkyLow = 54;
+ public const byte RightPinkyMid = 55;
+ public const byte RightPinkyHigh = 56;
+ public const byte RightArmUnk1 = 57;
+ public const byte RightArmUnk2 = 58;
+ public const byte RightArmUnk3 = 59;
+ public const byte RightArmUnk4 = 60;
+ public const byte Unknown1 = 61;
+ public const byte Unknown2 = 62;
+ public const byte LeftHip = 63;
+ public const byte LeftKnee = 64;
+ public const byte LeftAnkle = 65;
+ public const byte LeftToes = 66;
+ public const byte LeftAnkleNull = 67;
+ public const byte LeftKneeNull = 68;
+ public const byte LeftHipNull = 69;
+ public const byte Unknown3 = 70;
+ public const byte Unknown4 = 71;
+ public const byte RightHip = 72;
+ public const byte RightKnee = 73;
+ public const byte RightAnkle = 74;
+ public const byte RightToes = 75;
+ public const byte RightAnkleNull = 76;
+ public const byte RightKneeNull = 77;
+ public const byte RightHipNull = 78;
+ public const byte Unknown5 = 79;
+ public const byte Unknown6 = 80;
+ public const byte Unknown7 = 81;
+ public const byte Unknown8 = 82;
+ public const byte Unknown9 = 83;
+ public const byte Unknown10 = 84;
+ public const byte Unknown11 = 85;
+ }
+
+ private nint[] playerArmor = new nint[8];
+ private nint[] playerJoints = new nint[86];
- private nint[] playerArmor = new nint[6] { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+ private delegate void UpdateJoints(nint obj);
+ private Hook<UpdateJoints>? updateJointsHook;
+ private delegate void UpdateJointChild(nint child, nint joint, nint obj);
private List<nint> bodyJoints = new List<nint>();
- //private List<nint> faceJoints = new List<nint>();
- private List<nint> jiggleBones = new List<nint>();
+ private List<nint> ignoredJoints = new List<nint>();
+ private Dictionary<nint, List<Vector3>> jointOffsets = new Dictionary<nint, List<Vector3>>();
+ private bool didJointOffset = false;
+
+#if QUARANTINED_FEATURES
+ private delegate void UpdateIK(nint superOfChild, nint joint, nint obj);
+ private Hook<UpdateIK>? updateIKHook;
+ private Dictionary<nint, List<Vector3>> ikOffsets = new Dictionary<nint, List<Vector3>>();
+#endif
private List<nint> ikJoints = new List<nint>();
+ private bool ikForcedOff = false;
+ private Patch forceDisableIK;
+
+ private List<nint> jiggleBones = new List<nint>();
private bool attachToChest = false;
private bool swapChestSides = false;
private float chestMoveScale = 0.25f;
private nint chestBone1 = 0x0;
private nint chestBone2 = 0x0;
+ private List<nint> faceJoints = new List<nint>();
/*
private bool overrideFacePose;
private Patch noopFacePose;
private Patch noopFacePoseUpdate;
*/
- private bool ikForcedOff = false;
- private Patch forceDisableIK;
- private delegate void UpdateJoints(nint obj, nint unknownPtr, int unknownInt, int unknownInt2);
- private Hook<UpdateJoints>? updateJointsHook;
- private delegate void UpdateJointChild(nint child, nint joint, nint obj);
- private Dictionary<nint, List<Vector3>> jointOffsets = new Dictionary<nint, List<Vector3>>();
- private bool didJointOffset = false;
-
- private delegate void UpdateIK(nint superOfChild, nint joint, nint obj);
- private Hook<UpdateIK>? updateIKHook;
- private Dictionary<nint, List<Vector3>> ikOffsets = new Dictionary<nint, List<Vector3>>();
-
/*
private delegate void ChangeEquipment(nint unknownPtr, int unknownInt);
private Hook<ChangeEquipment>? changeEquipmentHook;
@@ -528,11 +605,12 @@ namespace NewCamera
disableGravityEval.Disable();
}
- private enum ZoneState : int {
+ private enum ZoneState : int
+ {
Unknown = 0,
Hub = 1,
Combat = 2
- };
+ }
#if QUARANTINED_FEATURES
private ZoneState forceZoneState = ZoneState.Unknown;
@@ -812,16 +890,22 @@ namespace NewCamera
getSaveSlotGuiAddr = new NativeFunction<nint, nint>(0x141AC0B60);
getPlayerSettingsAddr = new NativeFunction<nint, nint>(0x141B8DBB0);
- //noopFacePose = new Patch(new nint(0x14237B093), [0x90, 0x90, 0x90, 0x90, 0x90]);
- //noopFacePoseUpdate = new Patch(new nint(0x14223BAAB), [0x90, 0x90, 0x90, 0x90, 0x90]);
+ /*
+ noopFacePose = new Patch(new nint(0x14237B093), [0x90, 0x90, 0x90, 0x90, 0x90]);
+ noopFacePoseUpdate = new Patch(new nint(0x14223BAAB), [0x90, 0x90, 0x90, 0x90, 0x90]);
+ */
forceDisableIK = new Patch(new nint(0x14031FD40), [0xC6, 0x81, 0x81, 0x01, 0x00, 0x00, 0x00, 0xC3]);
- updateJointsHook = Hook.Create<UpdateJoints>(0x14223B870, UpdateJointsHook);
+ updateJointsHook = Hook.Create<UpdateJoints>(0x14223BA30, UpdateJointsHook);
+#if QUARANTINED_FEATURES
updateIKHook = Hook.Create<UpdateIK>(0x142472C00, UpdateIKHook);
+#endif
- //changeEquipmentHook = Hook.Create<ChangeEquipment>(0x141DDEF80, ChangeEquipmentHook); // nint, int
- //newEquipmentPointer = new NativeFunction<nint, int, nint>(0x141DE56A0);
+ /*
+ changeEquipmentHook = Hook.Create<ChangeEquipment>(0x141DDEF80, ChangeEquipmentHook); // nint, int
+ newEquipmentPointer = new NativeFunction<nint, int, nint>(0x141DE56A0);
+ */
// Player + ECCC = How far underwater is the player.
jmpOverHotSpringsEval = new Patch(new nint(0x1417C1B03), [0xEB]);
@@ -865,12 +949,12 @@ namespace NewCamera
Assert(addr + 0x8 == 0x1413259ED);
#endif
disableGravityYUpdate = new Patch(addr + 0x8, [
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
]);
disableGravityXZUpdate = new Patch(addr, [
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // Will already be applied.
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // Will already be applied.
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
]);
addr = PatternScanner.FindFirst(Pattern.FromString("F3 0F 11 97 54 15 00 00 F3 0F 11 8F 58 15 00 00 F3 0F 10 47 68 F3 0F 5E D8 44 89 B7 6C 15 00 00 F3 0F 5E D0 F3 0F 5E C8 F3 0F 11 9F 60 15 00 00 F3 0F 11 97 64 15 00 00 F3 0F 11 8F 68 15 00 00"));
@@ -963,13 +1047,13 @@ namespace NewCamera
}
if (config.TuningToolInterop)
{
- if (tuningTool.InitFromLoadedInstance())
+ if (TuningToolInterop.InitFromLoadedInstance())
{
- Log.Info($"Successfully loaded '{WorldTuningTool.Interop.PluginName}' instance");
+ Log.Info($"Successfully loaded '{TuningToolInterop.PluginName}' instance");
}
else
{
- Log.Warn($"Couldn't find loaded '{WorldTuningTool.Interop.PluginName}' instance, features will be missing");
+ Log.Warn($"Couldn't find loaded '{TuningToolInterop.PluginName}' instance, features will be missing");
}
}
}
@@ -1019,9 +1103,20 @@ namespace NewCamera
return new Player(playerAddr);
}
+ private Player? getPlayer() { return Player.MainPlayer; }
+ private Player? getPlayerWithFallback()
+ {
+ Player? player = getPlayer();
+ if (player == null)
+ {
+ player = getPlayerFromSaveSlot();
+ }
+ return player;
+ }
+
private Player? checkPlayerChange()
{
- Player? player = Player.MainPlayer;
+ Player? player = getPlayer();
if (player != lastPlayer)
{
pCamera = null;
@@ -1164,12 +1259,12 @@ namespace NewCamera
{
if (disableNearDofOverride != 0)
{
- tuningTool.RemoveOverride(disableNearDofOverride);
+ TuningToolInterop.RemoveOverride(disableNearDofOverride);
disableNearDofOverride = 0;
}
else
{
- disableNearDofOverride = tuningTool.AddOverride("Near Enable", new Vector4(), 0);
+ disableNearDofOverride = TuningToolInterop.AddOverride("Near Enable", new Vector4(), 0);
}
}
}
@@ -1217,12 +1312,7 @@ namespace NewCamera
advanceFrame--;
}
- player = Player.MainPlayer;
- if (player == null)
- {
- player = getPlayerFromSaveSlot();
- }
-
+ player = getPlayerWithFallback();
if (player != null)
{
if (hideWeapon)
@@ -1377,7 +1467,7 @@ namespace NewCamera
forceMinimapFollowsCamera.Enable();
/*
//MemoryUtil.GetRef<nint>(psuedoViewModeObject + 0x10) = vCamera.Instance;
- Player? player = Player.MainPlayer;
+ Player? player = getPlayer();
if (player != null)
{
MemoryUtil.GetRef<nint>(psuedoViewModeObject + 0x118) = player.Instance;
@@ -1509,18 +1599,22 @@ namespace NewCamera
orbitDistance = 3.00f;
}
}
+ if (plusRight != 0.0f)
+ {
+ orbitMovementRotation += plusRight;
+ }
}
else
{
orbitMovementRotation += Lx / 5.0f;
- if (orbitMovementRotation >= 180.0f)
- {
- orbitMovementRotation -= 360.0f;
- }
- else if (orbitMovementRotation < -180.0f)
- {
- orbitMovementRotation += 360.0f;
- }
+ }
+ if (orbitMovementRotation >= 180.0f)
+ {
+ orbitMovementRotation -= 360.0f;
+ }
+ else if (orbitMovementRotation < -180.0f)
+ {
+ orbitMovementRotation += 360.0f;
}
}
else
@@ -1685,7 +1779,7 @@ namespace NewCamera
}
#endif
cameraYaw += Rx;
- if (plusRight != 0.0f)
+ if (plusRight != 0.0f && !orbitPlayer)
{
cameraYaw += plusRight * deltaTime;
}
@@ -1699,9 +1793,14 @@ namespace NewCamera
{
cameraYaw += 360.0f;
}
- if (cameraPitchLimit >= 0.0f)
+ float pitchLimit = cameraPitchLimit;
+ if (orbitJoint >= 0 && pitchLimit == -1.0f)
+ {
+ pitchLimit = Config.Settings.MAX_PITCH_LIMIT;
+ }
+ if (pitchLimit >= 0.0f)
{
- cameraPitch = Math.Clamp(cameraPitch, -cameraPitchLimit, cameraPitchLimit);
+ cameraPitch = Math.Clamp(cameraPitch, -pitchLimit, pitchLimit);
}
else
{
@@ -1739,18 +1838,42 @@ namespace NewCamera
if (orbitPlayer && player != null)
{
- Quaternion rotation = new Quaternion(player.Rotation.X, player.Rotation.Y, player.Rotation.Z, player.Rotation.W);
+ Quaternion rotation;
+ bool targetJoint = orbitJoint >= 0 && orbitJoint < bodyJoints.Count;
+ if (targetJoint)
+ {
+ nint jointAddr = bodyJoints[orbitJoint];
+ cameraTarget = MemoryUtil.GetRef<Vector3>(jointAddr + 0x50);
+ rotation = new Quaternion(player.Rotation.X, player.Rotation.Y, player.Rotation.Z, player.Rotation.W);
+ rotation *= MemoryUtil.GetRef<Quaternion>(jointAddr + 0x70);
+ rotation *= Quaternion.CreateFromYawPitchRoll(
+ Single.DegreesToRadians(-cameraYaw),
+ Single.DegreesToRadians(-cameraPitch),
+ Single.DegreesToRadians(-cameraRoll));
+ }
+ else
+ {
+ cameraTarget = player.Position;
+ 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);
orbitY += cameraFrame.Y;
- cameraTarget = player.Position;
cameraTarget += orbitY * up;
cameraTarget.X += orbitRight * right.X;
cameraTarget.Z += orbitRight * right.Z;
float dist = orbitDistance;
- cameraPosition.X = cameraTarget.X - dist * MathF.Cos(Single.DegreesToRadians(cameraPitch)) * MathF.Cos(Single.DegreesToRadians(cameraYaw));
- cameraPosition.Y = cameraTarget.Y - dist * MathF.Sin(Single.DegreesToRadians(cameraPitch));
- cameraPosition.Z = cameraTarget.Z - dist * MathF.Cos(Single.DegreesToRadians(cameraPitch)) * MathF.Sin(Single.DegreesToRadians(cameraYaw));
+ if (targetJoint)
+ {
+ Vector3 forward = Vector3.Transform(new Vector3(0.0f, 0.0f, 1.0f), rotation);
+ cameraPosition = cameraTarget - forward * dist;
+ }
+ else
+ {
+ cameraPosition.X = cameraTarget.X - dist * MathF.Cos(Single.DegreesToRadians(cameraPitch)) * MathF.Cos(Single.DegreesToRadians(cameraYaw));
+ cameraPosition.Y = cameraTarget.Y - dist * MathF.Sin(Single.DegreesToRadians(cameraPitch));
+ cameraPosition.Z = cameraTarget.Z - dist * MathF.Cos(Single.DegreesToRadians(cameraPitch)) * MathF.Sin(Single.DegreesToRadians(cameraYaw));
+ }
}
else
{
@@ -1777,7 +1900,7 @@ namespace NewCamera
}
#if HOOK_ORDER_ASSERTS
- debugLog($"SetCameraHook({cameraPointer:X}) @ {frameTick}");
+ debugLog($"SetCameraHook(0x{cameraPointer:X}) @ {frameTick}");
Assert(hookOrder == 0);
hookOrder = 1;
#endif
@@ -1826,7 +1949,7 @@ namespace NewCamera
}
#if HOOK_ORDER_ASSERTS
- debugLog($"CalculateCameraHook({cameraPointer:X}) @ {frameTick}");
+ debugLog($"CalculateCameraHook(0x{cameraPointer:X}) @ {frameTick}");
Assert(hookOrder == 2);
hookOrder = 3;
#endif
@@ -1908,7 +2031,7 @@ namespace NewCamera
}
#if HOOK_ORDER_ASSERTS
- debugLog($"CheckCameraHook({cameraPointer:X}) @ {frameTick}");
+ debugLog($"CheckCameraHook(0x{cameraPointer:X}) @ {frameTick}");
Assert(hookOrder == 1);
hookOrder = 2;
#endif
@@ -1941,7 +2064,7 @@ namespace NewCamera
}
#if HOOK_ORDER_ASSERTS
- debugLog($"StartViewMode({viewModeObject:X}) @ {frameTick}");
+ debugLog($"StartViewMode(0x{viewModeObject:X}) @ {frameTick}");
#endif
if (vCamera != null)
@@ -1961,7 +2084,7 @@ namespace NewCamera
#if HOOK_ORDER_ASSERTS
// The order of this hook between SetCameraHook() and CalculateCameraHook() is inconsistent.
- debugLog($"SetCameraTentHook({unknownPtr:X}) @ {frameTick}");
+ debugLog($"SetCameraTentHook(0x{unknownPtr:X}) @ {frameTick}");
#endif
if (freeCamera && vCamera != null)
@@ -1991,7 +2114,7 @@ namespace NewCamera
}
#if HOOK_ORDER_ASSERTS
- debugLog($"SetCameraCutsceneHook({unknownPtr:X}) @ {frameTick}");
+ debugLog($"SetCameraCutsceneHook(0x{unknownPtr:X}) @ {frameTick}");
#endif
setCameraCutsceneHook!.Original(unknownPtr);
@@ -2034,7 +2157,7 @@ namespace NewCamera
decoupleDtFromGameTime = true;
if (forceOffMotionBlurOverride == 0)
{
- forceOffMotionBlurOverride = tuningTool.AddOverride("Shutter Speed", new Vector4(0.0f), 0);
+ forceOffMotionBlurOverride = TuningToolInterop.AddOverride("Shutter Speed", new Vector4(0.0f), 0);
}
}
else
@@ -2042,7 +2165,7 @@ namespace NewCamera
decoupleDtFromGameTime = false;
if (forceOffMotionBlurOverride != 0)
{
- tuningTool.RemoveOverride(forceOffMotionBlurOverride);
+ TuningToolInterop.RemoveOverride(forceOffMotionBlurOverride);
forceOffMotionBlurOverride = 0;
}
}
@@ -2052,7 +2175,7 @@ namespace NewCamera
private bool playerInMenu()
{
// This doesn't align with in-game mouse controls. This can be observed when closing the pause
- // menu and there is a brief moment where the camera moves -> freezes again -> then starts normally.
+ // menu where there is a brief moment the camera moves -> freezes again -> then starts normally.
return !freeCameraNoMenu && MemoryUtil.GetRef<byte>(Gui.SingletonInstance.Instance + 0x147A8) == 0x1;
}
@@ -2072,7 +2195,7 @@ namespace NewCamera
}
#if HOOK_ORDER_ASSERTS
- debugLog($"WritePadInputHook({unknownPtr:X}, {unknownPtr2:X}, {unknownPtr3:X}) @ {frameTick}");
+ debugLog($"WritePadInputHook(0x{unknownPtr:X}, 0x{unknownPtr2:X}, 0x{unknownPtr3:X}) @ {frameTick}");
#endif
Button b1 = 0u, b2 = 0u;
@@ -2241,7 +2364,7 @@ namespace NewCamera
if (orbitPlayer)
{
- if (plusRight != 0.0f && !playerMovementLocked)
+ if (plusRight != 0.0f && !playerMovementLocked && !orbitIgnoreCamera)
{
int Lx = (int)(Int16.MaxValue * Math.Clamp(plusRight, -1.0f, 1.0f));
MemoryUtil.GetRef<int>(sMhController.Instance + 0x1B8) = Lx;
@@ -2286,7 +2409,7 @@ namespace NewCamera
{
if (buttonWasPressed(Button.Down))
{
- Player? player = Player.MainPlayer;
+ Player? player = getPlayer();
if (player != null)
{
// Y - 150 to approximately align the players head with the camera.
@@ -2309,12 +2432,12 @@ namespace NewCamera
{
if (disableNearDofOverride != 0)
{
- tuningTool.RemoveOverride(disableNearDofOverride);
+ TuningToolInterop.RemoveOverride(disableNearDofOverride);
disableNearDofOverride = 0;
}
else
{
- disableNearDofOverride = tuningTool.AddOverride("Near Enable", new Vector4(), 0);
+ disableNearDofOverride = TuningToolInterop.AddOverride("Near Enable", new Vector4(), 0);
}
}
}
@@ -2344,11 +2467,11 @@ namespace NewCamera
}
if (!unlockInputForMenu && buttonWasPressed(Button.Triangle))
{
- Player? player = Player.MainPlayer;
+ Player? player = getPlayer();
if (player != null)
{
nint baseAddr = MemoryUtil.Read<nint>(0x1451C4640);
- // MonsterHunterWorld.exe+1ADA26A - 48 8B 83 18400100 - mov rax,[rbx+00014018]
+ // MonsterHunterWorld.exe+1ADA26A - mov rax,[rbx+00014018]
nint gesturesAddr = MemoryUtil.Read<nint>(baseAddr + 0x14018);
if (buttonWasDown(Button.Share)) // MonsterHunterWorld.exe+1EC8000
{
@@ -2405,11 +2528,11 @@ namespace NewCamera
}
#if HOOK_ORDER_ASSERTS
- debugLog($"CollisionCheckHook({unknownPtr:X}, {unknownPtr2:X}) @ {frameTick}");
+ debugLog($"CollisionCheckHook(0x{unknownPtr:X}, 0x{unknownPtr2:X}) @ {frameTick}");
#endif
Player? player = null;
- if (enableCrawl && (player = Player.MainPlayer) != null)
+ if (enableCrawl && (player = getPlayer()) != null)
{
nint controlsAddr = MemoryUtil.Read<nint>(player.Instance + 0x12608);
bool combatControls = false;
@@ -2441,7 +2564,7 @@ namespace NewCamera
}
#if HOOK_ORDER_ASSERTS
- debugLog($"SetZoneStateHook({player:X}, {flags:X}) @ {frameTick}");
+ debugLog($"SetZoneStateHook(0x{player:X}, 0x{flags:X}) @ {frameTick}");
#endif
nint zoneStateAddr = MemoryUtil.Read<nint>(0x1451C42B8);
@@ -2492,18 +2615,14 @@ namespace NewCamera
return;
}
- Player? player = Player.MainPlayer;
- if (player == null)
- {
- player = getPlayerFromSaveSlot();
- }
+ Player? player = getPlayerWithFallback();
if (player != null && entity == player && playerOpacityOverride != 1.0f)
{
MemoryUtil.GetRef<float>(player.Instance + 0x78E0) = playerOpacityOverride;
}
}
- private string parsePartName(string fullString)
+ private static string extractPartName(string fullString)
{
string partName = "";
if (fullString.StartsWith("pl\\f_equip"))
@@ -2512,11 +2631,11 @@ namespace NewCamera
}
else if (fullString.StartsWith("pl\\hair"))
{
- partName = fullString.Split('\\')[1];
+ partName = fullString.Split('\\')[2];
}
else if (fullString.StartsWith("pl\\f_face"))
{
- partName = fullString.Split('\\')[2];
+ partName = fullString.Split('\\')[4].Substring(2);
}
else if (fullString.StartsWith("wp\\slg"))
{
@@ -2535,48 +2654,29 @@ namespace NewCamera
private void collectArmorParts(nint baseAddr, nint addr)
{
- string partName = parsePartName(Marshal.PtrToStringAnsi(addr + 0xC)!);
- if (partName == "body")
+ int part;
+ string partName = extractPartName(Marshal.PtrToStringAnsi(addr + 0xC)!);
+ if (partName == "body") part = Armor.Body;
+ else if (partName == "helm") part = Armor.Helmet;
+ else if (partName == "arm") part = Armor.Arm;
+ else if (partName == "wst") part = Armor.Waist;
+ else if (partName == "leg") part = Armor.Leg;
+ else if (partName == "face000") part = Armor.Face;
+ else if (partName == "face000_eyelens") part = Armor.EyeLens;
+ else if (partName.StartsWith("hair")) part = Armor.Hair;
+ else return;
+ playerArmor[part] = baseAddr;
+
+ if (part == Armor.Body)
{
- playerArmor[Armor.Body] = baseAddr;
chestBone1 = 0x0;
chestBone2 = 0x0;
}
- else if (partName == "helm")
- {
- playerArmor[Armor.Helmet] = baseAddr;
- }
- else if (partName == "arm")
- {
- playerArmor[Armor.Arm] = baseAddr;
- }
- else if (partName == "wst")
- {
- playerArmor[Armor.Waist] = baseAddr;
- }
- else if (partName == "leg")
- {
- playerArmor[Armor.Leg] = baseAddr;
- }
- else if (partName == "face000")
- {
- playerArmor[Armor.Face] = baseAddr;
- }
int jointCount = MemoryUtil.Read<int>(baseAddr + 0x4A0);
nint jointAddr = MemoryUtil.Read<nint>(baseAddr + 0x4A8);
for (int i = 0; i < jointCount; i++)
{
- if (partName == "body")
- {
- bodyJoints.Add(jointAddr);
- }
- /*
- else if (partName == "face000")
- {
- faceJoints.Add(jointAddr);
- }
- */
nint childAddr = MemoryUtil.Read<nint>(jointAddr + 0x8);
if (childAddr != 0x0 && MemoryUtil.Read<nint>(childAddr) == 0x142F21A90)
{
@@ -2584,7 +2684,14 @@ namespace NewCamera
if (childAddr != 0x0)
{
nint childVtable = MemoryUtil.Read<nint>(childAddr);
- if (childVtable == 0x143524BD8)
+ if (childVtable == 0x1435195B8) // Jiggle Bone Container.
+ {
+ if (part == Armor.Body)
+ {
+ ignoredJoints.Add(jointAddr);
+ }
+ }
+ else if (childVtable == 0x143524BD8)
{
childAddr = MemoryUtil.Read<nint>(childAddr + 0x188);
if (childAddr != 0x0 && MemoryUtil.Read<nint>(childAddr) == 0x143519530)
@@ -2595,8 +2702,9 @@ namespace NewCamera
if (!jiggleBones.Contains(jiggleData))
{
jiggleBones.Add(jiggleData);
- if (partName == "body")
+ if (part == Armor.Body)
{
+ // Guess that chest bones are the last jiggle bones.
if (chestBone1 == 0x0)
{
chestBone1 = jiggleData;
@@ -2617,201 +2725,652 @@ namespace NewCamera
}
}
}
+ if (part == Armor.Body)
+ {
+ ignoredJoints.Add(jointAddr);
+ }
}
else if (childVtable == 0x143249170)
{
childAddr = MemoryUtil.Read<nint>(childAddr + 0x188);
if (childAddr != 0x0 && MemoryUtil.Read<nint>(childAddr) == 0x1432492F0)
{
- if (!ikJoints.Contains(jointAddr))
- {
- ikJoints.Add(jointAddr);
- }
+ ikJoints.Add(jointAddr);
}
}
}
}
+ if (part == Armor.Body)
+ {
+ bodyJoints.Add(jointAddr);
+ }
+ else if (part == Armor.Face)
+ {
+ faceJoints.Add(jointAddr);
+ }
jointAddr += 0xC0;
}
- if (partName == "body")
+ if (part == Armor.Body)
{
- bodyJoints.Sort(delegate(nint x, nint y)
+ int extraBonesOffset = 0;
+ int skipExtraBones = 0;
+ for (int i = 0; i < bodyJoints.Count; i++)
{
- return MemoryUtil.Read<sbyte>(x + 0x14) - MemoryUtil.Read<sbyte>(y + 0x14);
- });
- for (int i = jointOffsets.Count - 1; i >= 0; i--)
+ jointAddr = bodyJoints[i];
+ if (ignoredJoints.Contains(jointAddr))
+ {
+ extraBonesOffset++;
+ continue;
+ }
+ byte treeLevel = MemoryUtil.Read<byte>(jointAddr + 0x14);
+ if (skipExtraBones > 0)
+ {
+ if (treeLevel != skipExtraBones)
+ {
+ extraBonesOffset++;
+ continue;
+ }
+ skipExtraBones = 0;
+ }
+ int adjustedIndex = i - extraBonesOffset;
+ if (adjustedIndex >= playerJoints.Length)
+ {
+ break;
+ }
+ // Guess that all extra joints come between Unknown2 and LeftHip and
+ // that none of them are at level 2 like LeftHip.
+ if (adjustedIndex == Joint.Unknown2)
+ {
+ skipExtraBones = 2;
+ }
+ playerJoints[i - extraBonesOffset] = jointAddr;
+ }
+ foreach (nint joint in jointOffsets.Where(e => !bodyJoints.Contains(e.Key)).Select(e => e.Key).ToList())
+ {
+ jointOffsets.Remove(joint);
+ }
+#if QUARANTINED_FEATURES
+ foreach (nint joint in ikOffsets.Where(e => !bodyJoints.Contains(e.Key)).Select(e => e.Key).ToList())
+ {
+ ikOffsets.Remove(joint);
+ }
+#endif
+ }
+ }
+
+ private void drawJoint(nint jointAddr)
+ {
+ if (jointAddr == 0x0) return;
+ ImGui.PushID(jointAddr);
+ ImGui.DragFloat4("Position", ref MemoryUtil.GetRef<Vector4>(jointAddr + 0x50), 0.005f);
+ bool ikJoint = false;
+#if QUARANTINED_FEATURES
+ if (ikJoints.Contains(jointAddr))
+ {
+ if (!ikOffsets.ContainsKey(jointAddr))
{
- jointAddr = jointOffsets.Keys.ElementAt(i);
- if (!bodyJoints.Contains(jointAddr))
+ if (ImGui.Button("Add IK Offset"))
{
- jointOffsets.Remove(jointAddr);
+ ikOffsets.Add(jointAddr, new List<Vector3>()
+ {
+ new Vector3()
+ });
}
}
- for (int i = ikOffsets.Count - 1; i >= 0; i--)
+ else
{
- jointAddr = ikOffsets.Keys.ElementAt(i);
- if (!bodyJoints.Contains(jointAddr))
+ bool doRemove = ImGui.Button("X");
+ ImGui.SameLine();
+ Vector3 v = ikOffsets[jointAddr][0];
+ if (ImGui.DragFloat3($"Offset", ref v, 0.025f))
{
- ikOffsets.Remove(jointAddr);
+ ikOffsets[jointAddr][0] = v;
}
+ if (doRemove) ikOffsets.Remove(jointAddr);
+ }
+ //ikJoint = true;
+ }
+#endif
+ ImGui.DragFloat4("Rotation", ref MemoryUtil.GetRef<Vector4>(jointAddr + 0x70), 0.005f);
+ if (ikJoint)
+ {
+ ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f);
+ }
+ bool hasOffset = jointOffsets.ContainsKey(jointAddr);
+ if (!hasOffset)
+ {
+ if (ImGui.Button("Add Offset"))
+ {
+ jointOffsets.Add(jointAddr, new List<Vector3>()
+ {
+ new Vector3()
+ });
+ }
+ if (ikJoint)
+ {
+ ImGui.SameLine();
}
}
+ if (ikJoint)
+ {
+ ImGui.Text("(Enforced by Inverse Kinematics)");
+ ImGui.PopStyleVar();
+ }
+ if (hasOffset)
+ {
+ bool doRemove = ImGui.Button("X");
+ ImGui.SameLine();
+ if (ImGui.Button("Reset"))
+ {
+ jointOffsets[jointAddr][0] = new Vector3();
+ }
+ ImGui.SameLine();
+ Vector3 v = jointOffsets[jointAddr][0];
+ if (ImGui.DragFloat3($"Offset", ref v, 0.005f))
+ {
+ jointOffsets[jointAddr][0] = v;
+ }
+ if (doRemove) jointOffsets.Remove(jointAddr);
+ }
+ ImGui.PopID();
}
- private void drawArmorParts(nint armorAddr)
+ private void drawJointLeaf(ref List<nint> joints, int i)
{
- ImGui.PushID(armorAddr);
- nint partsAddr = MemoryUtil.Read<nint>(armorAddr + 0x2A0);
- string fullString = Marshal.PtrToStringAnsi(partsAddr + 0xC)!;
- string partName = parsePartName(fullString);
- ImGui.Text($"{partName} ({partsAddr:X}, {fullString} @ {armorAddr:X}):");
- int numParts = MemoryUtil.Read<int>(partsAddr + 0x54C);
- nint baseInner = MemoryUtil.Read<nint>(partsAddr + 0xC8);
- nint offset = MemoryUtil.Read<nint>(partsAddr + 0x408);
- bool toggleAll = ImGui.Button("Toggle All");
- for (int i = 0; i < numParts; i++)
+ if (i >= joints.Count) return;
+ nint jointAddr = joints[i];
+ byte treeLevel = MemoryUtil.Read<byte>(jointAddr + 0x14);
+ ImGui.PushID(jointAddr);
+ if (ImGui.CollapsingHeader($"Joint #{i} (0x{jointAddr:X}, tree_level: 0x{treeLevel:X})"))
{
- nint baseOffset = offset + (i * 0x4) + (numParts * 0x4);
- ref byte bIndex = ref MemoryUtil.GetRef<byte>(baseOffset);
- baseOffset = baseInner + ((bIndex + (bIndex * 4)) << 4);
- ref byte bEnabled = ref MemoryUtil.GetRef<byte>(baseOffset);
- ref byte bSub = ref MemoryUtil.GetRef<byte>(baseOffset + 0xB);
- if (toggleAll)
+ drawJoint(jointAddr);
+ }
+ ImGui.PopID();
+ drawJointLeaf(ref joints, i + 1);
+ }
+
+ private void drawJoints(float width)
+ {
+ ImGui.PushItemWidth(width * 0.75f);
+ ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags.Framed;
+ if (ImGui.TreeNodeEx("Root", flags))
+ {
+ drawJoint(playerJoints[Joint.Root2]);
+ ImGui.TreePop();
+ }
+ ImGui.PushID("Neck");
+ if (ImGui.TreeNodeEx("Neck", flags))
+ {
+ if (ImGui.TreeNodeEx("Upper", flags))
{
- (bEnabled, bSub) = (bSub, bEnabled);
+ drawJoint(playerJoints[Joint.UpperNeck]);
+ ImGui.TreePop();
}
- bool isVisible = bEnabled != 0x0;
- if (ImGui.Checkbox($"##Part #{i}", ref isVisible))
+ if (ImGui.TreeNodeEx("Lower", flags))
+ {
+ drawJoint(playerJoints[Joint.LowerNeck]);
+ ImGui.TreePop();
+ }
+ ImGui.TreePop();
+ }
+ ImGui.PopID(); // Neck.
+ ImGui.PushID("Back");
+ if (ImGui.TreeNodeEx("Back", flags))
+ {
+ if (ImGui.TreeNodeEx("Upper", flags))
+ {
+ drawJoint(playerJoints[Joint.UpperBack]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Lower", flags))
+ {
+ drawJoint(playerJoints[Joint.LowerBack]);
+ ImGui.TreePop();
+ }
+ ImGui.TreePop();
+ }
+ ImGui.PopID(); // Back.
+ ImGui.PushID("Right Arm");
+ if (ImGui.TreeNodeEx("Right Arm", flags))
+ {
+ if (ImGui.TreeNodeEx("Collarbone", flags))
+ {
+ drawJoint(playerJoints[Joint.RightCollarbone]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Shoulder", flags))
+ {
+ drawJoint(playerJoints[Joint.RightShoulder]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Elbow", flags))
+ {
+ drawJoint(playerJoints[Joint.RightElbow]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Wrist", flags))
+ {
+ drawJoint(playerJoints[Joint.RightWrist]);
+ ImGui.TreePop();
+ }
+ ImGui.TreePop();
+ }
+ ImGui.PopID(); // Right Arm.
+ ImGui.PushID("Right Hand");
+ if (ImGui.TreeNodeEx("Right Hand", flags))
+ {
+ ImGui.PushID("Thumb");
+ if (ImGui.TreeNodeEx("Thumb", flags))
+ {
+ if (ImGui.TreeNodeEx("Base", flags))
+ {
+ drawJoint(playerJoints[Joint.RightThumbLow]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Middle", flags))
+ {
+ drawJoint(playerJoints[Joint.RightThumbMid]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Tip", flags))
+ {
+ drawJoint(playerJoints[Joint.RightThumbHigh]);
+ ImGui.TreePop();
+ }
+ ImGui.TreePop();
+ }
+ ImGui.PopID();
+ ImGui.PushID("Index");
+ if (ImGui.TreeNodeEx("Index", flags))
+ {
+ if (ImGui.TreeNodeEx("Base", flags))
+ {
+ drawJoint(playerJoints[Joint.RightIndexLow]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Middle", flags))
+ {
+ drawJoint(playerJoints[Joint.RightIndexMid]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Tip", flags))
+ {
+ drawJoint(playerJoints[Joint.RightIndexHigh]);
+ ImGui.TreePop();
+ }
+ ImGui.TreePop();
+ }
+ ImGui.PopID();
+ ImGui.PushID("Middle");
+ if (ImGui.TreeNodeEx("Middle", flags))
{
- (bEnabled, bSub) = (bSub, bEnabled);
+ if (ImGui.TreeNodeEx("Base", flags))
+ {
+ drawJoint(playerJoints[Joint.RightMiddleLow]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Middle", flags))
+ {
+ drawJoint(playerJoints[Joint.RightMiddleMid]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Tip", flags))
+ {
+ drawJoint(playerJoints[Joint.RightMiddleHigh]);
+ ImGui.TreePop();
+ }
+ ImGui.TreePop();
+ }
+ ImGui.PopID();
+ ImGui.PushID("Ring");
+ if (ImGui.TreeNodeEx("Ring", flags))
+ {
+ if (ImGui.TreeNodeEx("Base", flags))
+ {
+ drawJoint(playerJoints[Joint.RightRingLow]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Middle", flags))
+ {
+ drawJoint(playerJoints[Joint.RightRingMid]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Tip", flags))
+ {
+ drawJoint(playerJoints[Joint.RightRingHigh]);
+ ImGui.TreePop();
+ }
+ ImGui.TreePop();
+ }
+ ImGui.PopID();
+ ImGui.PushID("Pinky");
+ if (ImGui.TreeNodeEx("Pinky", flags))
+ {
+ if (ImGui.TreeNodeEx("Base", flags))
+ {
+ drawJoint(playerJoints[Joint.RightPinkyLow]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Middle", flags))
+ {
+ drawJoint(playerJoints[Joint.RightPinkyMid]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Tip", flags))
+ {
+ drawJoint(playerJoints[Joint.RightPinkyHigh]);
+ ImGui.TreePop();
+ }
+ ImGui.TreePop();
+ }
+ ImGui.PopID();
+ if (ImGui.TreeNodeEx("Palm", flags))
+ {
+ drawJoint(playerJoints[Joint.RightPalm]);
+ ImGui.TreePop();
}
if (ImGui.BeginItemTooltip())
{
- ImGui.Text($"Part #{i}");
+ ImGui.Text("Outer Palm/Pinky+Ring");
ImGui.EndTooltip();
}
- if (i % 10 != 9 && i != numParts - 1)
+ ImGui.TreePop();
+ }
+ ImGui.PopID(); // Right Hand.
+ ImGui.PushID("Right Leg");
+ if (ImGui.TreeNodeEx("Right Leg", flags))
+ {
+ if (ImGui.TreeNodeEx("Hip", flags))
{
- ImGui.SameLine();
+ drawJoint(playerJoints[Joint.RightHip]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Knee", flags))
+ {
+ drawJoint(playerJoints[Joint.RightKnee]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Ankle", flags))
+ {
+ drawJoint(playerJoints[Joint.RightAnkle]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Toes", flags))
+ {
+ drawJoint(playerJoints[Joint.RightToes]);
+ ImGui.TreePop();
}
+ ImGui.TreePop();
}
- if (ImGui.CollapsingHeader("Joints"))
+ ImGui.PopID(); // Right Leg.
+ ImGui.PushID("Left Arm");
+ if (ImGui.TreeNodeEx("Left Arm", flags))
{
- if (partName == "body")
+ if (ImGui.TreeNodeEx("Collarbone", flags))
{
- ImGui.Checkbox("Attach to Chest", ref attachToChest);
- if (ImGui.BeginItemTooltip())
+ drawJoint(playerJoints[Joint.LeftCollarbone]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Shoulder", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftShoulder]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Elbow", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftElbow]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Wrist", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftWrist]);
+ ImGui.TreePop();
+ }
+ ImGui.TreePop();
+ }
+ ImGui.PopID(); // Left Arm.
+ ImGui.PushID("Left Hand");
+ if (ImGui.TreeNodeEx("Left Hand", flags))
+ {
+ ImGui.PushID("Thumb");
+ if (ImGui.TreeNodeEx("Thumb", flags))
+ {
+ if (ImGui.TreeNodeEx("Base", flags))
{
- ImGui.Text("While in Free Camera, hold LT + RT and move your joysticks (armor has to have jiggle physics).");
- ImGui.EndTooltip();
+ drawJoint(playerJoints[Joint.LeftThumbLow]);
+ ImGui.TreePop();
}
- ImGui.Checkbox("Swap Sides", ref swapChestSides);
- ImGui.DragFloat("Scale", ref chestMoveScale);
- if (ImGui.CollapsingHeader("Jiggle Bones"))
+ if (ImGui.TreeNodeEx("Middle", flags))
{
- for (int i = 0; i < jiggleBones.Count; i++)
- {
- nint jiggleData = jiggleBones[i];
- if (ImGui.CollapsingHeader($"Jiggle Bones #{i} ({jiggleData:X})"))
- {
- ImGui.DragFloat3("Position", ref MemoryUtil.GetRef<Vector3>(jiggleData + 0xD0));
- }
- }
- foreach (nint jiggleData in jiggleBones)
- {
-
- }
+ drawJoint(playerJoints[Joint.LeftThumbMid]);
+ ImGui.TreePop();
}
- ImGui.Separator();
- for (int i = 0; i < bodyJoints.Count; i++)
+ if (ImGui.TreeNodeEx("Tip", flags))
{
- nint jointAddr = bodyJoints[i];
- ImGui.PushID(jointAddr);
- byte jointGroup = MemoryUtil.Read<byte>(jointAddr + 0x14);
- if (ImGui.CollapsingHeader($"Joint #{i} ({jointAddr:X}, {jointGroup:X})"))
- {
- ImGui.DragFloat4("Rotation", ref MemoryUtil.GetRef<Vector4>(jointAddr + 0x70), 0.005f);
- if (partName != "face000")
- {
- if (!jointOffsets.ContainsKey(jointAddr))
- {
- if (ImGui.Button("Add Offset"))
- {
- jointOffsets.Add(jointAddr, new List<Vector3>()
- {
- new Vector3()
- });
- }
- }
- else
- {
- bool doRemove = ImGui.Button("X");
- ImGui.SameLine();
- Vector3 v = jointOffsets[jointAddr][0];
- if (ImGui.DragFloat3($"Rotation Offset", ref v, 0.005f))
- {
- jointOffsets[jointAddr][0] = v;
- }
- if (doRemove) jointOffsets.Remove(jointAddr);
- }
- if (ikJoints.Contains(jointAddr))
- {
- if (!ikOffsets.ContainsKey(jointAddr))
- {
- if (ImGui.Button("Add IK Offset"))
- {
- ikOffsets.Add(jointAddr, new List<Vector3>()
- {
- new Vector3()
- });
- }
- }
- else
- {
- bool doRemove = ImGui.Button("X");
- ImGui.SameLine();
- Vector3 v = ikOffsets[jointAddr][0];
- if (ImGui.DragFloat3($"Position Offset", ref v, 0.025f))
- {
- ikOffsets[jointAddr][0] = v;
- }
- if (doRemove) ikOffsets.Remove(jointAddr);
- }
- }
- }
- }
- ImGui.PopID();
+ drawJoint(playerJoints[Joint.LeftThumbHigh]);
+ ImGui.TreePop();
}
+ ImGui.TreePop();
}
- /*
- else if (partName == "face000")
+ ImGui.PopID();
+ ImGui.PushID("Index");
+ if (ImGui.TreeNodeEx("Index", flags))
{
- if (ImGui.Checkbox("Override Pose", ref overrideFacePose))
+ if (ImGui.TreeNodeEx("Base", flags))
{
- if (overrideFacePose)
- {
- noopFacePose.Enable();
- noopFacePoseUpdate.Enable();
- }
- else
- {
- noopFacePose.Disable();
- noopFacePoseUpdate.Disable();
- }
+ drawJoint(playerJoints[Joint.LeftIndexLow]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Middle", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftIndexMid]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Tip", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftIndexHigh]);
+ ImGui.TreePop();
+ }
+ ImGui.TreePop();
+ }
+ ImGui.PopID();
+ ImGui.PushID("Middle");
+ if (ImGui.TreeNodeEx("Middle", flags))
+ {
+ if (ImGui.TreeNodeEx("Base", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftMiddleLow]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Middle", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftMiddleMid]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Tip", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftMiddleHigh]);
+ ImGui.TreePop();
+ }
+ ImGui.TreePop();
+ }
+ ImGui.PopID();
+ ImGui.PushID("Ring");
+ if (ImGui.TreeNodeEx("Ring", flags))
+ {
+ if (ImGui.TreeNodeEx("Base", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftRingLow]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Middle", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftRingMid]);
+ ImGui.TreePop();
}
- for (int i = 0; i < faceJoints.Count; i++)
+ if (ImGui.TreeNodeEx("Tip", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftRingHigh]);
+ ImGui.TreePop();
+ }
+ ImGui.TreePop();
+ }
+ ImGui.PopID();
+ ImGui.PushID("Pinky");
+ if (ImGui.TreeNodeEx("Pinky", flags))
+ {
+ if (ImGui.TreeNodeEx("Base", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftPinkyLow]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Middle", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftPinkyMid]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Tip", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftPinkyHigh]);
+ ImGui.TreePop();
+ }
+ ImGui.TreePop();
+ }
+ ImGui.PopID();
+ if (ImGui.TreeNodeEx("Palm", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftPalm]);
+ ImGui.TreePop();
+ }
+ if (ImGui.BeginItemTooltip())
+ {
+ ImGui.Text("Outer Palm/Pinky+Ring");
+ ImGui.EndTooltip();
+ }
+ ImGui.TreePop();
+ }
+ ImGui.PopID(); // Left Hand.
+ ImGui.PushID("Left Leg");
+ if (ImGui.TreeNodeEx("Left Leg", flags))
+ {
+ if (ImGui.TreeNodeEx("Hip", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftHip]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Knee", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftKnee]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Ankle", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftAnkle]);
+ ImGui.TreePop();
+ }
+ if (ImGui.TreeNodeEx("Toes", flags))
+ {
+ drawJoint(playerJoints[Joint.LeftToes]);
+ ImGui.TreePop();
+ }
+ ImGui.TreePop();
+ }
+ ImGui.PopID(); // Left Leg.
+ ImGui.Separator();
+ ImGui.Checkbox("Attach to Chest", ref attachToChest);
+ if (ImGui.BeginItemTooltip())
+ {
+ ImGui.Text("While in Free Camera, hold LT + RT and move your joysticks (armor has to have jiggle physics).");
+ ImGui.EndTooltip();
+ }
+ if (!attachToChest)
+ {
+ ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f);
+ }
+ ImGui.SameLine();
+ ImGui.Checkbox("Swap Sides", ref swapChestSides);
+ ImGui.SetNextItemWidth(width * 0.35f);
+ ImGui.DragFloat("Scale", ref chestMoveScale, 0.001f);
+ if (!attachToChest)
+ {
+ ImGui.PopStyleVar();
+ }
+ if (ImGui.CollapsingHeader("Jiggle Bones"))
+ {
+ for (int i = 0; i < jiggleBones.Count; i++)
+ {
+ nint jiggleData = jiggleBones[i];
+ ImGui.PushID(jiggleData);
+ if (ImGui.CollapsingHeader($"Jiggle Bones #{i} (0x{jiggleData:X})"))
{
- nint jointAddr = faceJoints[i];
- ImGui.PushID(jointAddr);
- if (ImGui.CollapsingHeader($"Joint #{i} ({jointAddr:X})"))
+ ImGui.DragFloat3("Position", ref MemoryUtil.GetRef<Vector3>(jiggleData + 0xD0));
+ if (ImGui.BeginItemTooltip())
{
- ImGui.DragFloat4("Position", ref MemoryUtil.GetRef<Vector4>(jointAddr + 0x50), 0.005f);
- ImGui.DragFloat4("Rotation", ref MemoryUtil.GetRef<Vector4>(jointAddr + 0x70), 0.005f);
+ ImGui.Text("Drag this position around to influence the bone.");
+ ImGui.EndTooltip();
}
- ImGui.PopID();
}
+ ImGui.PopID();
+ }
+ }
+ ImGui.Separator();
+ if (ImGui.CollapsingHeader("All Joints"))
+ {
+ drawJointLeaf(ref bodyJoints, 0);
+ }
+ ImGui.PopItemWidth();
+ }
+
+ private void drawArmorParts(nint armorAddr, nint partsAddr = 0x0)
+ {
+ if (partsAddr == 0x0)
+ {
+ if (armorAddr == 0x0 || (partsAddr = MemoryUtil.Read<nint>(armorAddr + 0x2A0)) == 0x0)
+ {
+ return;
+ }
+ }
+ ImGui.PushID(partsAddr);
+ string fullString = Marshal.PtrToStringAnsi(partsAddr + 0xC)!;
+ if (armorAddr != 0x0)
+ {
+ string partName = extractPartName(fullString);
+ ImGui.Text($"{partName} (0x{armorAddr:X}, {fullString} @ 0x{partsAddr:X}):");
+ }
+ else
+ {
+ ImGui.Text($"{fullString} @ 0x{partsAddr:X}:");
+ }
+ const int partsPerLine = 10;
+ nint baseInner = MemoryUtil.Read<nint>(partsAddr + 0xC8);
+ nint baseOffset = MemoryUtil.Read<nint>(partsAddr + 0x408);
+ int numParts = MemoryUtil.Read<int>(partsAddr + 0x54C);
+ bool toggleAll = ImGui.Button("Toggle All");
+ for (int i = 0; i < numParts; i++)
+ {
+ nint offset = baseOffset + (i * 0x4) + (numParts * 0x4);
+ ref byte bIndex = ref MemoryUtil.GetRef<byte>(offset);
+ offset = baseInner + ((bIndex + (bIndex * 4)) << 4);
+ ref byte bVisible = ref MemoryUtil.GetRef<byte>(offset);
+ ref byte bSub = ref MemoryUtil.GetRef<byte>(offset + 0xB);
+ if (toggleAll)
+ {
+ (bVisible, bSub) = (bSub, bVisible);
+ }
+ bool isVisible = bVisible != 0x0;
+ if (ImGui.Checkbox($"##Part #{i}", ref isVisible))
+ {
+ (bVisible, bSub) = (bSub, bVisible);
+ }
+ if (ImGui.BeginItemTooltip())
+ {
+ ImGui.Text($"Part #{i}");
+ ImGui.EndTooltip();
+ }
+ if (i != numParts - 1 && i % partsPerLine != partsPerLine - 1)
+ {
+ ImGui.SameLine();
}
- */
}
ImGui.PopID();
}
@@ -2819,15 +3378,19 @@ namespace NewCamera
private void dropArmorState()
{
Array.Clear(playerArmor, 0, playerArmor.Length);
+ Array.Clear(playerJoints, 0, playerJoints.Length);
bodyJoints.Clear();
- //faceJoints.Clear();
+ ignoredJoints.Clear();
jiggleBones.Clear();
+ faceJoints.Clear();
}
private void dropJointOffsets()
{
jointOffsets.Clear();
+#if QUARANTINED_FEATURES
ikOffsets.Clear();
+#endif
}
private bool collectArmorAndJoints(Player player)
@@ -2858,17 +3421,29 @@ namespace NewCamera
nint childAddr = MemoryUtil.Read<nint>(armorAddr + 0x548);
if (childAddr != 0x0)
{
- if (MemoryUtil.Read<nint>(childAddr) == 0x143451520)
+ if (MemoryUtil.Read<nint>(childAddr) == 0x143451520) // Face.
{
nint ownerAddr = MemoryUtil.Read<nint>(childAddr + 0x998);
- if (playerArmor[Armor.Face] != 0x0 || ownerAddr != player.Instance)
+ if (ownerAddr != player.Instance)
{
continue;
}
- partsAddr = MemoryUtil.Read<nint>(childAddr + 0x2A0);
- if (partsAddr != 0x0)
+ if (playerArmor[Armor.Face] == 0x0)
{
- collectArmorParts(childAddr, partsAddr);
+ partsAddr = MemoryUtil.Read<nint>(childAddr + 0x2A0);
+ if (partsAddr != 0x0)
+ {
+ collectArmorParts(childAddr, partsAddr);
+ }
+ childAddr = MemoryUtil.Read<nint>(childAddr + 0x9C8);
+ if (childAddr != 0x0 && MemoryUtil.Read<nint>(childAddr) == 0x143505E98) // Eye lens.
+ {
+ partsAddr = MemoryUtil.Read<nint>(childAddr + 0x2A0);
+ if (partsAddr != 0x0)
+ {
+ collectArmorParts(childAddr, partsAddr);
+ }
+ }
}
}
else if (childAddr != player.Instance)
@@ -2886,36 +3461,38 @@ namespace NewCamera
return true;
}
- private void UpdateJointsHook(nint obj, nint unknownPtr, int unknownInt, int unknownInt2)
+ private void refreshArmorState(Player player)
{
- if (jointOffsets.Count > 0 && !didJointOffset)
+ dropArmorState();
+ if (!collectArmorAndJoints(player))
{
- Player? player = Player.MainPlayer;
- if (player == null)
- {
- player = getPlayerFromSaveSlot();
- }
+ dropJointOffsets();
+ }
+ }
+
+ private void UpdateJointsHook(nint obj)
+ {
+ if (!disableMod && !didJointOffset && (jointOffsets.Count > 0 || hideKnife || (enableFreeCamera && orbitPlayer && orbitJoint >= 0)))
+ {
+ Player? player = getPlayerWithFallback();
if (player != null && obj == player.Instance)
{
- dropArmorState();
- if (!collectArmorAndJoints(player))
+ refreshArmorState(player);
+ foreach ((nint addr, List<Vector3> offsets) in jointOffsets)
{
- dropJointOffsets();
+ MemoryUtil.GetRef<Quaternion>(addr + 0x70) *= Quaternion.CreateFromYawPitchRoll(offsets[0].X, offsets[0].Y, offsets[0].Z);
}
+ didJointOffset = true;
if (playerArmor[Armor.Waist] != 0x0)
{
MemoryUtil.GetRef<byte>(playerArmor[Armor.Waist] + 0x2D0) = hideKnife ? (byte)0xFD : (byte)0xFF;
}
- foreach ((nint addr, List<Vector3> offsets) in jointOffsets)
- {
- MemoryUtil.GetRef<Quaternion>(addr + 0x70) *= Quaternion.CreateFromYawPitchRoll(offsets[0].X, offsets[0].Y, offsets[0].Z);
- }
- didJointOffset = true;
}
}
- updateJointsHook!.Original(obj, unknownPtr, unknownInt, unknownInt2);
+ updateJointsHook!.Original(obj);
}
+#if QUARANTINED_FEATURES
private void UpdateIKHook(nint superOfChild, nint joint, nint obj)
{
if (ikOffsets.ContainsKey(joint))
@@ -2925,6 +3502,7 @@ namespace NewCamera
}
updateIKHook!.Original(superOfChild, joint, obj);
}
+#endif
/*
private void ChangeEquipmentHook(nint unknownPtr, int unknownInt)
@@ -2950,7 +3528,7 @@ namespace NewCamera
}
#if HOOK_ORDER_ASSERTS
- debugLog($"UnderwaterCheckHook({unknownPtr:X}) @ {frameTick}");
+ debugLog($"UnderwaterCheckHook(0x{unknownPtr:X}) @ {frameTick}");
#endif
cameraIsUnderwater = MemoryUtil.Read<byte>(unknownPtr + 0x1E83) == 0x1;
@@ -2965,7 +3543,7 @@ namespace NewCamera
}
#if HOOK_ORDER_ASSERTS
- debugLog($"CameraEffectHook({unknownPtr:X}, {unknownPtr2:X}, {unknownPtr3:X}) @ {frameTick}");
+ debugLog($"CameraEffectHook(0x{unknownPtr:X}, 0x{unknownPtr2:X}, 0x{unknownPtr3:X}) @ {frameTick}");
#endif
byte[]? underwaterValues = null;
@@ -3014,9 +3592,9 @@ namespace NewCamera
Viewport vp = CameraSystem.GetViewport(i);
if (debug)
{
- ImGui.Text($"Address: {vp.Instance:X}");
+ ImGui.Text($"Address: 0x{vp.Instance:X}");
ImGui.Text($"Visible: {vp.Visible}");
- ImGui.Text($"Region: {vp.Region.X} {vp.Region.Y} {vp.Region.Width} {vp.Region.Height}");
+ ImGui.Text($"Region: {vp.Region.Width}x{vp.Region.Height} ({vp.Region.X},{vp.Region.Y})");
}
else
{
@@ -3039,48 +3617,8 @@ namespace NewCamera
{
Camera camera = vp.Camera;
bool usedByFreeCamera = freeCamera && enableFreeCamera && camera == vCamera;
- if (debug) ImGui.Text($"Camera Pointer: {camera.Instance:X}");
- Player? player = checkPlayerChange();
- if (debug && player != null)
- {
- // MonsterHunterWorld.exe+12A9AEC - mov rcx,[rdi+00001E90]
- // MonsterHunterWorld.exe+11A9AB9 - add rcx,00001410
- // MonsterHunterWorld.exe+12A9AE0 - mov rcx,[MonsterHunterWorld.exe+5013950]
- ImGui.Text("Camera Distance");
- ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 4.0f));
- nint playerCameraAddr = MemoryUtil.Read<nint>(player.Instance + 0x14F8);
- playerCameraAddr = MemoryUtil.Read<nint>(playerCameraAddr + 0x1410 + 0x1E90);
- ref byte settingB = ref MemoryUtil.GetRef<byte>(getPlayerSettings() + 0x1403FD);
- int settingI = settingB;
- ImGui.SameLine();
- ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 4.0f));
- if (ImGui.RadioButton("Close", ref settingI, 0))
- {
- settingB = (byte)settingI;
- }
- ImGui.SameLine();
- ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 4.0f));
- if (ImGui.RadioButton("Default", ref settingI, 1))
- {
- settingB = (byte)settingI;
- }
- ImGui.SameLine();
- ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 4.0f));
- if (ImGui.RadioButton("Far", ref settingI, 2))
- {
- settingB = (byte)settingI;
- }
- nint viewParamOffset = getViewParamOffset.Invoke(playerCameraAddr + 0x1380, 0, 0xC9);
- if (viewParamOffset != 0x0)
- {
- ImGui.DragFloat3("Close", ref MemoryUtil.GetRef<Vector3>(viewParamOffset + 0x20), 0.1f);
- }
- viewParamOffset = getViewParamOffset.Invoke(playerCameraAddr + 0x1380, 0, 0xCA);
- if (viewParamOffset != 0x0)
- {
- ImGui.DragFloat3("Far", ref MemoryUtil.GetRef<Vector3>(viewParamOffset + 0x20), 0.1f);
- }
- }
+ if (debug) ImGui.Text($"Camera Pointer: 0x{camera.Instance:X}");
+
if (ImGui.DragFloat("Field of View", ref camera.FieldOfView, 0.1f))
{
if (usedByFreeCamera)
@@ -3088,7 +3626,7 @@ namespace NewCamera
cameraFov = camera.FieldOfView;
}
}
- if (camera == pCamera)
+ if (enableOffsetPerspective && camera == pCamera)
{
ImGui.Text($"Internal FOV: {previousFov}");
if (ImGui.BeginItemTooltip())
@@ -3200,12 +3738,70 @@ namespace NewCamera
camera.Fix = fix;
}
}
+ if (camera == pCamera)
+ {
+ Player? player = checkPlayerChange();
+ if (!debug && player != null)
+ {
+ ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(0.0f, 7.0f));
+ ImGui.Text("Camera Distance");
+ if (ImGui.BeginItemTooltip())
+ {
+ ImGui.Text("To save this setting, save your game.");
+ ImGui.EndTooltip();
+ }
+ ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 4.0f));
+ ref byte settingB = ref MemoryUtil.GetRef<byte>(getPlayerSettings() + 0x1403FD);
+ int settingI = settingB;
+ ImGui.SameLine();
+ ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 4.0f));
+ if (ImGui.RadioButton("Close", ref settingI, 0))
+ {
+ settingB = (byte)settingI;
+ }
+ ImGui.SameLine();
+ ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 4.0f));
+ if (ImGui.RadioButton("Default", ref settingI, 1))
+ {
+ settingB = (byte)settingI;
+ }
+ ImGui.SameLine();
+ ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 4.0f));
+ if (ImGui.RadioButton("Far", ref settingI, 2))
+ {
+ settingB = (byte)settingI;
+ }
+ // MonsterHunterWorld.exe+12A9AEC - mov rcx,[rdi+00001E90]
+ // MonsterHunterWorld.exe+11A9AB9 - add rcx,00001410
+ // MonsterHunterWorld.exe+12A9AE0 - mov rcx,[MonsterHunterWorld.exe+5013950]
+ nint playerCameraAddr = MemoryUtil.Read<nint>(player.Instance + 0x14F8);
+ if (playerCameraAddr != 0x0)
+ {
+ playerCameraAddr = MemoryUtil.Read<nint>(playerCameraAddr + 0x1410 + 0x1E90);
+ }
+ if (playerCameraAddr != 0x0)
+ {
+ ImGui.Text("Offset");
+ nint viewParamOffset = getViewParamOffset.Invoke(playerCameraAddr + 0x1380, 0, 0xC9);
+ if (viewParamOffset != 0x0)
+ {
+ ImGui.DragFloat3("Close", ref MemoryUtil.GetRef<Vector3>(viewParamOffset + 0x20), 0.1f);
+ }
+ viewParamOffset = getViewParamOffset.Invoke(playerCameraAddr + 0x1380, 0, 0xCA);
+ if (viewParamOffset != 0x0)
+ {
+ ImGui.DragFloat3("Far", ref MemoryUtil.GetRef<Vector3>(viewParamOffset + 0x20), 0.1f);
+ }
+ }
+ }
+ }
if (camera == vCamera)
{
if (!usedByFreeCamera)
{
ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true);
}
+ ImGui.Text("Angle");
// If our camera hooks aren't being run, these values won't be updated.
ImGui.DragFloat("Yaw", ref cameraYaw, 0.2f);
ImGui.DragFloat("Pitch", ref cameraPitch, 0.2f);
@@ -3219,7 +3815,7 @@ namespace NewCamera
{
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f);
}
- ImGui.Text("Offsets");
+ ImGui.Text("Move");
float offsetForward = 0.0f;
if (ImGui.DragFloat("Forward", ref offsetForward, 0.425f))
{
@@ -3270,7 +3866,7 @@ namespace NewCamera
}
if (debug)
{
- ImGui.Text($"ActionController: {actionController.Instance:X}");
+ ImGui.Text($"ActionController: 0x{actionController.Instance:X}");
ImGui.Text($" Current: {currentAction} {currentActionInfo}");
if (currentAction != null)
{
@@ -3283,16 +3879,16 @@ namespace NewCamera
AnimationLayerComponent? animationLayer = entity.AnimationLayer;
if (animationLayer != null)
{
- ImGui.Text(debug ? $"AnimationLayer: {animationLayer.Instance:X}" : "Animation:");
- ImGui.Text($" Current: {currentAnimation}");
+ 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}, Action: {(currentAction != null ? currentAction.Name : "None")}");
ImGui.SetNextItemWidth(width * 0.8f);
ImGui.SliderFloat("Frame", ref animationLayer.CurrentFrame, 0.0f, animationLayer.MaxFrame, "%.3f");
}
@@ -3302,15 +3898,14 @@ namespace NewCamera
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)
{
- lockedSpeed = animationLayer.Speed;
- animationLayer.LockSpeed((float)lockedSpeed);
+ animationLayer.LockSpeed(speed);
}
else
{
@@ -3318,14 +3913,11 @@ namespace NewCamera
}
}
ImGui.SameLine();
- ImGui.PushItemWidth(width * 0.35f);
- float speed = animationLocked ? (float)lockedSpeed! : animationLayer.Speed;
+ ImGui.SetNextItemWidth(width * 0.35f);
if (ImGui.DragFloat($"Speed", ref speed, 0.01f, 0.0f, 0.0f, "%.3f"))
{
if (animationLocked) animationLayer.LockSpeed(speed);
}
- */
- ImGui.PopItemWidth();
}
}
@@ -3394,6 +3986,10 @@ namespace NewCamera
{
jmpOverHotSpringsSteam.Disable();
}
+ if (ikForcedOff)
+ {
+ forceDisableIK.Disable();
+ }
}
private void tryToEnableMod()
@@ -3418,6 +4014,10 @@ namespace NewCamera
{
jmpOverHotSpringsSteam.Enable();
}
+ if (ikForcedOff)
+ {
+ forceDisableIK.Enable();
+ }
}
private void drawPlayerInfo(Player player, float width)
@@ -3425,10 +4025,11 @@ namespace NewCamera
nint playerSettings = getPlayerSettings();
ImGui.Text($"{Marshal.PtrToStringAnsi(playerSettings + 0x50)}");
- ImGui.Text($"Settings: {playerSettings:X}");
ImGui.Checkbox("Hide Weapon", ref hideWeapon);
+ ImGui.SameLine();
ImGui.Checkbox("Hide Knife", ref hideKnife);
+ ImGui.SameLine();
ImGui.Checkbox("Hide Slinger", ref hideSlinger);
ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(0.0f, 6.0f));
ImGui.Text("Head Armor Display");
@@ -3456,6 +4057,7 @@ namespace NewCamera
ImGui.Separator();
+ /*
ref byte ikDisabledB = ref MemoryUtil.GetRef<byte>(MemoryUtil.Read<nint>(player.Instance + 0x990) + 0x5C);
bool ikDisabled = ikDisabledB == 0x0;
if (ImGui.Checkbox("Disable IK", ref ikDisabled))
@@ -3468,7 +4070,8 @@ namespace NewCamera
ImGui.EndTooltip();
}
ImGui.SameLine();
- if (ImGui.Checkbox("Force Disable IK", ref ikForcedOff))
+ */
+ if (ImGui.Checkbox("Disable IK", ref ikForcedOff))
{
if (ikForcedOff)
{
@@ -3479,46 +4082,94 @@ namespace NewCamera
forceDisableIK.Disable();
}
}
+ if (ImGui.BeginItemTooltip())
+ {
+ ImGui.Text("Forcefully disable inverse kinematics.");
+ ImGui.EndTooltip();
+ }
- if (ImGui.CollapsingHeader("Armor Parts"))
+ ImGui.PushID("PartsAndJoints");
+ if (ImGui.CollapsingHeader("Armor Parts & Joints"))
{
- dropArmorState();
- if (!collectArmorAndJoints(player))
+ refreshArmorState(player);
+ ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(0.0f, 6.0f));
+#if QUARANTINED_FEATURES
+ ImGui.Text($"Joint Offsets: {jointOffsets.Count}, IK Offsets: {ikOffsets.Count}");
+#else
+ ImGui.Text($"Joint Offsets: {jointOffsets.Count}");
+#endif
+ ImGui.SameLine();
+ ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 4.0f));
+ if (ImGui.Button("Clear"))
{
dropJointOffsets();
}
- ImGui.Text($"Offset Count: {jointOffsets.Count}, IK Offset Count: {ikOffsets.Count}");
- if (ImGui.CollapsingHeader($"Body (id: 0x{MemoryUtil.Read<int>(player.Instance + 0x13740):X})"))
+ if (ImGui.CollapsingHeader("Joints"))
{
- drawArmorParts(playerArmor[Armor.Body]);
+ drawJoints(width);
+ ImGui.Separator();
}
- if (ImGui.CollapsingHeader($"Helmet (id: 0x{MemoryUtil.Read<int>(player.Instance + 0x1373C):X})"))
+ bool helmetExpaned = ImGui.CollapsingHeader("Helmet");
+ ImGui.SameLine();
+ ImGui.Text($"(id: 0x{MemoryUtil.Read<int>(player.Instance + 0x1373C):X})");
+ if (helmetExpaned)
{
drawArmorParts(playerArmor[Armor.Helmet]);
+ ImGui.Separator();
}
- if (ImGui.CollapsingHeader($"Arms (id: 0x{MemoryUtil.Read<int>(player.Instance + 0x13744):X})"))
+ bool bodyExpaned = ImGui.CollapsingHeader("Body");
+ ImGui.SameLine();
+ ImGui.Text($"(id: 0x{MemoryUtil.Read<int>(player.Instance + 0x13740):X})");
+ if (bodyExpaned)
+ {
+ drawArmorParts(playerArmor[Armor.Body]);
+ ImGui.Separator();
+ }
+ bool armsExpaned = ImGui.CollapsingHeader("Arms");
+ ImGui.SameLine();
+ ImGui.Text($"(id: 0x{MemoryUtil.Read<int>(player.Instance + 0x13744):X})");
+ if (armsExpaned)
{
drawArmorParts(playerArmor[Armor.Arm]);
+ ImGui.Separator();
}
- if (ImGui.CollapsingHeader($"Waist (id: 0x{MemoryUtil.Read<int>(player.Instance + 0x13748):X})"))
+ bool waistExpaned = ImGui.CollapsingHeader("Waist");
+ ImGui.SameLine();
+ ImGui.Text($"(id: 0x{MemoryUtil.Read<int>(player.Instance + 0x13748):X})");
+ if (waistExpaned)
{
drawArmorParts(playerArmor[Armor.Waist]);
+ ImGui.Separator();
}
- if (ImGui.CollapsingHeader($"Legs (id: 0x{MemoryUtil.Read<int>(player.Instance + 0x1374C):X})"))
+ bool legsExpaned = ImGui.CollapsingHeader("Legs");
+ ImGui.SameLine();
+ ImGui.Text($"(id: 0x{MemoryUtil.Read<int>(player.Instance + 0x1374C):X})");
+ if (legsExpaned)
{
drawArmorParts(playerArmor[Armor.Leg]);
+ ImGui.Separator();
}
- ImGui.Text($"Slinger: {MemoryUtil.Read<int>(player.Instance + 0x13D8C):X}_{MemoryUtil.Read<int>(player.Instance + 0x13D90):X}");
+ ImGui.Text($"Slinger: 0x{MemoryUtil.Read<int>(player.Instance + 0x13D8C):X}, 0x{MemoryUtil.Read<int>(player.Instance + 0x13D90):X}");
/*
- ImGui.Text($"Last Equipped: {lastEquipedId:X}");
+ ImGui.Text($"Last Equipped: 0x{lastEquipedId:X}");
*/
- /*
if (ImGui.CollapsingHeader("Face"))
{
drawArmorParts(playerArmor[Armor.Face]);
+ ImGui.Separator();
}
- */
+ if (ImGui.CollapsingHeader("Eye Lens"))
+ {
+ drawArmorParts(playerArmor[Armor.EyeLens]);
+ ImGui.Separator();
+ }
+ if (ImGui.CollapsingHeader("Hair"))
+ {
+ drawArmorParts(playerArmor[Armor.Hair]);
+ }
+ ImGui.Separator();
}
+ ImGui.PopID();
nint controlsAddr = MemoryUtil.Read<nint>(player.Instance + 0x12608);
nint zoneStateAddr = MemoryUtil.Read<nint>(0x1451C42B8);
@@ -3540,7 +4191,9 @@ namespace NewCamera
}
bool combatControls = MemoryUtil.Read<byte>(controlsAddr + 0xB18) == 0x80;
zoneState = combatControls ? ZoneState.Combat : ZoneState.Hub;
-#if QUARANTINED_FEATURES
+#if !QUARANTINED_FEATURES
+ ImGui.Text($"Current Zone State: {((MemoryUtil.GetRef<byte>(zoneStateAddr + 0xD2EA) == 0x1) ? "Hub" : "Combat")}");
+#else
if (ImGui.Checkbox("Combat Controls", ref combatControls))
{
passiveFlag = ByteFlag(!combatControls);
@@ -3720,16 +4373,19 @@ namespace NewCamera
playerOpacityOverride = playerOpacity;
}
+ ImGui.PushID("Wetness");
if (ImGui.CollapsingHeader("Wetness"))
{
nint wetnessAddr = player.Instance + 0x13BD0;
- ImGui.PushItemWidth(width * 0.25f);
+ ImGui.PushItemWidth(width * 0.15f);
ImGui.DragFloat("Head", ref MemoryUtil.GetRef<float>(wetnessAddr), 0.005f);
+ ImGui.SameLine();
ImGui.DragFloat("Body", ref MemoryUtil.GetRef<float>(wetnessAddr + 0x28), 0.005f);
ImGui.DragFloat("Waist", ref MemoryUtil.GetRef<float>(wetnessAddr + 0x50), 0.005f);
+ ImGui.SameLine();
ImGui.DragFloat("Legs", ref MemoryUtil.GetRef<float>(wetnessAddr + 0x78), 0.005f);
ImGui.PopItemWidth();
- ImGui.PushItemWidth(width * 0.35f);
+ ImGui.SetNextItemWidth(width * 0.35f);
if (ImGui.DragFloat("Whole Body", ref wholeBodyWetness, 0.005f))
{
if (overridePlayerWetness)
@@ -3737,7 +4393,6 @@ namespace NewCamera
writePlayerWholeBodyWetness(wetnessAddr);
}
}
- ImGui.PopItemWidth();
if (ImGui.Button("Reset"))
{
wholeBodyWetness = 0.0f;
@@ -3756,16 +4411,22 @@ namespace NewCamera
overridePlayerWetnessDisable();
}
}
+ ImGui.Separator();
}
+ ImGui.PopID();
- ImGui.PushItemWidth(width * 0.8f);
+ ImGui.PushItemWidth(width * 0.75f);
ImGui.DragFloat3("Position", ref player.Position, 0.5f);
Vector3 forward = new Vector3(player.Forward.X, player.Forward.Y, player.Forward.Z);
ImGui.DragFloat3("Forward", ref forward, 0.0f);
Vector4 rotation = new Vector4(player.Rotation.X, player.Rotation.Y, player.Rotation.Z, player.Rotation.W);
- if (ImGui.SliderFloat4("Rotation", ref rotation, -1.0f, 1.0f))
+ ImGui.SliderFloat4("Rotation", ref rotation, -1.0f, 1.0f);
+ Vector3 rotationOffset = new Vector3();
+ if (ImGui.DragFloat3("Rotation Offset", ref rotationOffset, 0.0025f))
{
- player.Rotation = new MtQuaternion(rotation.X, rotation.Y, rotation.Z, rotation.W);
+ Quaternion qRotation = new Quaternion(rotation.X, rotation.Y, rotation.Z, rotation.W);
+ qRotation *= Quaternion.CreateFromYawPitchRoll(rotationOffset.X, rotationOffset.Y, rotationOffset.Z);
+ player.Rotation = new MtQuaternion(qRotation.X, qRotation.Y, qRotation.Z, qRotation.W);
}
ImGui.PopItemWidth();
if (ImGui.Button("Reset"))
@@ -3892,7 +4553,6 @@ namespace NewCamera
ImGui.PopItemFlag();
ImGui.PopStyleVar();
}
-
drawAnimationInfo(player, width, false);
}
@@ -4201,6 +4861,7 @@ namespace NewCamera
vCamera.NearClip = alternateNearClip;
}
}
+ ImGui.PopItemWidth();
ImGui.SameLine();
if (ImGui.Button("Save"))
{
@@ -4209,7 +4870,6 @@ namespace NewCamera
config.Camera = camera;
ConfigManager.SaveConfig<Config>(this);
}
- ImGui.PopItemWidth();
}
ImGui.Separator();
@@ -4260,7 +4920,7 @@ namespace NewCamera
{
ImGui.PushStyleColor(ImGuiCol.Text, 0xFF0000FF);
}
- ImGui.PushItemWidth(width * 0.15f);
+ ImGui.SetNextItemWidth(width * 0.15f);
ImGui.InputText("##Toggle Free Camera", ref typedCombo, 12);
if (freeCameraCombo == null)
{
@@ -4271,7 +4931,6 @@ namespace NewCamera
ImGui.Text("Form: RT+LB, R3+L2, A+LStick, Up+RT, Cross+Triangle, etc.");
ImGui.EndTooltip();
}
- ImGui.PopItemWidth();
ImGui.SameLine();
if (ImGui.Button("Save"))
{
@@ -4396,6 +5055,7 @@ namespace NewCamera
ImGui.TableSetColumnIndex(1);
ImGui.Text("Open Poses Menu");
+ /*
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
ImGui.Text(" + Press B");
@@ -4407,6 +5067,7 @@ namespace NewCamera
ImGui.Text(" + Press A");
ImGui.TableSetColumnIndex(1);
ImGui.Text("Toggle SSAO");
+ */
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
@@ -4484,12 +5145,12 @@ namespace NewCamera
config.Binds = binds;
ConfigManager.SaveConfig<Config>(this);
}
+ ImGui.PopItemWidth();
if (ImGui.BeginItemTooltip())
{
ImGui.Text("Value that gets sent as a simulated joystick movement. Range: [0, 32767].");
ImGui.EndTooltip();
}
- ImGui.PopItemWidth();
if (ImGui.BeginTable("Keyboard Binds", 2, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Borders))
{
ImGui.TableNextRow();
@@ -4540,11 +5201,13 @@ namespace NewCamera
ImGui.TableSetColumnIndex(1);
ImGui.Text("Toggle UI");
+ /*
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
ImGui.Text("Num /");
ImGui.TableSetColumnIndex(1);
ImGui.Text("Toggle Depth of Field");
+ */
ImGui.EndTable();
}
@@ -4595,8 +5258,8 @@ namespace NewCamera
}
}
- ImGui.PushItemWidth(width * 0.125f);
ref float gameSpeed = ref MemoryUtil.GetRef<float>(sMain.Instance + 0xA4);
+ ImGui.SetNextItemWidth(width * 0.125f);
if (ImGui.DragFloat("Game Speed", ref gameSpeed, 0.005f, 0.0f, Single.MaxValue))
{
if (gameSpeed == 1.0f)
@@ -4614,7 +5277,6 @@ namespace NewCamera
{
advanceFrame++;
}
- ImGui.PopItemWidth();
ImGui.Checkbox("Decouple Camera Speed from Game Speed", ref decoupleDtFromGameTime);
if (ImGui.BeginItemTooltip())
{
@@ -4659,16 +5321,16 @@ namespace NewCamera
{
if (vCamera != null || pCamera != null)
{
- ImGui.Text("Camera:");
+ ImGui.Text("Camera");
if (vCamera != null)
{
- ImGui.Text($"Visible Camera: {vCamera.Instance:X}");
+ ImGui.Text($"Visible Camera: 0x{vCamera.Instance:X}");
ImGui.Text($"freeCameraFallback: {freeCameraFallback}");
- //ImGui.Text($"viewModeObject: {psuedoViewModeObject:X}");
+ //ImGui.Text($"viewModeObject: 0x{psuedoViewModeObject:X}");
}
if (pCamera != null)
{
- ImGui.Text($"Player Camera: {pCamera.Instance:X}");
+ ImGui.Text($"Player Camera: 0x{pCamera.Instance:X}");
ImGui.Text($"Applying Offset: {applyPerspective}");
ImGui.Text($"previousCameraAnimState: {previousCameraAnimState}");
ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true);
@@ -4679,11 +5341,14 @@ namespace NewCamera
}
ImGui.PushID("Viewports");
- ImGui.Text("Viewports:");
+ ImGui.Text("Viewports");
for (int i = 0; i < 8; i++)
{
ImGui.PushID($"Viewport{i}");
- if (ImGui.CollapsingHeader($"Viewport #{i} ({((i == vCameraViewportIndex) ? "visible" : "inactive")})"))
+ bool viewportExpanded = ImGui.CollapsingHeader($"Viewport #{i}");
+ ImGui.SameLine();
+ ImGui.Text($"({((i == vCameraViewportIndex) ? "visible" : "inactive")})");
+ if (viewportExpanded)
{
drawViewportInfo(i, width, config, true);
}
@@ -4694,11 +5359,12 @@ namespace NewCamera
ImGui.Separator();
ImGui.PushID("Player");
- ImGui.Text("Player:");
- ImGui.Text($"sMhPlayer: {sPlayer.Instance:X}");
+ ImGui.Text("Player");
+ ImGui.Text($"sMhPlayer: 0x{sPlayer.Instance:X}");
if (player != null)
{
- ImGui.Text($"Address: {player.Instance:X}");
+ ImGui.Text($"Address: 0x{player.Instance:X}");
+ ImGui.Text($"Settings: 0x{getPlayerSettings():X}");
drawAnimationInfo(player, width, true);
@@ -4719,21 +5385,34 @@ namespace NewCamera
ImGui.PopID();
ImGui.PushID("Palico");
- ImGui.Text("Palico/Otomo:");
- ImGui.Text($"sOtomo: {sOtomo.Instance:X}");
+ ImGui.Text("Palico/Otomo");
+ ImGui.Text($"sOtomo: 0x{sOtomo.Instance:X}");
ImGui.PopID();
ImGui.Separator();
- Monster[] monsters = Monster.GetAllMonsters();
- if (ImGui.CollapsingHeader("Monsters"))
+ if (ImGui.CollapsingHeader($"Monsters"))
{
+ Monster[] monsters = Monster.GetAllMonsters();
+ ImGui.Text($"Count: {monsters.Length}");
+ ImGui.Checkbox("Sort by distance from camera", ref sortMonsters);
+ if (sortMonsters && vCamera != null)
+ {
+ Array.Sort(monsters, delegate(Monster x, Monster y)
+ {
+ float distX = Vector3.Distance(vCamera.Position, x.Position);
+ float distY = Vector3.Distance(vCamera.Position, y.Position);
+ if (distX < distY) return 1;
+ else if (distX > distY) return -1;
+ return 0;
+ });
+ }
for (int i = monsters.Length - 1; i >= 0; i--)
{
Monster monster = monsters[i];
ImGui.PushID(monster.Instance);
ImGui.Text($"{monster.Name}:");
- ImGui.Text($" Address: {monster.Instance:X}");
+ ImGui.Text($" Address: 0x{monster.Instance:X}");
ImGui.DragFloat3("Position", ref monster.Position, 0.5f);
drawAnimationInfo(monster, width, true);
ImGui.PopID();
@@ -4741,15 +5420,28 @@ namespace NewCamera
}
}
- Animal[] animals = Animal.GetAllAnimals();
- if (ImGui.CollapsingHeader("Animals"))
+ if (ImGui.CollapsingHeader($"Animals"))
{
+ Animal[] animals = Animal.GetAllAnimals();
+ ImGui.Text($"Count: {animals.Length}");
+ ImGui.Checkbox("Sort by distance from camera", ref sortAnimals);
+ if (sortAnimals && vCamera != null)
+ {
+ Array.Sort(animals, delegate(Animal x, Animal y)
+ {
+ float distX = Vector3.Distance(vCamera.Position, x.Position);
+ float distY = Vector3.Distance(vCamera.Position, y.Position);
+ if (distX < distY) return 1;
+ else if (distX > distY) return -1;
+ return 0;
+ });
+ }
for (int i = animals.Length - 1; i >= 0; i--)
{
Animal animal = animals[i];
ImGui.PushID(animal.Instance);
- ImGui.Text($"{animal.Id:X} ({animal.OtherId:X}):");
- ImGui.Text($" Address: {animal.Instance:X}");
+ ImGui.Text($"0x{animal.Id:X} (0x{animal.OtherId:X}):");
+ ImGui.Text($" Address: 0x{animal.Instance:X}");
ImGui.DragFloat3("Position", ref animal.Position, 0.5f);
// Freeze: +0x1AFC = 0xFFFFFFFC
if (ImGui.Button("Remove"))
@@ -4761,18 +5453,111 @@ namespace NewCamera
}
}
+ ImGui.Separator();
+
+ if (ImGui.CollapsingHeader("Loaded Models") && player != null)
+ {
+ ImGui.Text("Filter");
+ bool updateRegex = false;
+ ImGui.SetNextItemWidth(width * 0.6f);
+ if (ImGui.InputText("##Filter", ref modelFilter, 256))
+ {
+ 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<nint>(player.Instance + 0x2A0);
+ if (bodyArmorParts != 0x0)
+ {
+ nint next = bodyArmorParts - 0x40;
+ nint head = next;
+ nint prev = MemoryUtil.Read<nint>(next + 0x10);
+ for (;next != 0x0;)
+ {
+ ImGui.PushID(next);
+ nint partsAddr = next + 0x40;
+ nint vtable = MemoryUtil.Read<nint>(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)
+ {
+ drawArmorParts(0x0, partsAddr);
+ }
+ }
+ ImGui.PopID();
+ if (head == prev)
+ {
+ next = MemoryUtil.Read<nint>(next + 0x10);
+ }
+ else
+ {
+ next = MemoryUtil.Read<nint>(next + 0x18);
+ if (next == 0x0)
+ {
+ head = prev;
+ next = prev;
+ }
+ }
+ }
+ }
+ }
+ if (ImGui.BeginItemTooltip())
+ {
+ ImGui.Text($"Part toggling only applies to LOD0.");
+ ImGui.EndTooltip();
+ }
+
+ ImGui.Separator();
+
#if MOUSE_AND_KEYBOARD_LAYER
ImGui.PushID("Mouse/Keyboard");
- ImGui.Text("Mouse:");
- ImGui.Text($"Address: {sMhMouse.Instance:X}");
- ImGui.Text("Keyboard:");
- ImGui.Text($"Address: {sMhKeyboard.Instance:X}");
+ 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:");
- ImGui.Text($"Address: {sMhController.Instance:X}");
+ ImGui.Text("Pad");
+ ImGui.Text($"Address: 0x{sMhController.Instance:X}");
int Rx = MemoryUtil.Read<int>(sMhController.Instance + 0x1B0);
int Ry = MemoryUtil.Read<int>(sMhController.Instance + 0x1B4);
int Lx = MemoryUtil.Read<int>(sMhController.Instance + 0x1B8);
@@ -4791,6 +5576,7 @@ namespace NewCamera
ImGui.DragFloat("+Right", ref plusRight, 0.01f);
ImGui.SameLine();
ImGui.DragFloat("+Forward", ref plusForward, 0.01f);
+ ImGui.PopItemWidth();
ImGui.SameLine();
if (ImGui.Button("Reset"))
{
@@ -4809,13 +5595,12 @@ namespace NewCamera
plusForward = -plusForward;
}
}
- ImGui.PopItemWidth();
ImGui.PopID();
ImGui.Separator();
ImGui.PushID("Orbit");
- ImGui.Text("Orbital Camera:");
+ ImGui.Text("Orbital Camera");
ImGui.PushItemWidth(width * 0.15f);
ImGui.DragFloat("Distance", ref orbitDistance, 1.0f);
ImGui.SameLine();
@@ -4823,6 +5608,7 @@ namespace NewCamera
ImGui.SameLine();
ImGui.DragFloat("Target Right", ref orbitRight, 1.0f);
ImGui.DragFloat("Movement Rotation", ref orbitMovementRotation, 1.0f);
+ ImGui.InputInt("Target Joint", ref orbitJoint);
ImGui.PopItemWidth();
ImGui.PopID();
@@ -4837,6 +5623,7 @@ namespace NewCamera
ImGui.TextWrapped("Otis_Inf: Initial LOD and object fading adjustment locations, time of day and game speed.");
ImGui.TextWrapped("Andoryuuta: MHW-ClassPropDump/MHW-DTI-Dumps.");
ImGui.TextWrapped("MonsterHunterWorldModding/wiki Authors.");
+ ImGui.Separator();
}
ImGui.PopID();
}