diff options
| author | 2026-09-21 11:29:55 -0400 | |
|---|---|---|
| committer | 2026-09-21 11:29:55 -0400 | |
| commit | 6802618079b7d8ec5e383d7356be3db4def5e172 (patch) | |
| tree | b34f5757ebb5b487fbcaef7e05971192edc00f73 | |
| parent | a4c70bb279e93588f14fc1fd6b80baa87f4d118c (diff) | |
| download | NewCamera-6802618079b7d8ec5e383d7356be3db4def5e172.tar.gz NewCamera-6802618079b7d8ec5e383d7356be3db4def5e172.tar.bz2 NewCamera-6802618079b7d8ec5e383d7356be3db4def5e172.zip | |
Separate player stuff
Signed-off-by: Andrew Opalach <andrew@akon.city>
| -rw-r--r-- | Player.cs | 2222 | ||||
| -rwxr-xr-x | Plugin.cs | 2383 |
2 files changed, 2263 insertions, 2342 deletions
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<nint, nint> getSaveSlotGuiAddr; + private static NativeFunction<nint, nint> getPlayerSettingsAddr; + public static nint getPlayerSettings() + { + nint rcx = MemoryUtil.Read<nint>(0x145013950); + if (saveSlotIndex >= 0) + { + // MonsterHunterWorld.exe+ADC442 - imul rdx,rcx,0026CC00 + nint rax = saveSlotIndex * 0x26CC00; + rax += MemoryUtil.Read<nint>(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<CollisionCheckDelegate>? 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<UpdateJoints>? updateJointRotationHook; + private static Hook<UpdateJoints>? updateJointPositionHook; + public static List<nint> bodyJoints = new List<nint>(); + private static List<nint> ignoredJoints = new List<nint>(); + private static Dictionary<nint, List<Vector3>> bodyRotations = new Dictionary<nint, List<Vector3>>(); + private static Dictionary<nint, List<Vector3>> bodyOffsets = new Dictionary<nint, List<Vector3>>(); + + private static List<nint> faceJoints = new List<nint>(); + private static Dictionary<nint, List<Vector3>> faceRotations = new Dictionary<nint, List<Vector3>>(); + private static Dictionary<nint, List<Vector3>> faceOffsets = new Dictionary<nint, List<Vector3>>(); + +#if QUARANTINED_FEATURES + private delegate void UpdateIK(nint superOfChild, nint joint, nint obj); + private static Hook<UpdateIK>? updateIKHook; + private static Dictionary<nint, List<Vector3>> ikOffsets = new Dictionary<nint, List<Vector3>>(); + private static List<nint> ikJoints = new List<nint>(); +#endif + private static bool ikForcedOff = false; + private static Patch forceDisableIK; + + private static List<nint> jiggleBones = new List<nint>(); + 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<ChangeEquipment>? changeEquipmentHook; + private NativeFunction<nint, int, nint> 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<nint, int> setZoneState; + private static NativeAction<nint> setPlayerController1; + private static NativeAction<nint> 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<ZoneStateDelegate>? 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<nint, nint> 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<RefreshEntityParams>? 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<float>(wetnessAddr) = wholeBodyWetness; + MemoryUtil.GetRef<float>(wetnessAddr + 0x28) = wholeBodyWetness; + MemoryUtil.GetRef<float>(wetnessAddr + 0x50) = wholeBodyWetness; + MemoryUtil.GetRef<float>(wetnessAddr + 0x78) = wholeBodyWetness; + } + + public static void Initialize() + { + + collisionCheckHook = Hook.Create<CollisionCheckDelegate>(0x1411C4E50, CollisionCheckHook); // nint, nint + +#if QUARANTINED_FEATURES + // MonsterHunterWorld.exe+20354F7 - call MonsterHunterWorld.exe+1F73850 + setZoneState = new NativeAction<nint, int>(0x142035020); + setPlayerController1 = new NativeAction<nint>(0x141F73850); + setPlayerController5 = new NativeAction<nint>(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<ZoneStateDelegate>(0x142035020, SetZoneStateHook); // nint, int + + procEnvironmentCollision = new NativeAction<nint, nint>(0x141F737D0); + psuedoObject1 = (nint)NativeMemory.AllocZeroed(0x7C); + MemoryUtil.WriteBytes(psuedoObject1 + 0x30, [0x03]); + psuedoObject2 = (nint)NativeMemory.AllocZeroed(0x7C); + MemoryUtil.WriteBytes(psuedoObject2 + 0x30, [0x08]); + + getSaveSlotGuiAddr = new NativeFunction<nint, nint>(0x141AC0B60); + getPlayerSettingsAddr = new NativeFunction<nint, nint>(0x141B8DBB0); + + forceDisableIK = new Patch(lton(0x14031FD40), [0xC6, 0x81, 0x81, 0x01, 0x00, 0x00, 0x00, 0xC3]); + + // Alt: 0x141FBC7A0 (model - 0x958) + updateJointRotationHook = Hook.Create<UpdateJoints>(0x14223BA30, UpdateJointRotationHook); + updateJointPositionHook = Hook.Create<UpdateJoints>(0x142228F50, UpdateJointPositionHook); +#if QUARANTINED_FEATURES + updateIKHook = Hook.Create<UpdateIK>(0x142472C00, UpdateIKHook); +#endif + + /* + changeEquipmentHook = Hook.Create<ChangeEquipment>(0x141DDEF80, ChangeEquipmentHook); // nint, int + newEquipmentPointer = new NativeFunction<nint, int, nint>(0x141DE56A0); + */ + + // 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<RefreshEntityParams>(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<nint>(0x1451C42B8)); + if (guiAddr == 0x0) + { + saveSlotIndex = -1; + return null; + } + // MonsterHunterWorld.exe+ADC42F - movsxd rcx,dword ptr [rax+00000334] + saveSlotIndex = MemoryUtil.Read<int>(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<nint>(offset) != 0x1433FE588) + { + return null; + } + nint playerAddr = MemoryUtil.Read<nint>(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<nint>(player.Instance + 0x76B0); + if (baseAddr != 0x0) + { + MemoryUtil.WriteBytes(baseAddr + 0x1A98, [0x1]); + int weaponParts = MemoryUtil.Read<int>(baseAddr + 0x2250); + for (int i = 0; i < weaponParts; i++) + { + nint partsAddr = MemoryUtil.Read<nint>(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<int>(player.Instance + 0x8938) |= (1 << 6); + MemoryUtil.GetRef<int>(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<nint>(player.Instance + 0x12608); + bool combatControls = false; + if (controlsAddr != 0x0) + { + combatControls = MemoryUtil.Read<byte>(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<nint>(0x1451C42B8); + ref byte zoneState = ref MemoryUtil.GetRef<byte>(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<float>(wetnessAddr); + bodyWet = MemoryUtil.Read<float>(wetnessAddr + 0x28); + waistWet = MemoryUtil.Read<float>(wetnessAddr + 0x50); + legsWet = MemoryUtil.Read<float>(wetnessAddr + 0x78); + } + + setZoneStateHook!.Original(player, flags); + + if (overridePlayerWetness) + { + MemoryUtil.GetRef<float>(wetnessAddr) = headWet; + MemoryUtil.GetRef<float>(wetnessAddr + 0x28) = bodyWet; + MemoryUtil.GetRef<float>(wetnessAddr + 0x50) = waistWet; + MemoryUtil.GetRef<float>(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<float>(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<int>(baseAddr + 0x4A0); + nint jointAddr = MemoryUtil.Read<nint>(baseAddr + 0x4A8); + for (int i = 0; i < jointCount; i++) + { + nint childAddr = MemoryUtil.Read<nint>(jointAddr + 0x8); + if (childAddr != 0x0 && MemoryUtil.Read<nint>(childAddr) == 0x142F21A90) + { + childAddr = MemoryUtil.Read<nint>(childAddr + 0x8); + if (childAddr != 0x0) + { + nint childVtable = MemoryUtil.Read<nint>(childAddr); + if (childVtable == 0x1435195B8) // Jiggle Bone Container. + { + if (part == Armor.Body) + { + ignoredJoints.Add(jointAddr); + } + } + else if (childVtable == 0x143524BD8) + { + childAddr = MemoryUtil.Read<nint>(childAddr + 0x188); + if (childAddr != 0x0 && MemoryUtil.Read<nint>(childAddr) == 0x143519530) + { + nint jiggleData = MemoryUtil.Read<nint>(MemoryUtil.Read<nint>(childAddr + 0xA0)); + if (MemoryUtil.Read<nint>(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<nint>(childAddr + 0x188); + if (childAddr != 0x0 && MemoryUtil.Read<nint>(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<byte>(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<nint, List<Vector3>> rotations, Dictionary<nint, List<Vector3>> 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<Vector4>(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<Vector4>(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<Vector3>() + { + new Vector3() + }); + } + } + if (!hasOffset) + { + if (!hasRotation) + { + ImGui.SameLine(); + } + if (ImGui.Button("Add Offset")) + { + offsets.Add(jointAddr, new List<Vector3>() + { + 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<Vector3>() + { + new Vector3() + }); + } + } +#endif + ImGui.PopID(); + } + + private static void drawJoint(nint jointAddr) + { + drawJoint(jointAddr, bodyRotations, bodyOffsets); + } + + private static void drawJointLeaf(ref List<nint> joints, int i, Dictionary<nint, List<Vector3>> rotations, Dictionary<nint, List<Vector3>> offsets) + { + if (i >= joints.Count) return; + nint jointAddr = joints[i]; + byte id = MemoryUtil.Read<byte>(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<Vector3>(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<nint>(armorAddr + 0x2A0)) == 0x0) + { + return; + } + } + ImGui.PushID(partsAddr); + string fullString = Marshal.PtrToStringAnsi(partsAddr + 0xC)!; + if (armorAddr != 0x0) + { + string partName = extractPartName(fullString); + ImGui.Text($"{partName} (0x{armorAddr:X}, {fullString} @ 0x{partsAddr:X}):"); + } + else + { + ImGui.Text($"{fullString} @ 0x{partsAddr:X}:"); + } + // MonsterHunterWorld.exe+222E651 - mov rax,[r8+000000C8] + nint baseLod = MemoryUtil.Read<nint>(partsAddr + 0xC8); + nint baseOffset = MemoryUtil.Read<nint>(partsAddr + 0x408 + (0x8 * 0x1)); + int numParts = MemoryUtil.Read<int>(partsAddr + 0x548 + (0x4 * 0x1)); + // Setting lodCount to 0 is probably the best way to completely hide a model. + int lodCount = MemoryUtil.Read<int>(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<int>(baseOffset + (i * 0x4)); + nint lod0 = baseLod + lodOffset * lodStructSize; + bool isVisible = MemoryUtil.GetRef<ushort>(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<int>(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<ushort>(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<ushort>(lod); + ref ushort padSub = ref MemoryUtil.GetRef<ushort>(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<nint>(player.Instance + 0x2A0); + if (bodyArmorParts == 0x0) + { + return false; + } + // MonsterHunterWorld.exe+203E8A2 - mov rax,[rbx+000126C8] + nint combineArmorList = MemoryUtil.Read<nint>(player.Instance + 0x126C8); + if (combineArmorList == 0x0) + { + return false; + } + collectArmorParts(player.Instance, bodyArmorParts); + nint weapon = MemoryUtil.Read<nint>(player.Instance + 0x76B0); + if (weapon != 0x0) + { + nint weaponParts = MemoryUtil.Read<nint>(weapon + 0x2A0); + if (weaponParts != 0x0) + { + collectArmorParts(weapon, weaponParts); + } + } + nint slinger = MemoryUtil.Read<nint>(player.Instance + 0x8918); + if (slinger != 0x0) + { + nint slingerParts = MemoryUtil.Read<nint>(slinger + 0x2A0); + if (slingerParts != 0x0) + { + collectArmorParts(slinger, slingerParts); + } + } + combineArmorList = MemoryUtil.Read<nint>(combineArmorList + 0x70); + nint next = combineArmorList; + while (next != 0x0) + { + nint armorAddr = next; + next = MemoryUtil.Read<nint>(armorAddr + 0x30); + nint vTable = MemoryUtil.Read<nint>(armorAddr); + // uWeaponParts: 0x1434D2400, uWeaponEmblem: 0x1434D1D58 + if (vTable == 0x1434A7560) // uPlCombineArmor + { + nint partsAddr = 0x0; + nint childAddr = MemoryUtil.Read<nint>(armorAddr + 0x548); + if (childAddr != 0x0) + { + if (MemoryUtil.Read<nint>(childAddr) == 0x143451520) // Face. + { + nint ownerAddr = MemoryUtil.Read<nint>(childAddr + 0x998); + if (ownerAddr != player.Instance) + { + continue; + } + if (playerArmor[Armor.Face] == 0x0) + { + partsAddr = MemoryUtil.Read<nint>(childAddr + 0x2A0); + if (partsAddr != 0x0) + { + collectArmorParts(childAddr, partsAddr); + } + childAddr = MemoryUtil.Read<nint>(childAddr + 0x9C8); + if (childAddr != 0x0 && MemoryUtil.Read<nint>(childAddr) == 0x143505E98) // Eye lens. + { + partsAddr = MemoryUtil.Read<nint>(childAddr + 0x2A0); + if (partsAddr != 0x0) + { + collectArmorParts(childAddr, partsAddr); + } + } + } + } + else if (childAddr != player.Instance) + { + continue; + } + } + partsAddr = MemoryUtil.Read<nint>(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<Vector3> rotations) in bodyRotations) + { + MemoryUtil.GetRef<Quaternion>(addr + 0x70) *= Quaternion.CreateFromYawPitchRoll(rotations[0].X, rotations[0].Y, rotations[0].Z); + } + if (playerArmor[Armor.Waist] != 0x0) + { + MemoryUtil.GetRef<byte>(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<Vector3> rotations) in faceRotations) + { + MemoryUtil.GetRef<Quaternion>(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<Vector3> offsets) in bodyOffsets) + { + MemoryUtil.GetRef<Vector3>(addr + 0x50) += offsets[0]; + } + } + else if (player != null && model == playerArmor[Armor.Face]) + { + refreshArmorState(player); + foreach ((nint addr, List<Vector3> offsets) in faceOffsets) + { + MemoryUtil.GetRef<Vector3>(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<Vector3>(superOfChild + 0x1380) += offset; + } + updateIKHook!.Original(superOfChild, joint, obj); + } +#endif + + /* + private void ChangeEquipmentHook(nint unknownPtr, int unknownInt) + { + nint rax = MemoryUtil.Read<nint>(unknownPtr + 0x2968); + nint r9 = MemoryUtil.Read<nint>(unknownPtr + 0x2950); + int esi = MemoryUtil.Read<int>(rax + 0x240); + esi *= MemoryUtil.Read<int>(r9 + 0x1D8); + esi += unknownInt; + nint newEquipment = newEquipmentPointer.Invoke(unknownPtr, esi); + lastEquipedId = MemoryUtil.Read<int>(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<byte>(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<byte>(MemoryUtil.Read<nint>(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<int>(player.Instance + 0x1373C):X})"); + if (expaned) + { + drawModelParts(playerArmor[Armor.Helmet]); + ImGui.Separator(); + } + expaned = ImGui.CollapsingHeader("Body"); + ImGui.SameLine(); + ImGui.Text($"(id: {MemoryUtil.Read<int>(player.Instance + 0x13740):X})"); + if (expaned) + { + drawModelParts(playerArmor[Armor.Body]); + ImGui.Separator(); + } + expaned = ImGui.CollapsingHeader("Arms"); + ImGui.SameLine(); + ImGui.Text($"(id: {MemoryUtil.Read<int>(player.Instance + 0x13744):X})"); + if (expaned) + { + drawModelParts(playerArmor[Armor.Arm]); + ImGui.Separator(); + } + expaned = ImGui.CollapsingHeader("Waist"); + ImGui.SameLine(); + ImGui.Text($"(id: {MemoryUtil.Read<int>(player.Instance + 0x13748):X})"); + if (expaned) + { + drawModelParts(playerArmor[Armor.Waist]); + ImGui.Separator(); + } + expaned = ImGui.CollapsingHeader("Legs"); + ImGui.SameLine(); + ImGui.Text($"(id: {MemoryUtil.Read<int>(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<int>(player.Instance + 0x13D8C):X}_{MemoryUtil.Read<int>(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<nint>(player.Instance + 0x12608); + nint zoneStateAddr = MemoryUtil.Read<nint>(0x1451C42B8); + ZoneState zoneState = ZoneState.Unknown; + if (controlsAddr != 0x0 && zoneStateAddr != 0x0) + { + ref byte passiveFlag = ref MemoryUtil.GetRef<byte>(player.Instance + 0x7626); + ref byte passiveFlag2 = ref MemoryUtil.GetRef<byte>(MemoryUtil.Read<nint>(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<byte>(controlsAddr + 0xB18) == 0x80; + zoneState = combatControls ? ZoneState.Combat : ZoneState.Hub; +#if !QUARANTINED_FEATURES + ImGui.Text($"Current Zone State: {((MemoryUtil.GetRef<byte>(zoneStateAddr + 0xD2EA) == 0x1) ? "Hub" : "Combat")}"); +#else + if (ImGui.Checkbox("Combat Controls", ref combatControls)) + { + passiveFlag = ByteFlag(!combatControls); + 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<byte>(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<float>(psuedoObject2 + 0x70) = player.Position.X + player.Forward.X; + MemoryUtil.GetRef<float>(psuedoObject2 + 0x74) = player.Position.Y + player.Forward.Y; + MemoryUtil.GetRef<float>(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<float>(psuedoObject2 + 0x40) = objectRotation.X; + MemoryUtil.GetRef<float>(psuedoObject2 + 0x44) = objectRotation.Y; + MemoryUtil.GetRef<float>(psuedoObject2 + 0x48) = objectRotation.Z; + MemoryUtil.GetRef<float>(psuedoObject2 + 0x4C) = objectRotation.W; + + MemoryUtil.GetRef<float>(psuedoObject2 + 0x50) = 0.0f; + MemoryUtil.GetRef<float>(psuedoObject2 + 0x54) = 1.0f; + MemoryUtil.GetRef<float>(psuedoObject2 + 0x58) = 0.0f; + MemoryUtil.GetRef<float>(psuedoObject2 + 0x5C) = 0.0f; + + MemoryUtil.GetRef<float>(psuedoObject2 + 0x60) = playerRotation.X; + MemoryUtil.GetRef<float>(psuedoObject2 + 0x64) = playerRotation.Y; + MemoryUtil.GetRef<float>(psuedoObject2 + 0x68) = playerRotation.Z; + MemoryUtil.GetRef<float>(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<float>(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<float>(wetnessAddr), 0.005f); + ImGui.SameLine(); + ImGui.DragFloat("Body", ref MemoryUtil.GetRef<float>(wetnessAddr + 0x28), 0.005f); + ImGui.DragFloat("Waist", ref MemoryUtil.GetRef<float>(wetnessAddr + 0x50), 0.005f); + ImGui.SameLine(); + ImGui.DragFloat("Legs", ref MemoryUtil.GetRef<float>(wetnessAddr + 0x78), 0.005f); + ImGui.PopItemWidth(); + ImGui.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); + } + } +} @@ -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<nint, int, int, nint> 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<ProcessCameraDelegate>? setCameraHook;
@@ -341,9 +341,6 @@ namespace NewCamera private delegate float CheckMovementDelegate(int stickValue, float alwaysZero);
private Hook<CheckMovementDelegate>? checkMovementHook;
- private delegate void CollisionCheckDelegate(nint unknownPtr, nint unknownPtr2);
- private Hook<CollisionCheckDelegate>? collisionCheckHook;
-
private delegate void CameraEffectDelegate(nint unknownPtr, nint unknownPtr2, nint unknownPtr3);
private Hook<CameraEffectDelegate>? cameraEffectHook;
@@ -388,299 +385,6 @@ namespace NewCamera underwaterCamera5.Disable();
}
- private static readonly MtObject sPlayer = SingletonManager.GetSingleton("sPlayer")!;
- private int saveSlotIndex = -1;
- private NativeFunction<nint, nint> getSaveSlotGuiAddr;
- private NativeFunction<nint, nint> getPlayerSettingsAddr;
- private nint getPlayerSettings()
- {
- nint rcx = MemoryUtil.Read<nint>(0x145013950);
- if (saveSlotIndex >= 0)
- {
- // MonsterHunterWorld.exe+ADC442 - imul rdx,rcx,0026CC00
- nint rax = saveSlotIndex * 0x26CC00;
- rax += MemoryUtil.Read<nint>(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<UpdateJoints>? updateJointRotationHook;
- private Hook<UpdateJoints>? updateJointPositionHook;
- private List<nint> bodyJoints = new List<nint>();
- private List<nint> ignoredJoints = new List<nint>();
- private Dictionary<nint, List<Vector3>> bodyRotations = new Dictionary<nint, List<Vector3>>();
- private Dictionary<nint, List<Vector3>> bodyOffsets = new Dictionary<nint, List<Vector3>>();
-
- private List<nint> faceJoints = new List<nint>();
- private Dictionary<nint, List<Vector3>> faceRotations = new Dictionary<nint, List<Vector3>>();
- private Dictionary<nint, List<Vector3>> faceOffsets = new Dictionary<nint, List<Vector3>>();
-
-#if QUARANTINED_FEATURES
- private delegate void UpdateIK(nint superOfChild, nint joint, nint obj);
- private Hook<UpdateIK>? updateIKHook;
- private Dictionary<nint, List<Vector3>> ikOffsets = new Dictionary<nint, List<Vector3>>();
- private List<nint> ikJoints = new List<nint>();
-#endif
- private bool ikForcedOff = false;
- private Patch forceDisableIK;
-
- private List<nint> jiggleBones = new List<nint>();
- 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<ChangeEquipment>? changeEquipmentHook;
- private NativeFunction<nint, int, nint> 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<nint, int> setZoneState;
- private NativeAction<nint> setPlayerController1;
- private NativeAction<nint> 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<ZoneStateDelegate>? setZoneStateHook;
-
- private bool allowHotSpringsAnywhere = false;
- private Patch jmpOverHotSpringsEval;
-
- private bool disableHotSpringsSteam = false;
- private Patch jmpOverHotSpringsSteam;
-
- private bool enableCrawl = false;
- private NativeAction<nint, nint> procEnvironmentCollision;
- private nint psuedoObject1;
- private nint psuedoObject2;
-
- private float playerOpacityOverride = 1.0f;
- private delegate void RefreshEntityParams(nint entity, nint unknownPtr2);
- private Hook<RefreshEntityParams>? 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<float>(wetnessAddr) = wholeBodyWetness;
- MemoryUtil.GetRef<float>(wetnessAddr + 0x28) = wholeBodyWetness;
- MemoryUtil.GetRef<float>(wetnessAddr + 0x50) = wholeBodyWetness;
- MemoryUtil.GetRef<float>(wetnessAddr + 0x78) = wholeBodyWetness;
- }
-
private static readonly MtObject sOtomo = SingletonManager.GetSingleton("sOtomo")!;
// Gui strings.
@@ -749,25 +453,9 @@ namespace NewCamera Animal.Initialize();
- getViewParamOffset = new NativeFunction<nint, int, int, nint>(0x14136E6C0);
-
-#if QUARANTINED_FEATURES
- // MonsterHunterWorld.exe+20354F7 - call MonsterHunterWorld.exe+1F73850
- setZoneState = new NativeAction<nint, int>(0x142035020);
- setPlayerController1 = new NativeAction<nint>(0x141F73850);
- setPlayerController5 = new NativeAction<nint>(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<ZoneStateDelegate>(0x142035020, SetZoneStateHook); // nint, int
+ PlayerExt.Initialize();
- procEnvironmentCollision = new NativeAction<nint, nint>(0x141F737D0);
- psuedoObject1 = (nint)NativeMemory.AllocZeroed(0x7C);
- MemoryUtil.WriteBytes(psuedoObject1 + 0x30, [0x03]);
- psuedoObject2 = (nint)NativeMemory.AllocZeroed(0x7C);
- MemoryUtil.WriteBytes(psuedoObject2 + 0x30, [0x08]);
+ getViewParamOffset = new NativeFunction<nint, int, int, nint>(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<CheckMovementDelegate>(addr, CheckMovementHook);
- collisionCheckHook = Hook.Create<CollisionCheckDelegate>(0x1411C4E50, CollisionCheckHook); // nint, nint
-
cameraEffectHook = Hook.Create<CameraEffectDelegate>(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<UnderwaterCheck>(0x1412AD500, UnderwaterCheckHook); // nint
- getSaveSlotGuiAddr = new NativeFunction<nint, nint>(0x141AC0B60);
- getPlayerSettingsAddr = new NativeFunction<nint, nint>(0x141B8DBB0);
-
- forceDisableIK = new Patch(lton(0x14031FD40), [0xC6, 0x81, 0x81, 0x01, 0x00, 0x00, 0x00, 0xC3]);
-
- // Alt: 0x141FBC7A0 (model - 0x958)
- updateJointRotationHook = Hook.Create<UpdateJoints>(0x14223BA30, UpdateJointRotationHook);
- updateJointPositionHook = Hook.Create<UpdateJoints>(0x142228F50, UpdateJointPositionHook);
-
-#if QUARANTINED_FEATURES
- updateIKHook = Hook.Create<UpdateIK>(0x142472C00, UpdateIKHook);
-#endif
-
- /*
- changeEquipmentHook = Hook.Create<ChangeEquipment>(0x141DDEF80, ChangeEquipmentHook); // nint, int
- newEquipmentPointer = new NativeFunction<nint, int, nint>(0x141DE56A0);
- */
-
- // 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<RefreshEntityParams>(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<nint>(0x1451C42B8));
- if (guiAddr == 0x0)
- {
- saveSlotIndex = -1;
- return null;
- }
- // MonsterHunterWorld.exe+ADC42F - movsxd rcx,dword ptr [rax+00000334]
- saveSlotIndex = MemoryUtil.Read<int>(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<nint>(offset) != 0x1433FE588)
- {
- return null;
- }
- nint playerAddr = MemoryUtil.Read<nint>(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<nint>(player.Instance + 0x76B0);
- if (baseAddr != 0x0)
- {
- MemoryUtil.WriteBytes(baseAddr + 0x1A98, [0x1]);
- int weaponParts = MemoryUtil.Read<int>(baseAddr + 0x2250);
- for (int i = 0; i < weaponParts; i++)
- {
- nint partsAddr = MemoryUtil.Read<nint>(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<int>(player.Instance + 0x8938) |= (1 << 6);
- MemoryUtil.GetRef<int>(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<Vector3>(jointAddr + 0x50);
rotation = new Quaternion(player.Rotation.X, player.Rotation.Y, player.Rotation.Z, player.Rotation.W);
rotation *= MemoryUtil.GetRef<Quaternion>(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<nint>(0x1451C4640);
@@ -2497,1180 +2055,6 @@ namespace NewCamera return checkMovementHook!.Original(stickValue, alwaysZero);
}
- private 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<nint>(player.Instance + 0x12608);
- bool combatControls = false;
- if (controlsAddr != 0x0)
- {
- combatControls = MemoryUtil.Read<byte>(controlsAddr + 0xB18) == 0x80;
- }
- if (combatControls)
- {
- procEnvironmentCollision.Invoke(player.Instance, psuedoObject1);
- procEnvironmentCollision.Invoke(player.Instance, psuedoObject2);
- }
- else
- {
- enableCrawl = false;
- }
- }
-
- collisionCheckHook!.Original(unknownPtr, unknownPtr2);
- }
-
- private 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<nint>(0x1451C42B8);
- ref byte zoneState = ref MemoryUtil.GetRef<byte>(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<float>(wetnessAddr);
- bodyWet = MemoryUtil.Read<float>(wetnessAddr + 0x28);
- waistWet = MemoryUtil.Read<float>(wetnessAddr + 0x50);
- legsWet = MemoryUtil.Read<float>(wetnessAddr + 0x78);
- }
-
- setZoneStateHook!.Original(player, flags);
-
- if (overridePlayerWetness)
- {
- MemoryUtil.GetRef<float>(wetnessAddr) = headWet;
- MemoryUtil.GetRef<float>(wetnessAddr + 0x28) = bodyWet;
- MemoryUtil.GetRef<float>(wetnessAddr + 0x50) = waistWet;
- MemoryUtil.GetRef<float>(wetnessAddr + 0x78) = legsWet;
- }
- }
-
- private 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<float>(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 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<int>(baseAddr + 0x4A0);
- nint jointAddr = MemoryUtil.Read<nint>(baseAddr + 0x4A8);
- for (int i = 0; i < jointCount; i++)
- {
- nint childAddr = MemoryUtil.Read<nint>(jointAddr + 0x8);
- if (childAddr != 0x0 && MemoryUtil.Read<nint>(childAddr) == 0x142F21A90)
- {
- childAddr = MemoryUtil.Read<nint>(childAddr + 0x8);
- if (childAddr != 0x0)
- {
- nint childVtable = MemoryUtil.Read<nint>(childAddr);
- if (childVtable == 0x1435195B8) // Jiggle Bone Container.
- {
- if (part == Armor.Body)
- {
- ignoredJoints.Add(jointAddr);
- }
- }
- else if (childVtable == 0x143524BD8)
- {
- childAddr = MemoryUtil.Read<nint>(childAddr + 0x188);
- if (childAddr != 0x0 && MemoryUtil.Read<nint>(childAddr) == 0x143519530)
- {
- nint jiggleData = MemoryUtil.Read<nint>(MemoryUtil.Read<nint>(childAddr + 0xA0));
- if (MemoryUtil.Read<nint>(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<nint>(childAddr + 0x188);
- if (childAddr != 0x0 && MemoryUtil.Read<nint>(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<byte>(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 void drawJoint(nint jointAddr, Dictionary<nint, List<Vector3>> rotations, Dictionary<nint, List<Vector3>> 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<Vector4>(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<Vector4>(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<Vector3>()
- {
- new Vector3()
- });
- }
- }
- if (!hasOffset)
- {
- if (!hasRotation)
- {
- ImGui.SameLine();
- }
- if (ImGui.Button("Add Offset"))
- {
- offsets.Add(jointAddr, new List<Vector3>()
- {
- 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<Vector3>()
- {
- new Vector3()
- });
- }
- }
-#endif
- ImGui.PopID();
- }
-
- private void drawJoint(nint jointAddr)
- {
- drawJoint(jointAddr, bodyRotations, bodyOffsets);
- }
-
- private void drawJointLeaf(ref List<nint> joints, int i, Dictionary<nint, List<Vector3>> rotations, Dictionary<nint, List<Vector3>> offsets)
- {
- if (i >= joints.Count) return;
- nint jointAddr = joints[i];
- byte id = MemoryUtil.Read<byte>(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<Vector3>(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<nint>(armorAddr + 0x2A0)) == 0x0)
- {
- return;
- }
- }
- ImGui.PushID(partsAddr);
- string fullString = Marshal.PtrToStringAnsi(partsAddr + 0xC)!;
- if (armorAddr != 0x0)
- {
- string partName = extractPartName(fullString);
- ImGui.Text($"{partName} (0x{armorAddr:X}, {fullString} @ 0x{partsAddr:X}):");
- }
- else
- {
- ImGui.Text($"{fullString} @ 0x{partsAddr:X}:");
- }
- // MonsterHunterWorld.exe+222E651 - mov rax,[r8+000000C8]
- nint baseLod = MemoryUtil.Read<nint>(partsAddr + 0xC8);
- nint baseOffset = MemoryUtil.Read<nint>(partsAddr + 0x408 + (0x8 * 0x1));
- int numParts = MemoryUtil.Read<int>(partsAddr + 0x548 + (0x4 * 0x1));
- // Setting lodCount to 0 is probably the best way to completely hide a model.
- int lodCount = MemoryUtil.Read<int>(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<int>(baseOffset + (i * 0x4));
- nint lod0 = baseLod + lodOffset * lodStructSize;
- bool isVisible = MemoryUtil.GetRef<ushort>(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<int>(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<ushort>(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<ushort>(lod);
- ref ushort padSub = ref MemoryUtil.GetRef<ushort>(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<nint>(player.Instance + 0x2A0);
- if (bodyArmorParts == 0x0)
- {
- return false;
- }
- // MonsterHunterWorld.exe+203E8A2 - mov rax,[rbx+000126C8]
- nint combineArmorList = MemoryUtil.Read<nint>(player.Instance + 0x126C8);
- if (combineArmorList == 0x0)
- {
- return false;
- }
- collectArmorParts(player.Instance, bodyArmorParts);
- nint weapon = MemoryUtil.Read<nint>(player.Instance + 0x76B0);
- if (weapon != 0x0)
- {
- nint weaponParts = MemoryUtil.Read<nint>(weapon + 0x2A0);
- if (weaponParts != 0x0)
- {
- collectArmorParts(weapon, weaponParts);
- }
- }
- nint slinger = MemoryUtil.Read<nint>(player.Instance + 0x8918);
- if (slinger != 0x0)
- {
- nint slingerParts = MemoryUtil.Read<nint>(slinger + 0x2A0);
- if (slingerParts != 0x0)
- {
- collectArmorParts(slinger, slingerParts);
- }
- }
- combineArmorList = MemoryUtil.Read<nint>(combineArmorList + 0x70);
- nint next = combineArmorList;
- while (next != 0x0)
- {
- nint armorAddr = next;
- next = MemoryUtil.Read<nint>(armorAddr + 0x30);
- nint vTable = MemoryUtil.Read<nint>(armorAddr);
- // uWeaponParts: 0x1434D2400, uWeaponEmblem: 0x1434D1D58
- if (vTable == 0x1434A7560) // uPlCombineArmor
- {
- nint partsAddr = 0x0;
- nint childAddr = MemoryUtil.Read<nint>(armorAddr + 0x548);
- if (childAddr != 0x0)
- {
- if (MemoryUtil.Read<nint>(childAddr) == 0x143451520) // Face.
- {
- nint ownerAddr = MemoryUtil.Read<nint>(childAddr + 0x998);
- if (ownerAddr != player.Instance)
- {
- continue;
- }
- if (playerArmor[Armor.Face] == 0x0)
- {
- partsAddr = MemoryUtil.Read<nint>(childAddr + 0x2A0);
- if (partsAddr != 0x0)
- {
- collectArmorParts(childAddr, partsAddr);
- }
- childAddr = MemoryUtil.Read<nint>(childAddr + 0x9C8);
- if (childAddr != 0x0 && MemoryUtil.Read<nint>(childAddr) == 0x143505E98) // Eye lens.
- {
- partsAddr = MemoryUtil.Read<nint>(childAddr + 0x2A0);
- if (partsAddr != 0x0)
- {
- collectArmorParts(childAddr, partsAddr);
- }
- }
- }
- }
- else if (childAddr != player.Instance)
- {
- continue;
- }
- }
- partsAddr = MemoryUtil.Read<nint>(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<Vector3> rotations) in bodyRotations)
- {
- MemoryUtil.GetRef<Quaternion>(addr + 0x70) *= Quaternion.CreateFromYawPitchRoll(rotations[0].X, rotations[0].Y, rotations[0].Z);
- }
- if (playerArmor[Armor.Waist] != 0x0)
- {
- MemoryUtil.GetRef<byte>(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<Vector3> rotations) in faceRotations)
- {
- MemoryUtil.GetRef<Quaternion>(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<Vector3> offsets) in bodyOffsets)
- {
- MemoryUtil.GetRef<Vector3>(addr + 0x50) += offsets[0];
- }
- }
- else if (player != null && model == playerArmor[Armor.Face])
- {
- refreshArmorState(player);
- foreach ((nint addr, List<Vector3> offsets) in faceOffsets)
- {
- MemoryUtil.GetRef<Vector3>(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<Vector3>(superOfChild + 0x1380) += offset;
- }
- updateIKHook!.Original(superOfChild, joint, obj);
- }
-#endif
-
- /*
- private void ChangeEquipmentHook(nint unknownPtr, int unknownInt)
- {
- nint rax = MemoryUtil.Read<nint>(unknownPtr + 0x2968);
- nint r9 = MemoryUtil.Read<nint>(unknownPtr + 0x2950);
- int esi = MemoryUtil.Read<int>(rax + 0x240);
- esi *= MemoryUtil.Read<int>(r9 + 0x1D8);
- esi += unknownInt;
- nint newEquipment = newEquipmentPointer.Invoke(unknownPtr, esi);
- lastEquipedId = MemoryUtil.Read<int>(newEquipment + 0x24);
- changeEquipmentHook!.Original(unknownPtr, unknownInt);
- }
- */
-
private void UnderwaterCheckHook(nint unknownPtr)
{
underwaterCheckHook!.Original(unknownPtr);
@@ -3904,7 +2288,7 @@ namespace NewCamera ImGui.EndTooltip();
}
ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f));
- ref byte settingB = ref MemoryUtil.GetRef<byte>(getPlayerSettings() + 0x1403FD);
+ ref byte settingB = ref MemoryUtil.GetRef<byte>(PlayerExt.getPlayerSettings() + 0x1403FD);
int settingI = settingB;
ImGui.SameLine();
ImGui.SetCursorPos(ImGui.GetCursorPos() - new Vector2(0.0f, 6.0f));
@@ -4005,7 +2389,7 @@ namespace NewCamera ImGui.PopItemWidth();
}
- private void drawAnimationInfo(Entity entity, float width, bool debug)
+ public static void drawAnimationInfo(Entity entity, float width, bool debug)
{
ActionController actionController = entity.ActionController;
ActionInfo currentActionInfo = actionController.CurrentAction;
@@ -4056,7 +2440,6 @@ namespace NewCamera {
animationLayer.Paused = animationPaused;
}
-#if QUARANTINED_FEATURES
ImGui.SameLine();
float? lockedSpeed = animationLayer.LockedSpeed;
float speed = lockedSpeed ?? animationLayer.Speed;
@@ -4078,675 +2461,9 @@ namespace NewCamera {
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<byte>(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<byte>(MemoryUtil.Read<nint>(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<int>(player.Instance + 0x1373C):X})");
- if (expaned)
- {
- drawModelParts(playerArmor[Armor.Helmet]);
- ImGui.Separator();
- }
- expaned = ImGui.CollapsingHeader("Body");
- ImGui.SameLine();
- ImGui.Text($"(id: {MemoryUtil.Read<int>(player.Instance + 0x13740):X})");
- if (expaned)
- {
- drawModelParts(playerArmor[Armor.Body]);
- ImGui.Separator();
- }
- expaned = ImGui.CollapsingHeader("Arms");
- ImGui.SameLine();
- ImGui.Text($"(id: {MemoryUtil.Read<int>(player.Instance + 0x13744):X})");
- if (expaned)
- {
- drawModelParts(playerArmor[Armor.Arm]);
- ImGui.Separator();
- }
- expaned = ImGui.CollapsingHeader("Waist");
- ImGui.SameLine();
- ImGui.Text($"(id: {MemoryUtil.Read<int>(player.Instance + 0x13748):X})");
- if (expaned)
- {
- drawModelParts(playerArmor[Armor.Waist]);
- ImGui.Separator();
- }
- expaned = ImGui.CollapsingHeader("Legs");
- ImGui.SameLine();
- ImGui.Text($"(id: {MemoryUtil.Read<int>(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<int>(player.Instance + 0x13D8C):X}_{MemoryUtil.Read<int>(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<nint>(player.Instance + 0x12608);
- nint zoneStateAddr = MemoryUtil.Read<nint>(0x1451C42B8);
- ZoneState zoneState = ZoneState.Unknown;
- if (controlsAddr != 0x0 && zoneStateAddr != 0x0)
- {
- ref byte passiveFlag = ref MemoryUtil.GetRef<byte>(player.Instance + 0x7626);
- ref byte passiveFlag2 = ref MemoryUtil.GetRef<byte>(MemoryUtil.Read<nint>(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<byte>(controlsAddr + 0xB18) == 0x80;
- zoneState = combatControls ? ZoneState.Combat : ZoneState.Hub;
-#if !QUARANTINED_FEATURES
- ImGui.Text($"Current Zone State: {((MemoryUtil.GetRef<byte>(zoneStateAddr + 0xD2EA) == 0x1) ? "Hub" : "Combat")}");
-#else
- if (ImGui.Checkbox("Combat Controls", ref combatControls))
- {
- passiveFlag = ByteFlag(!combatControls);
- 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<byte>(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<float>(psuedoObject2 + 0x70) = player.Position.X + player.Forward.X;
- MemoryUtil.GetRef<float>(psuedoObject2 + 0x74) = player.Position.Y + player.Forward.Y;
- MemoryUtil.GetRef<float>(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<float>(psuedoObject2 + 0x40) = objectRotation.X;
- MemoryUtil.GetRef<float>(psuedoObject2 + 0x44) = objectRotation.Y;
- MemoryUtil.GetRef<float>(psuedoObject2 + 0x48) = objectRotation.Z;
- MemoryUtil.GetRef<float>(psuedoObject2 + 0x4C) = objectRotation.W;
-
- MemoryUtil.GetRef<float>(psuedoObject2 + 0x50) = 0.0f;
- MemoryUtil.GetRef<float>(psuedoObject2 + 0x54) = 1.0f;
- MemoryUtil.GetRef<float>(psuedoObject2 + 0x58) = 0.0f;
- MemoryUtil.GetRef<float>(psuedoObject2 + 0x5C) = 0.0f;
-
- MemoryUtil.GetRef<float>(psuedoObject2 + 0x60) = playerRotation.X;
- MemoryUtil.GetRef<float>(psuedoObject2 + 0x64) = playerRotation.Y;
- MemoryUtil.GetRef<float>(psuedoObject2 + 0x68) = playerRotation.Z;
- MemoryUtil.GetRef<float>(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<float>(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<float>(wetnessAddr), 0.005f);
- ImGui.SameLine();
- ImGui.DragFloat("Body", ref MemoryUtil.GetRef<float>(wetnessAddr + 0x28), 0.005f);
- ImGui.DragFloat("Waist", ref MemoryUtil.GetRef<float>(wetnessAddr + 0x50), 0.005f);
- ImGui.SameLine();
- ImGui.DragFloat("Legs", ref MemoryUtil.GetRef<float>(wetnessAddr + 0x78), 0.005f);
- ImGui.PopItemWidth();
- ImGui.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);
- }
-
public void OnImGuiRender()
{
#if HOOK_ORDER_ASSERTS
@@ -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<Config>(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();
|