diff --git a/BossMod/AI/AIBehaviour.cs b/BossMod/AI/AIBehaviour.cs index 58e3fa7af..3ccd43ec6 100644 --- a/BossMod/AI/AIBehaviour.cs +++ b/BossMod/AI/AIBehaviour.cs @@ -133,7 +133,7 @@ private NavigationDecision BuildNavigationDecision(Actor player, Actor master, r private void FocusMaster(Actor master) { - bool masterChanged = Service.TargetManager.FocusTarget?.ObjectId != master.InstanceID; + bool masterChanged = Service.TargetManager.FocusTarget?.EntityId != master.InstanceID; if (masterChanged) { ctrl.SetFocusTarget(master); diff --git a/BossMod/AI/AIController.cs b/BossMod/AI/AIController.cs index f3768b7f1..fb48d516c 100644 --- a/BossMod/AI/AIController.cs +++ b/BossMod/AI/AIController.cs @@ -96,7 +96,7 @@ public void Clear() public void SetFocusTarget(Actor? actor) { - if (Service.TargetManager.FocusTarget?.ObjectId != actor?.InstanceID) + if (Service.TargetManager.FocusTarget?.EntityId != actor?.InstanceID) Service.TargetManager.FocusTarget = actor != null ? Service.ObjectTable.SearchById((uint)actor.InstanceID) : null; } diff --git a/BossMod/AI/AIManager.cs b/BossMod/AI/AIManager.cs index f9e7e9b10..765990d43 100644 --- a/BossMod/AI/AIManager.cs +++ b/BossMod/AI/AIManager.cs @@ -125,7 +125,7 @@ private int FindPartyMemberSlotFromSender(SeString sender) return pm != null ? WorldState.Party.ContentIDs.IndexOf((ulong)pm.ContentId) : -1; } - private void OnChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) + private void OnChatMessage(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled) { if (!_config.Enabled || type != XivChatType.Party) return; diff --git a/BossMod/BossMod.csproj b/BossMod/BossMod.csproj index eb3f858b8..8a99a5bfc 100644 --- a/BossMod/BossMod.csproj +++ b/BossMod/BossMod.csproj @@ -46,7 +46,7 @@ - + false diff --git a/BossMod/Config/ModuleViewer.cs b/BossMod/Config/ModuleViewer.cs index 35275ad96..ae4518191 100644 --- a/BossMod/Config/ModuleViewer.cs +++ b/BossMod/Config/ModuleViewer.cs @@ -14,7 +14,7 @@ namespace BossMod; public sealed class ModuleViewer : IDisposable { private record struct ModuleInfo(ModuleRegistry.Info Info, string Name, int SortOrder); - private record struct ModuleGroupInfo(string Name, uint Id, uint SortOrder, IDalamudTextureWrap? Icon = null); + private record struct ModuleGroupInfo(string Name, uint Id, uint SortOrder, uint Icon = 0); private record struct ModuleGroup(ModuleGroupInfo Info, List Modules); private readonly PlanDatabase? _planDB; @@ -22,10 +22,10 @@ private record struct ModuleGroup(ModuleGroupInfo Info, List Modules private BitMask _filterExpansions; private BitMask _filterCategories; - private readonly (string name, IDalamudTextureWrap? icon)[] _expansions; - private readonly (string name, IDalamudTextureWrap? icon)[] _categories; - private readonly IDalamudTextureWrap? _iconFATE; - private readonly IDalamudTextureWrap? _iconHunt; + private readonly (string name, uint icon)[] _expansions; + private readonly (string name, uint icon)[] _categories; + private readonly uint _iconFATE; + private readonly uint _iconHunt; private readonly List[,] _groups; private readonly Vector2 _iconSize = new(30, 30); @@ -33,7 +33,7 @@ public ModuleViewer(PlanDatabase? planDB) { _planDB = planDB; - var defaultIcon = GetIcon(61762); + uint defaultIcon = 61762; _expansions = Enum.GetNames().Take((int)BossModuleInfo.Expansion.Count).Select(n => (n, defaultIcon)).ToArray(); _categories = Enum.GetNames().Take((int)BossModuleInfo.Category.Count).Select(n => (n, defaultIcon)).ToArray(); @@ -68,8 +68,8 @@ public ModuleViewer(PlanDatabase? planDB) _categories[(int)BossModuleInfo.Category.Alliance].icon = _categories[(int)BossModuleInfo.Category.Raid].icon; //_categories[(int)BossModuleInfo.Category.Event].icon = GetIcon(61757); - _iconFATE = GetIcon(contentType?.GetRow(8)?.Icon ?? 0); - _iconHunt = GetIcon((uint)(playStyle?.GetRow(10)?.Icon ?? 0)); + _iconFATE = contentType?.GetRow(8)?.Icon ?? 0; + _iconHunt = (uint)(playStyle?.GetRow(10)?.Icon ?? 0); _groups = new List[(int)BossModuleInfo.Expansion.Count, (int)BossModuleInfo.Category.Count]; for (int i = 0; i < (int)BossModuleInfo.Expansion.Count; ++i) @@ -112,12 +112,6 @@ public ModuleViewer(PlanDatabase? planDB) public void Dispose() { - foreach (var e in _expansions) - e.icon?.Dispose(); - foreach (var c in _categories) - c.icon?.Dispose(); - _iconFATE?.Dispose(); - _iconHunt?.Dispose(); } public void Draw(UITree tree, WorldState ws) @@ -155,7 +149,7 @@ private void DrawExpansionFilters() for (var e = BossModuleInfo.Expansion.RealmReborn; e < BossModuleInfo.Expansion.Count; ++e) { ref var expansion = ref _expansions[(int)e]; - UIMisc.ImageToggleButton(expansion.icon, _iconSize, !_filterExpansions[(int)e], expansion.name); + UIMisc.ImageToggleButton(Service.Texture.GetFromGameIcon(expansion.icon), _iconSize, !_filterExpansions[(int)e], expansion.name); if (ImGui.IsItemClicked()) { _filterExpansions.Toggle((int)e); @@ -173,7 +167,7 @@ private void DrawContentTypeFilters() for (var c = BossModuleInfo.Category.Uncategorized; c < BossModuleInfo.Category.Count; ++c) { ref var category = ref _categories[(int)c]; - UIMisc.ImageToggleButton(category.icon, _iconSize, !_filterCategories[(int)c], category.name); + UIMisc.ImageToggleButton(Service.Texture.GetFromGameIcon(category.icon), _iconSize, !_filterCategories[(int)c], category.name); if (ImGui.IsItemClicked()) { _filterCategories.Toggle((int)c); @@ -205,9 +199,9 @@ private void DrawModules(UITree tree, WorldState ws) { ImGui.TableNextRow(); ImGui.TableNextColumn(); - UIMisc.Image(_expansions[i].icon, new(36)); + UIMisc.Image(Service.Texture.GetFromGameIcon(_expansions[i].icon), new(36)); ImGui.SameLine(); - UIMisc.Image(group.Info.Icon ?? _categories[j].icon, new(36)); + UIMisc.Image(Service.Texture.GetFromGameIcon(group.Info.Icon != 0 ? group.Info.Icon : _categories[j].icon), new(36)); ImGui.TableNextColumn(); foreach (var ng in tree.Node($"{group.Info.Name}###{i}/{j}/{group.Info.Id}")) @@ -243,11 +237,9 @@ private void DrawModules(UITree tree, WorldState ws) } } - private void Customize((string name, IDalamudTextureWrap? icon)[] array, int element, uint iconId, SeString? name) + private void Customize((string name, uint icon)[] array, int element, uint iconId, SeString? name) { - var icon = GetIcon(iconId); - if (icon != null) - array[element].icon = icon; + array[element].icon = iconId; if (name != null) array[element].name = name; } @@ -256,7 +248,7 @@ private void Customize((string name, IDalamudTextureWrap? icon)[] array, int ele private void Customize(BossModuleInfo.Category category, ContentType? ct) => Customize(category, ct?.Icon ?? 0, ct?.Name); private void Customize(BossModuleInfo.Category category, CharaCardPlayStyle? ps) => Customize(category, (uint)(ps?.Icon ?? 0), ps?.Name); - private static IDalamudTextureWrap? GetIcon(uint iconId) => iconId != 0 ? Service.Texture?.GetIcon(iconId, Dalamud.Plugin.Services.ITextureProvider.IconFlags.HiRes) : null; + //private static IDalamudTextureWrap? GetIcon(uint iconId) => iconId != 0 ? Service.Texture?.GetIcon(iconId, Dalamud.Plugin.Services.ITextureProvider.IconFlags.HiRes) : null; private static string FixCase(SeString? str) => CultureInfo.InvariantCulture.TextInfo.ToTitleCase(str ?? ""); private static string BNpcName(uint id) => FixCase(Service.LuminaRow(id)?.Singular); diff --git a/BossMod/Debug/DebugInput.cs b/BossMod/Debug/DebugInput.cs index ce1d944d4..8177534aa 100644 --- a/BossMod/Debug/DebugInput.cs +++ b/BossMod/Debug/DebugInput.cs @@ -1,370 +1,370 @@ -using BossMod.Autorotation; -using Dalamud.Game.ClientState.Keys; -using Dalamud.Hooking; -using ImGuiNET; -using System.Reflection; -using System.Runtime.InteropServices; - -namespace BossMod; - -[StructLayout(LayoutKind.Explicit, Size = 0xB)] -public unsafe struct InputDataKeybind -{ - [FieldOffset(0)] public fixed ushort Bindings[5]; - [FieldOffset(10)] public byte Terminator; -} - -[StructLayout(LayoutKind.Explicit, Size = 0x9C8)] -public unsafe struct InputData -{ - [FieldOffset(0)] public void** Vtbl; - - [FieldOffset(0x9AC)] public int KeybindCount; - [FieldOffset(0x9B0)] public InputDataKeybind* Keybinds; - [FieldOffset(0x9B8)] public fixed byte GamepadAxisRemap[7]; -} - -[StructLayout(LayoutKind.Explicit, Size = 0x140)] -public unsafe struct PlayerMoveControllerWalk -{ - [FieldOffset(0x10)] public Vector3 MovementDir; - [FieldOffset(0x58)] public float BaseMovementSpeed; - [FieldOffset(0x90)] public float MovementDirRelToCharacterFacing; - [FieldOffset(0x94)] public byte Forced; - [FieldOffset(0xA0)] public Vector3 MovementDirWorld; - [FieldOffset(0xB0)] public float RotationDir; - [FieldOffset(0x110)] public uint MovementState; - [FieldOffset(0x114)] public float MovementLeft; - [FieldOffset(0x118)] public float MovementFwd; -} - -[StructLayout(LayoutKind.Explicit, Size = 0xB0)] -public unsafe struct PlayerMoveControllerFly -{ - [FieldOffset(0x66)] public byte IsFlying; - [FieldOffset(0x9C)] public float AngularAscent; -} - -[StructLayout(LayoutKind.Explicit)] -public unsafe struct PlayerController -{ - [FieldOffset(0x10)] public PlayerMoveControllerWalk MoveControllerWalk; - [FieldOffset(0x150)] public PlayerMoveControllerFly MoveControllerFly; - [FieldOffset(0x559)] public byte ControlMode; -} - -[StructLayout(LayoutKind.Explicit, Size = 0x18)] -public unsafe struct PlayerMoveControllerFlyInput -{ - [FieldOffset(0x0)] public float Forward; - [FieldOffset(0x4)] public float Left; - [FieldOffset(0x8)] public float Up; - [FieldOffset(0xC)] public float Turn; - [FieldOffset(0x10)] public float u10; - [FieldOffset(0x14)] public byte DirMode; - [FieldOffset(0x15)] public byte HaveBackwardOrStrafe; -} - -[StructLayout(LayoutKind.Explicit, Size = 0x2B0)] -public unsafe struct CameraX -{ - [FieldOffset(0x130)] public float DirH; - [FieldOffset(0x134)] public float DirV; - [FieldOffset(0x138)] public float InputDeltaHAdjusted; - [FieldOffset(0x13C)] public float InputDeltaVAdjusted; - [FieldOffset(0x140)] public float InputDeltaH; - [FieldOffset(0x144)] public float InputDeltaV; - [FieldOffset(0x148)] public float DirVMin; - [FieldOffset(0x14C)] public float DirVMax; -} - -unsafe sealed class DebugInput : IDisposable -{ - private delegate byte ConvertVirtualKeyDelegate(int vkCode); - private readonly ConvertVirtualKeyDelegate _convertVirtualKey; - - private delegate ref int GetRefValueDelegate(int vkCode); - private readonly GetRefValueDelegate _getKeyRef; - - private readonly PlayerController* _playerController; - - private delegate void RMIWalkDelegate(PlayerMoveControllerWalk* self, float* sumLeft, float* sumForward, float* sumTurnLeft, byte* haveBackwardOrStrafe, byte* a6, byte bAdditiveUnk); - private readonly Hook _rmiWalkHook; - - private delegate void RMIFlyDelegate(PlayerMoveControllerFly* self, PlayerMoveControllerFlyInput* result); - private readonly Hook _rmiFlyHook; - - private delegate void RMICameraDelegate(CameraX* self, int inputMode, float speedH, float speedV); - private readonly Hook _rmiCameraHook; - - private readonly UITree _tree = new(); - private readonly WorldState _ws; - private readonly ActionManagerEx _amex; - private readonly AI.AIController _navi; - private Vector2 _dest; - private Vector3 _prevPos; - private bool _jump; - private bool _gamepadAxisOverrideEnable; - private float _gamepadAxisOverrideAngle; - private int _gamepadButtonOverride = -1; - private int _gamepadButtonValue; - private bool _gamepadNavigate; - private bool _pmcOverrideDirEnable; - private float _pmcOverrideDir; - private float _pmcOverrideVertical; - private float _pmcDesiredAzimuth; - private float _pmcDesiredAltitude; - private float _pmcCameraSpeedH; - private float _pmcCameraSpeedV; - - public DebugInput(RotationModuleManager autorot) - { - _convertVirtualKey = Service.KeyState.GetType().GetMethod("ConvertVirtualKey", BindingFlags.NonPublic | BindingFlags.Instance)!.CreateDelegate(Service.KeyState); - _getKeyRef = Service.KeyState.GetType().GetMethod("GetRefValue", BindingFlags.NonPublic | BindingFlags.Instance)!.CreateDelegate(Service.KeyState); - _ws = autorot.Bossmods.WorldState; - _amex = autorot.ActionManager; - _navi = new(_amex); - - _playerController = (PlayerController*)Service.SigScanner.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 3C 01 75 1E 48 8D 0D"); - Service.Log($"[DebugInput] playerController addess: 0x{(nint)_playerController:X}"); - - _rmiWalkHook = Service.Hook.HookFromSignature("E8 ?? ?? ?? ?? 80 7B 3E 00 48 8D 3D", RMIWalkDetour); - Service.Log($"[DebugInput] rmiwalk addess: 0x{_rmiWalkHook.Address:X}"); - - _rmiFlyHook = Service.Hook.HookFromSignature("E8 ?? ?? ?? ?? 0F B6 0D ?? ?? ?? ?? B8", RMIFlyDetour); - Service.Log($"[DebugInput] rmifly addess: 0x{_rmiFlyHook.Address:X}"); - - _rmiCameraHook = Service.Hook.HookFromSignature("40 53 48 83 EC 70 44 0F 29 44 24 ?? 48 8B D9", RMICameraDetour); - Service.Log($"[DebugInput] rmicamera addess: 0x{_rmiCameraHook.Address:X}"); - } - - public void Dispose() - { - _rmiWalkHook.Dispose(); - _rmiFlyHook.Dispose(); - _rmiCameraHook.Dispose(); - } - - public void Draw() - { - var dt = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance()->FrameDeltaTime; - - var player = _ws.Party.Player(); - var curPos = player?.PosRot.XYZ() ?? new(); - var speed = (curPos - _prevPos) / dt; - _prevPos = curPos; - ImGui.TextUnformatted($"Speed={speed.Length():f3}, SpeedH={speed.XZ().Length():f3}, SpeedV={speed.Y:f3}, Azimuth={Angle.FromDirection(new(speed.XZ()))}, Altitude={Angle.FromDirection(new(speed.Y, speed.XZ().Length()))}"); - - ImGui.Checkbox("Jump!", ref _jump); - ImGui.InputFloat2("Destination", ref _dest); - ImGui.SameLine(); - if (ImGui.Button("Move!")) - { - _navi.NaviTargetPos = new(_dest); - - //var toTarget = _navi.NaviTargetPos.Value - curPos; - //_navi.NaviTargetRot = toTarget.Normalized(); - - //var cameraFacing = _navi.CameraFacing; - //var dot = cameraFacing.Dot(_navi.NaviTargetRot.Value); - //if (dot < -0.707107f) - // _navi.NaviTargetRot = -_navi.NaviTargetRot.Value; - //else if (dot < 0.707107f) - // _navi.NaviTargetRot = cameraFacing.OrthoL().Dot(_navi.NaviTargetRot.Value) > 0 ? _navi.NaviTargetRot.Value.OrthoR() : _navi.NaviTargetRot.Value.OrthoL(); - - _navi.WantJump = _jump; - } - ImGui.SameLine(); - if (ImGui.Button("Cancel move")) - { - _navi.Clear(); - } - _navi.Update(player); - - DrawGamepad(); - - foreach (var n in _tree.Node("Input data")) - { - var idata = GetInputData(); - foreach (var n2 in _tree.Node($"Keybinds ({idata->KeybindCount} total)")) - { - var mapping = new VirtualKey[256]; - foreach (var vk in Service.KeyState.GetValidVirtualKeys()) - mapping[_convertVirtualKey((int)vk)] = vk; - - string bindString(byte v) => v switch - { - 0 => "---", - < 0xA0 => mapping[v].ToString(), - < 0xA7 => $"mouse{v - 0xA0}", - _ => $"gamepad{v - 0xA7}" - }; - string printBinding(ushort v) => $"{((v & 0x100) != 0 ? "shift+" : "")}{((v & 0x200) != 0 ? "ctrl+" : "")}{((v & 0x400) != 0 ? "alt+" : "")}{((v & 0xF800) != 0 ? "?+" : "")}{bindString((byte)v)} ({v:X4})"; - for (int i = 0; i < idata->KeybindCount; ++i) - { - _tree.LeafNode($"{i} = {string.Join(", ", Enumerable.Range(0, 5).Select(j => printBinding(idata->Keybinds[i].Bindings[j])))}"); - } - } - } - - foreach (var n in _tree.Node("Virtual keys")) - { - _tree.LeafNodes(Service.KeyState.GetValidVirtualKeys(), vk => $"{vk} ({(int)vk}): internal code={_convertVirtualKey((int)vk)}, state={_getKeyRef((int)vk)}"); - } - - foreach (var n in _tree.Node("PMC")) - { - _tree.LeafNode($"Instance: 0x{(nint)_playerController:X}"); - _tree.LeafNode($"Flying: {_playerController->MoveControllerFly.IsFlying != 0}"); - _tree.LeafNode($"Control mode: {_playerController->ControlMode}"); - if (_playerController->MoveControllerFly.IsFlying == 0) - { - _tree.LeafNode($"Movement dir 0x10: {Utils.Vec3String(_playerController->MoveControllerWalk.MovementDir)}"); - _tree.LeafNode($"Base movement speed: {_playerController->MoveControllerWalk.BaseMovementSpeed:f3}"); - _tree.LeafNode($"Relative movement dir: {_playerController->MoveControllerWalk.MovementDirRelToCharacterFacing.Radians()}"); - _tree.LeafNode($"Forced: {_playerController->MoveControllerWalk.Forced}"); - _tree.LeafNode($"Movement dir 0xA0: {Utils.Vec3String(_playerController->MoveControllerWalk.MovementDirWorld)}"); - _tree.LeafNode($"Rotation dir: {_playerController->MoveControllerWalk.RotationDir}"); - _tree.LeafNode($"Movement state: {_playerController->MoveControllerWalk.MovementState}"); - _tree.LeafNode($"Movement left: {_playerController->MoveControllerWalk.MovementLeft}"); - _tree.LeafNode($"Movement forward: {_playerController->MoveControllerWalk.MovementFwd}"); - } - else - { - _tree.LeafNode($"Angular ascent: {_playerController->MoveControllerFly.AngularAscent.Radians()}"); - } - - bool walkOverride = _rmiWalkHook.IsEnabled; - if (ImGui.Checkbox("Override walk", ref walkOverride)) - { - if (walkOverride) - _rmiWalkHook.Enable(); - else - _rmiWalkHook.Disable(); - } - bool flyOverride = _rmiFlyHook.IsEnabled; - if (ImGui.Checkbox("Override fly", ref flyOverride)) - { - if (flyOverride) - _rmiFlyHook.Enable(); - else - _rmiFlyHook.Disable(); - } - if (walkOverride || flyOverride) - { - ImGui.Checkbox("Override move direction", ref _pmcOverrideDirEnable); - if (_pmcOverrideDirEnable) - ImGui.DragFloat("Override move direction", ref _pmcOverrideDir, 1, -180, 180); - ImGui.DragFloat("Override vertical", ref _pmcOverrideVertical, 1, -90, 90); - } - - bool cameraOverride = _rmiCameraHook.IsEnabled; - if (ImGui.Checkbox("Override camera", ref cameraOverride)) - { - if (cameraOverride) - _rmiCameraHook.Enable(); - else - _rmiCameraHook.Disable(); - } - if (cameraOverride) - { - ImGui.DragFloat("Camera desired azimuth", ref _pmcDesiredAzimuth, 1, -180, 180); - ImGui.DragFloat("Camera desired altitude", ref _pmcDesiredAltitude, 1, -85, 45); - ImGui.DragFloat("Camera speed H (deg/sec)", ref _pmcCameraSpeedH, 1, 0, 360); - ImGui.DragFloat("Camera speed V (deg/sec)", ref _pmcCameraSpeedV, 1, 0, 360); - } - } - } - - private void DrawGamepad() - { - ImGui.SliderFloat("Gamepad angle", ref _gamepadAxisOverrideAngle, -180, 180); - ImGui.SameLine(); - ImGui.Checkbox("Gamepad move", ref _gamepadAxisOverrideEnable); - - ImGui.SliderInt("Gamepad value", ref _gamepadButtonValue, -100, 100); - ImGui.SameLine(); - ImGui.InputInt("Gamepad button", ref _gamepadButtonOverride); - - ImGui.Checkbox("Gamepad navigate", ref _gamepadNavigate); - - var input = _amex.InputOverride; - Array.Fill(input.GamepadOverrides, 0); - if (_gamepadButtonOverride >= 0 && _gamepadButtonOverride < input.GamepadOverrides.Length) - { - input.GamepadOverridesEnabled = true; - input.GamepadOverrides[_gamepadButtonOverride] = _gamepadButtonValue; - } - else if (_gamepadAxisOverrideEnable) - { - input.GamepadOverridesEnabled = true; - input.GamepadOverrides[3] = (int)(100 * _gamepadAxisOverrideAngle.Degrees().Sin()); - input.GamepadOverrides[4] = (int)(100 * _gamepadAxisOverrideAngle.Degrees().Cos()); - } - else if (_gamepadNavigate) - { - var dest = new WPos(_dest); - var dir = (Camera.Instance?.CameraAzimuth ?? 0).Radians() - Angle.FromDirection(dest - (_ws.Party.Player()?.Position ?? dest)) + 180.Degrees(); - input.GamepadOverridesEnabled = true; - input.GamepadOverrides[3] = (int)(100 * dir.Sin()); - input.GamepadOverrides[4] = (int)(100 * dir.Cos()); - } - else - { - input.GamepadOverridesEnabled = false; - } - } - - private InputData* GetInputData() => (InputData*)FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance()->GetUIModule()->GetUIInputData(); - - private void RMIWalkDetour(PlayerMoveControllerWalk* self, float* sumLeft, float* sumForward, float* sumTurnLeft, byte* haveBackwardOrStrafe, byte* a6, byte bAdditiveUnk) - { - _rmiWalkHook.Original(self, sumLeft, sumForward, sumTurnLeft, haveBackwardOrStrafe, a6, bAdditiveUnk); - if (_pmcOverrideDirEnable) - { - var dir = _pmcOverrideDir.Degrees().ToDirection(); - *sumLeft = dir.X; - *sumForward = dir.Z; - } - else - { - *sumLeft = 0; - *sumForward = 0; - } - //Service.Log($"RMIWalk: l={*sumLeft:f3}, f={*sumForward:f3}, t={*sumTurnLeft:f3}, bs={*haveBackwardOrStrafe}, a6={*a6}, a7={bAdditiveUnk}"); - } - - private void RMIFlyDetour(PlayerMoveControllerFly* self, PlayerMoveControllerFlyInput* result) - { - _rmiFlyHook.Original(self, result); - if (_pmcOverrideDirEnable) - { - var dir = _pmcOverrideDir.Degrees().ToDirection(); - result->Left = dir.X; - result->Forward = dir.Z; - } - else - { - result->Left = 0; - result->Forward = 0; - } - result->Up = _pmcOverrideVertical != 0 ? _pmcOverrideVertical.Degrees().Rad : float.Epsilon; - //Service.Log($"RMIFly: f={result->Forward:f3}, l={result->Left:f3}, up={result->Up:f3}, t={result->Turn:f3}, f10={result->u10:f3}, dmode={result->DirMode}, bs={result->HaveBackwardOrStrafe}"); - } - - private void RMICameraDetour(CameraX* self, int inputMode, float speedH, float speedV) - { - _rmiCameraHook.Original(self, inputMode, speedH, speedV); - if (inputMode == 0) // let user override... - { - var dt = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance()->FrameDeltaTime; - var deltaH = (_pmcDesiredAzimuth.Degrees() - self->DirH.Radians()).Normalized(); - var deltaV = (_pmcDesiredAltitude.Degrees() - self->DirV.Radians()).Normalized(); - var maxH = _pmcCameraSpeedH.Degrees().Rad * dt; - var maxV = _pmcCameraSpeedV.Degrees().Rad * dt; - self->InputDeltaH = Math.Clamp(deltaH.Rad, -maxH, maxH); - self->InputDeltaV = Math.Clamp(deltaV.Rad, -maxV, maxV); - } - //Service.Log($"RMICamera: dir={self->DirH.Radians()}/{self->DirV.Radians()} [{self->DirVMin.Radians()}-{self->DirVMax.Radians()}], mode={inputMode}, speed={speedH:f1}/{speedV:f1}, delta={self->InputDeltaH.Radians().Deg:f3}/{self->InputDeltaV.Radians().Deg:f3}, speed={self->InputDeltaH.Radians() / Utils.FrameDuration()}/{self->InputDeltaV.Radians() / Utils.FrameDuration()}"); - } -} +//using BossMod.Autorotation; +//using Dalamud.Game.ClientState.Keys; +//using Dalamud.Hooking; +//using ImGuiNET; +//using System.Reflection; +//using System.Runtime.InteropServices; + +//namespace BossMod; + +//[StructLayout(LayoutKind.Explicit, Size = 0xB)] +//public unsafe struct InputDataKeybind +//{ +// [FieldOffset(0)] public fixed ushort Bindings[5]; +// [FieldOffset(10)] public byte Terminator; +//} + +//[StructLayout(LayoutKind.Explicit, Size = 0x9C8)] +//public unsafe struct InputData +//{ +// [FieldOffset(0)] public void** Vtbl; + +// [FieldOffset(0x9AC)] public int KeybindCount; +// [FieldOffset(0x9B0)] public InputDataKeybind* Keybinds; +// [FieldOffset(0x9B8)] public fixed byte GamepadAxisRemap[7]; +//} + +//[StructLayout(LayoutKind.Explicit, Size = 0x140)] +//public unsafe struct PlayerMoveControllerWalk +//{ +// [FieldOffset(0x10)] public Vector3 MovementDir; +// [FieldOffset(0x58)] public float BaseMovementSpeed; +// [FieldOffset(0x90)] public float MovementDirRelToCharacterFacing; +// [FieldOffset(0x94)] public byte Forced; +// [FieldOffset(0xA0)] public Vector3 MovementDirWorld; +// [FieldOffset(0xB0)] public float RotationDir; +// [FieldOffset(0x110)] public uint MovementState; +// [FieldOffset(0x114)] public float MovementLeft; +// [FieldOffset(0x118)] public float MovementFwd; +//} + +//[StructLayout(LayoutKind.Explicit, Size = 0xB0)] +//public unsafe struct PlayerMoveControllerFly +//{ +// [FieldOffset(0x66)] public byte IsFlying; +// [FieldOffset(0x9C)] public float AngularAscent; +//} + +//[StructLayout(LayoutKind.Explicit)] +//public unsafe struct PlayerController +//{ +// [FieldOffset(0x10)] public PlayerMoveControllerWalk MoveControllerWalk; +// [FieldOffset(0x150)] public PlayerMoveControllerFly MoveControllerFly; +// [FieldOffset(0x559)] public byte ControlMode; +//} + +//[StructLayout(LayoutKind.Explicit, Size = 0x18)] +//public unsafe struct PlayerMoveControllerFlyInput +//{ +// [FieldOffset(0x0)] public float Forward; +// [FieldOffset(0x4)] public float Left; +// [FieldOffset(0x8)] public float Up; +// [FieldOffset(0xC)] public float Turn; +// [FieldOffset(0x10)] public float u10; +// [FieldOffset(0x14)] public byte DirMode; +// [FieldOffset(0x15)] public byte HaveBackwardOrStrafe; +//} + +//[StructLayout(LayoutKind.Explicit, Size = 0x2B0)] +//public unsafe struct CameraX +//{ +// [FieldOffset(0x130)] public float DirH; +// [FieldOffset(0x134)] public float DirV; +// [FieldOffset(0x138)] public float InputDeltaHAdjusted; +// [FieldOffset(0x13C)] public float InputDeltaVAdjusted; +// [FieldOffset(0x140)] public float InputDeltaH; +// [FieldOffset(0x144)] public float InputDeltaV; +// [FieldOffset(0x148)] public float DirVMin; +// [FieldOffset(0x14C)] public float DirVMax; +//} + +//unsafe sealed class DebugInput : IDisposable +//{ +// private delegate byte ConvertVirtualKeyDelegate(int vkCode); +// private readonly ConvertVirtualKeyDelegate _convertVirtualKey; + +// private delegate ref int GetRefValueDelegate(int vkCode); +// private readonly GetRefValueDelegate _getKeyRef; + +// private readonly PlayerController* _playerController; + +// private delegate void RMIWalkDelegate(PlayerMoveControllerWalk* self, float* sumLeft, float* sumForward, float* sumTurnLeft, byte* haveBackwardOrStrafe, byte* a6, byte bAdditiveUnk); +// private readonly Hook _rmiWalkHook; + +// private delegate void RMIFlyDelegate(PlayerMoveControllerFly* self, PlayerMoveControllerFlyInput* result); +// private readonly Hook _rmiFlyHook; + +// private delegate void RMICameraDelegate(CameraX* self, int inputMode, float speedH, float speedV); +// private readonly Hook _rmiCameraHook; + +// private readonly UITree _tree = new(); +// private readonly WorldState _ws; +// private readonly ActionManagerEx _amex; +// private readonly AI.AIController _navi; +// private Vector2 _dest; +// private Vector3 _prevPos; +// private bool _jump; +// private bool _gamepadAxisOverrideEnable; +// private float _gamepadAxisOverrideAngle; +// private int _gamepadButtonOverride = -1; +// private int _gamepadButtonValue; +// private bool _gamepadNavigate; +// private bool _pmcOverrideDirEnable; +// private float _pmcOverrideDir; +// private float _pmcOverrideVertical; +// private float _pmcDesiredAzimuth; +// private float _pmcDesiredAltitude; +// private float _pmcCameraSpeedH; +// private float _pmcCameraSpeedV; + +// public DebugInput(RotationModuleManager autorot) +// { +// _convertVirtualKey = Service.KeyState.GetType().GetMethod("ConvertVirtualKey", BindingFlags.NonPublic | BindingFlags.Instance)!.CreateDelegate(Service.KeyState); +// _getKeyRef = Service.KeyState.GetType().GetMethod("GetRefValue", BindingFlags.NonPublic | BindingFlags.Instance)!.CreateDelegate(Service.KeyState); +// _ws = autorot.Bossmods.WorldState; +// _amex = autorot.ActionManager; +// _navi = new(_amex); + +// _playerController = (PlayerController*)Service.SigScanner.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 3C 01 75 1E 48 8D 0D"); +// Service.Log($"[DebugInput] playerController addess: 0x{(nint)_playerController:X}"); + +// _rmiWalkHook = Service.Hook.HookFromSignature("E8 ?? ?? ?? ?? 80 7B 3E 00 48 8D 3D", RMIWalkDetour); +// Service.Log($"[DebugInput] rmiwalk addess: 0x{_rmiWalkHook.Address:X}"); + +// _rmiFlyHook = Service.Hook.HookFromSignature("E8 ?? ?? ?? ?? 0F B6 0D ?? ?? ?? ?? B8", RMIFlyDetour); +// Service.Log($"[DebugInput] rmifly addess: 0x{_rmiFlyHook.Address:X}"); + +// _rmiCameraHook = Service.Hook.HookFromSignature("40 53 48 83 EC 70 44 0F 29 44 24 ?? 48 8B D9", RMICameraDetour); +// Service.Log($"[DebugInput] rmicamera addess: 0x{_rmiCameraHook.Address:X}"); +// } + +// public void Dispose() +// { +// _rmiWalkHook.Dispose(); +// _rmiFlyHook.Dispose(); +// _rmiCameraHook.Dispose(); +// } + +// public void Draw() +// { +// var dt = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance()->FrameDeltaTime; + +// var player = _ws.Party.Player(); +// var curPos = player?.PosRot.XYZ() ?? new(); +// var speed = (curPos - _prevPos) / dt; +// _prevPos = curPos; +// ImGui.TextUnformatted($"Speed={speed.Length():f3}, SpeedH={speed.XZ().Length():f3}, SpeedV={speed.Y:f3}, Azimuth={Angle.FromDirection(new(speed.XZ()))}, Altitude={Angle.FromDirection(new(speed.Y, speed.XZ().Length()))}"); + +// ImGui.Checkbox("Jump!", ref _jump); +// ImGui.InputFloat2("Destination", ref _dest); +// ImGui.SameLine(); +// if (ImGui.Button("Move!")) +// { +// _navi.NaviTargetPos = new(_dest); + +// //var toTarget = _navi.NaviTargetPos.Value - curPos; +// //_navi.NaviTargetRot = toTarget.Normalized(); + +// //var cameraFacing = _navi.CameraFacing; +// //var dot = cameraFacing.Dot(_navi.NaviTargetRot.Value); +// //if (dot < -0.707107f) +// // _navi.NaviTargetRot = -_navi.NaviTargetRot.Value; +// //else if (dot < 0.707107f) +// // _navi.NaviTargetRot = cameraFacing.OrthoL().Dot(_navi.NaviTargetRot.Value) > 0 ? _navi.NaviTargetRot.Value.OrthoR() : _navi.NaviTargetRot.Value.OrthoL(); + +// _navi.WantJump = _jump; +// } +// ImGui.SameLine(); +// if (ImGui.Button("Cancel move")) +// { +// _navi.Clear(); +// } +// _navi.Update(player); + +// DrawGamepad(); + +// foreach (var n in _tree.Node("Input data")) +// { +// var idata = GetInputData(); +// foreach (var n2 in _tree.Node($"Keybinds ({idata->KeybindCount} total)")) +// { +// var mapping = new VirtualKey[256]; +// foreach (var vk in Service.KeyState.GetValidVirtualKeys()) +// mapping[_convertVirtualKey((int)vk)] = vk; + +// string bindString(byte v) => v switch +// { +// 0 => "---", +// < 0xA0 => mapping[v].ToString(), +// < 0xA7 => $"mouse{v - 0xA0}", +// _ => $"gamepad{v - 0xA7}" +// }; +// string printBinding(ushort v) => $"{((v & 0x100) != 0 ? "shift+" : "")}{((v & 0x200) != 0 ? "ctrl+" : "")}{((v & 0x400) != 0 ? "alt+" : "")}{((v & 0xF800) != 0 ? "?+" : "")}{bindString((byte)v)} ({v:X4})"; +// for (int i = 0; i < idata->KeybindCount; ++i) +// { +// _tree.LeafNode($"{i} = {string.Join(", ", Enumerable.Range(0, 5).Select(j => printBinding(idata->Keybinds[i].Bindings[j])))}"); +// } +// } +// } + +// foreach (var n in _tree.Node("Virtual keys")) +// { +// _tree.LeafNodes(Service.KeyState.GetValidVirtualKeys(), vk => $"{vk} ({(int)vk}): internal code={_convertVirtualKey((int)vk)}, state={_getKeyRef((int)vk)}"); +// } + +// foreach (var n in _tree.Node("PMC")) +// { +// _tree.LeafNode($"Instance: 0x{(nint)_playerController:X}"); +// _tree.LeafNode($"Flying: {_playerController->MoveControllerFly.IsFlying != 0}"); +// _tree.LeafNode($"Control mode: {_playerController->ControlMode}"); +// if (_playerController->MoveControllerFly.IsFlying == 0) +// { +// _tree.LeafNode($"Movement dir 0x10: {Utils.Vec3String(_playerController->MoveControllerWalk.MovementDir)}"); +// _tree.LeafNode($"Base movement speed: {_playerController->MoveControllerWalk.BaseMovementSpeed:f3}"); +// _tree.LeafNode($"Relative movement dir: {_playerController->MoveControllerWalk.MovementDirRelToCharacterFacing.Radians()}"); +// _tree.LeafNode($"Forced: {_playerController->MoveControllerWalk.Forced}"); +// _tree.LeafNode($"Movement dir 0xA0: {Utils.Vec3String(_playerController->MoveControllerWalk.MovementDirWorld)}"); +// _tree.LeafNode($"Rotation dir: {_playerController->MoveControllerWalk.RotationDir}"); +// _tree.LeafNode($"Movement state: {_playerController->MoveControllerWalk.MovementState}"); +// _tree.LeafNode($"Movement left: {_playerController->MoveControllerWalk.MovementLeft}"); +// _tree.LeafNode($"Movement forward: {_playerController->MoveControllerWalk.MovementFwd}"); +// } +// else +// { +// _tree.LeafNode($"Angular ascent: {_playerController->MoveControllerFly.AngularAscent.Radians()}"); +// } + +// bool walkOverride = _rmiWalkHook.IsEnabled; +// if (ImGui.Checkbox("Override walk", ref walkOverride)) +// { +// if (walkOverride) +// _rmiWalkHook.Enable(); +// else +// _rmiWalkHook.Disable(); +// } +// bool flyOverride = _rmiFlyHook.IsEnabled; +// if (ImGui.Checkbox("Override fly", ref flyOverride)) +// { +// if (flyOverride) +// _rmiFlyHook.Enable(); +// else +// _rmiFlyHook.Disable(); +// } +// if (walkOverride || flyOverride) +// { +// ImGui.Checkbox("Override move direction", ref _pmcOverrideDirEnable); +// if (_pmcOverrideDirEnable) +// ImGui.DragFloat("Override move direction", ref _pmcOverrideDir, 1, -180, 180); +// ImGui.DragFloat("Override vertical", ref _pmcOverrideVertical, 1, -90, 90); +// } + +// bool cameraOverride = _rmiCameraHook.IsEnabled; +// if (ImGui.Checkbox("Override camera", ref cameraOverride)) +// { +// if (cameraOverride) +// _rmiCameraHook.Enable(); +// else +// _rmiCameraHook.Disable(); +// } +// if (cameraOverride) +// { +// ImGui.DragFloat("Camera desired azimuth", ref _pmcDesiredAzimuth, 1, -180, 180); +// ImGui.DragFloat("Camera desired altitude", ref _pmcDesiredAltitude, 1, -85, 45); +// ImGui.DragFloat("Camera speed H (deg/sec)", ref _pmcCameraSpeedH, 1, 0, 360); +// ImGui.DragFloat("Camera speed V (deg/sec)", ref _pmcCameraSpeedV, 1, 0, 360); +// } +// } +// } + +// private void DrawGamepad() +// { +// ImGui.SliderFloat("Gamepad angle", ref _gamepadAxisOverrideAngle, -180, 180); +// ImGui.SameLine(); +// ImGui.Checkbox("Gamepad move", ref _gamepadAxisOverrideEnable); + +// ImGui.SliderInt("Gamepad value", ref _gamepadButtonValue, -100, 100); +// ImGui.SameLine(); +// ImGui.InputInt("Gamepad button", ref _gamepadButtonOverride); + +// ImGui.Checkbox("Gamepad navigate", ref _gamepadNavigate); + +// var input = _amex.InputOverride; +// Array.Fill(input.GamepadOverrides, 0); +// if (_gamepadButtonOverride >= 0 && _gamepadButtonOverride < input.GamepadOverrides.Length) +// { +// input.GamepadOverridesEnabled = true; +// input.GamepadOverrides[_gamepadButtonOverride] = _gamepadButtonValue; +// } +// else if (_gamepadAxisOverrideEnable) +// { +// input.GamepadOverridesEnabled = true; +// input.GamepadOverrides[3] = (int)(100 * _gamepadAxisOverrideAngle.Degrees().Sin()); +// input.GamepadOverrides[4] = (int)(100 * _gamepadAxisOverrideAngle.Degrees().Cos()); +// } +// else if (_gamepadNavigate) +// { +// var dest = new WPos(_dest); +// var dir = (Camera.Instance?.CameraAzimuth ?? 0).Radians() - Angle.FromDirection(dest - (_ws.Party.Player()?.Position ?? dest)) + 180.Degrees(); +// input.GamepadOverridesEnabled = true; +// input.GamepadOverrides[3] = (int)(100 * dir.Sin()); +// input.GamepadOverrides[4] = (int)(100 * dir.Cos()); +// } +// else +// { +// input.GamepadOverridesEnabled = false; +// } +// } + +// private InputData* GetInputData() => (InputData*)FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance()->GetUIModule()->GetUIInputData(); + +// private void RMIWalkDetour(PlayerMoveControllerWalk* self, float* sumLeft, float* sumForward, float* sumTurnLeft, byte* haveBackwardOrStrafe, byte* a6, byte bAdditiveUnk) +// { +// _rmiWalkHook.Original(self, sumLeft, sumForward, sumTurnLeft, haveBackwardOrStrafe, a6, bAdditiveUnk); +// if (_pmcOverrideDirEnable) +// { +// var dir = _pmcOverrideDir.Degrees().ToDirection(); +// *sumLeft = dir.X; +// *sumForward = dir.Z; +// } +// else +// { +// *sumLeft = 0; +// *sumForward = 0; +// } +// //Service.Log($"RMIWalk: l={*sumLeft:f3}, f={*sumForward:f3}, t={*sumTurnLeft:f3}, bs={*haveBackwardOrStrafe}, a6={*a6}, a7={bAdditiveUnk}"); +// } + +// private void RMIFlyDetour(PlayerMoveControllerFly* self, PlayerMoveControllerFlyInput* result) +// { +// _rmiFlyHook.Original(self, result); +// if (_pmcOverrideDirEnable) +// { +// var dir = _pmcOverrideDir.Degrees().ToDirection(); +// result->Left = dir.X; +// result->Forward = dir.Z; +// } +// else +// { +// result->Left = 0; +// result->Forward = 0; +// } +// result->Up = _pmcOverrideVertical != 0 ? _pmcOverrideVertical.Degrees().Rad : float.Epsilon; +// //Service.Log($"RMIFly: f={result->Forward:f3}, l={result->Left:f3}, up={result->Up:f3}, t={result->Turn:f3}, f10={result->u10:f3}, dmode={result->DirMode}, bs={result->HaveBackwardOrStrafe}"); +// } + +// private void RMICameraDetour(CameraX* self, int inputMode, float speedH, float speedV) +// { +// _rmiCameraHook.Original(self, inputMode, speedH, speedV); +// if (inputMode == 0) // let user override... +// { +// var dt = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance()->FrameDeltaTime; +// var deltaH = (_pmcDesiredAzimuth.Degrees() - self->DirH.Radians()).Normalized(); +// var deltaV = (_pmcDesiredAltitude.Degrees() - self->DirV.Radians()).Normalized(); +// var maxH = _pmcCameraSpeedH.Degrees().Rad * dt; +// var maxV = _pmcCameraSpeedV.Degrees().Rad * dt; +// self->InputDeltaH = Math.Clamp(deltaH.Rad, -maxH, maxH); +// self->InputDeltaV = Math.Clamp(deltaV.Rad, -maxV, maxV); +// } +// //Service.Log($"RMICamera: dir={self->DirH.Radians()}/{self->DirV.Radians()} [{self->DirVMin.Radians()}-{self->DirVMax.Radians()}], mode={inputMode}, speed={speedH:f1}/{speedV:f1}, delta={self->InputDeltaH.Radians().Deg:f3}/{self->InputDeltaV.Radians().Deg:f3}, speed={self->InputDeltaH.Radians() / Utils.FrameDuration()}/{self->InputDeltaV.Radians() / Utils.FrameDuration()}"); +// } +//} diff --git a/BossMod/Debug/DebugObjects.cs b/BossMod/Debug/DebugObjects.cs index 4d462fff0..67f768d6b 100644 --- a/BossMod/Debug/DebugObjects.cs +++ b/BossMod/Debug/DebugObjects.cs @@ -15,7 +15,7 @@ public unsafe void DrawObjectTable() { ImGui.Checkbox("Show players, minions and mounts", ref _showCrap); - GameObject? selected = null; + IGameObject? selected = null; for (int i = 0; i < Service.ObjectTable.Length; ++i) { var obj = Service.ObjectTable[i]; @@ -31,8 +31,7 @@ public unsafe void DrawObjectTable() var posRot = new Vector4(obj.Position.X, obj.Position.Y, obj.Position.Z, obj.Rotation); foreach (var n in _tree.Node($"#{i} {Utils.ObjectString(obj)} ({localID:X}) ({Utils.ObjectKindString(obj)}) {Utils.PosRotString(posRot)}###{uniqueID:X}", contextMenu: () => ObjectContextMenu(obj), select: () => _selectedID = uniqueID)) { - var character = obj as Character; - var battleChara = obj as BattleChara; + var character = obj as ICharacter; var internalChara = Utils.CharacterInternal(character); _tree.LeafNode($"Unique ID: {uniqueID:X}"); @@ -50,7 +49,7 @@ public unsafe void DrawObjectTable() _tree.LeafNode($"HP: {character.CurrentHp}/{character.MaxHp} ({internalChara->ShieldValue})"); _tree.LeafNode($"Status flags: {character.StatusFlags}"); } - if (battleChara != null) + if (obj is IBattleChara battleChara) { _tree.LeafNode($"Cast: {Utils.CastTimeString(battleChara.CurrentCastTime, battleChara.TotalCastTime)} {new ActionID((ActionType)battleChara.CastActionType, battleChara.CastActionId)}"); foreach (var nn in _tree.Node("Statuses")) @@ -117,19 +116,18 @@ public static unsafe void DumpObjectTable() res.Append($", drawPos={Utils.Vec3String(internalObj->DrawObject->Object.Position)}, drawScale={Utils.Vec3String(internalObj->DrawObject->Object.Scale)}"); } - var chara = obj as BattleChara; - if (chara != null) + if (obj is IBattleChara chara) { res.Append($", vfxObj=0x{Utils.ReadField(internalObj, 0x1840):X}/0x{Utils.ReadField(internalObj, 0x1848):X}"); if (chara.IsCasting) { var target = Service.ObjectTable.SearchById(chara.CastTargetObjectId); - var targetString = target ? Utils.ObjectString(target!) : "unknown"; + var targetString = target != null ? Utils.ObjectString(target) : "unknown"; res.Append($", castAction={new ActionID((ActionType)chara.CastActionType, chara.CastActionId)}, castTarget={targetString}, castLoc={Utils.Vec3String(Utils.BattleCharaInternal(chara)->GetCastInfo()->TargetLocation)}, castTime={Utils.CastTimeString(chara.CurrentCastTime, chara.TotalCastTime)}"); } foreach (var status in chara!.StatusList) { - var src = status.SourceObject ? Utils.ObjectString(status.SourceObject!) : "none"; + var src = status.SourceObject != null ? Utils.ObjectString(status.SourceObject) : "none"; res.Append($"\n status {status.StatusId} '{status.GameData.Name}': param={status.Param}, stacks={status.StackCount}, time={status.RemainingTime:f2}, source={src}"); } } @@ -137,7 +135,7 @@ public static unsafe void DumpObjectTable() Service.Log(res.ToString()); } - private unsafe void ObjectContextMenu(GameObject obj) + private unsafe void ObjectContextMenu(IGameObject obj) { if (ImGui.MenuItem("Target")) { diff --git a/BossMod/Debug/DebugVfx.cs b/BossMod/Debug/DebugVfx.cs index 96add52b7..3618c777d 100644 --- a/BossMod/Debug/DebugVfx.cs +++ b/BossMod/Debug/DebugVfx.cs @@ -1,58 +1,58 @@ -using ImGuiNET; -using System.Runtime.InteropServices; - -namespace BossMod; - -[StructLayout(LayoutKind.Explicit, Size = 0x1A0)] -public unsafe struct VfxInitData -{ -} - -[StructLayout(LayoutKind.Explicit, Size = 0x1D0)] -public unsafe struct VfxInstance -{ -} - -public unsafe sealed class DebugVfx : IDisposable -{ - private delegate VfxInitData* VfxInitDataCtorDelegate(VfxInitData* self); - private readonly VfxInitDataCtorDelegate VfxInitDataCtor; - - // StartOmen: a3=2, a4=0, a13=-1 - private delegate VfxInstance* CreateVfxDelegate(byte* path, VfxInitData* init, byte a3, byte a4, float originX, float originY, float originZ, float sizeX, float sizeY, float sizeZ, float angle, float duration, int a13); - private readonly CreateVfxDelegate CreateVfx; - - public DebugVfx() - { - VfxInitDataCtor = Marshal.GetDelegateForFunctionPointer(Service.SigScanner.ScanText("0F 28 05 ?? ?? ?? ?? 49 83 CA FF")); - CreateVfx = Marshal.GetDelegateForFunctionPointer(Service.SigScanner.ScanText("E8 ?? ?? ?? ?? 48 8B D8 48 8D 95")); - } - - public void Dispose() - { - } - - public void Draw() - { - if (ImGui.Button("Create!")) - { - CreateTestVfx(); - } - } - - private void CreateTestVfx() - { - var pos = Service.ClientState.LocalPlayer?.Position ?? new(); - var path = "vfx/omen/eff/general_1bf.avfx"; - var pathBytes = System.Text.Encoding.UTF8.GetBytes(path); - - var init = new VfxInitData(); - VfxInitDataCtor(&init); - - fixed (byte* pathPtr = pathBytes) - { - var vfx = CreateVfx(pathPtr, &init, 2, 0, pos.X, pos.Y, pos.Z, 10, 5, 10, 0, 20, -1); - Service.Log($"vfx: {(nint)vfx:X}"); - } - } -} +//using ImGuiNET; +//using System.Runtime.InteropServices; + +//namespace BossMod; + +//[StructLayout(LayoutKind.Explicit, Size = 0x1A0)] +//public unsafe struct VfxInitData +//{ +//} + +//[StructLayout(LayoutKind.Explicit, Size = 0x1D0)] +//public unsafe struct VfxInstance +//{ +//} + +//public unsafe sealed class DebugVfx : IDisposable +//{ +// private delegate VfxInitData* VfxInitDataCtorDelegate(VfxInitData* self); +// private readonly VfxInitDataCtorDelegate VfxInitDataCtor; + +// // StartOmen: a3=2, a4=0, a13=-1 +// private delegate VfxInstance* CreateVfxDelegate(byte* path, VfxInitData* init, byte a3, byte a4, float originX, float originY, float originZ, float sizeX, float sizeY, float sizeZ, float angle, float duration, int a13); +// private readonly CreateVfxDelegate CreateVfx; + +// public DebugVfx() +// { +// VfxInitDataCtor = Marshal.GetDelegateForFunctionPointer(Service.SigScanner.ScanText("0F 28 05 ?? ?? ?? ?? 49 83 CA FF")); +// CreateVfx = Marshal.GetDelegateForFunctionPointer(Service.SigScanner.ScanText("E8 ?? ?? ?? ?? 48 8B D8 48 8D 95")); +// } + +// public void Dispose() +// { +// } + +// public void Draw() +// { +// if (ImGui.Button("Create!")) +// { +// CreateTestVfx(); +// } +// } + +// private void CreateTestVfx() +// { +// var pos = Service.ClientState.LocalPlayer?.Position ?? new(); +// var path = "vfx/omen/eff/general_1bf.avfx"; +// var pathBytes = System.Text.Encoding.UTF8.GetBytes(path); + +// var init = new VfxInitData(); +// VfxInitDataCtor(&init); + +// fixed (byte* pathPtr = pathBytes) +// { +// var vfx = CreateVfx(pathPtr, &init, 2, 0, pos.X, pos.Y, pos.Z, 10, 5, 10, 0, 20, -1); +// Service.Log($"vfx: {(nint)vfx:X}"); +// } +// } +//} diff --git a/BossMod/Debug/MainDebugWindow.cs b/BossMod/Debug/MainDebugWindow.cs index 2632e68a1..ac37ab25e 100644 --- a/BossMod/Debug/MainDebugWindow.cs +++ b/BossMod/Debug/MainDebugWindow.cs @@ -13,20 +13,20 @@ class MainDebugWindow(WorldState ws, RotationModuleManager autorot) : UIWindow(" private readonly DebugGraphics _debugGraphics = new(); private readonly DebugAction _debugAction = new(ws, autorot.ActionManager); private readonly DebugHate _debugHate = new(); - private readonly DebugInput _debugInput = new(autorot); + //private readonly DebugInput _debugInput = new(autorot); private readonly DebugAutorotation _debugAutorot = new(autorot); private readonly DebugClassDefinitions _debugClassDefinitions = new(ws); private readonly DebugAddon _debugAddon = new(); private readonly DebugTiming _debugTiming = new(); - private readonly DebugVfx _debugVfx = new(); + //private readonly DebugVfx _debugVfx = new(); protected override void Dispose(bool disposing) { _debugAction.Dispose(); - _debugInput.Dispose(); + //_debugInput.Dispose(); _debugClassDefinitions.Dispose(); _debugAddon.Dispose(); - _debugVfx.Dispose(); + //_debugVfx.Dispose(); base.Dispose(disposing); } @@ -112,10 +112,10 @@ public unsafe override void Draw() { DrawTargets(); } - if (ImGui.CollapsingHeader("Input")) - { - _debugInput.Draw(); - } + //if (ImGui.CollapsingHeader("Input")) + //{ + // _debugInput.Draw(); + //} if (ImGui.CollapsingHeader("Class definitions")) { _debugClassDefinitions.Draw(); @@ -140,10 +140,10 @@ public unsafe override void Draw() { DrawWindowSystem(); } - if (ImGui.CollapsingHeader("VFX")) - { - _debugVfx.Draw(); - } + //if (ImGui.CollapsingHeader("VFX")) + //{ + // _debugVfx.Draw(); + //} if (ImGui.CollapsingHeader("Limit break")) { DrawLimitBreak(); @@ -157,12 +157,11 @@ private void DrawStatuses() var obj = (elem.InstanceID >> 32) == 0 ? Service.ObjectTable.SearchById((uint)elem.InstanceID) : null; if (ImGui.TreeNode(Utils.ObjectString(obj!))) { - var chara = obj as BattleChara; - if (chara != null) + if (obj is IBattleChara chara) { foreach (var status in chara.StatusList) { - var src = status.SourceObject ? Utils.ObjectString(status.SourceObject!) : "none"; + var src = status.SourceObject != null ? Utils.ObjectString(status.SourceObject) : "none"; ImGui.TextUnformatted($"{status.StatusId} '{status.GameData.Name}': param={status.Param}, stacks={status.StackCount}, time={status.RemainingTime:f2}, source={src}"); } } diff --git a/BossMod/Framework/IPCProvider.cs b/BossMod/Framework/IPCProvider.cs index 560526589..a84da15bf 100644 --- a/BossMod/Framework/IPCProvider.cs +++ b/BossMod/Framework/IPCProvider.cs @@ -15,7 +15,7 @@ public IPCProvider(RotationModuleManager autorotation) Register("ActiveModuleComponentList", () => autorotation.Bossmods.ActiveModule?.Components.Select(c => c.GetType().Name).ToList() ?? default); Register("ActiveModuleHasComponent", (string name) => autorotation.Bossmods.ActiveModule?.Components.Any(c => c.GetType().Name == name || c.GetType().BaseType?.Name == name) ?? false); - Register("HasModule", (GameObject obj) => ModuleRegistry.FindByOID(obj.DataId) != null); + Register("HasModule", (IGameObject obj) => ModuleRegistry.FindByOID(obj.DataId) != null); Register("IsMoving", autorotation.ActionManager.InputOverride.IsMoving); Register("ForbiddenZonesCount", () => autorotation.Hints.ForbiddenZones.Count); //Register("InitiateCombat", () => autorotation.ClassActions?.UpdateAutoAction(CommonActions.AutoActionAIFight, float.MaxValue, true)); diff --git a/BossMod/Framework/Plugin.cs b/BossMod/Framework/Plugin.cs index e6cacc4b8..85326e972 100644 --- a/BossMod/Framework/Plugin.cs +++ b/BossMod/Framework/Plugin.cs @@ -36,7 +36,7 @@ public sealed class Plugin : IDalamudPlugin private readonly UIRotationWindow _wndRotation; private readonly MainDebugWindow _wndDebug; - public unsafe Plugin(DalamudPluginInterface dalamud, ICommandManager commandManager, ISigScanner sigScanner, IDataManager dataManager) + public unsafe Plugin(IDalamudPluginInterface dalamud, ICommandManager commandManager, ISigScanner sigScanner, IDataManager dataManager) { if (!dalamud.ConfigDirectory.Exists) dalamud.ConfigDirectory.Create(); @@ -200,7 +200,7 @@ private unsafe void ExecuteHints() } foreach (var s in _hints.StatusesToCancel) { - var res = FFXIVClientStructs.FFXIV.Client.Game.StatusManager.ExecuteStatusOff(s.statusId, s.sourceId != 0 ? (uint)s.sourceId : Dalamud.Game.ClientState.Objects.Types.GameObject.InvalidGameObjectId); + var res = FFXIVClientStructs.FFXIV.Client.Game.StatusManager.ExecuteStatusOff(s.statusId, s.sourceId != 0 ? (uint)s.sourceId : 0xE0000000); Service.Log($"[ExecHints] Canceling status {s.statusId} from {s.sourceId:X} -> {res}"); } } diff --git a/BossMod/Framework/Service.cs b/BossMod/Framework/Service.cs index be505b006..1d2a3f4e6 100644 --- a/BossMod/Framework/Service.cs +++ b/BossMod/Framework/Service.cs @@ -19,7 +19,7 @@ public sealed class Service [PluginService] public static IFramework Framework { get; private set; } [PluginService] public static ITextureProvider Texture { get; private set; } [PluginService] public static ICommandManager CommandManager { get; private set; } - [PluginService] public static DalamudPluginInterface PluginInterface { get; private set; } + [PluginService] public static IDalamudPluginInterface PluginInterface { get; private set; } // TODO: get rid of stuff below in favour of CS [PluginService] public static IClientState ClientState { get; private set; } [PluginService] public static IObjectTable ObjectTable { get; private set; } diff --git a/BossMod/Framework/Utils.cs b/BossMod/Framework/Utils.cs index 19fc9b27d..531c6a45a 100644 --- a/BossMod/Framework/Utils.cs +++ b/BossMod/Framework/Utils.cs @@ -8,7 +8,7 @@ namespace BossMod; public static partial class Utils { - public static string ObjectString(GameObject obj) => $"{obj.DataId:X} '{obj.Name}' <{obj.ObjectId:X}>"; + public static string ObjectString(IGameObject obj) => $"{obj.DataId:X} '{obj.Name}' <{obj.EntityId:X}>"; public static string ObjectString(ulong id) { @@ -16,7 +16,7 @@ public static string ObjectString(ulong id) return obj != null ? ObjectString(obj) : $"(not found) <{id:X}>"; } - public static string ObjectKindString(GameObject obj) + public static string ObjectKindString(IGameObject obj) => obj.ObjectKind == Dalamud.Game.ClientState.Objects.Enums.ObjectKind.BattleNpc ? $"{obj.ObjectKind}/{(Dalamud.Game.ClientState.Objects.Enums.BattleNpcSubKind)obj.SubKind}" : obj.SubKind == 0 ? $"{obj.ObjectKind}" : $"{obj.ObjectKind}/{obj.SubKind}"; @@ -46,9 +46,9 @@ public static string ObjectKindString(GameObject obj) public unsafe delegate byte GameObjectIsFriendlyDelegate(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* obj); public static readonly GameObjectIsFriendlyDelegate GameObjectIsFriendly = Marshal.GetDelegateForFunctionPointer(Service.SigScanner.ScanText("E8 ?? ?? ?? ?? 33 C9 84 C0 0F 95 C1 8D 41 03")); - public static unsafe FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* GameObjectInternal(GameObject? obj) => obj != null ? (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)obj.Address : null; - public static unsafe FFXIVClientStructs.FFXIV.Client.Game.Character.Character* CharacterInternal(Character? chr) => chr != null ? (FFXIVClientStructs.FFXIV.Client.Game.Character.Character*)chr.Address : null; - public static unsafe FFXIVClientStructs.FFXIV.Client.Game.Character.BattleChara* BattleCharaInternal(BattleChara? chara) => chara != null ? (FFXIVClientStructs.FFXIV.Client.Game.Character.BattleChara*)chara.Address : null; + public static unsafe FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* GameObjectInternal(IGameObject? obj) => obj != null ? (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)obj.Address : null; + public static unsafe FFXIVClientStructs.FFXIV.Client.Game.Character.Character* CharacterInternal(ICharacter? chr) => chr != null ? (FFXIVClientStructs.FFXIV.Client.Game.Character.Character*)chr.Address : null; + public static unsafe FFXIVClientStructs.FFXIV.Client.Game.Character.BattleChara* BattleCharaInternal(IBattleChara? chara) => chara != null ? (FFXIVClientStructs.FFXIV.Client.Game.Character.BattleChara*)chara.Address : null; public static unsafe ulong SceneObjectFlags(FFXIVClientStructs.FFXIV.Client.Graphics.Scene.Object* o) => ReadField(o, 0x38); diff --git a/BossMod/Util/UIMisc.cs b/BossMod/Util/UIMisc.cs index e603cc050..bf46b9a34 100644 --- a/BossMod/Util/UIMisc.cs +++ b/BossMod/Util/UIMisc.cs @@ -1,5 +1,6 @@ using Dalamud.Interface; using Dalamud.Interface.Internal; +using Dalamud.Interface.Textures; using Dalamud.Interface.Utility.Raii; using ImGuiNET; @@ -38,15 +39,16 @@ public static void TextUnderlined(Vector4 colour, string text) ImGui.TextColored(colour, text); } - public static void Image(IDalamudTextureWrap? icon, Vector2 size) + public static void Image(ISharedImmediateTexture? icon, Vector2 size) { - if (icon != null) - ImGui.Image(icon.ImGuiHandle, size); + var wrap = icon?.GetWrapOrDefault(); + if (wrap != null) + ImGui.Image(wrap.ImGuiHandle, size); else ImGui.Dummy(size); } - public static bool ImageToggleButton(IDalamudTextureWrap? icon, Vector2 size, bool state, string text) + public static bool ImageToggleButton(ISharedImmediateTexture? icon, Vector2 size, bool state, string text) { var cursor = ImGui.GetCursorPos(); var padding = ImGui.GetStyle().FramePadding; @@ -54,10 +56,11 @@ public static bool ImageToggleButton(IDalamudTextureWrap? icon, Vector2 size, bo ImGui.TextUnformatted(text); ImGui.SetCursorPos(cursor); - if (icon != null) + var wrap = icon?.GetWrapOrDefault(); + if (wrap != null) { Vector4 tintColor = state ? new(1f, 1f, 1f, 1f) : new(0.5f, 0.5f, 0.5f, 0.85f); - return ImGui.ImageButton(icon.ImGuiHandle, size, Vector2.Zero, Vector2.One, 1, Vector4.Zero, tintColor); + return ImGui.ImageButton(wrap.ImGuiHandle, size, Vector2.Zero, Vector2.One, 1, Vector4.Zero, tintColor); } else { diff --git a/BossMod/packages.lock.json b/BossMod/packages.lock.json index 30cc957fc..70de531fb 100644 --- a/BossMod/packages.lock.json +++ b/BossMod/packages.lock.json @@ -4,9 +4,9 @@ "net8.0-windows7.0": { "DalamudPackager": { "type": "Direct", - "requested": "[2.1.12, )", - "resolved": "2.1.12", - "contentHash": "Sc0PVxvgg4NQjcI8n10/VfUQBAS4O+Fw2pZrAqBdRMbthYGeogzu5+xmIGCGmsEZ/ukMOBuAqiNiB5qA3MRalg==" + "requested": "[2.1.13, )", + "resolved": "2.1.13", + "contentHash": "rMN1omGe8536f4xLMvx9NwfvpAc9YFFfeXJ1t4P4PE6Gu8WCIoFliR1sh07hM+bfODmesk/dvMbji7vNI+B/pQ==" }, "SharpDX.Mathematics": { "type": "Direct",