From 6802618079b7d8ec5e383d7356be3db4def5e172 Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Mon, 21 Sep 2026 11:29:55 -0400 Subject: Separate player stuff Signed-off-by: Andrew Opalach --- Player.cs | 2222 +++++++++++++++++++++++++++++++++++++++++++++ Plugin.cs | 2979 +++++++------------------------------------------------------ 2 files changed, 2561 insertions(+), 2640 deletions(-) create mode 100644 Player.cs diff --git a/Player.cs b/Player.cs new file mode 100644 index 0000000..762acdf --- /dev/null +++ b/Player.cs @@ -0,0 +1,2222 @@ +//#define QUARANTINED_FEATURES + +using System.Numerics; +using System.Runtime.InteropServices; + +using ImGuiNET; +using SharpPluginLoader.Core; +using SharpPluginLoader.Core.MtTypes; +using SharpPluginLoader.Core.Entities; +using SharpPluginLoader.Core.Memory; + +namespace NewCamera +{ + using static Plugin; + + public unsafe class PlayerExt + { + public static MtObject? sPlayer = null; + + private static int saveSlotIndex = -1; + private static NativeFunction getSaveSlotGuiAddr; + private static NativeFunction getPlayerSettingsAddr; + public static nint getPlayerSettings() + { + nint rcx = MemoryUtil.Read(0x145013950); + if (saveSlotIndex >= 0) + { + // MonsterHunterWorld.exe+ADC442 - imul rdx,rcx,0026CC00 + nint rax = saveSlotIndex * 0x26CC00; + rax += MemoryUtil.Read(rcx + 0xA8); + return rax; + } + // MonsterHunterWorld.exe+1B8DBB0 - movsxd rax,dword ptr [rcx+000000A0] + return getPlayerSettingsAddr.Invoke(rcx); + } + private static bool hideWeapon = false; + private static bool hideKnife = false; + private static bool checkKnifeHidden = false; + + private delegate void CollisionCheckDelegate(nint unknownPtr, nint unknownPtr2); + private static Hook? collisionCheckHook; + + 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 Weapon = 5; + public const byte Slinger = 6; + public const byte Hair = 7; + public const byte Face = 8; + public const byte EyeLens = 9; + } + + private static class Joint + { + public const byte Root = 0x0; + public const byte Root2 = 0xD; + public const byte LowerBack = 0x1; + public const byte UpperBack = 0x2; + public const byte LowerNeck = 0x3; + public const byte LowerNeckNull = 0xFE; + public const byte UpperNeck = 0x4; + public const byte LeftCollarbone = 0x5; + public const byte LeftShoulderNull = 0x46; + public const byte LeftShoulder = 0x6; + public const byte LeftElbow = 0x7; + public const byte LeftWrist = 0x8; + public const byte LeftWristNull = 0x1E; + public const byte LeftThumbLow = 0x1F; + public const byte LeftThumbMid = 0x20; + public const byte LeftThumbHigh = 0x21; + public const byte LeftIndexLow = 0x22; + public const byte LeftIndexMid = 0x23; + public const byte LeftIndexHigh = 0x24; + public const byte LeftMiddleLow = 0x25; + public const byte LeftMiddleMid = 0x26; + public const byte LeftMiddleHigh = 0x27; + public const byte LeftPalm = 0x28; + public const byte LeftRingLow = 0x29; + public const byte LeftRingMid = 0x2A; + public const byte LeftRingHigh = 0x2B; + public const byte LeftPinkyLow = 0x2C; + public const byte LeftPinkyMid = 0x2D; + public const byte LeftPinkyHigh = 0x2E; + public const byte LeftArmUnk1 = 0x51; + public const byte LeftArmUnk2 = 0x65; + public const byte LeftArmUnk3 = 0x66; + public const byte LeftArmUnk4 = 0x67; + public const byte LeftArmUnk5 = 0x68; + public const byte LeftArmUnk6 = 0x47; + public const byte LeftArmUnk7 = 0x50; + public const byte RightCollarbone = 0x9; + public const byte RightShoulder = 0xA; + public const byte RightElbow = 0xB; + public const byte RightWrist = 0xC; + public const byte RightWristNull = 0x2F; + public const byte RightThumbLow = 0x30; + public const byte RightThumbMid = 0x31; + public const byte RightThumbHigh = 0x32; + public const byte RightIndexLow = 0x33; + public const byte RightIndexMid = 0x34; + public const byte RightIndexHigh = 0x35; + public const byte RightMiddleLow = 0x36; + public const byte RightMiddleMid = 0x37; + public const byte RightMiddleHigh = 0x38; + public const byte RightPalm = 0x39; + public const byte RightRingLow = 0x3A; + public const byte RightRingMid = 0x3B; + public const byte RightRingHigh = 0x3C; + public const byte RightPinkyLow = 0x3D; + public const byte RightPinkyMid = 0x3E; + public const byte RightPinkyHigh = 0x3F; + public const byte RightArmUnk1 = 0x53; + public const byte RightArmUnk2 = 0x49; + public const byte RightArmUnk3 = 0x52; + public const byte RightArmUnk4 = 0x48; + public const byte Unknown1 = 0xF7; + public const byte Unknown2 = 0xF8; + public const byte LeftHip = 0xE; + public const byte LeftKnee = 0xF; + public const byte LeftAnkle = 0x10; + public const byte LeftToes = 0x11; + public const byte LeftAnkleNull = 0x54; + public const byte LeftKneeNull = 0x4B; + public const byte LeftHipNull = 0x4A; + public const byte Unknown3 = 0x40; + public const byte Unknown4 = 0x42; + public const byte RightHip = 0x12; + public const byte RightKnee = 0x13; + public const byte RightAnkle = 0x14; + public const byte RightToes = 0x15; + public const byte RightAnkleNull = 0x55; + public const byte RightKneeNull = 0x4D; + public const byte RightHipNull = 0x4C; + public const byte Unknown5 = 0x43; + public const byte Unknown6 = 0x45; + public const byte Unknown7 = 0xF9; + public const byte Unknown8 = 0xFA; + public const byte Unknown9 = 0xFB; + public const byte Unknown10 = 0xFC; + public const byte Unknown11 = 0xFD; + } + + private static nint[] playerArmor = new nint[10]; + private static nint[] playerJoints = new nint[0xFF]; + + private delegate void UpdateJoints(nint obj); + private static Hook? updateJointRotationHook; + private static Hook? updateJointPositionHook; + public static List bodyJoints = new List(); + private static List ignoredJoints = new List(); + private static Dictionary> bodyRotations = new Dictionary>(); + private static Dictionary> bodyOffsets = new Dictionary>(); + + private static List faceJoints = new List(); + private static Dictionary> faceRotations = new Dictionary>(); + private static Dictionary> faceOffsets = new Dictionary>(); + +#if QUARANTINED_FEATURES + private delegate void UpdateIK(nint superOfChild, nint joint, nint obj); + private static Hook? updateIKHook; + private static Dictionary> ikOffsets = new Dictionary>(); + private static List ikJoints = new List(); +#endif + private static bool ikForcedOff = false; + private static Patch forceDisableIK; + + private static List jiggleBones = new List(); + private static bool attachToChest = false; + public static bool toggleAttachToChest = false; + private static bool swapChestSides = false; + private static float chestMoveScale = 0.25f; + private static bool setChestIndex = false; + private static int chestBoneIndex1 = 0; + private static int chestBoneIndex2 = 1; + private static nint chestBone1 = 0x0; + private static nint chestBone2 = 0x0; + + /* + private delegate void ChangeEquipment(nint unknownPtr, int unknownInt); + private Hook? changeEquipmentHook; + private NativeFunction newEquipmentPointer; + private int lastEquipedId = 0; + */ + + private static bool disableCollision = false; + private static bool disableExtraCollision = false; + private static bool disableGravity = false; + private static bool disableExtraGravity = false; + private static Patch disableXCollision; + private static Patch disableYCollision; + private static Patch disableSecondaryYCollision; + private static Patch disableZCollision; + private static Patch disableExtraYCollision; + private static Patch disableGravityYUpdate; + private static Patch disableGravityXZUpdate; + private static Patch disableGravityEval; + + private static void disableCollisionEnable() + { + disableXCollision.Enable(); + disableYCollision.Enable(); + disableSecondaryYCollision.Enable(); + disableZCollision.Enable(); + } + + private static void disableCollisionDisable() + { + disableXCollision.Disable(); + disableYCollision.Disable(); + disableSecondaryYCollision.Disable(); + disableZCollision.Disable(); + } + + private static void disableExtraCollisionEnable() + { + disableExtraYCollision.Enable(); + } + + private static void disableExtraCollisionDisable() + { + disableExtraYCollision.Disable(); + } + + private static void disableGravityEnable() + { + disableGravityYUpdate.Enable(); + } + + private static void disableGravityDisable() + { + disableGravityYUpdate.Disable(); + } + + private static void disableExtraGravityEnable() + { + disableGravityEval.Enable(); + } + + private static void disableExtraGravityDisable() + { + disableGravityEval.Disable(); + } + + private enum ZoneState : int + { + Unknown = 0, + Hub = 1, + Combat = 2 + } + +#if QUARANTINED_FEATURES + private static ZoneState forceZoneState = ZoneState.Unknown; + private static ZoneState lastZoneState = ZoneState.Unknown; + private static NativeAction setZoneState; + private static NativeAction setPlayerController1; + private static NativeAction setPlayerController5; + private static bool zoneStateManualInvoke = false; + private static bool forcePassiveInCombatZone = false; + private static Patch zoneStateForcePassive1; + private static Patch zoneStateForcePassive2; + private static bool forceCombatInPassiveZone = false; + private static Patch zoneStateForceCombat1; + private static Patch zoneStateForceCombat2; +#endif + private delegate void ZoneStateDelegate(nint player, int flags); + private static Hook? setZoneStateHook; + + private static bool allowHotSpringsAnywhere = false; + private static Patch jmpOverHotSpringsEval; + + private static bool disableHotSpringsSteam = false; + private static Patch jmpOverHotSpringsSteam; + + private static bool enableCrawl = false; + private static NativeAction procEnvironmentCollision; + private static nint psuedoObject1; + private static nint psuedoObject2; + + private static float playerOpacityOverride = 1.0f; + private delegate void RefreshEntityParams(nint entity, nint unknownPtr2); + private static Hook? refreshEntityParamsHook; + + private static bool overridePlayerWetness = false; + private static Patch noopPlayerWetnessUpdate; + private static Patch jmpOverChangeEquipmentWetnessUpdate_1; + private static Patch jmpOverChangeEquipmentWetnessUpdate_2; + private static float wholeBodyWetness = 0.0f; + + private static void overridePlayerWetnessEnable() + { + noopPlayerWetnessUpdate.Enable(); + jmpOverChangeEquipmentWetnessUpdate_1.Enable(); + jmpOverChangeEquipmentWetnessUpdate_2.Enable(); + } + + private static void overridePlayerWetnessDisable() + { + noopPlayerWetnessUpdate.Disable(); + jmpOverChangeEquipmentWetnessUpdate_1.Disable(); + jmpOverChangeEquipmentWetnessUpdate_2.Disable(); + } + + private static void writePlayerWholeBodyWetness(nint wetnessAddr) + { + MemoryUtil.GetRef(wetnessAddr) = wholeBodyWetness; + MemoryUtil.GetRef(wetnessAddr + 0x28) = wholeBodyWetness; + MemoryUtil.GetRef(wetnessAddr + 0x50) = wholeBodyWetness; + MemoryUtil.GetRef(wetnessAddr + 0x78) = wholeBodyWetness; + } + + public static void Initialize() + { + + collisionCheckHook = Hook.Create(0x1411C4E50, CollisionCheckHook); // nint, nint + +#if QUARANTINED_FEATURES + // MonsterHunterWorld.exe+20354F7 - call MonsterHunterWorld.exe+1F73850 + setZoneState = new NativeAction(0x142035020); + setPlayerController1 = new NativeAction(0x141F73850); + setPlayerController5 = new NativeAction(0x14118DDC0); + zoneStateForcePassive1 = new Patch(lton(0x140256A3F) + 0x6, [0x1]); + zoneStateForcePassive2 = new Patch(lton(0x141AC2865) + 0x6, [0x1]); + zoneStateForceCombat1 = new Patch(lton(0x141AC2938) + 0x6, [0x0]); + zoneStateForceCombat2 = new Patch(lton(0x141AC28EC) + 0x6, [0x0]); +#endif + setZoneStateHook = Hook.Create(0x142035020, SetZoneStateHook); // nint, int + + procEnvironmentCollision = new NativeAction(0x141F737D0); + psuedoObject1 = (nint)NativeMemory.AllocZeroed(0x7C); + MemoryUtil.WriteBytes(psuedoObject1 + 0x30, [0x03]); + psuedoObject2 = (nint)NativeMemory.AllocZeroed(0x7C); + MemoryUtil.WriteBytes(psuedoObject2 + 0x30, [0x08]); + + getSaveSlotGuiAddr = new NativeFunction(0x141AC0B60); + getPlayerSettingsAddr = new NativeFunction(0x141B8DBB0); + + forceDisableIK = new Patch(lton(0x14031FD40), [0xC6, 0x81, 0x81, 0x01, 0x00, 0x00, 0x00, 0xC3]); + + // Alt: 0x141FBC7A0 (model - 0x958) + updateJointRotationHook = Hook.Create(0x14223BA30, UpdateJointRotationHook); + updateJointPositionHook = Hook.Create(0x142228F50, UpdateJointPositionHook); +#if QUARANTINED_FEATURES + updateIKHook = Hook.Create(0x142472C00, UpdateIKHook); +#endif + + /* + changeEquipmentHook = Hook.Create(0x141DDEF80, ChangeEquipmentHook); // nint, int + newEquipmentPointer = new NativeFunction(0x141DE56A0); + */ + + // Player + ECCC = How far underwater is the player. + jmpOverHotSpringsEval = new Patch(lton(0x1417C1B03), [0xEB]); + jmpOverHotSpringsSteam = new Patch(lton(0x14203A494), [0xE9, 0x8D, 0x00, 0x00, 0x00, 0x90]); + + + refreshEntityParamsHook = Hook.Create(0x141F605F0, RefreshEntityParamsHook); // nint, nint + + noopPlayerWetnessUpdate = new Patch(lton(0x14203E893), [0x90, 0x90, 0x90, 0x90, 0x90]); + jmpOverChangeEquipmentWetnessUpdate_1 = new Patch(lton(0x14203E310), [0xEB]); // je -> jmp. + jmpOverChangeEquipmentWetnessUpdate_2 = new Patch(lton(0x14203E397), [0xE9, 0xB9, 0x00, 0x00, 0x00, 0x90]); // je -> jmp. + + // Noop collision checks. + nint addr = PatternScanner.FindFirst(Pattern.FromString("F3 0F 11 06 F3 0F 10 48 04 F3 0F 58 4E 04 F3 0F 11 4E 04 F3 0F 10 40 08 F3 0F 58 46 08 F3 0F 11 46 08 44 8B AF E0 0B 00 00")); + Assert(addr == 0x141C001B5); + disableXCollision = new Patch(addr, [0x90, 0x90, 0x90, 0x90]); + Assert(addr + 0xE == 0x141C001C3); + disableYCollision = new Patch(addr + 0xE, [0x90, 0x90, 0x90, 0x90, 0x90]); + Assert(addr + 0x1D == 0x141C001D2); + disableZCollision = new Patch(addr + 0x1D, [0x90, 0x90, 0x90, 0x90, 0x90]); + + addr = PatternScanner.FindFirst(Pattern.FromString("F3 0F 11 46 04 F3 0F 10 46 08 F3 0F 5C C2 F3 0F 11 46 08 ?? ?? F3 0F")); + Assert(addr == 0x141C000D2); + disableSecondaryYCollision = new Patch(addr, [0x90, 0x90, 0x90, 0x90, 0x90]); + + addr = PatternScanner.FindFirst(Pattern.FromString("F3 0F 11 46 04 F3 0F 10 58 08 F3 0F 58 5E 08 F3 0F 11 5E 08 44 8B 87 D0 0B 00 00 41 F6 C0 03")); + Assert(addr == 0x141BFFF90); + disableExtraYCollision = new Patch(addr, [0x90, 0x90, 0x90, 0x90, 0x90]); + + addr = PatternScanner.FindFirst(Pattern.FromString("F3 0F 11 83 80 00 00 00 F3 0F 11 8B 84 00 00 00 F3 0F 11 93 88 00 00 00 89 B3 8C 00 00 00 8B 83 A4 01 00 00 C1 E8 05 44 0F 29 A4 24 D0 01 00 00 44 0F 29 B4 24 B0 01 00 00 A8 01")); + Assert(addr + 0x8 == 0x1413259ED); + disableGravityYUpdate = new Patch(addr + 0x8, [ + 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 + ]); + + 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")); + Assert(addr + 0x40 == 0x141BFFF75); + disableGravityEval = new Patch(addr + 0x40, [0x90, 0x90, 0x90, 0x90, 0x90]); // call MonsterHunterWorld.exe+1325810. + } + + public static Player? getPlayerFromSaveSlot() + { + nint guiAddr = getSaveSlotGuiAddr.Invoke(MemoryUtil.Read(0x1451C42B8)); + if (guiAddr == 0x0) + { + saveSlotIndex = -1; + return null; + } + // MonsterHunterWorld.exe+ADC42F - movsxd rcx,dword ptr [rax+00000334] + saveSlotIndex = MemoryUtil.Read(guiAddr + 0x334); + if (saveSlotIndex == -1) + { + return null; + } + // MonsterHunterWorld.exe+1B42047 - add r8,00000740 + nint offset = (sPlayer!.Instance + 0x40) + (0x740 * saveSlotIndex); + if (offset == 0x0 || MemoryUtil.Read(offset) != 0x1433FE588) + { + return null; + } + nint playerAddr = MemoryUtil.Read(offset + 0x18); + if (playerAddr == 0x0) + { + return null; + } + return new Player(playerAddr); + } + + public static Player? getPlayer() + { + Player? player = Player.MainPlayer; + if (player != null) + { + saveSlotIndex = -1; + } + return Player.MainPlayer; + } + + public static Player? getPlayerWithFallback() + { + Player? player = getPlayer(); + if (player == null) + { + player = getPlayerFromSaveSlot(); + } + return player; + } + + public static void OnUpdate() + { + Player? player = getPlayerWithFallback(); + if (player != null) + { + if (hideWeapon) + { + // MonsterHunterWorld.exe+1789ABA - mov rdi,[rcx+000076B0] + nint baseAddr = MemoryUtil.Read(player.Instance + 0x76B0); + if (baseAddr != 0x0) + { + MemoryUtil.WriteBytes(baseAddr + 0x1A98, [0x1]); + int weaponParts = MemoryUtil.Read(baseAddr + 0x2250); + for (int i = 0; i < weaponParts; i++) + { + nint partsAddr = MemoryUtil.Read(baseAddr + ((i + 0x16B) * 24)); + if (partsAddr != 0x0) + { + MemoryUtil.WriteBytes(partsAddr + 0x1A98, [0x1]); + } + } + } + } + /* + if (hideKnife) + { + // Emulate what Carving and Flourish emote do at + // MonsterHunterWorld.exe+1F68832 - bts eax,06 + // if set, skips + // MonsterHunterWorld.exe+203A0D2 - bts ecx,01 + MemoryUtil.GetRef(player.Instance + 0x8938) |= (1 << 6); + MemoryUtil.GetRef(player.Instance + 0x8968) |= (1 << 6); + } + */ + } + } + + private static void CollisionCheckHook(nint unknownPtr, nint unknownPtr2) + { + if (disableMod) + { + collisionCheckHook!.Original(unknownPtr, unknownPtr2); + return; + } + +#if HOOK_ORDER_ASSERTS + debugLog($"CollisionCheckHook(0x{unknownPtr:X}, 0x{unknownPtr2:X}) @ {frameTick}"); +#endif + + Player? player = null; + if (enableCrawl && (player = getPlayer()) != null) + { + nint controlsAddr = MemoryUtil.Read(player.Instance + 0x12608); + bool combatControls = false; + if (controlsAddr != 0x0) + { + combatControls = MemoryUtil.Read(controlsAddr + 0xB18) == 0x80; + } + if (combatControls) + { + procEnvironmentCollision.Invoke(player.Instance, psuedoObject1); + procEnvironmentCollision.Invoke(player.Instance, psuedoObject2); + } + else + { + enableCrawl = false; + } + } + + collisionCheckHook!.Original(unknownPtr, unknownPtr2); + } + + private static void SetZoneStateHook(nint player, int flags) + { + if (disableMod) + { + setZoneStateHook!.Original(player, flags); + return; + } + +#if HOOK_ORDER_ASSERTS + debugLog($"SetZoneStateHook(0x{player:X}, 0x{flags:X}) @ {frameTick}"); +#endif + +#if QUARANTINED_FEATURES + nint zoneStateAddr = MemoryUtil.Read(0x1451C42B8); + ref byte zoneState = ref MemoryUtil.GetRef(zoneStateAddr + 0xD2EA); + if (!zoneStateManualInvoke) + { + lastZoneState = (zoneState == 0x1) ? ZoneState.Hub : ZoneState.Combat; + } + else + { + zoneStateManualInvoke = false; + } + + ZoneState overrideZoneState = (forceZoneState == ZoneState.Unknown) ? lastZoneState : forceZoneState; + if (overrideZoneState != ZoneState.Unknown) + { + zoneState = ByteFlag(overrideZoneState == ZoneState.Hub); + } +#endif + + float headWet = 0.0f, bodyWet = 0.0f, waistWet = 0.0f, legsWet = 0.0f; + nint wetnessAddr = player + 0x13BD0; + if (overridePlayerWetness) + { + headWet = MemoryUtil.Read(wetnessAddr); + bodyWet = MemoryUtil.Read(wetnessAddr + 0x28); + waistWet = MemoryUtil.Read(wetnessAddr + 0x50); + legsWet = MemoryUtil.Read(wetnessAddr + 0x78); + } + + setZoneStateHook!.Original(player, flags); + + if (overridePlayerWetness) + { + MemoryUtil.GetRef(wetnessAddr) = headWet; + MemoryUtil.GetRef(wetnessAddr + 0x28) = bodyWet; + MemoryUtil.GetRef(wetnessAddr + 0x50) = waistWet; + MemoryUtil.GetRef(wetnessAddr + 0x78) = legsWet; + } + } + + private static void RefreshEntityParamsHook(nint entity, nint unknownPtr2) + { + refreshEntityParamsHook!.Original(entity, unknownPtr2); + + if (disableMod) + { + return; + } + + Player? player = getPlayerWithFallback(); + if (player != null && entity == player && playerOpacityOverride != 1.0f) + { + MemoryUtil.GetRef(player.Instance + 0x78E0) = playerOpacityOverride; + } + } + + private static string extractPartName(string fullString) + { + string partName = ""; + if (fullString.StartsWith("pl\\f_equip") || fullString.StartsWith("pl\\m_equip")) + { + partName = fullString.Split('\\')[3]; + } + else if (fullString.StartsWith("wp\\")) + { + partName = fullString.Split('\\')[2]; + } + else if (fullString.StartsWith("pl\\hair")) + { + partName = fullString.Split('\\')[2]; + } + else if (fullString.StartsWith("pl\\f_face") || fullString.StartsWith("pl\\m_face")) + { + partName = fullString.Split('\\')[4].Substring(2); + } + return partName; + } + + private static void collectArmorParts(nint baseAddr, nint addr) + { + int part; + string fullString = Marshal.PtrToStringAnsi(addr + 0xC)!; + string partName = extractPartName(fullString); + 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.StartsWith("slg")) part = Armor.Slinger; + else if (fullString.StartsWith("wp\\")) part = Armor.Weapon; + else if (partName.StartsWith("hair")) part = Armor.Hair; + else if (partName == "face000") part = Armor.Face; + else if (partName == "face000_eyelens") part = Armor.EyeLens; + else return; + playerArmor[part] = baseAddr; + + int jointCount = MemoryUtil.Read(baseAddr + 0x4A0); + nint jointAddr = MemoryUtil.Read(baseAddr + 0x4A8); + for (int i = 0; i < jointCount; i++) + { + nint childAddr = MemoryUtil.Read(jointAddr + 0x8); + if (childAddr != 0x0 && MemoryUtil.Read(childAddr) == 0x142F21A90) + { + childAddr = MemoryUtil.Read(childAddr + 0x8); + if (childAddr != 0x0) + { + nint childVtable = MemoryUtil.Read(childAddr); + if (childVtable == 0x1435195B8) // Jiggle Bone Container. + { + if (part == Armor.Body) + { + ignoredJoints.Add(jointAddr); + } + } + else if (childVtable == 0x143524BD8) + { + childAddr = MemoryUtil.Read(childAddr + 0x188); + if (childAddr != 0x0 && MemoryUtil.Read(childAddr) == 0x143519530) + { + nint jiggleData = MemoryUtil.Read(MemoryUtil.Read(childAddr + 0xA0)); + if (MemoryUtil.Read(jiggleData) == 0x143519508) + { + if (!jiggleBones.Contains(jiggleData)) + { + int jiggleIndex = jiggleBones.Count(); + jiggleBones.Add(jiggleData); + if (setChestIndex) + { + if (jiggleIndex == chestBoneIndex1) + { + chestBone1 = jiggleData; + } + if (jiggleIndex == chestBoneIndex2) + { + chestBone2 = jiggleData; + } + } + else if (part == Armor.Body) + { + // Guess that chest bones are the last jiggle bones on the body. + if (chestBone1 == 0x0) + { + chestBone1 = jiggleData; + chestBoneIndex1 = jiggleIndex; + } + else + { + if (chestBone2 != 0x0) + { + chestBone1 = chestBone2; + chestBoneIndex1 = chestBoneIndex2; + } + chestBone2 = jiggleData; + chestBoneIndex2 = jiggleIndex; + } + } + } + } + } + if (part == Armor.Body) + { + ignoredJoints.Add(jointAddr); + } + } +#if QUARANTINED_FEATURES + else if (childVtable == 0x143249170) + { + childAddr = MemoryUtil.Read(childAddr + 0x188); + if (childAddr != 0x0 && MemoryUtil.Read(childAddr) == 0x1432492F0) + { + ikJoints.Add(jointAddr); + } + } +#endif + } + } + if (part == Armor.Body) + { + bodyJoints.Add(jointAddr); + } + else if (part == Armor.Face) + { + faceJoints.Add(jointAddr); + } + jointAddr += 0xC0; + } + + if (part == Armor.Body) + { + for (int i = 0; i < bodyJoints.Count; i++) + { + jointAddr = bodyJoints[i]; + if (ignoredJoints.Contains(jointAddr)) + { + continue; + } + byte id = MemoryUtil.Read(jointAddr + 0xA0); + Assert(playerJoints[id] == 0x0); + playerJoints[id] = jointAddr; + } + foreach (nint joint in bodyRotations.Where(e => !bodyJoints.Contains(e.Key)).Select(e => e.Key).ToList()) + { + bodyRotations.Remove(joint); + } + foreach (nint joint in bodyOffsets.Where(e => !bodyJoints.Contains(e.Key)).Select(e => e.Key).ToList()) + { + bodyOffsets.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 + } + else if (part == Armor.Face) + { + foreach (nint joint in faceRotations.Where(e => !faceJoints.Contains(e.Key)).Select(e => e.Key).ToList()) + { + faceRotations.Remove(joint); + } + foreach (nint joint in faceOffsets.Where(e => !faceJoints.Contains(e.Key)).Select(e => e.Key).ToList()) + { + faceOffsets.Remove(joint); + } + } + } + + private static void drawJoint(nint jointAddr, Dictionary> rotations, Dictionary> offsets) + { + if (jointAddr == 0x0) return; + ImGui.PushID(jointAddr); + bool hasRotation = rotations.ContainsKey(jointAddr); + bool hasOffset = offsets.ContainsKey(jointAddr); +#if QUARANTINED_FEATURES + bool hasIkOffset = ikOffsets.ContainsKey(jointAddr); +#endif + ImGui.DragFloat4("Rotation", ref MemoryUtil.GetRef(jointAddr + 0x70), 0.005f); + if (hasRotation) + { + ImGui.PushID("Rotation"); + bool doRemove = ImGui.Button("X"); + ImGui.SameLine(); + if (ImGui.Button("Reset")) + { + rotations[jointAddr][0] = default; + } + ImGui.SameLine(); + Vector3 v = rotations[jointAddr][0]; + if (ImGui.DragFloat3($"##Rotation Offset", ref v, 0.005f)) + { + rotations[jointAddr][0] = v; + } + if (doRemove) rotations.Remove(jointAddr); + ImGui.PopID(); + } + ImGui.DragFloat4("Position", ref MemoryUtil.GetRef(jointAddr + 0x50), 0.005f); + if (hasOffset) + { + ImGui.PushID("Position"); + bool doRemove = ImGui.Button("X"); + ImGui.SameLine(); + if (ImGui.Button("Reset")) + { + offsets[jointAddr][0] = default; + } + ImGui.SameLine(); + Vector3 v = offsets[jointAddr][0]; + if (ImGui.DragFloat3($"##Position Offset", ref v, 0.005f)) + { + offsets[jointAddr][0] = v; + } + if (doRemove) offsets.Remove(jointAddr); + ImGui.PopID(); + } +#if QUARANTINED_FEATURES + if (hasIkOffset) + { + ImGui.PushID("IK"); + bool doRemove = ImGui.Button("X"); + ImGui.SameLine(); + if (ImGui.Button("Reset")) + { + ikOffsets[jointAddr][0] = default; + } + ImGui.SameLine(); + Vector3 v = ikOffsets[jointAddr][0]; + if (ImGui.DragFloat3($"##IK Offset", ref v, 0.025f)) + { + ikOffsets[jointAddr][0] = v; + } + if (doRemove) ikOffsets.Remove(jointAddr); + ImGui.PopID(); + } +#endif + if (!hasRotation) + { + if (ImGui.Button("Add Rotation")) + { + rotations.Add(jointAddr, new List() + { + new Vector3() + }); + } + } + if (!hasOffset) + { + if (!hasRotation) + { + ImGui.SameLine(); + } + if (ImGui.Button("Add Offset")) + { + offsets.Add(jointAddr, new List() + { + new Vector3() + }); + } + } +#if QUARANTINED_FEATURES + if (ikJoints.Contains(jointAddr) && !hasIkOffset) + { + if (!hasOffset) + { + ImGui.SameLine(); + } + if (ImGui.Button("Add IK Offset")) + { + ikOffsets.Add(jointAddr, new List() + { + new Vector3() + }); + } + } +#endif + ImGui.PopID(); + } + + private static void drawJoint(nint jointAddr) + { + drawJoint(jointAddr, bodyRotations, bodyOffsets); + } + + private static void drawJointLeaf(ref List joints, int i, Dictionary> rotations, Dictionary> offsets) + { + if (i >= joints.Count) return; + nint jointAddr = joints[i]; + byte id = MemoryUtil.Read(jointAddr + 0xA0); + ImGui.PushID(jointAddr); + if (ImGui.CollapsingHeader($"Joint #{i} (0x{jointAddr:X}, id: 0x{id:X})")) + { + drawJoint(jointAddr, rotations, offsets); + } + ImGui.PopID(); + drawJointLeaf(ref joints, i + 1, rotations, offsets); + } + + private static void drawJoints(float width) + { + ImGui.PushItemWidth(width * 0.75f); + ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags.Framed; + bool expanded; + if (ImGui.TreeNodeEx("Root", flags)) + { + drawJoint(playerJoints[Joint.Root2]); + ImGui.TreePop(); + } + ImGui.PushID("Neck"); + if (ImGui.TreeNodeEx("Neck", flags)) + { + if (ImGui.TreeNodeEx("Upper", flags)) + { + drawJoint(playerJoints[Joint.UpperNeck]); + ImGui.TreePop(); + } + 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)) + { + 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(); + expanded = ImGui.TreeNodeEx("Palm", flags); + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Outer Palm/Pinky+Ring"); + ImGui.EndTooltip(); + } + if (expanded) + { + drawJoint(playerJoints[Joint.RightPalm]); + ImGui.TreePop(); + } + ImGui.TreePop(); + } + ImGui.PopID(); // Right Hand. + ImGui.PushID("Right Leg"); + if (ImGui.TreeNodeEx("Right Leg", flags)) + { + if (ImGui.TreeNodeEx("Hip", flags)) + { + 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(); + } + ImGui.PopID(); // Right Leg. + ImGui.PushID("Left Arm"); + if (ImGui.TreeNodeEx("Left Arm", flags)) + { + if (ImGui.TreeNodeEx("Collarbone", flags)) + { + 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)) + { + drawJoint(playerJoints[Joint.LeftThumbLow]); + ImGui.TreePop(); + } + if (ImGui.TreeNodeEx("Middle", flags)) + { + drawJoint(playerJoints[Joint.LeftThumbMid]); + ImGui.TreePop(); + } + if (ImGui.TreeNodeEx("Tip", flags)) + { + drawJoint(playerJoints[Joint.LeftThumbHigh]); + ImGui.TreePop(); + } + ImGui.TreePop(); + } + ImGui.PopID(); + ImGui.PushID("Index"); + if (ImGui.TreeNodeEx("Index", flags)) + { + if (ImGui.TreeNodeEx("Base", flags)) + { + 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(); + } + 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(); + expanded = ImGui.TreeNodeEx("Palm", flags); + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Outer Palm/Pinky+Ring"); + ImGui.EndTooltip(); + } + if (expanded) + { + drawJoint(playerJoints[Joint.LeftPalm]); + ImGui.TreePop(); + } + 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(); + if (ImGui.Checkbox("Attach to Chest", ref attachToChest)) + { + if (!attachToChest) + { + toggleAttachToChest = false; + } + } + 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("Toggle", ref toggleAttachToChest); + ImGui.SameLine(); + ImGui.Checkbox("Swap Sides", ref swapChestSides); + ImGui.SetNextItemWidth(width * 0.35f); + ImGui.DragFloat("Strength", ref chestMoveScale, 0.001f); + ImGui.Checkbox("Set Index", ref setChestIndex); + ImGui.SameLine(); + if (!setChestIndex) + { + ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f); + } + if (setChestIndex && chestBone1 == 0x0) + { + ImGui.PushStyleColor(ImGuiCol.Text, 0xFF0000FF); + } + ImGui.SetNextItemWidth(width * 0.17f); + if (ImGui.InputInt("##Index 1", ref chestBoneIndex1, 1)) + { + if (chestBoneIndex1 < 0) chestBoneIndex1 = 0; + } + if (setChestIndex && chestBone1 == 0x0) + { + ImGui.PopStyleColor(); + } + ImGui.SameLine(); + if (setChestIndex && chestBone2 == 0x0) + { + ImGui.PushStyleColor(ImGuiCol.Text, 0xFF0000FF); + } + ImGui.SetNextItemWidth(width * 0.17f); + if (ImGui.InputInt("##Index 2", ref chestBoneIndex2, 1)) + { + if (chestBoneIndex2 < 0) chestBoneIndex2 = 0; + } + if (setChestIndex && chestBone2 == 0x0) + { + ImGui.PopStyleColor(); + } + if (!setChestIndex) + { + ImGui.PopStyleVar(); + } + 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 Bone #{i} (0x{jiggleData:X})")) + { + ImGui.DragFloat3("Position", ref MemoryUtil.GetRef(jiggleData + 0xD0), 0.05f); + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Drag this position around to influence the bone."); + ImGui.EndTooltip(); + } + } + ImGui.PopID(); + } + } + ImGui.Separator(); + if (ImGui.CollapsingHeader("Body Joints")) + { + drawJointLeaf(ref bodyJoints, 0, bodyRotations, bodyOffsets); + } + if (ImGui.CollapsingHeader("Face Joints")) + { + drawJointLeaf(ref faceJoints, 0, faceRotations, faceOffsets); + } + ImGui.PopItemWidth(); + } + + public static void drawModelParts(nint armorAddr, nint partsAddr = 0x0) + { + if (partsAddr == 0x0) + { + if (armorAddr == 0x0 || (partsAddr = MemoryUtil.Read(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}:"); + } + // MonsterHunterWorld.exe+222E651 - mov rax,[r8+000000C8] + nint baseLod = MemoryUtil.Read(partsAddr + 0xC8); + nint baseOffset = MemoryUtil.Read(partsAddr + 0x408 + (0x8 * 0x1)); + int numParts = MemoryUtil.Read(partsAddr + 0x548 + (0x4 * 0x1)); + // Setting lodCount to 0 is probably the best way to completely hide a model. + int lodCount = MemoryUtil.Read(partsAddr + 0xD0); + const int lodStructSize = 0x50; + const int partsPerLine = 10; + bool allOn = ImGui.Button("Show All"); + ImGui.SameLine(); + bool allOff = ImGui.Button("Hide All"); + for (int i = 0; i < numParts; i++) + { + ref int lodOffset = ref MemoryUtil.GetRef(baseOffset + (i * 0x4)); + nint lod0 = baseLod + lodOffset * lodStructSize; + bool isVisible = MemoryUtil.GetRef(lod0) != 0; + bool togglePart = ImGui.Checkbox($"##Part #{i}", ref isVisible); + if (ImGui.BeginItemTooltip()) + { + ImGui.Text($"Part #{i} (0x{lod0:X})"); + ImGui.EndTooltip(); + } + int lastLod = (i < numParts - 1) ? MemoryUtil.Read(baseOffset + ((i + 1) * 0x4)) : lodCount; + int partLodCount = lastLod - lodOffset; + // This is not a "proper" way to hide a part. It abuses the fact that if the lower + // 16 bits (lodVisible) of these 4 bytes are 0, a check to skip rendering it will + // always pass. Also that +0xA appears to be unused/padding. + // MonsterHunterWorld.exe+222FCE3 - mov eax,[r8] + ushort lod0Visible = MemoryUtil.GetRef(lod0); + for (int j = 0; j < partLodCount; j++) + { + if (togglePart || (lod0Visible != 0 && allOff) || (lod0Visible == 0 && allOn)) + { + nint lod = lod0 + (j * lodStructSize); + ref ushort lodVisible = ref MemoryUtil.GetRef(lod); + ref ushort padSub = ref MemoryUtil.GetRef(lod + 0xA); + if (lod0Visible != 0) Assert(padSub == 0); + // Check against LOD0 to prevent an inconsistent state. + if ((lodVisible != 0) == (lod0Visible != 0)) + { + (lodVisible, padSub) = (padSub, lodVisible); + } + } + if (modelOnlyAddressLod0) break; + } + if (i != numParts - 1 && i % partsPerLine != partsPerLine - 1) + { + ImGui.SameLine(); + } + } + ImGui.PopID(); + } + + private static void dropArmorState() + { + Array.Clear(playerArmor, 0, playerArmor.Length); + Array.Clear(playerJoints, 0, playerJoints.Length); + bodyJoints.Clear(); + ignoredJoints.Clear(); + faceJoints.Clear(); +#if QUARANTINED_FEATURES + ikJoints.Clear(); +#endif + jiggleBones.Clear(); + chestBone1 = 0x0; + chestBone2 = 0x0; + } + + private static void dropJointOffsets() + { + bodyRotations.Clear(); + bodyOffsets.Clear(); + faceRotations.Clear(); + faceOffsets.Clear(); +#if QUARANTINED_FEATURES + ikOffsets.Clear(); +#endif + } + + private static bool collectArmorAndJoints(Player player) + { + nint bodyArmorParts = MemoryUtil.Read(player.Instance + 0x2A0); + if (bodyArmorParts == 0x0) + { + return false; + } + // MonsterHunterWorld.exe+203E8A2 - mov rax,[rbx+000126C8] + nint combineArmorList = MemoryUtil.Read(player.Instance + 0x126C8); + if (combineArmorList == 0x0) + { + return false; + } + collectArmorParts(player.Instance, bodyArmorParts); + nint weapon = MemoryUtil.Read(player.Instance + 0x76B0); + if (weapon != 0x0) + { + nint weaponParts = MemoryUtil.Read(weapon + 0x2A0); + if (weaponParts != 0x0) + { + collectArmorParts(weapon, weaponParts); + } + } + nint slinger = MemoryUtil.Read(player.Instance + 0x8918); + if (slinger != 0x0) + { + nint slingerParts = MemoryUtil.Read(slinger + 0x2A0); + if (slingerParts != 0x0) + { + collectArmorParts(slinger, slingerParts); + } + } + combineArmorList = MemoryUtil.Read(combineArmorList + 0x70); + nint next = combineArmorList; + while (next != 0x0) + { + nint armorAddr = next; + next = MemoryUtil.Read(armorAddr + 0x30); + nint vTable = MemoryUtil.Read(armorAddr); + // uWeaponParts: 0x1434D2400, uWeaponEmblem: 0x1434D1D58 + if (vTable == 0x1434A7560) // uPlCombineArmor + { + nint partsAddr = 0x0; + nint childAddr = MemoryUtil.Read(armorAddr + 0x548); + if (childAddr != 0x0) + { + if (MemoryUtil.Read(childAddr) == 0x143451520) // Face. + { + nint ownerAddr = MemoryUtil.Read(childAddr + 0x998); + if (ownerAddr != player.Instance) + { + continue; + } + if (playerArmor[Armor.Face] == 0x0) + { + partsAddr = MemoryUtil.Read(childAddr + 0x2A0); + if (partsAddr != 0x0) + { + collectArmorParts(childAddr, partsAddr); + } + childAddr = MemoryUtil.Read(childAddr + 0x9C8); + if (childAddr != 0x0 && MemoryUtil.Read(childAddr) == 0x143505E98) // Eye lens. + { + partsAddr = MemoryUtil.Read(childAddr + 0x2A0); + if (partsAddr != 0x0) + { + collectArmorParts(childAddr, partsAddr); + } + } + } + } + else if (childAddr != player.Instance) + { + continue; + } + } + partsAddr = MemoryUtil.Read(armorAddr + 0x2A0); + if (partsAddr != 0x0) + { + collectArmorParts(armorAddr, partsAddr); + } + } + if (!playerArmor.Where(p => (p == 0x0)).Any()) + { + break; + } + } + return true; + } + + private static void refreshArmorState(Player player) + { + dropArmorState(); + if (!collectArmorAndJoints(player)) + { + dropJointOffsets(); + } + } + + private static bool usingArmorState() + { + return (bodyRotations.Count > 0 || bodyOffsets.Count > 0 || faceRotations.Count > 0 || faceOffsets.Count > 0) || + (hideKnife || checkKnifeHidden) || (enableFreeCamera && orbitPlayer && orbitJoint >= 0); + } + + private static void UpdateJointRotationHook(nint model) + { + if (!disableMod && usingArmorState()) + { + Player? player = getPlayerWithFallback(); + if (player != null && model == player.Instance) + { + refreshArmorState(player); + foreach ((nint addr, List rotations) in bodyRotations) + { + MemoryUtil.GetRef(addr + 0x70) *= Quaternion.CreateFromYawPitchRoll(rotations[0].X, rotations[0].Y, rotations[0].Z); + } + if (playerArmor[Armor.Waist] != 0x0) + { + MemoryUtil.GetRef(playerArmor[Armor.Waist] + 0x2D0) = hideKnife ? (byte)0xFD : (byte)0xFF; + checkKnifeHidden = false; + } + } + else if (player != null && model == playerArmor[Armor.Face]) + { + refreshArmorState(player); + foreach ((nint addr, List rotations) in faceRotations) + { + MemoryUtil.GetRef(addr + 0x70) *= Quaternion.CreateFromYawPitchRoll(rotations[0].X, rotations[0].Y, rotations[0].Z); + } + + } + } + updateJointRotationHook!.Original(model); + } + + private static void UpdateJointPositionHook(nint model) + { + updateJointPositionHook!.Original(model); + if (!disableMod && usingArmorState()) + { + Player? player = getPlayerWithFallback(); + if (player != null && model == player.Instance) + { + refreshArmorState(player); + foreach ((nint addr, List offsets) in bodyOffsets) + { + MemoryUtil.GetRef(addr + 0x50) += offsets[0]; + } + } + else if (player != null && model == playerArmor[Armor.Face]) + { + refreshArmorState(player); + foreach ((nint addr, List offsets) in faceOffsets) + { + MemoryUtil.GetRef(addr + 0x50) += offsets[0]; + } + } + } + } + +#if QUARANTINED_FEATURES + private static void UpdateIKHook(nint superOfChild, nint joint, nint obj) + { + if (!disableMod && ikOffsets.ContainsKey(joint)) + { + Vector3 offset = ikOffsets[joint][0]; + MemoryUtil.GetRef(superOfChild + 0x1380) += offset; + } + updateIKHook!.Original(superOfChild, joint, obj); + } +#endif + + /* + private void ChangeEquipmentHook(nint unknownPtr, int unknownInt) + { + nint rax = MemoryUtil.Read(unknownPtr + 0x2968); + nint r9 = MemoryUtil.Read(unknownPtr + 0x2950); + int esi = MemoryUtil.Read(rax + 0x240); + esi *= MemoryUtil.Read(r9 + 0x1D8); + esi += unknownInt; + nint newEquipment = newEquipmentPointer.Invoke(unknownPtr, esi); + lastEquipedId = MemoryUtil.Read(newEquipment + 0x24); + changeEquipmentHook!.Original(unknownPtr, unknownInt); + } + */ + + public static void drawPlayerInfo(Player player, float width) + { + nint playerSettings = getPlayerSettings(); + + ImGui.Text($"{Marshal.PtrToStringAnsi(playerSettings + 0x50)}"); + + ImGui.Checkbox("Hide Weapon", ref hideWeapon); + ImGui.SameLine(); + if (ImGui.Checkbox("Hide Knife", ref hideKnife)) + { + checkKnifeHidden = true; + } + ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(0.0f, 6.0f)); + ImGui.Text("Head Armor Display"); + // MonsterHunterWorld.exe+11A2967 - cmp byte ptr [rax+001403E1],01 + ref byte showHeadArmor = ref MemoryUtil.GetRef(playerSettings + 0x1403E1); + int showHeadArmorInt = showHeadArmor; + ImGui.SameLine(); + ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); + if (ImGui.RadioButton("Show", ref showHeadArmorInt, 0)) + { + showHeadArmor = (byte)showHeadArmorInt; + } + ImGui.SameLine(); + ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); + if (ImGui.RadioButton("Hide", ref showHeadArmorInt, 1)) + { + showHeadArmor = (byte)showHeadArmorInt; + } + ImGui.SameLine(); + ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); + if (ImGui.RadioButton("Hide in Cutscenes", ref showHeadArmorInt, 2)) + { + showHeadArmor = (byte)showHeadArmorInt; + } + + ImGui.Separator(); + + bool armorStateRefreshed = false; + + ImGui.PushID("Joints"); + if (ImGui.CollapsingHeader("Joints")) + { + if (!armorStateRefreshed) + { + refreshArmorState(player); + armorStateRefreshed = true; + } + ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(0.0f, 6.0f)); +#if QUARANTINED_FEATURES + ImGui.Text($"Joint Rotations: {bodyRotations.Count + faceRotations.Count}, Joint Offsets: {bodyOffsets.Count + faceOffsets.Count}, IK Offsets: {ikOffsets.Count}"); +#else + ImGui.Text($"Joint Rotations: {bodyRotations.Count + faceRotations.Count}, Joint Offsets: {bodyOffsets.Count + faceOffsets.Count}"); +#endif + ImGui.SameLine(); + ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); + if (ImGui.Button("Clear")) + { + dropJointOffsets(); + } + ImGui.SameLine(); + /* + ref byte ikDisabledB = ref MemoryUtil.GetRef(MemoryUtil.Read(player.Instance + 0x990) + 0x5C); + bool ikDisabled = ikDisabledB == 0x0; + if (ImGui.Checkbox("Disable IK", ref ikDisabled)) + { + ikDisabledB = ByteFlag(!ikDisabled); + } + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Mostly disable inverse kinematics on your player. To rotate ankles, you need to use Force Disable IK."); + ImGui.EndTooltip(); + } + ImGui.SameLine(); + */ + ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); + if (ImGui.Checkbox("Disable IK", ref ikForcedOff)) + { + if (ikForcedOff) + { + forceDisableIK.Enable(); + } + else + { + forceDisableIK.Disable(); + } + } + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Forcefully disable inverse kinematics."); + ImGui.EndTooltip(); + } + drawJoints(width); + ImGui.Separator(); + } + ImGui.PopID(); + + ImGui.PushID("Parts"); + if (ImGui.CollapsingHeader("Armor Parts")) + { + if (!armorStateRefreshed) + { + refreshArmorState(player); + armorStateRefreshed = true; + } + bool expaned = ImGui.CollapsingHeader("Helmet"); + ImGui.SameLine(); + ImGui.Text($"(id: {MemoryUtil.Read(player.Instance + 0x1373C):X})"); + if (expaned) + { + drawModelParts(playerArmor[Armor.Helmet]); + ImGui.Separator(); + } + expaned = ImGui.CollapsingHeader("Body"); + ImGui.SameLine(); + ImGui.Text($"(id: {MemoryUtil.Read(player.Instance + 0x13740):X})"); + if (expaned) + { + drawModelParts(playerArmor[Armor.Body]); + ImGui.Separator(); + } + expaned = ImGui.CollapsingHeader("Arms"); + ImGui.SameLine(); + ImGui.Text($"(id: {MemoryUtil.Read(player.Instance + 0x13744):X})"); + if (expaned) + { + drawModelParts(playerArmor[Armor.Arm]); + ImGui.Separator(); + } + expaned = ImGui.CollapsingHeader("Waist"); + ImGui.SameLine(); + ImGui.Text($"(id: {MemoryUtil.Read(player.Instance + 0x13748):X})"); + if (expaned) + { + drawModelParts(playerArmor[Armor.Waist]); + ImGui.Separator(); + } + expaned = ImGui.CollapsingHeader("Legs"); + ImGui.SameLine(); + ImGui.Text($"(id: {MemoryUtil.Read(player.Instance + 0x1374C):X})"); + if (expaned) + { + drawModelParts(playerArmor[Armor.Leg]); + ImGui.Separator(); + } + /* + expaned = ImGui.CollapsingHeader("Weapon"); + if (expaned) + { + drawModelParts(playerArmor[Armor.Weapon]); + ImGui.Separator(); + } + */ + expaned = ImGui.CollapsingHeader("Slinger"); + ImGui.SameLine(); + ImGui.Text($"(id: {MemoryUtil.Read(player.Instance + 0x13D8C):X}_{MemoryUtil.Read(player.Instance + 0x13D90):X})"); + if (expaned) + { + drawModelParts(playerArmor[Armor.Slinger]); + ImGui.Separator(); + } + if (ImGui.CollapsingHeader("Hair")) + { + drawModelParts(playerArmor[Armor.Hair]); + ImGui.Separator(); + } + if (ImGui.CollapsingHeader("Face")) + { + drawModelParts(playerArmor[Armor.Face]); + ImGui.Separator(); + } + if (ImGui.CollapsingHeader("Eye Lens")) + { + drawModelParts(playerArmor[Armor.EyeLens]); + } + ImGui.Separator(); + } + ImGui.PopID(); + + nint controlsAddr = MemoryUtil.Read(player.Instance + 0x12608); + nint zoneStateAddr = MemoryUtil.Read(0x1451C42B8); + ZoneState zoneState = ZoneState.Unknown; + if (controlsAddr != 0x0 && zoneStateAddr != 0x0) + { + ref byte passiveFlag = ref MemoryUtil.GetRef(player.Instance + 0x7626); + ref byte passiveFlag2 = ref MemoryUtil.GetRef(MemoryUtil.Read(player.Instance + 0x7D20) + 0x9B8); + bool passive = passiveFlag == 0x1 && passiveFlag2 == 0x1; + if (ImGui.Checkbox("Passive", ref passive)) + { + passiveFlag = ByteFlag(passive); + passiveFlag2 = ByteFlag(passive); + } + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Passive: Calm camera and your hunter looks neutral/smiles.\nCombat: Intense camera and your hunter looks angry.\nIf you have Passive set and Combat Controls on, or vice versa, expect glitchy behavior."); + ImGui.EndTooltip(); + } + bool combatControls = MemoryUtil.Read(controlsAddr + 0xB18) == 0x80; + zoneState = combatControls ? ZoneState.Combat : ZoneState.Hub; +#if !QUARANTINED_FEATURES + ImGui.Text($"Current Zone State: {((MemoryUtil.GetRef(zoneStateAddr + 0xD2EA) == 0x1) ? "Hub" : "Combat")}"); +#else + if (ImGui.Checkbox("Combat Controls", ref combatControls)) + { + passiveFlag = ByteFlag(!combatControls); + passiveFlag2 = ByteFlag(!combatControls); + setPlayerController1.Invoke(player.Instance); + setPlayerController5.Invoke(controlsAddr); + } + int zoneStateInt = (int)forceZoneState; + ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(0.0f, 6.0f)); + ImGui.Text($"Force Zone State (Current: {((MemoryUtil.GetRef(zoneStateAddr + 0xD2EA) == 0x1) ? "Hub" : "Combat")})"); + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("This will apply when moving to a different area."); + ImGui.EndTooltip(); + } + ImGui.SameLine(); + ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); + ImGui.RadioButton("Off", ref zoneStateInt, 0); + ImGui.SameLine(); + ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); + ImGui.RadioButton("Hub", ref zoneStateInt, 1); + ImGui.SameLine(); + ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); + ImGui.RadioButton("Combat", ref zoneStateInt, 2); + forceZoneState = (ZoneState)zoneStateInt; + if (ImGui.Button("Run Change Zone State")) + { + zoneStateManualInvoke = true; + setZoneState.Invoke(player.Instance, 0x000106C0); // or 0x00010780. + } + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("You can use this to apply the value of Force Zone State.\nIf you're in a map and Force Zone State is set to Off or Combat, this will send you back to camp."); + ImGui.EndTooltip(); + } + if (ImGui.Checkbox("Force Passive in Combat Zones", ref forcePassiveInCombatZone)) + { + if (forcePassiveInCombatZone) + { + zoneStateForcePassive1.Enable(); + zoneStateForcePassive2.Enable(); + } + else + { + zoneStateForcePassive1.Disable(); + zoneStateForcePassive2.Disable(); + } + } + if (ImGui.Checkbox("Force Combat in Passive Zones", ref forceCombatInPassiveZone)) + { + if (forceCombatInPassiveZone) + { + zoneStateForceCombat1.Enable(); + zoneStateForceCombat2.Enable(); + } + else + { + zoneStateForceCombat1.Disable(); + zoneStateForceCombat2.Disable(); + } + } +#endif + } + + if (zoneState != ZoneState.Combat) + { + ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); + ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f); + } + if (ImGui.Checkbox("Force Crawl", ref enableCrawl)) + { + if (enableCrawl) + { + MemoryUtil.GetRef(psuedoObject2 + 0x70) = player.Position.X + player.Forward.X; + MemoryUtil.GetRef(psuedoObject2 + 0x74) = player.Position.Y + player.Forward.Y; + MemoryUtil.GetRef(psuedoObject2 + 0x78) = player.Position.Z + player.Forward.Z; + + Quaternion playerRotation = new Quaternion(player.Forward.X, player.Forward.Y, player.Forward.Z, 0.0f); + Quaternion objectRotation = getRight(playerRotation); + + MemoryUtil.GetRef(psuedoObject2 + 0x40) = objectRotation.X; + MemoryUtil.GetRef(psuedoObject2 + 0x44) = objectRotation.Y; + MemoryUtil.GetRef(psuedoObject2 + 0x48) = objectRotation.Z; + MemoryUtil.GetRef(psuedoObject2 + 0x4C) = objectRotation.W; + + MemoryUtil.GetRef(psuedoObject2 + 0x50) = 0.0f; + MemoryUtil.GetRef(psuedoObject2 + 0x54) = 1.0f; + MemoryUtil.GetRef(psuedoObject2 + 0x58) = 0.0f; + MemoryUtil.GetRef(psuedoObject2 + 0x5C) = 0.0f; + + MemoryUtil.GetRef(psuedoObject2 + 0x60) = playerRotation.X; + MemoryUtil.GetRef(psuedoObject2 + 0x64) = playerRotation.Y; + MemoryUtil.GetRef(psuedoObject2 + 0x68) = playerRotation.Z; + MemoryUtil.GetRef(psuedoObject2 + 0x6C) = playerRotation.W; + } + } + if (zoneState != ZoneState.Combat) + { + ImGui.PopItemFlag(); + ImGui.PopStyleVar(); + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("You have to be out in a map to use this."); + ImGui.EndTooltip(); + } + } + else + { + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Simulate crawling under an object in the direction your character was facing when enabled."); + ImGui.EndTooltip(); + } + } + + if (zoneState != ZoneState.Hub) + { + ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); + ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f); + } + if (ImGui.Button("Sit in Hot Springs")) + { + // Run sit in hot springs action (top of function). + // MonsterHunterWorld.exe+17601F0 - mov [rsp+08],rbx + MemoryUtil.WriteBytes(player.ActionController.Instance + 0xC0, [0x65, 0x00, 0x00, 0x00]); + MemoryUtil.WriteBytes(player.ActionController.Instance + 0xBC, [0x01, 0x00, 0x00, 0x00]); + } + if (zoneState != ZoneState.Hub) + { + ImGui.PopItemFlag(); + ImGui.PopStyleVar(); + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("You have to be in a hub area to use this."); + ImGui.EndTooltip(); + } + } + + if (ImGui.Checkbox("Allow Hot Springs Anywhere", ref allowHotSpringsAnywhere)) + { + if (allowHotSpringsAnywhere) + { + jmpOverHotSpringsEval.Enable(); + } + else + { + jmpOverHotSpringsEval.Disable(); + } + } + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Disable check for being about halfway submerged in water to stay sitting."); + ImGui.EndTooltip(); + } + + if (ImGui.Checkbox("Disable Hot Springs Steam", ref disableHotSpringsSteam)) + { + if (disableHotSpringsSteam) + { + jmpOverHotSpringsSteam.Enable(); + } + else + { + jmpOverHotSpringsSteam.Disable(); + } + } + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("It will take a couple of seconds to fade away."); + ImGui.EndTooltip(); + } + + ref float playerOpacity = ref MemoryUtil.GetRef(player.Instance + 0x78E0); + ImGui.SetNextItemWidth(width * 0.325f); + if (ImGui.DragFloat("Opacity", ref playerOpacity, 0.01f, 0.0f, Single.MaxValue)) + { + playerOpacityOverride = playerOpacity; + } + + ImGui.PushID("Wetness"); + if (ImGui.CollapsingHeader("Wetness")) + { + nint wetnessAddr = player.Instance + 0x13BD0; + ImGui.PushItemWidth(width * 0.15f); + ImGui.DragFloat("Head", ref MemoryUtil.GetRef(wetnessAddr), 0.005f); + ImGui.SameLine(); + ImGui.DragFloat("Body", ref MemoryUtil.GetRef(wetnessAddr + 0x28), 0.005f); + ImGui.DragFloat("Waist", ref MemoryUtil.GetRef(wetnessAddr + 0x50), 0.005f); + ImGui.SameLine(); + ImGui.DragFloat("Legs", ref MemoryUtil.GetRef(wetnessAddr + 0x78), 0.005f); + ImGui.PopItemWidth(); + ImGui.SetNextItemWidth(width * 0.35f); + if (ImGui.DragFloat("Whole Body", ref wholeBodyWetness, 0.005f)) + { + if (overridePlayerWetness) + { + writePlayerWholeBodyWetness(wetnessAddr); + } + } + if (ImGui.Button("Reset")) + { + wholeBodyWetness = 0.0f; + writePlayerWholeBodyWetness(wetnessAddr); + } + ImGui.SameLine(); + if (ImGui.Checkbox("Override Player Wetness", ref overridePlayerWetness)) + { + if (overridePlayerWetness) + { + overridePlayerWetnessEnable(); + writePlayerWholeBodyWetness(wetnessAddr); + } + else + { + overridePlayerWetnessDisable(); + } + } + ImGui.Separator(); + } + ImGui.PopID(); + + 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); + ImGui.SliderFloat4("Rotation", ref rotation, -1.0f, 1.0f); + Vector3 rotationOffset = new Vector3(); + if (ImGui.DragFloat3("Rotation Offset", ref rotationOffset, 0.0025f)) + { + 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")) + { + player.Rotation.X = 0.0f; + player.Rotation.Z = 0.0f; + } + if (ImGui.Checkbox("Disable Collision", ref disableCollision)) + { + if (disableCollision) + { + disableCollisionEnable(); + } + else + { + if (disableExtraGravity) + { + disableExtraGravity = false; + disableExtraGravityDisable(); + } + if (disableGravity) + { + disableGravity = false; + disableGravityDisable(); + } + if (disableExtraCollision) + { + disableExtraCollision = false; + disableExtraCollisionDisable(); + } + disableCollisionDisable(); + } + } + if (!disableCollision) + { + ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); + ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f); + } + if (ImGui.Checkbox("Disable Another Y Collision", ref disableExtraCollision)) + { + if (disableExtraCollision) + { + disableExtraCollisionEnable(); + } + else + { + if (disableExtraGravity) + { + disableExtraGravity = false; + disableExtraGravityDisable(); + } + if (disableGravity) + { + disableGravity = false; + disableGravityDisable(); + } + disableExtraCollisionDisable(); + } + } + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("This will make your legs goofy, but is needed to get on top of some things."); + ImGui.EndTooltip(); + } + if (!disableCollision) + { + ImGui.PopItemFlag(); + ImGui.PopStyleVar(); + } + if (!disableExtraCollision) + { + ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); + ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f); + } + if (ImGui.Checkbox("Disable Y Gravity", ref disableGravity)) + { + if (disableGravity) + { + disableGravityEnable(); + } + else + { + if (disableExtraGravity) + { + disableExtraGravity = false; + disableExtraGravityDisable(); + } + disableGravityDisable(); + } + } + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Avoid falling when going too high (Y axis)."); + ImGui.EndTooltip(); + } + if (!disableExtraCollision) + { + ImGui.PopItemFlag(); + ImGui.PopStyleVar(); + } + if (!disableGravity) + { + ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); + ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f); + } + if (ImGui.Checkbox("Disable More Gravity", ref disableExtraGravity)) + { + if (disableExtraGravity) + { + disableExtraGravityEnable(); + } + else + { + disableExtraGravityDisable(); + } + } + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("This can stop you from falling when going out of bounds and/or rotating."); + ImGui.EndTooltip(); + } + if (!disableGravity) + { + ImGui.PopItemFlag(); + ImGui.PopStyleVar(); + } + drawAnimationInfo(player, width, false); + } + } +} diff --git a/Plugin.cs b/Plugin.cs index ca042e1..39ddf94 100755 --- a/Plugin.cs +++ b/Plugin.cs @@ -2,7 +2,7 @@ //#define HOOK_ORDER_ASSERTS //#define LOG_DEBUG_MESSAGES #define MOUSE_AND_KEYBOARD_LAYER -//#define QUARANTINED_FEATURES +//#define INTEROP_FEATURE using System.Numerics; using System.Runtime.InteropServices; @@ -145,7 +145,7 @@ namespace NewCamera public static bool InitFromLoadedInstance() { -#if QUARANTINED_FEATURES +#if INTEROP_FEATURE Instance = IPlugin.GetInstance(PluginName); #endif return Instance != null; @@ -177,18 +177,18 @@ namespace NewCamera private const float DEFAULT_FOV = Config.DEFAULT_FOV; private const float DEFAULT_NEAR_CLIP = Config.DEFAULT_NEAR_CLIP; - private static void Assert(bool condition) + public static void Assert(bool condition) { #if ENABLE_ASSERTS Trace.Assert(condition); #endif } - private static nint lton(long l) { unchecked { return (nint)l; } } + public static nint lton(long l) { unchecked { return (nint)l; } } - private static byte ByteFlag(bool f) { return f ? (byte)0x1 : (byte)0x0; } + public static byte ByteFlag(bool f) { return f ? (byte)0x1 : (byte)0x0; } - private bool disableMod = false; + public static bool disableMod = false; private static readonly MtObject sMain = SingletonManager.GetSingleton("sMhMain")!; private bool freezeGame = false; @@ -215,7 +215,7 @@ namespace NewCamera private bool disableFading = false; private int cameraWrapState = 0; - private bool enableFreeCamera = false; + public static bool enableFreeCamera = false; private bool freeCamera = false; private bool freeCameraFromViewMode = false; private bool freeCameraFallback = false; @@ -236,14 +236,14 @@ namespace NewCamera private NativeFunction getViewParamOffset; - private bool orbitPlayer = false; + public static bool orbitPlayer = false; private bool orbitIgnoreCamera = false; private float orbitMovementRotation = 0.0f; private float orbitDistance = 350.0f; private float orbitY = 150.0f; private float orbitRight = 0.0f; private float orbitLerp = 0.25f; - private int orbitJoint = -1; + public static int orbitJoint = -1; private bool enableOffsetPerspective = false; private bool offsetPerspective = false; @@ -301,7 +301,7 @@ namespace NewCamera private string modelFilter = ""; private bool modelFilterIsRegex = false; private Regex? modelRegex = null; - private bool modelOnlyAddressLod0 = false; + public static bool modelOnlyAddressLod0 = false; private delegate void ProcessCameraDelegate(nint cameraPointer); private Hook? setCameraHook; @@ -341,9 +341,6 @@ namespace NewCamera private delegate float CheckMovementDelegate(int stickValue, float alwaysZero); private Hook? checkMovementHook; - private delegate void CollisionCheckDelegate(nint unknownPtr, nint unknownPtr2); - private Hook? collisionCheckHook; - private delegate void CameraEffectDelegate(nint unknownPtr, nint unknownPtr2, nint unknownPtr3); private Hook? cameraEffectHook; @@ -388,299 +385,6 @@ namespace NewCamera underwaterCamera5.Disable(); } - private static readonly MtObject sPlayer = SingletonManager.GetSingleton("sPlayer")!; - private int saveSlotIndex = -1; - private NativeFunction getSaveSlotGuiAddr; - private NativeFunction getPlayerSettingsAddr; - private nint getPlayerSettings() - { - nint rcx = MemoryUtil.Read(0x145013950); - if (saveSlotIndex >= 0) - { - // MonsterHunterWorld.exe+ADC442 - imul rdx,rcx,0026CC00 - nint rax = saveSlotIndex * 0x26CC00; - rax += MemoryUtil.Read(rcx + 0xA8); - return rax; - } - // MonsterHunterWorld.exe+1B8DBB0 - movsxd rax,dword ptr [rcx+000000A0] - return getPlayerSettingsAddr.Invoke(rcx); - } - private bool hideWeapon = false; - private bool hideKnife = false; - private bool checkKnifeHidden = false; - - 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 Weapon = 5; - public const byte Slinger = 6; - public const byte Hair = 7; - public const byte Face = 8; - public const byte EyeLens = 9; - } - - private static class Joint - { - public const byte Root = 0x0; - public const byte Root2 = 0xD; - public const byte LowerBack = 0x1; - public const byte UpperBack = 0x2; - public const byte LowerNeck = 0x3; - public const byte LowerNeckNull = 0xFE; - public const byte UpperNeck = 0x4; - public const byte LeftCollarbone = 0x5; - public const byte LeftShoulderNull = 0x46; - public const byte LeftShoulder = 0x6; - public const byte LeftElbow = 0x7; - public const byte LeftWrist = 0x8; - public const byte LeftWristNull = 0x1E; - public const byte LeftThumbLow = 0x1F; - public const byte LeftThumbMid = 0x20; - public const byte LeftThumbHigh = 0x21; - public const byte LeftIndexLow = 0x22; - public const byte LeftIndexMid = 0x23; - public const byte LeftIndexHigh = 0x24; - public const byte LeftMiddleLow = 0x25; - public const byte LeftMiddleMid = 0x26; - public const byte LeftMiddleHigh = 0x27; - public const byte LeftPalm = 0x28; - public const byte LeftRingLow = 0x29; - public const byte LeftRingMid = 0x2A; - public const byte LeftRingHigh = 0x2B; - public const byte LeftPinkyLow = 0x2C; - public const byte LeftPinkyMid = 0x2D; - public const byte LeftPinkyHigh = 0x2E; - public const byte LeftArmUnk1 = 0x51; - public const byte LeftArmUnk2 = 0x65; - public const byte LeftArmUnk3 = 0x66; - public const byte LeftArmUnk4 = 0x67; - public const byte LeftArmUnk5 = 0x68; - public const byte LeftArmUnk6 = 0x47; - public const byte LeftArmUnk7 = 0x50; - public const byte RightCollarbone = 0x9; - public const byte RightShoulder = 0xA; - public const byte RightElbow = 0xB; - public const byte RightWrist = 0xC; - public const byte RightWristNull = 0x2F; - public const byte RightThumbLow = 0x30; - public const byte RightThumbMid = 0x31; - public const byte RightThumbHigh = 0x32; - public const byte RightIndexLow = 0x33; - public const byte RightIndexMid = 0x34; - public const byte RightIndexHigh = 0x35; - public const byte RightMiddleLow = 0x36; - public const byte RightMiddleMid = 0x37; - public const byte RightMiddleHigh = 0x38; - public const byte RightPalm = 0x39; - public const byte RightRingLow = 0x3A; - public const byte RightRingMid = 0x3B; - public const byte RightRingHigh = 0x3C; - public const byte RightPinkyLow = 0x3D; - public const byte RightPinkyMid = 0x3E; - public const byte RightPinkyHigh = 0x3F; - public const byte RightArmUnk1 = 0x53; - public const byte RightArmUnk2 = 0x49; - public const byte RightArmUnk3 = 0x52; - public const byte RightArmUnk4 = 0x48; - public const byte Unknown1 = 0xF7; - public const byte Unknown2 = 0xF8; - public const byte LeftHip = 0xE; - public const byte LeftKnee = 0xF; - public const byte LeftAnkle = 0x10; - public const byte LeftToes = 0x11; - public const byte LeftAnkleNull = 0x54; - public const byte LeftKneeNull = 0x4B; - public const byte LeftHipNull = 0x4A; - public const byte Unknown3 = 0x40; - public const byte Unknown4 = 0x42; - public const byte RightHip = 0x12; - public const byte RightKnee = 0x13; - public const byte RightAnkle = 0x14; - public const byte RightToes = 0x15; - public const byte RightAnkleNull = 0x55; - public const byte RightKneeNull = 0x4D; - public const byte RightHipNull = 0x4C; - public const byte Unknown5 = 0x43; - public const byte Unknown6 = 0x45; - public const byte Unknown7 = 0xF9; - public const byte Unknown8 = 0xFA; - public const byte Unknown9 = 0xFB; - public const byte Unknown10 = 0xFC; - public const byte Unknown11 = 0xFD; - } - - private nint[] playerArmor = new nint[10]; - private nint[] playerJoints = new nint[0xFF]; - - private delegate void UpdateJoints(nint obj); - private Hook? updateJointRotationHook; - private Hook? updateJointPositionHook; - private List bodyJoints = new List(); - private List ignoredJoints = new List(); - private Dictionary> bodyRotations = new Dictionary>(); - private Dictionary> bodyOffsets = new Dictionary>(); - - private List faceJoints = new List(); - private Dictionary> faceRotations = new Dictionary>(); - private Dictionary> faceOffsets = new Dictionary>(); - -#if QUARANTINED_FEATURES - private delegate void UpdateIK(nint superOfChild, nint joint, nint obj); - private Hook? updateIKHook; - private Dictionary> ikOffsets = new Dictionary>(); - private List ikJoints = new List(); -#endif - private bool ikForcedOff = false; - private Patch forceDisableIK; - - private List jiggleBones = new List(); - private bool attachToChest = false; - private bool toggleAttachToChest = false; - private bool swapChestSides = false; - private float chestMoveScale = 0.25f; - private bool setChestIndex = false; - private int chestBoneIndex1 = 0; - private int chestBoneIndex2 = 1; - private nint chestBone1 = 0x0; - private nint chestBone2 = 0x0; - - /* - private delegate void ChangeEquipment(nint unknownPtr, int unknownInt); - private Hook? changeEquipmentHook; - private NativeFunction newEquipmentPointer; - private int lastEquipedId = 0; - */ - - private bool disableCollision = false; - private bool disableExtraCollision = false; - private bool disableGravity = false; - private bool disableExtraGravity = false; - private Patch disableXCollision; - private Patch disableYCollision; - private Patch disableSecondaryYCollision; - private Patch disableZCollision; - private Patch disableExtraYCollision; - private Patch disableGravityYUpdate; - private Patch disableGravityXZUpdate; - private Patch disableGravityEval; - - private void disableCollisionEnable() - { - disableXCollision.Enable(); - disableYCollision.Enable(); - disableSecondaryYCollision.Enable(); - disableZCollision.Enable(); - } - - private void disableCollisionDisable() - { - disableXCollision.Disable(); - disableYCollision.Disable(); - disableSecondaryYCollision.Disable(); - disableZCollision.Disable(); - } - - private void disableExtraCollisionEnable() - { - disableExtraYCollision.Enable(); - } - - private void disableExtraCollisionDisable() - { - disableExtraYCollision.Disable(); - } - - private void disableGravityEnable() - { - disableGravityYUpdate.Enable(); - } - - private void disableGravityDisable() - { - disableGravityYUpdate.Disable(); - } - - private void disableExtraGravityEnable() - { - disableGravityEval.Enable(); - } - - private void disableExtraGravityDisable() - { - disableGravityEval.Disable(); - } - - private enum ZoneState : int - { - Unknown = 0, - Hub = 1, - Combat = 2 - } - -#if QUARANTINED_FEATURES - private ZoneState forceZoneState = ZoneState.Unknown; - private ZoneState lastZoneState = ZoneState.Unknown; - private NativeAction setZoneState; - private NativeAction setPlayerController1; - private NativeAction setPlayerController5; - private bool zoneStateManualInvoke = false; - private bool forcePassiveInCombatZone = false; - private Patch zoneStateForcePassive1; - private Patch zoneStateForcePassive2; - private bool forceCombatInPassiveZone = false; - private Patch zoneStateForceCombat1; - private Patch zoneStateForceCombat2; -#endif - private delegate void ZoneStateDelegate(nint player, int flags); - private Hook? setZoneStateHook; - - private bool allowHotSpringsAnywhere = false; - private Patch jmpOverHotSpringsEval; - - private bool disableHotSpringsSteam = false; - private Patch jmpOverHotSpringsSteam; - - private bool enableCrawl = false; - private NativeAction procEnvironmentCollision; - private nint psuedoObject1; - private nint psuedoObject2; - - private float playerOpacityOverride = 1.0f; - private delegate void RefreshEntityParams(nint entity, nint unknownPtr2); - private Hook? refreshEntityParamsHook; - - private bool overridePlayerWetness = false; - private Patch noopPlayerWetnessUpdate; - private Patch jmpOverChangeEquipmentWetnessUpdate_1; - private Patch jmpOverChangeEquipmentWetnessUpdate_2; - private float wholeBodyWetness = 0.0f; - - private void overridePlayerWetnessEnable() - { - noopPlayerWetnessUpdate.Enable(); - jmpOverChangeEquipmentWetnessUpdate_1.Enable(); - jmpOverChangeEquipmentWetnessUpdate_2.Enable(); - } - - private void overridePlayerWetnessDisable() - { - noopPlayerWetnessUpdate.Disable(); - jmpOverChangeEquipmentWetnessUpdate_1.Disable(); - jmpOverChangeEquipmentWetnessUpdate_2.Disable(); - } - - private void writePlayerWholeBodyWetness(nint wetnessAddr) - { - MemoryUtil.GetRef(wetnessAddr) = wholeBodyWetness; - MemoryUtil.GetRef(wetnessAddr + 0x28) = wholeBodyWetness; - MemoryUtil.GetRef(wetnessAddr + 0x50) = wholeBodyWetness; - MemoryUtil.GetRef(wetnessAddr + 0x78) = wholeBodyWetness; - } - private static readonly MtObject sOtomo = SingletonManager.GetSingleton("sOtomo")!; // Gui strings. @@ -749,25 +453,9 @@ namespace NewCamera Animal.Initialize(); - getViewParamOffset = new NativeFunction(0x14136E6C0); - -#if QUARANTINED_FEATURES - // MonsterHunterWorld.exe+20354F7 - call MonsterHunterWorld.exe+1F73850 - setZoneState = new NativeAction(0x142035020); - setPlayerController1 = new NativeAction(0x141F73850); - setPlayerController5 = new NativeAction(0x14118DDC0); - zoneStateForcePassive1 = new Patch(lton(0x140256A3F) + 0x6, [0x1]); - zoneStateForcePassive2 = new Patch(lton(0x141AC2865) + 0x6, [0x1]); - zoneStateForceCombat1 = new Patch(lton(0x141AC2938) + 0x6, [0x0]); - zoneStateForceCombat2 = new Patch(lton(0x141AC28EC) + 0x6, [0x0]); -#endif - setZoneStateHook = Hook.Create(0x142035020, SetZoneStateHook); // nint, int + PlayerExt.Initialize(); - procEnvironmentCollision = new NativeAction(0x141F737D0); - psuedoObject1 = (nint)NativeMemory.AllocZeroed(0x7C); - MemoryUtil.WriteBytes(psuedoObject1 + 0x30, [0x03]); - psuedoObject2 = (nint)NativeMemory.AllocZeroed(0x7C); - MemoryUtil.WriteBytes(psuedoObject2 + 0x30, [0x08]); + getViewParamOffset = new NativeFunction(0x14136E6C0); // Asserts based on version 15.23.00. // @TODO: Handle addr not found. @@ -850,8 +538,6 @@ namespace NewCamera Assert(addr == 0x142107CB0); // int, float checkMovementHook = Hook.Create(addr, CheckMovementHook); - collisionCheckHook = Hook.Create(0x1411C4E50, CollisionCheckHook); // nint, nint - cameraEffectHook = Hook.Create(0x141AB6AE0, CameraEffectHook); // nint, nint, nint addr = PatternScanner.FindFirst(Pattern.FromString("84 C0 0F 84 ?? ?? ?? ?? 48 8B 57 28 45 33 C0 48 8B CE E8 ?? ?? ?? ?? 48 8B 97 E0 01 00 00 41 B0 01 48 8B CE E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B D8")); @@ -878,66 +564,6 @@ namespace NewCamera nullifyDofCoc = new Patch(lton(0x1424236DD), [0x0F, 0x57, 0xF6, 0x90, 0x90, 0x90, 0x90]); underwaterCheckHook = Hook.Create(0x1412AD500, UnderwaterCheckHook); // nint - getSaveSlotGuiAddr = new NativeFunction(0x141AC0B60); - getPlayerSettingsAddr = new NativeFunction(0x141B8DBB0); - - forceDisableIK = new Patch(lton(0x14031FD40), [0xC6, 0x81, 0x81, 0x01, 0x00, 0x00, 0x00, 0xC3]); - - // Alt: 0x141FBC7A0 (model - 0x958) - updateJointRotationHook = Hook.Create(0x14223BA30, UpdateJointRotationHook); - updateJointPositionHook = Hook.Create(0x142228F50, UpdateJointPositionHook); - -#if QUARANTINED_FEATURES - updateIKHook = Hook.Create(0x142472C00, UpdateIKHook); -#endif - - /* - changeEquipmentHook = Hook.Create(0x141DDEF80, ChangeEquipmentHook); // nint, int - newEquipmentPointer = new NativeFunction(0x141DE56A0); - */ - - // Player + ECCC = How far underwater is the player. - jmpOverHotSpringsEval = new Patch(lton(0x1417C1B03), [0xEB]); - jmpOverHotSpringsSteam = new Patch(lton(0x14203A494), [0xE9, 0x8D, 0x00, 0x00, 0x00, 0x90]); - - refreshEntityParamsHook = Hook.Create(0x141F605F0, RefreshEntityParamsHook); // nint, nint - - noopPlayerWetnessUpdate = new Patch(lton(0x14203E893), [0x90, 0x90, 0x90, 0x90, 0x90]); - jmpOverChangeEquipmentWetnessUpdate_1 = new Patch(lton(0x14203E310), [0xEB]); // je -> jmp. - jmpOverChangeEquipmentWetnessUpdate_2 = new Patch(lton(0x14203E397), [0xE9, 0xB9, 0x00, 0x00, 0x00, 0x90]); // je -> jmp. - - // Noop collision checks. - addr = PatternScanner.FindFirst(Pattern.FromString("F3 0F 11 06 F3 0F 10 48 04 F3 0F 58 4E 04 F3 0F 11 4E 04 F3 0F 10 40 08 F3 0F 58 46 08 F3 0F 11 46 08 44 8B AF E0 0B 00 00")); - Assert(addr == 0x141C001B5); - disableXCollision = new Patch(addr, [0x90, 0x90, 0x90, 0x90]); - Assert(addr + 0xE == 0x141C001C3); - disableYCollision = new Patch(addr + 0xE, [0x90, 0x90, 0x90, 0x90, 0x90]); - Assert(addr + 0x1D == 0x141C001D2); - disableZCollision = new Patch(addr + 0x1D, [0x90, 0x90, 0x90, 0x90, 0x90]); - - addr = PatternScanner.FindFirst(Pattern.FromString("F3 0F 11 46 04 F3 0F 10 46 08 F3 0F 5C C2 F3 0F 11 46 08 ?? ?? F3 0F")); - Assert(addr == 0x141C000D2); - disableSecondaryYCollision = new Patch(addr, [0x90, 0x90, 0x90, 0x90, 0x90]); - - addr = PatternScanner.FindFirst(Pattern.FromString("F3 0F 11 46 04 F3 0F 10 58 08 F3 0F 58 5E 08 F3 0F 11 5E 08 44 8B 87 D0 0B 00 00 41 F6 C0 03")); - Assert(addr == 0x141BFFF90); - disableExtraYCollision = new Patch(addr, [0x90, 0x90, 0x90, 0x90, 0x90]); - - addr = PatternScanner.FindFirst(Pattern.FromString("F3 0F 11 83 80 00 00 00 F3 0F 11 8B 84 00 00 00 F3 0F 11 93 88 00 00 00 89 B3 8C 00 00 00 8B 83 A4 01 00 00 C1 E8 05 44 0F 29 A4 24 D0 01 00 00 44 0F 29 B4 24 B0 01 00 00 A8 01")); - Assert(addr + 0x8 == 0x1413259ED); - disableGravityYUpdate = new Patch(addr + 0x8, [ - 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 - ]); - - 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")); - Assert(addr + 0x40 == 0x141BFFF75); - disableGravityEval = new Patch(addr + 0x40, [0x90, 0x90, 0x90, 0x90, 0x90]); // call MonsterHunterWorld.exe+1325810. - return data; } @@ -1015,12 +641,13 @@ namespace NewCamera public void OnLoad() { + PlayerExt.sPlayer = SingletonManager.GetSingleton("sPlayer")!; Config config = loadConfig(); if (enableOffsetPerspective && config.Selected != "") { setPerspectivePreset(config.Presets[config.Selected]); } -#if QUARANTINED_FEATURES +#if INTEROP_FEATURE if (config.TuningToolInterop) { if (TuningToolInterop.InitFromLoadedInstance()) @@ -1052,48 +679,9 @@ namespace NewCamera } } - private Player? getPlayerFromSaveSlot() - { - nint guiAddr = getSaveSlotGuiAddr.Invoke(MemoryUtil.Read(0x1451C42B8)); - if (guiAddr == 0x0) - { - saveSlotIndex = -1; - return null; - } - // MonsterHunterWorld.exe+ADC42F - movsxd rcx,dword ptr [rax+00000334] - saveSlotIndex = MemoryUtil.Read(guiAddr + 0x334); - if (saveSlotIndex == -1) - { - return null; - } - // MonsterHunterWorld.exe+1B42047 - add r8,00000740 - nint offset = (sPlayer.Instance + 0x40) + (0x740 * saveSlotIndex); - if (offset == 0x0 || MemoryUtil.Read(offset) != 0x1433FE588) - { - return null; - } - nint playerAddr = MemoryUtil.Read(offset + 0x18); - if (playerAddr == 0x0) - { - return null; - } - 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 = getPlayer(); + Player? player = PlayerExt.getPlayer(); if (player != lastPlayer) { pCamera = null; @@ -1287,39 +875,7 @@ namespace NewCamera advanceFrame--; } - player = getPlayerWithFallback(); - if (player != null) - { - // @TODO: Comment this. - if (hideWeapon) - { - nint baseAddr = MemoryUtil.Read(player.Instance + 0x76B0); - if (baseAddr != 0x0) - { - MemoryUtil.WriteBytes(baseAddr + 0x1A98, [0x1]); - int weaponParts = MemoryUtil.Read(baseAddr + 0x2250); - for (int i = 0; i < weaponParts; i++) - { - nint partsAddr = MemoryUtil.Read(baseAddr + ((i + 0x16B) * 24)); - if (partsAddr != 0x0) - { - MemoryUtil.WriteBytes(partsAddr + 0x1A98, [0x1]); - } - } - } - } - /* - if (hideKnife) - { - // Emulate what Carving and Flourish emote do at - // MonsterHunterWorld.exe+1F68832 - bts eax,06 - // if set, skips - // MonsterHunterWorld.exe+203A0D2 - bts ecx,01 - MemoryUtil.GetRef(player.Instance + 0x8938) |= (1 << 6); - MemoryUtil.GetRef(player.Instance + 0x8968) |= (1 << 6); - } - */ - } + PlayerExt.OnUpdate(); resetStatePerFrame(); } @@ -1329,7 +885,7 @@ namespace NewCamera return new Quaternion(target.X - pos.X, target.Y - pos.Y, target.Z - pos.Z, 0.0f); } - private static Quaternion getRight(Quaternion q) + public static Quaternion getRight(Quaternion q) { return q * Quaternion.CreateFromYawPitchRoll(MathF.PI, 0.0f, 0.0f); } @@ -1510,9 +1066,10 @@ namespace NewCamera Player? player = lastPlayer; if (player == null) { - player = getPlayerFromSaveSlot(); + player = PlayerExt.getPlayerFromSaveSlot(); } + /* // PadLx/y is read in WritePadInputHook(). if ((buttonWasDown(Button.L2) && buttonWasDown(Button.R2)) || toggleAttachToChest) { @@ -1534,7 +1091,8 @@ namespace NewCamera cameraFov = Math.Clamp(cameraFov - Ly, 1.0f, 179.0f); } } - else if (playerMovementLocked || orbitPlayer) // Move camera. + */ + if (playerMovementLocked || orbitPlayer) // Move camera. { #if MOUSE_AND_KEYBOARD_LAYER if (keyboardEnabled) @@ -1805,10 +1363,10 @@ namespace NewCamera { Quaternion rotation; Vector3 target; - bool targetJoint = orbitJoint >= 0 && orbitJoint < bodyJoints.Count; + bool targetJoint = orbitJoint >= 0 && orbitJoint < PlayerExt.bodyJoints.Count; if (targetJoint) { - nint jointAddr = bodyJoints[orbitJoint]; + nint jointAddr = PlayerExt.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); @@ -2387,7 +1945,7 @@ namespace NewCamera { if (buttonWasPressed(Button.Down)) { - Player? player = getPlayer(); + Player? player = PlayerExt.getPlayer(); if (player != null) { // Y - 150 to approximately align the players head with the camera. @@ -2445,7 +2003,7 @@ namespace NewCamera } if (!unlockInputForMenu && buttonWasPressed(Button.Triangle)) { - Player? player = getPlayer(); + Player? player = PlayerExt.getPlayer(); if (player != null) { nint baseAddr = MemoryUtil.Read(0x1451C4640); @@ -2497,2254 +2055,413 @@ namespace NewCamera return checkMovementHook!.Original(stickValue, alwaysZero); } - private void CollisionCheckHook(nint unknownPtr, nint unknownPtr2) + private void UnderwaterCheckHook(nint unknownPtr) { - if (disableMod) + underwaterCheckHook!.Original(unknownPtr); + + if (disableMod || !enableUnderwaterCamera) { - collisionCheckHook!.Original(unknownPtr, unknownPtr2); return; } #if HOOK_ORDER_ASSERTS - debugLog($"CollisionCheckHook(0x{unknownPtr:X}, 0x{unknownPtr2:X}) @ {frameTick}"); + debugLog($"UnderwaterCheckHook(0x{unknownPtr:X}) @ {frameTick}"); #endif - Player? player = null; - if (enableCrawl && (player = getPlayer()) != null) - { - nint controlsAddr = MemoryUtil.Read(player.Instance + 0x12608); - bool combatControls = false; - if (controlsAddr != 0x0) - { - combatControls = MemoryUtil.Read(controlsAddr + 0xB18) == 0x80; - } - if (combatControls) - { - procEnvironmentCollision.Invoke(player.Instance, psuedoObject1); - procEnvironmentCollision.Invoke(player.Instance, psuedoObject2); - } - else - { - enableCrawl = false; - } - } - - collisionCheckHook!.Original(unknownPtr, unknownPtr2); + cameraIsUnderwater = MemoryUtil.Read(unknownPtr + 0x1E83) == 0x1; } - private void SetZoneStateHook(nint player, int flags) + private void CameraEffectHook(nint unknownPtr, nint unknownPtr2, nint unknownPtr3) { - if (disableMod) + if (disableMod || !enableUnderwaterCamera) { - setZoneStateHook!.Original(player, flags); + cameraEffectHook!.Original(unknownPtr, unknownPtr2, unknownPtr3); return; } #if HOOK_ORDER_ASSERTS - debugLog($"SetZoneStateHook(0x{player:X}, 0x{flags:X}) @ {frameTick}"); + debugLog($"CameraEffectHook(0x{unknownPtr:X}, 0x{unknownPtr2:X}, 0x{unknownPtr3:X}) @ {frameTick}"); #endif -#if QUARANTINED_FEATURES - nint zoneStateAddr = MemoryUtil.Read(0x1451C42B8); - ref byte zoneState = ref MemoryUtil.GetRef(zoneStateAddr + 0xD2EA); - if (!zoneStateManualInvoke) - { - lastZoneState = (zoneState == 0x1) ? ZoneState.Hub : ZoneState.Combat; - } - else - { - zoneStateManualInvoke = false; - } + byte[]? underwaterValues = null; + nint targetAddr = 0x0; - ZoneState overrideZoneState = (forceZoneState == ZoneState.Unknown) ? lastZoneState : forceZoneState; - if (overrideZoneState != ZoneState.Unknown) + nint rax = MemoryUtil.Read(unknownPtr + 0x550); + int index1 = MemoryUtil.Read(unknownPtr + 0xA50); + rax = MemoryUtil.Read(rax + (index1 * 0x8)); + if (rax != 0x0) { - zoneState = ByteFlag(overrideZoneState == ZoneState.Hub); + rax = MemoryUtil.Read(rax + 0x188); + if (rax != 0x0) + { + targetAddr = rax + 0x140; + } } -#endif - float headWet = 0.0f, bodyWet = 0.0f, waistWet = 0.0f, legsWet = 0.0f; - nint wetnessAddr = player + 0x13BD0; - if (overridePlayerWetness) + if (cameraIsUnderwater && !disableDofCoc) { - headWet = MemoryUtil.Read(wetnessAddr); - bodyWet = MemoryUtil.Read(wetnessAddr + 0x28); - waistWet = MemoryUtil.Read(wetnessAddr + 0x50); - legsWet = MemoryUtil.Read(wetnessAddr + 0x78); + nullifyDofCoc.Enable(); + disableDofCoc = true; } - - setZoneStateHook!.Original(player, flags); - - if (overridePlayerWetness) + else if (!cameraIsUnderwater && disableDofCoc) { - MemoryUtil.GetRef(wetnessAddr) = headWet; - MemoryUtil.GetRef(wetnessAddr + 0x28) = bodyWet; - MemoryUtil.GetRef(wetnessAddr + 0x50) = waistWet; - MemoryUtil.GetRef(wetnessAddr + 0x78) = legsWet; + nullifyDofCoc.Disable(); + disableDofCoc = false; } - } - - private void RefreshEntityParamsHook(nint entity, nint unknownPtr2) - { - refreshEntityParamsHook!.Original(entity, unknownPtr2); - if (disableMod) + if (cameraIsUnderwater) { - return; + underwaterValues = MemoryUtil.ReadArray(targetAddr + 0x8, 120); + // Straight copy-paste from The Great Forest. + MemoryUtil.WriteBytes(targetAddr + 0x8, [0x01, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x6F, 0x12, 0x03, 0x3B, 0x01, 0x00, 0x00, 0x00, 0xCE, 0xCC, 0xCC, 0x3E, 0x01, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x3F, 0x8F, 0xC2, 0xF5, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, 0x44, 0x01, 0x00, 0x00, 0x00, 0x00, 0x60, 0xEA, 0x46, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x42]); } - Player? player = getPlayerWithFallback(); - if (player != null && entity == player && playerOpacityOverride != 1.0f) + cameraEffectHook!.Original(unknownPtr, unknownPtr2, unknownPtr3); + + if (underwaterValues != null) { - MemoryUtil.GetRef(player.Instance + 0x78E0) = playerOpacityOverride; + MemoryUtil.WriteBytes(targetAddr + 0x8, underwaterValues); } } - private static string extractPartName(string fullString) + private void drawViewportInfo(int i, float width, Config config, bool debug) { - string partName = ""; - if (fullString.StartsWith("pl\\f_equip") || fullString.StartsWith("pl\\m_equip")) - { - partName = fullString.Split('\\')[3]; - } - else if (fullString.StartsWith("wp\\")) + ImGui.PushItemWidth(width * 0.75f); + Viewport vp = CameraSystem.GetViewport(i); + if (debug) { - partName = fullString.Split('\\')[2]; + ImGui.Text($"Address: 0x{vp.Instance:X}"); + ImGui.Text($"Visible: {vp.Visible}"); + ImGui.Text($"Region: {vp.Region.Width}x{vp.Region.Height} ({vp.Region.X},{vp.Region.Y})"); } - else if (fullString.StartsWith("pl\\hair")) + else { - partName = fullString.Split('\\')[2]; + ImGui.Text($"Resolution: {vp.Region.Width}x{vp.Region.Height}"); } - else if (fullString.StartsWith("pl\\f_face") || fullString.StartsWith("pl\\m_face")) + if (debug && vp.Visible) { - partName = fullString.Split('\\')[4].Substring(2); - } - return partName; - } - - private void collectArmorParts(nint baseAddr, nint addr) - { - int part; - string fullString = Marshal.PtrToStringAnsi(addr + 0xC)!; - string partName = extractPartName(fullString); - 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.StartsWith("slg")) part = Armor.Slinger; - else if (fullString.StartsWith("wp\\")) part = Armor.Weapon; - else if (partName.StartsWith("hair")) part = Armor.Hair; - else if (partName == "face000") part = Armor.Face; - else if (partName == "face000_eyelens") part = Armor.EyeLens; - else return; - playerArmor[part] = baseAddr; - - int jointCount = MemoryUtil.Read(baseAddr + 0x4A0); - nint jointAddr = MemoryUtil.Read(baseAddr + 0x4A8); - for (int i = 0; i < jointCount; i++) - { - nint childAddr = MemoryUtil.Read(jointAddr + 0x8); - if (childAddr != 0x0 && MemoryUtil.Read(childAddr) == 0x142F21A90) - { - childAddr = MemoryUtil.Read(childAddr + 0x8); - if (childAddr != 0x0) - { - nint childVtable = MemoryUtil.Read(childAddr); - if (childVtable == 0x1435195B8) // Jiggle Bone Container. - { - if (part == Armor.Body) - { - ignoredJoints.Add(jointAddr); - } - } - else if (childVtable == 0x143524BD8) - { - childAddr = MemoryUtil.Read(childAddr + 0x188); - if (childAddr != 0x0 && MemoryUtil.Read(childAddr) == 0x143519530) - { - nint jiggleData = MemoryUtil.Read(MemoryUtil.Read(childAddr + 0xA0)); - if (MemoryUtil.Read(jiggleData) == 0x143519508) - { - if (!jiggleBones.Contains(jiggleData)) - { - jiggleBones.Add(jiggleData); - int jiggleIndex = jiggleBones.Count() - 1; - if (setChestIndex) - { - if (jiggleIndex == chestBoneIndex1) - { - chestBone1 = jiggleData; - } - if (jiggleIndex == chestBoneIndex2) - { - chestBone2 = jiggleData; - } - } - else if (part == Armor.Body) - { - // Guess that chest bones are the last jiggle bones on the body. - if (chestBone1 == 0x0) - { - chestBone1 = jiggleData; - chestBoneIndex1 = jiggleIndex; - } - else - { - if (chestBone2 != 0x0) - { - chestBone1 = chestBone2; - chestBoneIndex1 = chestBoneIndex2; - } - chestBone2 = jiggleData; - chestBoneIndex2 = jiggleIndex; - } - } - } - } - } - if (part == Armor.Body) - { - ignoredJoints.Add(jointAddr); - } - } -#if QUARANTINED_FEATURES - else if (childVtable == 0x143249170) - { - childAddr = MemoryUtil.Read(childAddr + 0x188); - if (childAddr != 0x0 && MemoryUtil.Read(childAddr) == 0x1432492F0) - { - ikJoints.Add(jointAddr); - } - } -#endif - } - } - if (part == Armor.Body) + bool fadeObjects = getViewportFadeObjects(i); + if (ImGui.Checkbox("Fade Objects When Close to Camera", ref fadeObjects)) { - bodyJoints.Add(jointAddr); + setViewportFadeObjects(i, fadeObjects); } - else if (part == Armor.Face) + if (ImGui.BeginItemTooltip()) { - faceJoints.Add(jointAddr); + ImGui.Text("This is a viewport flag which is not used by the \"Disable Fading\" option. It doesn't apply to decals or monsters."); + ImGui.EndTooltip(); } - jointAddr += 0xC0; } - - if (part == Armor.Body) + if (vp.Camera != null) { - for (int i = 0; i < bodyJoints.Count; i++) + Camera camera = vp.Camera; + bool usedByFreeCamera = freeCamera && enableFreeCamera && camera == vCamera; + if (debug) ImGui.Text($"Camera Pointer: 0x{camera.Instance:X}"); + if (ImGui.DragFloat("Field of View", ref camera.FieldOfView, 0.1f)) { - jointAddr = bodyJoints[i]; - if (ignoredJoints.Contains(jointAddr)) + if (usedByFreeCamera) { - continue; + cameraFov = camera.FieldOfView; } - byte id = MemoryUtil.Read(jointAddr + 0xA0); - Assert(playerJoints[id] == 0x0); - playerJoints[id] = jointAddr; - } - foreach (nint joint in bodyRotations.Where(e => !bodyJoints.Contains(e.Key)).Select(e => e.Key).ToList()) - { - bodyRotations.Remove(joint); - } - foreach (nint joint in bodyOffsets.Where(e => !bodyJoints.Contains(e.Key)).Select(e => e.Key).ToList()) - { - bodyOffsets.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 - } - else if (part == Armor.Face) - { - foreach (nint joint in faceRotations.Where(e => !faceJoints.Contains(e.Key)).Select(e => e.Key).ToList()) + if (enableOffsetPerspective && camera == pCamera) { - faceRotations.Remove(joint); + ImGui.Text($"Internal FOV: {previousFov}"); + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("What the FOV would be if not set by us."); + ImGui.EndTooltip(); + } } - foreach (nint joint in faceOffsets.Where(e => !faceJoints.Contains(e.Key)).Select(e => e.Key).ToList()) + if (debug) ImGui.InputFloat("Aspect Ratio", ref camera.AspectRatio); + ImGui.InputFloat("Near Clip", ref camera.NearClip); + ImGui.InputFloat("Far Clip", ref camera.FarClip); + if (usedByFreeCamera) { - faceOffsets.Remove(joint); + ImGui.DragFloat3("Position", ref cameraPosition, 0.425f); } - } - } - - private void drawJoint(nint jointAddr, Dictionary> rotations, Dictionary> offsets) - { - if (jointAddr == 0x0) return; - ImGui.PushID(jointAddr); - bool hasRotation = rotations.ContainsKey(jointAddr); - bool hasOffset = offsets.ContainsKey(jointAddr); -#if QUARANTINED_FEATURES - bool hasIkOffset = ikOffsets.ContainsKey(jointAddr); -#endif - ImGui.DragFloat4("Rotation", ref MemoryUtil.GetRef(jointAddr + 0x70), 0.005f); - if (hasRotation) - { - ImGui.PushID("Rotation"); - bool doRemove = ImGui.Button("X"); - ImGui.SameLine(); - if (ImGui.Button("Reset")) + else { - rotations[jointAddr][0] = default; + ImGui.DragFloat3("Position", ref camera.Position, 0.425f); } + ImGui.DragFloat3("Target", ref camera.Target, 0.425f); + ImGui.DragFloat3("Up", ref camera.Up, 0.425f); + ImGui.PushItemWidth(width * 0.3f); + ImGui.InputText("##Position Name", ref typedPositionName, 99); ImGui.SameLine(); - Vector3 v = rotations[jointAddr][0]; - if (ImGui.DragFloat3($"##Rotation Offset", ref v, 0.005f)) + if (ImGui.Button("Save")) { - rotations[jointAddr][0] = v; - } - if (doRemove) rotations.Remove(jointAddr); - ImGui.PopID(); - } - ImGui.DragFloat4("Position", ref MemoryUtil.GetRef(jointAddr + 0x50), 0.005f); - if (hasOffset) - { - ImGui.PushID("Position"); - bool doRemove = ImGui.Button("X"); - ImGui.SameLine(); - if (ImGui.Button("Reset")) - { - offsets[jointAddr][0] = default; - } - ImGui.SameLine(); - Vector3 v = offsets[jointAddr][0]; - if (ImGui.DragFloat3($"##Position Offset", ref v, 0.005f)) - { - offsets[jointAddr][0] = v; - } - if (doRemove) offsets.Remove(jointAddr); - ImGui.PopID(); - } -#if QUARANTINED_FEATURES - if (hasIkOffset) - { - ImGui.PushID("IK"); - bool doRemove = ImGui.Button("X"); - ImGui.SameLine(); - if (ImGui.Button("Reset")) - { - ikOffsets[jointAddr][0] = default; - } - ImGui.SameLine(); - Vector3 v = ikOffsets[jointAddr][0]; - if (ImGui.DragFloat3($"##IK Offset", ref v, 0.025f)) - { - ikOffsets[jointAddr][0] = v; - } - if (doRemove) ikOffsets.Remove(jointAddr); - ImGui.PopID(); - } -#endif - if (!hasRotation) - { - if (ImGui.Button("Add Rotation")) - { - rotations.Add(jointAddr, new List() - { - new Vector3() - }); - } - } - if (!hasOffset) - { - if (!hasRotation) - { - ImGui.SameLine(); - } - if (ImGui.Button("Add Offset")) - { - offsets.Add(jointAddr, new List() - { - new Vector3() - }); - } - } -#if QUARANTINED_FEATURES - if (ikJoints.Contains(jointAddr) && !hasIkOffset) - { - if (!hasOffset) - { - ImGui.SameLine(); - } - if (ImGui.Button("Add IK Offset")) - { - ikOffsets.Add(jointAddr, new List() - { - new Vector3() - }); - } - } -#endif - ImGui.PopID(); - } - - private void drawJoint(nint jointAddr) - { - drawJoint(jointAddr, bodyRotations, bodyOffsets); - } - - private void drawJointLeaf(ref List joints, int i, Dictionary> rotations, Dictionary> offsets) - { - if (i >= joints.Count) return; - nint jointAddr = joints[i]; - byte id = MemoryUtil.Read(jointAddr + 0xA0); - ImGui.PushID(jointAddr); - if (ImGui.CollapsingHeader($"Joint #{i} (0x{jointAddr:X}, id: 0x{id:X})")) - { - drawJoint(jointAddr, rotations, offsets); - } - ImGui.PopID(); - drawJointLeaf(ref joints, i + 1, rotations, offsets); - } - - private void drawJoints(float width) - { - ImGui.PushItemWidth(width * 0.75f); - ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags.Framed; - bool expanded; - if (ImGui.TreeNodeEx("Root", flags)) - { - drawJoint(playerJoints[Joint.Root2]); - ImGui.TreePop(); - } - ImGui.PushID("Neck"); - if (ImGui.TreeNodeEx("Neck", flags)) - { - if (ImGui.TreeNodeEx("Upper", flags)) - { - drawJoint(playerJoints[Joint.UpperNeck]); - ImGui.TreePop(); - } - 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)) - { - 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(); - expanded = ImGui.TreeNodeEx("Palm", flags); - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("Outer Palm/Pinky+Ring"); - ImGui.EndTooltip(); - } - if (expanded) - { - drawJoint(playerJoints[Joint.RightPalm]); - ImGui.TreePop(); - } - ImGui.TreePop(); - } - ImGui.PopID(); // Right Hand. - ImGui.PushID("Right Leg"); - if (ImGui.TreeNodeEx("Right Leg", flags)) - { - if (ImGui.TreeNodeEx("Hip", flags)) - { - 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(); - } - ImGui.PopID(); // Right Leg. - ImGui.PushID("Left Arm"); - if (ImGui.TreeNodeEx("Left Arm", flags)) - { - if (ImGui.TreeNodeEx("Collarbone", flags)) - { - 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)) - { - drawJoint(playerJoints[Joint.LeftThumbLow]); - ImGui.TreePop(); - } - if (ImGui.TreeNodeEx("Middle", flags)) - { - drawJoint(playerJoints[Joint.LeftThumbMid]); - ImGui.TreePop(); - } - if (ImGui.TreeNodeEx("Tip", flags)) - { - drawJoint(playerJoints[Joint.LeftThumbHigh]); - ImGui.TreePop(); - } - ImGui.TreePop(); - } - ImGui.PopID(); - ImGui.PushID("Index"); - if (ImGui.TreeNodeEx("Index", flags)) - { - if (ImGui.TreeNodeEx("Base", flags)) - { - 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(); - } - 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(); - expanded = ImGui.TreeNodeEx("Palm", flags); - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("Outer Palm/Pinky+Ring"); - ImGui.EndTooltip(); - } - if (expanded) - { - drawJoint(playerJoints[Joint.LeftPalm]); - ImGui.TreePop(); - } - 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(); - if (ImGui.Checkbox("Attach to Chest", ref attachToChest)) - { - if (!attachToChest) - { - toggleAttachToChest = false; - } - } - 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("Toggle", ref toggleAttachToChest); - ImGui.SameLine(); - ImGui.Checkbox("Swap Sides", ref swapChestSides); - ImGui.SetNextItemWidth(width * 0.35f); - ImGui.DragFloat("Strength", ref chestMoveScale, 0.001f); - ImGui.Checkbox("Set Index", ref setChestIndex); - ImGui.SameLine(); - if (!setChestIndex) - { - ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f); - } - if (setChestIndex && chestBone1 == 0x0) - { - ImGui.PushStyleColor(ImGuiCol.Text, 0xFF0000FF); - } - ImGui.SetNextItemWidth(width * 0.17f); - if (ImGui.InputInt("##Index 1", ref chestBoneIndex1, 1)) - { - if (chestBoneIndex1 < 0) chestBoneIndex1 = 0; - } - if (setChestIndex && chestBone1 == 0x0) - { - ImGui.PopStyleColor(); - } - ImGui.SameLine(); - if (setChestIndex && chestBone2 == 0x0) - { - ImGui.PushStyleColor(ImGuiCol.Text, 0xFF0000FF); - } - ImGui.SetNextItemWidth(width * 0.17f); - if (ImGui.InputInt("##Index 2", ref chestBoneIndex2, 1)) - { - if (chestBoneIndex2 < 0) chestBoneIndex2 = 0; - } - if (setChestIndex && chestBone2 == 0x0) - { - ImGui.PopStyleColor(); - } - if (!setChestIndex) - { - ImGui.PopStyleVar(); - } - 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 Bone #{i} (0x{jiggleData:X})")) - { - ImGui.DragFloat3("Position", ref MemoryUtil.GetRef(jiggleData + 0xD0), 0.05f); - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("Drag this position around to influence the bone."); - ImGui.EndTooltip(); - } - } - ImGui.PopID(); - } - } - ImGui.Separator(); - if (ImGui.CollapsingHeader("Body Joints")) - { - drawJointLeaf(ref bodyJoints, 0, bodyRotations, bodyOffsets); - } - if (ImGui.CollapsingHeader("Face Joints")) - { - drawJointLeaf(ref faceJoints, 0, faceRotations, faceOffsets); - } - ImGui.PopItemWidth(); - } - - private void drawModelParts(nint armorAddr, nint partsAddr = 0x0) - { - if (partsAddr == 0x0) - { - if (armorAddr == 0x0 || (partsAddr = MemoryUtil.Read(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}:"); - } - // MonsterHunterWorld.exe+222E651 - mov rax,[r8+000000C8] - nint baseLod = MemoryUtil.Read(partsAddr + 0xC8); - nint baseOffset = MemoryUtil.Read(partsAddr + 0x408 + (0x8 * 0x1)); - int numParts = MemoryUtil.Read(partsAddr + 0x548 + (0x4 * 0x1)); - // Setting lodCount to 0 is probably the best way to completely hide a model. - int lodCount = MemoryUtil.Read(partsAddr + 0xD0); - const int lodStructSize = 0x50; - const int partsPerLine = 10; - bool allOn = ImGui.Button("Show All"); - ImGui.SameLine(); - bool allOff = ImGui.Button("Hide All"); - for (int i = 0; i < numParts; i++) - { - ref int lodOffset = ref MemoryUtil.GetRef(baseOffset + (i * 0x4)); - nint lod0 = baseLod + lodOffset * lodStructSize; - bool isVisible = MemoryUtil.GetRef(lod0) != 0; - bool togglePart = ImGui.Checkbox($"##Part #{i}", ref isVisible); - if (ImGui.BeginItemTooltip()) - { - ImGui.Text($"Part #{i} (0x{lod0:X})"); - ImGui.EndTooltip(); - } - int lastLod = (i < numParts - 1) ? MemoryUtil.Read(baseOffset + ((i + 1) * 0x4)) : lodCount; - int partLodCount = lastLod - lodOffset; - // This is not a "proper" way to hide a part. It abuses the fact that if the lower - // 16 bits (lodVisible) of these 4 bytes are 0, a check to skip rendering it will - // always pass. Also that +0xA appears to be unused/padding. - // MonsterHunterWorld.exe+222FCE3 - mov eax,[r8] - ushort lod0Visible = MemoryUtil.GetRef(lod0); - for (int j = 0; j < partLodCount; j++) - { - if (togglePart || (lod0Visible != 0 && allOff) || (lod0Visible == 0 && allOn)) - { - nint lod = lod0 + (j * lodStructSize); - ref ushort lodVisible = ref MemoryUtil.GetRef(lod); - ref ushort padSub = ref MemoryUtil.GetRef(lod + 0xA); - if (lod0Visible != 0) Assert(padSub == 0); - // Check against LOD0 to prevent an inconsistent state. - if ((lodVisible != 0) == (lod0Visible != 0)) - { - (lodVisible, padSub) = (padSub, lodVisible); - } - } - if (modelOnlyAddressLod0) break; - } - if (i != numParts - 1 && i % partsPerLine != partsPerLine - 1) - { - ImGui.SameLine(); - } - } - ImGui.PopID(); - } - - private void dropArmorState() - { - Array.Clear(playerArmor, 0, playerArmor.Length); - Array.Clear(playerJoints, 0, playerJoints.Length); - bodyJoints.Clear(); - ignoredJoints.Clear(); - faceJoints.Clear(); -#if QUARANTINED_FEATURES - ikJoints.Clear(); -#endif - jiggleBones.Clear(); - chestBone1 = 0x0; - chestBone2 = 0x0; - } - - private void dropJointOffsets() - { - bodyRotations.Clear(); - bodyOffsets.Clear(); - faceRotations.Clear(); - faceOffsets.Clear(); -#if QUARANTINED_FEATURES - ikOffsets.Clear(); -#endif - } - - private bool collectArmorAndJoints(Player player) - { - nint bodyArmorParts = MemoryUtil.Read(player.Instance + 0x2A0); - if (bodyArmorParts == 0x0) - { - return false; - } - // MonsterHunterWorld.exe+203E8A2 - mov rax,[rbx+000126C8] - nint combineArmorList = MemoryUtil.Read(player.Instance + 0x126C8); - if (combineArmorList == 0x0) - { - return false; - } - collectArmorParts(player.Instance, bodyArmorParts); - nint weapon = MemoryUtil.Read(player.Instance + 0x76B0); - if (weapon != 0x0) - { - nint weaponParts = MemoryUtil.Read(weapon + 0x2A0); - if (weaponParts != 0x0) - { - collectArmorParts(weapon, weaponParts); - } - } - nint slinger = MemoryUtil.Read(player.Instance + 0x8918); - if (slinger != 0x0) - { - nint slingerParts = MemoryUtil.Read(slinger + 0x2A0); - if (slingerParts != 0x0) - { - collectArmorParts(slinger, slingerParts); - } - } - combineArmorList = MemoryUtil.Read(combineArmorList + 0x70); - nint next = combineArmorList; - while (next != 0x0) - { - nint armorAddr = next; - next = MemoryUtil.Read(armorAddr + 0x30); - nint vTable = MemoryUtil.Read(armorAddr); - // uWeaponParts: 0x1434D2400, uWeaponEmblem: 0x1434D1D58 - if (vTable == 0x1434A7560) // uPlCombineArmor - { - nint partsAddr = 0x0; - nint childAddr = MemoryUtil.Read(armorAddr + 0x548); - if (childAddr != 0x0) - { - if (MemoryUtil.Read(childAddr) == 0x143451520) // Face. - { - nint ownerAddr = MemoryUtil.Read(childAddr + 0x998); - if (ownerAddr != player.Instance) - { - continue; - } - if (playerArmor[Armor.Face] == 0x0) - { - partsAddr = MemoryUtil.Read(childAddr + 0x2A0); - if (partsAddr != 0x0) - { - collectArmorParts(childAddr, partsAddr); - } - childAddr = MemoryUtil.Read(childAddr + 0x9C8); - if (childAddr != 0x0 && MemoryUtil.Read(childAddr) == 0x143505E98) // Eye lens. - { - partsAddr = MemoryUtil.Read(childAddr + 0x2A0); - if (partsAddr != 0x0) - { - collectArmorParts(childAddr, partsAddr); - } - } - } - } - else if (childAddr != player.Instance) - { - continue; - } - } - partsAddr = MemoryUtil.Read(armorAddr + 0x2A0); - if (partsAddr != 0x0) - { - collectArmorParts(armorAddr, partsAddr); - } - } - if (!playerArmor.Where(p => (p == 0x0)).Any()) - { - break; - } - } - return true; - } - - private void refreshArmorState(Player player) - { - dropArmorState(); - if (!collectArmorAndJoints(player)) - { - dropJointOffsets(); - } - } - - private bool usingArmorState() - { - return (bodyRotations.Count > 0 || bodyOffsets.Count > 0 || faceRotations.Count > 0 || faceOffsets.Count > 0) || - (hideKnife || checkKnifeHidden) || (enableFreeCamera && orbitPlayer && orbitJoint >= 0); - } - - private void UpdateJointRotationHook(nint model) - { - if (!disableMod && usingArmorState()) - { - Player? player = getPlayerWithFallback(); - if (player != null && model == player.Instance) - { - refreshArmorState(player); - foreach ((nint addr, List rotations) in bodyRotations) - { - MemoryUtil.GetRef(addr + 0x70) *= Quaternion.CreateFromYawPitchRoll(rotations[0].X, rotations[0].Y, rotations[0].Z); - } - if (playerArmor[Armor.Waist] != 0x0) - { - MemoryUtil.GetRef(playerArmor[Armor.Waist] + 0x2D0) = hideKnife ? (byte)0xFD : (byte)0xFF; - checkKnifeHidden = false; - } - } - else if (player != null && model == playerArmor[Armor.Face]) - { - refreshArmorState(player); - foreach ((nint addr, List rotations) in faceRotations) - { - MemoryUtil.GetRef(addr + 0x70) *= Quaternion.CreateFromYawPitchRoll(rotations[0].X, rotations[0].Y, rotations[0].Z); - } - - } - } - updateJointRotationHook!.Original(model); - } - - private void UpdateJointPositionHook(nint model) - { - updateJointPositionHook!.Original(model); - if (!disableMod && usingArmorState()) - { - Player? player = getPlayerWithFallback(); - if (player != null && model == player.Instance) - { - refreshArmorState(player); - foreach ((nint addr, List offsets) in bodyOffsets) - { - MemoryUtil.GetRef(addr + 0x50) += offsets[0]; - } - } - else if (player != null && model == playerArmor[Armor.Face]) - { - refreshArmorState(player); - foreach ((nint addr, List offsets) in faceOffsets) - { - MemoryUtil.GetRef(addr + 0x50) += offsets[0]; - } - } - } - } - -#if QUARANTINED_FEATURES - private void UpdateIKHook(nint superOfChild, nint joint, nint obj) - { - if (!disableMod && ikOffsets.ContainsKey(joint)) - { - Vector3 offset = ikOffsets[joint][0]; - MemoryUtil.GetRef(superOfChild + 0x1380) += offset; - } - updateIKHook!.Original(superOfChild, joint, obj); - } -#endif - - /* - private void ChangeEquipmentHook(nint unknownPtr, int unknownInt) - { - nint rax = MemoryUtil.Read(unknownPtr + 0x2968); - nint r9 = MemoryUtil.Read(unknownPtr + 0x2950); - int esi = MemoryUtil.Read(rax + 0x240); - esi *= MemoryUtil.Read(r9 + 0x1D8); - esi += unknownInt; - nint newEquipment = newEquipmentPointer.Invoke(unknownPtr, esi); - lastEquipedId = MemoryUtil.Read(newEquipment + 0x24); - changeEquipmentHook!.Original(unknownPtr, unknownInt); - } - */ - - private void UnderwaterCheckHook(nint unknownPtr) - { - underwaterCheckHook!.Original(unknownPtr); - - if (disableMod || !enableUnderwaterCamera) - { - return; - } - -#if HOOK_ORDER_ASSERTS - debugLog($"UnderwaterCheckHook(0x{unknownPtr:X}) @ {frameTick}"); -#endif - - cameraIsUnderwater = MemoryUtil.Read(unknownPtr + 0x1E83) == 0x1; - } - - private void CameraEffectHook(nint unknownPtr, nint unknownPtr2, nint unknownPtr3) - { - if (disableMod || !enableUnderwaterCamera) - { - cameraEffectHook!.Original(unknownPtr, unknownPtr2, unknownPtr3); - return; - } - -#if HOOK_ORDER_ASSERTS - debugLog($"CameraEffectHook(0x{unknownPtr:X}, 0x{unknownPtr2:X}, 0x{unknownPtr3:X}) @ {frameTick}"); -#endif - - byte[]? underwaterValues = null; - nint targetAddr = 0x0; - - nint rax = MemoryUtil.Read(unknownPtr + 0x550); - int index1 = MemoryUtil.Read(unknownPtr + 0xA50); - rax = MemoryUtil.Read(rax + (index1 * 0x8)); - if (rax != 0x0) - { - rax = MemoryUtil.Read(rax + 0x188); - if (rax != 0x0) - { - targetAddr = rax + 0x140; - } - } - - if (cameraIsUnderwater && !disableDofCoc) - { - nullifyDofCoc.Enable(); - disableDofCoc = true; - } - else if (!cameraIsUnderwater && disableDofCoc) - { - nullifyDofCoc.Disable(); - disableDofCoc = false; - } - - if (cameraIsUnderwater) - { - underwaterValues = MemoryUtil.ReadArray(targetAddr + 0x8, 120); - // Straight copy-paste from The Great Forest. - MemoryUtil.WriteBytes(targetAddr + 0x8, [0x01, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x6F, 0x12, 0x03, 0x3B, 0x01, 0x00, 0x00, 0x00, 0xCE, 0xCC, 0xCC, 0x3E, 0x01, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x3F, 0x8F, 0xC2, 0xF5, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, 0x44, 0x01, 0x00, 0x00, 0x00, 0x00, 0x60, 0xEA, 0x46, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x42]); - } - - cameraEffectHook!.Original(unknownPtr, unknownPtr2, unknownPtr3); - - if (underwaterValues != null) - { - MemoryUtil.WriteBytes(targetAddr + 0x8, underwaterValues); - } - } - - private void drawViewportInfo(int i, float width, Config config, bool debug) - { - ImGui.PushItemWidth(width * 0.75f); - Viewport vp = CameraSystem.GetViewport(i); - if (debug) - { - ImGui.Text($"Address: 0x{vp.Instance:X}"); - ImGui.Text($"Visible: {vp.Visible}"); - ImGui.Text($"Region: {vp.Region.Width}x{vp.Region.Height} ({vp.Region.X},{vp.Region.Y})"); - } - else - { - ImGui.Text($"Resolution: {vp.Region.Width}x{vp.Region.Height}"); - } - if (debug && vp.Visible) - { - bool fadeObjects = getViewportFadeObjects(i); - if (ImGui.Checkbox("Fade Objects When Close to Camera", ref fadeObjects)) - { - setViewportFadeObjects(i, fadeObjects); - } - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("This is a viewport flag which is not used by the \"Disable Fading\" option. It doesn't apply to decals or monsters."); - ImGui.EndTooltip(); - } - } - if (vp.Camera != null) - { - Camera camera = vp.Camera; - bool usedByFreeCamera = freeCamera && enableFreeCamera && camera == vCamera; - if (debug) ImGui.Text($"Camera Pointer: 0x{camera.Instance:X}"); - if (ImGui.DragFloat("Field of View", ref camera.FieldOfView, 0.1f)) - { - if (usedByFreeCamera) - { - cameraFov = camera.FieldOfView; - } - } - if (enableOffsetPerspective && camera == pCamera) - { - ImGui.Text($"Internal FOV: {previousFov}"); - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("What the FOV would be if not set by us."); - ImGui.EndTooltip(); - } - } - if (debug) ImGui.InputFloat("Aspect Ratio", ref camera.AspectRatio); - ImGui.InputFloat("Near Clip", ref camera.NearClip); - ImGui.InputFloat("Far Clip", ref camera.FarClip); - if (usedByFreeCamera) - { - ImGui.DragFloat3("Position", ref cameraPosition, 0.425f); - } - else - { - ImGui.DragFloat3("Position", ref camera.Position, 0.425f); - } - ImGui.DragFloat3("Target", ref camera.Target, 0.425f); - ImGui.DragFloat3("Up", ref camera.Up, 0.425f); - ImGui.PushItemWidth(width * 0.3f); - ImGui.InputText("##Position Name", ref typedPositionName, 99); - ImGui.SameLine(); - if (ImGui.Button("Save")) - { - string name = typedPositionName; - if (name != "") - { - Config.Position pos = new Config.Position(); - pos.FieldOfView = camera.FieldOfView; - pos.Roll = cameraRoll; - pos.PosX = camera.Position.X; - pos.PosY = camera.Position.Y; - pos.PosZ = camera.Position.Z; - pos.TargetX = camera.Target.X; - pos.TargetY = camera.Target.Y; - pos.TargetZ = camera.Target.Z; - if (config.Positions.ContainsKey(name)) - { - config.Positions[name] = pos; - } - else - { - config.Positions.Add(name, pos); - } - ConfigManager.SaveConfig(this); - } - } - ImGui.SameLine(); - if (ImGui.BeginCombo("##Positions", selectedPositionName)) - { - Dictionary.KeyCollection positionKeys = config.Positions.Keys; - for (int j = 0; j < positionKeys.Count + 1; j++) - { - if (j == 0) - { - if (ImGui.Selectable("(None)")) - { - selectedPositionName = ""; - } - continue; - } - string positionKey = positionKeys.ElementAt(j - 1); - if (ImGui.Selectable(positionKey)) - { - Config.Position pos = config.Positions[positionKey]; - selectedPositionName = positionKey; - camera.FieldOfView = pos.FieldOfView; - cameraRoll = pos.Roll; - cameraPosition = new Vector3(pos.PosX, pos.PosY, pos.PosZ); - cameraTarget = new Vector3(pos.TargetX, pos.TargetY, pos.TargetZ); - Quaternion forward = Quaternion.Normalize(getForward(cameraPosition, cameraTarget)); - cameraYaw = Single.RadiansToDegrees(MathF.Atan2(forward.Z, forward.X)); - cameraPitch = Single.RadiansToDegrees(MathF.Asin(forward.Y)); - camera.Position = cameraPosition; - camera.Target = cameraTarget; - } - } - ImGui.EndCombo(); - } - ImGui.PopItemWidth(); - ImGui.SameLine(); - if (ImGui.Button("Delete")) - { - if (selectedPositionName != "") - { - config.Positions.Remove(selectedPositionName); - selectedPositionName = ""; - ConfigManager.SaveConfig(this); - } - } - if (debug) - { - bool move = camera.Move; - if (ImGui.Checkbox("Move", ref move)) - { - camera.Move = move; - } - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("Uncheck this to allow manually overriding the camera position.\nIf your camera is frozen, make sure this is checked."); - ImGui.EndTooltip(); - } - ImGui.SameLine(); - bool fix = camera.Fix; - if (ImGui.Checkbox("Fix", ref fix)) - { - camera.Fix = fix; - } - } - if (camera == pCamera) - { - Player? player = checkPlayerChange(); - if (!debug && player != null) - { - ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(0.0f, 6.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, 6.0f)); - ref byte settingB = ref MemoryUtil.GetRef(getPlayerSettings() + 0x1403FD); - int settingI = settingB; - ImGui.SameLine(); - ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); - if (ImGui.RadioButton("Close", ref settingI, 0)) - { - settingB = (byte)settingI; - } - ImGui.SameLine(); - ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); - if (ImGui.RadioButton("Default", ref settingI, 1)) - { - settingB = (byte)settingI; - } - ImGui.SameLine(); - ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.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(player.Instance + 0x14F8); - if (playerCameraAddr != 0x0) - { - playerCameraAddr = MemoryUtil.Read(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(viewParamOffset + 0x20), 0.1f); - } - viewParamOffset = getViewParamOffset.Invoke(playerCameraAddr + 0x1380, 0, 0xCA); - if (viewParamOffset != 0x0) - { - ImGui.DragFloat3("Far", ref MemoryUtil.GetRef(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); - ImGui.DragFloat("Roll", ref cameraRoll, 0.2f); - if (!usedByFreeCamera) - { - ImGui.PopItemFlag(); - } - // Try to grey out offsets when they probably have no effect. - if ((camera == pCamera && !usedByFreeCamera) && camera.Move) - { - ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f); - } - ImGui.Text("Move"); - float offsetForward = 0.0f; - if (ImGui.DragFloat("Forward", ref offsetForward, 0.425f)) - { - Quaternion forward = getForward(camera.Position, camera.Target); - forward = Quaternion.Normalize(forward); - camera.Position.X += forward.X * offsetForward; - camera.Position.Y += forward.Y * offsetForward; - camera.Position.Z += forward.Z * offsetForward; - if (usedByFreeCamera) cameraPosition = camera.Position; - } - float offsetRight = 0.0f; - if (ImGui.DragFloat("Right", ref offsetRight, 0.425f)) - { - Quaternion forward = getForward(camera.Position, camera.Target); - Quaternion right = getRight(forward); - forward = Quaternion.Normalize(forward); - right = Quaternion.Normalize(right); - camera.Position.X += right.X * offsetRight; - camera.Position.Z += right.Z * offsetRight; - if (usedByFreeCamera) cameraPosition = camera.Position; - } - float offsetUp = 0.0f; - if (ImGui.DragFloat("Up", ref offsetUp, 0.425f)) - { - camera.Position.Y += offsetUp; - if (usedByFreeCamera) cameraPosition = camera.Position; - } - if (camera == pCamera && !(freeCamera || enableFreeCamera)) - { - ImGui.PopStyleVar(); - } - } - } - ImGui.PopItemWidth(); - } - - private void drawAnimationInfo(Entity entity, float width, bool debug) - { - 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; - } -#if QUARANTINED_FEATURES - 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); - } -#endif - } - } - - private void disableAllCollisionHooks() - { - if (disableExtraGravity) - { - disableExtraGravity = false; - disableExtraGravityDisable(); - } - if (disableGravity) - { - disableGravity = false; - disableGravityDisable(); - } - if (disableExtraCollision) - { - disableExtraCollision = false; - disableExtraCollisionDisable(); - } - if (disableCollision) - { - disableCollision = false; - disableCollisionDisable(); - } - } - - private void tryToDisableMod(Player? player) - { - disableAllCollisionHooks(); - if (player != null) - { - player.Rotation.X = 0.0f; - player.Rotation.Z = 0.0f; - } - if (freeCamera) - { - disableFreeCamera(); - } - for (int i = 0; i < 8; i++) - { - Viewport vp = CameraSystem.GetViewport(i); - if (vp.Camera != null) - { - vp.Camera.Move = true; - } - setViewportFadeObjects(i, true); - } - if (enableOffsetPerspective && disableFading) - { - setPassthroughEnabled(true); - } - if (disableCharacterFade) - { - noopCharacterFade.Disable(); - } - if (enableUnderwaterCamera) - { - underwaterCameraDisable(); - } - if (allowHotSpringsAnywhere) - { - jmpOverHotSpringsEval.Disable(); - } - if (disableHotSpringsSteam) - { - jmpOverHotSpringsSteam.Disable(); - } - if (ikForcedOff) - { - forceDisableIK.Disable(); - } - } - - private void tryToEnableMod() - { - if (enableOffsetPerspective && disableFading) - { - setPassthroughEnabled(false); - } - if (disableCharacterFade) - { - noopCharacterFade.Enable(); - } - if (enableUnderwaterCamera) - { - underwaterCameraEnable(); - } - if (allowHotSpringsAnywhere) - { - jmpOverHotSpringsEval.Enable(); - } - if (disableHotSpringsSteam) - { - jmpOverHotSpringsSteam.Enable(); - } - if (ikForcedOff) - { - forceDisableIK.Enable(); - } - } - - private void drawPlayerInfo(Player player, float width) - { - nint playerSettings = getPlayerSettings(); - - ImGui.Text($"{Marshal.PtrToStringAnsi(playerSettings + 0x50)}"); - - ImGui.Checkbox("Hide Weapon", ref hideWeapon); - ImGui.SameLine(); - if (ImGui.Checkbox("Hide Knife", ref hideKnife)) - { - checkKnifeHidden = true; - } - ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(0.0f, 6.0f)); - ImGui.Text("Head Armor Display"); - // MonsterHunterWorld.exe+11A2967 - cmp byte ptr [rax+001403E1],01 - ref byte showHeadArmor = ref MemoryUtil.GetRef(playerSettings + 0x1403E1); - int showHeadArmorInt = showHeadArmor; - ImGui.SameLine(); - ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); - if (ImGui.RadioButton("Show", ref showHeadArmorInt, 0)) - { - showHeadArmor = (byte)showHeadArmorInt; - } - ImGui.SameLine(); - ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); - if (ImGui.RadioButton("Hide", ref showHeadArmorInt, 1)) - { - showHeadArmor = (byte)showHeadArmorInt; - } - ImGui.SameLine(); - ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); - if (ImGui.RadioButton("Hide in Cutscenes", ref showHeadArmorInt, 2)) - { - showHeadArmor = (byte)showHeadArmorInt; - } - - ImGui.Separator(); - - - - bool armorStateRefreshed = false; - - ImGui.PushID("Joints"); - if (ImGui.CollapsingHeader("Joints")) - { - if (!armorStateRefreshed) - { - refreshArmorState(player); - armorStateRefreshed = true; - } - ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(0.0f, 6.0f)); -#if QUARANTINED_FEATURES - ImGui.Text($"Joint Rotations: {bodyRotations.Count + faceRotations.Count}, Joint Offsets: {bodyOffsets.Count + faceOffsets.Count}, IK Offsets: {ikOffsets.Count}"); -#else - ImGui.Text($"Joint Rotations: {bodyRotations.Count + faceRotations.Count}, Joint Offsets: {bodyOffsets.Count + faceOffsets.Count}"); -#endif - ImGui.SameLine(); - ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); - if (ImGui.Button("Clear")) - { - dropJointOffsets(); - } - ImGui.SameLine(); - /* - ref byte ikDisabledB = ref MemoryUtil.GetRef(MemoryUtil.Read(player.Instance + 0x990) + 0x5C); - bool ikDisabled = ikDisabledB == 0x0; - if (ImGui.Checkbox("Disable IK", ref ikDisabled)) - { - ikDisabledB = ByteFlag(!ikDisabled); - } - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("Mostly disable inverse kinematics on your player. To rotate ankles, you need to use Force Disable IK."); - ImGui.EndTooltip(); - } - ImGui.SameLine(); - */ - ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); - if (ImGui.Checkbox("Disable IK", ref ikForcedOff)) - { - if (ikForcedOff) - { - forceDisableIK.Enable(); - } - else + string name = typedPositionName; + if (name != "") { - forceDisableIK.Disable(); + Config.Position pos = new Config.Position(); + pos.FieldOfView = camera.FieldOfView; + pos.Roll = cameraRoll; + pos.PosX = camera.Position.X; + pos.PosY = camera.Position.Y; + pos.PosZ = camera.Position.Z; + pos.TargetX = camera.Target.X; + pos.TargetY = camera.Target.Y; + pos.TargetZ = camera.Target.Z; + if (config.Positions.ContainsKey(name)) + { + config.Positions[name] = pos; + } + else + { + config.Positions.Add(name, pos); + } + ConfigManager.SaveConfig(this); } } - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("Forcefully disable inverse kinematics."); - ImGui.EndTooltip(); - } - drawJoints(width); - ImGui.Separator(); - } - ImGui.PopID(); - - ImGui.PushID("Parts"); - if (ImGui.CollapsingHeader("Armor Parts")) - { - if (!armorStateRefreshed) - { - refreshArmorState(player); - armorStateRefreshed = true; - } - bool expaned = ImGui.CollapsingHeader("Helmet"); - ImGui.SameLine(); - ImGui.Text($"(id: {MemoryUtil.Read(player.Instance + 0x1373C):X})"); - if (expaned) - { - drawModelParts(playerArmor[Armor.Helmet]); - ImGui.Separator(); - } - expaned = ImGui.CollapsingHeader("Body"); - ImGui.SameLine(); - ImGui.Text($"(id: {MemoryUtil.Read(player.Instance + 0x13740):X})"); - if (expaned) - { - drawModelParts(playerArmor[Armor.Body]); - ImGui.Separator(); - } - expaned = ImGui.CollapsingHeader("Arms"); - ImGui.SameLine(); - ImGui.Text($"(id: {MemoryUtil.Read(player.Instance + 0x13744):X})"); - if (expaned) - { - drawModelParts(playerArmor[Armor.Arm]); - ImGui.Separator(); - } - expaned = ImGui.CollapsingHeader("Waist"); - ImGui.SameLine(); - ImGui.Text($"(id: {MemoryUtil.Read(player.Instance + 0x13748):X})"); - if (expaned) - { - drawModelParts(playerArmor[Armor.Waist]); - ImGui.Separator(); - } - expaned = ImGui.CollapsingHeader("Legs"); - ImGui.SameLine(); - ImGui.Text($"(id: {MemoryUtil.Read(player.Instance + 0x1374C):X})"); - if (expaned) - { - drawModelParts(playerArmor[Armor.Leg]); - ImGui.Separator(); - } - /* - expaned = ImGui.CollapsingHeader("Weapon"); - if (expaned) - { - drawModelParts(playerArmor[Armor.Weapon]); - ImGui.Separator(); - } - */ - expaned = ImGui.CollapsingHeader("Slinger"); - ImGui.SameLine(); - ImGui.Text($"(id: {MemoryUtil.Read(player.Instance + 0x13D8C):X}_{MemoryUtil.Read(player.Instance + 0x13D90):X})"); - if (expaned) - { - drawModelParts(playerArmor[Armor.Slinger]); - ImGui.Separator(); - } - if (ImGui.CollapsingHeader("Hair")) - { - drawModelParts(playerArmor[Armor.Hair]); - ImGui.Separator(); - } - if (ImGui.CollapsingHeader("Face")) - { - drawModelParts(playerArmor[Armor.Face]); - ImGui.Separator(); - } - if (ImGui.CollapsingHeader("Eye Lens")) - { - drawModelParts(playerArmor[Armor.EyeLens]); - } - ImGui.Separator(); - } - ImGui.PopID(); - - nint controlsAddr = MemoryUtil.Read(player.Instance + 0x12608); - nint zoneStateAddr = MemoryUtil.Read(0x1451C42B8); - ZoneState zoneState = ZoneState.Unknown; - if (controlsAddr != 0x0 && zoneStateAddr != 0x0) - { - ref byte passiveFlag = ref MemoryUtil.GetRef(player.Instance + 0x7626); - ref byte passiveFlag2 = ref MemoryUtil.GetRef(MemoryUtil.Read(player.Instance + 0x7D20) + 0x9B8); - bool passive = passiveFlag == 0x1 && passiveFlag2 == 0x1; - if (ImGui.Checkbox("Passive", ref passive)) - { - passiveFlag = ByteFlag(passive); - passiveFlag2 = ByteFlag(passive); - } - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("Passive: Calm camera and your hunter looks neutral/smiles.\nCombat: Intense camera and your hunter looks angry.\nIf you have Passive set and Combat Controls on, or vice versa, expect glitchy behavior."); - ImGui.EndTooltip(); - } - bool combatControls = MemoryUtil.Read(controlsAddr + 0xB18) == 0x80; - zoneState = combatControls ? ZoneState.Combat : ZoneState.Hub; -#if !QUARANTINED_FEATURES - ImGui.Text($"Current Zone State: {((MemoryUtil.GetRef(zoneStateAddr + 0xD2EA) == 0x1) ? "Hub" : "Combat")}"); -#else - if (ImGui.Checkbox("Combat Controls", ref combatControls)) - { - passiveFlag = ByteFlag(!combatControls); - passiveFlag2 = ByteFlag(!combatControls); - setPlayerController1.Invoke(player.Instance); - setPlayerController5.Invoke(controlsAddr); - } - int zoneStateInt = (int)forceZoneState; - ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(0.0f, 6.0f)); - ImGui.Text($"Force Zone State (Current: {((MemoryUtil.GetRef(zoneStateAddr + 0xD2EA) == 0x1) ? "Hub" : "Combat")})"); - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("This will apply when moving to a different area."); - ImGui.EndTooltip(); - } - ImGui.SameLine(); - ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); - ImGui.RadioButton("Off", ref zoneStateInt, 0); - ImGui.SameLine(); - ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); - ImGui.RadioButton("Hub", ref zoneStateInt, 1); ImGui.SameLine(); - ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); - ImGui.RadioButton("Combat", ref zoneStateInt, 2); - forceZoneState = (ZoneState)zoneStateInt; - if (ImGui.Button("Run Change Zone State")) - { - zoneStateManualInvoke = true; - setZoneState.Invoke(player.Instance, 0x000106C0); // or 0x00010780. - } - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("You can use this to apply the value of Force Zone State.\nIf you're in a map and Force Zone State is set to Off or Combat, this will send you back to camp."); - ImGui.EndTooltip(); - } - if (ImGui.Checkbox("Force Passive in Combat Zones", ref forcePassiveInCombatZone)) - { - if (forcePassiveInCombatZone) - { - zoneStateForcePassive1.Enable(); - zoneStateForcePassive2.Enable(); - } - else - { - zoneStateForcePassive1.Disable(); - zoneStateForcePassive2.Disable(); - } - } - if (ImGui.Checkbox("Force Combat in Passive Zones", ref forceCombatInPassiveZone)) + if (ImGui.BeginCombo("##Positions", selectedPositionName)) { - if (forceCombatInPassiveZone) - { - zoneStateForceCombat1.Enable(); - zoneStateForceCombat2.Enable(); - } - else + Dictionary.KeyCollection positionKeys = config.Positions.Keys; + for (int j = 0; j < positionKeys.Count + 1; j++) { - zoneStateForceCombat1.Disable(); - zoneStateForceCombat2.Disable(); - } - } -#endif - } - - if (zoneState != ZoneState.Combat) - { - ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); - ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f); - } - if (ImGui.Checkbox("Force Crawl", ref enableCrawl)) - { - if (enableCrawl) - { - MemoryUtil.GetRef(psuedoObject2 + 0x70) = player.Position.X + player.Forward.X; - MemoryUtil.GetRef(psuedoObject2 + 0x74) = player.Position.Y + player.Forward.Y; - MemoryUtil.GetRef(psuedoObject2 + 0x78) = player.Position.Z + player.Forward.Z; - - Quaternion playerRotation = new Quaternion(player.Forward.X, player.Forward.Y, player.Forward.Z, 0.0f); - Quaternion objectRotation = getRight(playerRotation); - - MemoryUtil.GetRef(psuedoObject2 + 0x40) = objectRotation.X; - MemoryUtil.GetRef(psuedoObject2 + 0x44) = objectRotation.Y; - MemoryUtil.GetRef(psuedoObject2 + 0x48) = objectRotation.Z; - MemoryUtil.GetRef(psuedoObject2 + 0x4C) = objectRotation.W; - - MemoryUtil.GetRef(psuedoObject2 + 0x50) = 0.0f; - MemoryUtil.GetRef(psuedoObject2 + 0x54) = 1.0f; - MemoryUtil.GetRef(psuedoObject2 + 0x58) = 0.0f; - MemoryUtil.GetRef(psuedoObject2 + 0x5C) = 0.0f; - - MemoryUtil.GetRef(psuedoObject2 + 0x60) = playerRotation.X; - MemoryUtil.GetRef(psuedoObject2 + 0x64) = playerRotation.Y; - MemoryUtil.GetRef(psuedoObject2 + 0x68) = playerRotation.Z; - MemoryUtil.GetRef(psuedoObject2 + 0x6C) = playerRotation.W; - } - } - if (zoneState != ZoneState.Combat) - { - ImGui.PopItemFlag(); - ImGui.PopStyleVar(); - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("You have to be out in a map to use this."); - ImGui.EndTooltip(); - } - } - else - { - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("Simulate crawling under an object in the direction your character was facing when enabled."); - ImGui.EndTooltip(); - } - } - - if (zoneState != ZoneState.Hub) - { - ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); - ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f); - } - if (ImGui.Button("Sit in Hot Springs")) - { - // Run sit in hot springs action (top of function). - // MonsterHunterWorld.exe+17601F0 - mov [rsp+08],rbx - MemoryUtil.WriteBytes(player.ActionController.Instance + 0xC0, [0x65, 0x00, 0x00, 0x00]); - MemoryUtil.WriteBytes(player.ActionController.Instance + 0xBC, [0x01, 0x00, 0x00, 0x00]); - } - if (zoneState != ZoneState.Hub) - { - ImGui.PopItemFlag(); - ImGui.PopStyleVar(); - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("You have to be in a hub area to use this."); - ImGui.EndTooltip(); - } - } - - if (ImGui.Checkbox("Allow Hot Springs Anywhere", ref allowHotSpringsAnywhere)) - { - if (allowHotSpringsAnywhere) - { - jmpOverHotSpringsEval.Enable(); - } - else - { - jmpOverHotSpringsEval.Disable(); - } - } - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("Disable check for being about halfway submerged in water to stay sitting."); - ImGui.EndTooltip(); - } - - if (ImGui.Checkbox("Disable Hot Springs Steam", ref disableHotSpringsSteam)) - { - if (disableHotSpringsSteam) - { - jmpOverHotSpringsSteam.Enable(); - } - else - { - jmpOverHotSpringsSteam.Disable(); - } - } - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("It will take a couple of seconds to fade away."); - ImGui.EndTooltip(); - } - - ref float playerOpacity = ref MemoryUtil.GetRef(player.Instance + 0x78E0); - ImGui.SetNextItemWidth(width * 0.325f); - if (ImGui.DragFloat("Opacity", ref playerOpacity, 0.01f, 0.0f, Single.MaxValue)) - { - playerOpacityOverride = playerOpacity; - } - - ImGui.PushID("Wetness"); - if (ImGui.CollapsingHeader("Wetness")) - { - nint wetnessAddr = player.Instance + 0x13BD0; - ImGui.PushItemWidth(width * 0.15f); - ImGui.DragFloat("Head", ref MemoryUtil.GetRef(wetnessAddr), 0.005f); - ImGui.SameLine(); - ImGui.DragFloat("Body", ref MemoryUtil.GetRef(wetnessAddr + 0x28), 0.005f); - ImGui.DragFloat("Waist", ref MemoryUtil.GetRef(wetnessAddr + 0x50), 0.005f); - ImGui.SameLine(); - ImGui.DragFloat("Legs", ref MemoryUtil.GetRef(wetnessAddr + 0x78), 0.005f); + if (j == 0) + { + if (ImGui.Selectable("(None)")) + { + selectedPositionName = ""; + } + continue; + } + string positionKey = positionKeys.ElementAt(j - 1); + if (ImGui.Selectable(positionKey)) + { + Config.Position pos = config.Positions[positionKey]; + selectedPositionName = positionKey; + camera.FieldOfView = pos.FieldOfView; + cameraRoll = pos.Roll; + cameraPosition = new Vector3(pos.PosX, pos.PosY, pos.PosZ); + cameraTarget = new Vector3(pos.TargetX, pos.TargetY, pos.TargetZ); + Quaternion forward = Quaternion.Normalize(getForward(cameraPosition, cameraTarget)); + cameraYaw = Single.RadiansToDegrees(MathF.Atan2(forward.Z, forward.X)); + cameraPitch = Single.RadiansToDegrees(MathF.Asin(forward.Y)); + camera.Position = cameraPosition; + camera.Target = cameraTarget; + } + } + ImGui.EndCombo(); + } ImGui.PopItemWidth(); - ImGui.SetNextItemWidth(width * 0.35f); - if (ImGui.DragFloat("Whole Body", ref wholeBodyWetness, 0.005f)) + ImGui.SameLine(); + if (ImGui.Button("Delete")) { - if (overridePlayerWetness) + if (selectedPositionName != "") { - writePlayerWholeBodyWetness(wetnessAddr); + config.Positions.Remove(selectedPositionName); + selectedPositionName = ""; + ConfigManager.SaveConfig(this); } } - if (ImGui.Button("Reset")) - { - wholeBodyWetness = 0.0f; - writePlayerWholeBodyWetness(wetnessAddr); - } - ImGui.SameLine(); - if (ImGui.Checkbox("Override Player Wetness", ref overridePlayerWetness)) + if (debug) { - if (overridePlayerWetness) + bool move = camera.Move; + if (ImGui.Checkbox("Move", ref move)) { - overridePlayerWetnessEnable(); - writePlayerWholeBodyWetness(wetnessAddr); + camera.Move = move; } - else + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Uncheck this to allow manually overriding the camera position.\nIf your camera is frozen, make sure this is checked."); + ImGui.EndTooltip(); + } + ImGui.SameLine(); + bool fix = camera.Fix; + if (ImGui.Checkbox("Fix", ref fix)) { - overridePlayerWetnessDisable(); + camera.Fix = fix; } } - ImGui.Separator(); - } - ImGui.PopID(); - - 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); - ImGui.SliderFloat4("Rotation", ref rotation, -1.0f, 1.0f); - Vector3 rotationOffset = new Vector3(); - if (ImGui.DragFloat3("Rotation Offset", ref rotationOffset, 0.0025f)) - { - 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")) - { - player.Rotation.X = 0.0f; - player.Rotation.Z = 0.0f; - } - if (ImGui.Checkbox("Disable Collision", ref disableCollision)) - { - if (disableCollision) + if (camera == pCamera) { - disableCollisionEnable(); + Player? player = checkPlayerChange(); + if (!debug && player != null) + { + ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(0.0f, 6.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, 6.0f)); + ref byte settingB = ref MemoryUtil.GetRef(PlayerExt.getPlayerSettings() + 0x1403FD); + int settingI = settingB; + ImGui.SameLine(); + ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); + if (ImGui.RadioButton("Close", ref settingI, 0)) + { + settingB = (byte)settingI; + } + ImGui.SameLine(); + ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f)); + if (ImGui.RadioButton("Default", ref settingI, 1)) + { + settingB = (byte)settingI; + } + ImGui.SameLine(); + ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.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(player.Instance + 0x14F8); + if (playerCameraAddr != 0x0) + { + playerCameraAddr = MemoryUtil.Read(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(viewParamOffset + 0x20), 0.1f); + } + viewParamOffset = getViewParamOffset.Invoke(playerCameraAddr + 0x1380, 0, 0xCA); + if (viewParamOffset != 0x0) + { + ImGui.DragFloat3("Far", ref MemoryUtil.GetRef(viewParamOffset + 0x20), 0.1f); + } + } + } } - else + if (camera == vCamera) { - if (disableExtraGravity) + if (!usedByFreeCamera) { - disableExtraGravity = false; - disableExtraGravityDisable(); + ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); } - if (disableGravity) + 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); + ImGui.DragFloat("Roll", ref cameraRoll, 0.2f); + if (!usedByFreeCamera) { - disableGravity = false; - disableGravityDisable(); + ImGui.PopItemFlag(); } - if (disableExtraCollision) + // Try to grey out offsets when they probably have no effect. + if ((camera == pCamera && !usedByFreeCamera) && camera.Move) { - disableExtraCollision = false; - disableExtraCollisionDisable(); + ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f); } - disableCollisionDisable(); - } - } - if (!disableCollision) - { - ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); - ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f); - } - if (ImGui.Checkbox("Disable Another Y Collision", ref disableExtraCollision)) - { - if (disableExtraCollision) - { - disableExtraCollisionEnable(); - } - else - { - if (disableExtraGravity) + ImGui.Text("Move"); + float offsetForward = 0.0f; + if (ImGui.DragFloat("Forward", ref offsetForward, 0.425f)) + { + Quaternion forward = getForward(camera.Position, camera.Target); + forward = Quaternion.Normalize(forward); + camera.Position.X += forward.X * offsetForward; + camera.Position.Y += forward.Y * offsetForward; + camera.Position.Z += forward.Z * offsetForward; + if (usedByFreeCamera) cameraPosition = camera.Position; + } + float offsetRight = 0.0f; + if (ImGui.DragFloat("Right", ref offsetRight, 0.425f)) + { + Quaternion forward = getForward(camera.Position, camera.Target); + Quaternion right = getRight(forward); + forward = Quaternion.Normalize(forward); + right = Quaternion.Normalize(right); + camera.Position.X += right.X * offsetRight; + camera.Position.Z += right.Z * offsetRight; + if (usedByFreeCamera) cameraPosition = camera.Position; + } + float offsetUp = 0.0f; + if (ImGui.DragFloat("Up", ref offsetUp, 0.425f)) { - disableExtraGravity = false; - disableExtraGravityDisable(); + camera.Position.Y += offsetUp; + if (usedByFreeCamera) cameraPosition = camera.Position; } - if (disableGravity) + if (camera == pCamera && !(freeCamera || enableFreeCamera)) { - disableGravity = false; - disableGravityDisable(); + ImGui.PopStyleVar(); } - disableExtraCollisionDisable(); } } - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("This will make your legs goofy, but is needed to get on top of some things."); - ImGui.EndTooltip(); - } - if (!disableCollision) + ImGui.PopItemWidth(); + } + + public static void drawAnimationInfo(Entity entity, float width, bool debug) + { + ActionController actionController = entity.ActionController; + ActionInfo currentActionInfo = actionController.CurrentAction; + SharpPluginLoader.Core.Actions.Action? currentAction = null; + if (currentActionInfo.ActionSet >= 0 && currentActionInfo.ActionSet <= 3) { - ImGui.PopItemFlag(); - ImGui.PopStyleVar(); + ActionList actionList = actionController.GetActionList(currentActionInfo.ActionSet); + if (currentActionInfo.ActionId >= 0 && currentActionInfo.ActionId < actionList.Count) + { + currentAction = actionList[currentActionInfo.ActionId]; + } } - if (!disableExtraCollision) + if (debug) { - ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); - ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f); + 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}"); + } } - if (ImGui.Checkbox("Disable Y Gravity", ref disableGravity)) + AnimationId currentAnimation = entity.CurrentAnimation; + AnimationLayerComponent? animationLayer = entity.AnimationLayer; + if (animationLayer != null) { - if (disableGravity) + ImGui.Text(debug ? $"AnimationLayer: 0x{animationLayer.Instance:X}" : "Animation"); + if (debug) { - disableGravityEnable(); + ImGui.Text($" Current: {currentAnimation}"); + ImGui.Text($" Frame: {animationLayer.CurrentFrame:0.000}/{animationLayer.MaxFrame:0.000}"); + return; } else { - if (disableExtraGravity) + ImGui.Text($" Current: {currentAnimation.Lmt}.{currentAnimation.Id}, {(currentAction != null ? currentAction.Name : "None")}"); + if (ImGui.BeginItemTooltip()) { - disableExtraGravity = false; - disableExtraGravityDisable(); + ImGui.Text("{Lmt}.{Id}, {Action}"); + ImGui.EndTooltip(); } - disableGravityDisable(); + ImGui.SetNextItemWidth(width * 0.8f); + ImGui.SliderFloat("Frame", ref animationLayer.CurrentFrame, 0.0f, animationLayer.MaxFrame, "%.3f"); } - } - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("Avoid falling when going too high (Y axis)."); - ImGui.EndTooltip(); - } - if (!disableExtraCollision) - { - ImGui.PopItemFlag(); - ImGui.PopStyleVar(); - } - if (!disableGravity) - { - ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); - ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f); - } - if (ImGui.Checkbox("Disable More Gravity", ref disableExtraGravity)) - { - if (disableExtraGravity) + bool animationPaused = animationLayer.Paused; + if (ImGui.Checkbox("Paused", ref animationPaused)) { - disableExtraGravityEnable(); + animationLayer.Paused = animationPaused; } - else + ImGui.SameLine(); + float? lockedSpeed = animationLayer.LockedSpeed; + float speed = lockedSpeed ?? animationLayer.Speed; + bool animationLocked = lockedSpeed != null; + if (ImGui.Checkbox("Set", ref animationLocked)) { - disableExtraGravityDisable(); + 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); } } - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("This can stop you from falling when going out of bounds and/or rotating."); - ImGui.EndTooltip(); - } - if (!disableGravity) - { - ImGui.PopItemFlag(); - ImGui.PopStyleVar(); - } - drawAnimationInfo(player, width, false); } public void OnImGuiRender() @@ -4762,29 +2479,6 @@ namespace NewCamera Player? player = checkPlayerChange(); checkCurrentVisibleCamera(player); - if (ImGui.Checkbox("Disable Mod", ref disableMod)) - { - if (disableMod) - { - tryToDisableMod(player); - } - else - { - tryToEnableMod(); - } - config.DisableMod = disableMod; - ConfigManager.SaveConfig(this); - } - if (ImGui.BeginItemTooltip()) - { - ImGui.Text("Try to disable as much as possible."); - ImGui.EndTooltip(); - } - if (disableMod) - { - return; - } - ImGui.Separator(); if (ImGui.Checkbox("Enable Perspective Camera", ref enableOffsetPerspective)) @@ -5406,11 +3100,7 @@ namespace NewCamera if (player == null) { - player = getPlayerFromSaveSlot(); - } - else - { - saveSlotIndex = -1; + player = PlayerExt.getPlayerFromSaveSlot(); } ImGui.PushID("Player"); @@ -5418,7 +3108,7 @@ namespace NewCamera { if (player != null) { - drawPlayerInfo(player, width); + PlayerExt.drawPlayerInfo(player, width); ImGui.Separator(); } } @@ -5544,11 +3234,11 @@ namespace NewCamera ImGui.PushID("Player"); ImGui.Text("Player"); - ImGui.Text($"sMhPlayer: 0x{sPlayer.Instance:X}"); + ImGui.Text($"sPlayer: 0x{PlayerExt.sPlayer!.Instance:X}"); if (player != null) { ImGui.Text($"Address: 0x{player.Instance:X}"); - ImGui.Text($"Settings: 0x{getPlayerSettings():X}"); + ImGui.Text($"Settings: 0x{PlayerExt.getPlayerSettings():X}"); drawAnimationInfo(player, width, true); @@ -5598,6 +3288,15 @@ namespace NewCamera ImGui.Text($"{monster.Name}:"); ImGui.Text($" Address: 0x{monster.Instance:X}"); 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)) + { + 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); + } drawAnimationInfo(monster, width, true); ImGui.PopID(); ImGui.Separator(); @@ -5726,7 +3425,7 @@ namespace NewCamera } if (filterMatch) { - drawModelParts(0x0, partsAddr); + PlayerExt.drawModelParts(0x0, partsAddr); } } ImGui.PopID(); -- cgit v1.2.3-101-g0448