From fcf27e78022f591f6d98d520fe22755f03dddf3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E6=B0=B4?= <1123993881@qq.com> Date: Sun, 13 Aug 2023 13:58:51 +0800 Subject: [PATCH] fix: add auto open chest feature. --- RotationSolver.Basic/Configuration/Configs.cs | 3 + .../Localization/ConfigTranslation.cs | 4 + .../UI/RotationConfigWindowNew_Config.cs | 4 + .../UI/SearchableConfigs/Searchable.cs | 2 +- RotationSolver/Updaters/MajorUpdater.cs | 87 +++++++++++++++++++ 5 files changed, 99 insertions(+), 1 deletion(-) diff --git a/RotationSolver.Basic/Configuration/Configs.cs b/RotationSolver.Basic/Configuration/Configs.cs index e0d7713ae..a125eca81 100644 --- a/RotationSolver.Basic/Configuration/Configs.cs +++ b/RotationSolver.Basic/Configuration/Configs.cs @@ -299,6 +299,9 @@ public enum PluginConfigBool : byte [Default(true)] UseGroundBeneficialAbility, [Default(false)] TargetAllForFriendly, [Default(false)] ShowCooldownWindow, + + [Default(true)] AutoOpenChest, + [Default(true)] AutoCloseChestWindow, } public enum PluginConfigFloat : byte diff --git a/RotationSolver/Localization/ConfigTranslation.cs b/RotationSolver/Localization/ConfigTranslation.cs index 98c55bc92..f463c2d28 100644 --- a/RotationSolver/Localization/ConfigTranslation.cs +++ b/RotationSolver/Localization/ConfigTranslation.cs @@ -108,6 +108,8 @@ internal static class ConfigTranslation PluginConfigBool.ShowHealthRatio => LocalizationManager.RightLang.ConfigWindow_Param_ShowHealthRatio, PluginConfigBool.ShowTooltips => LocalizationManager.RightLang.ConfigWindow_Param_ShowTooltips, PluginConfigBool.InDebug => LocalizationManager.RightLang.ConfigWindow_Param_InDebug, + PluginConfigBool.AutoOpenChest => "Auto Open the treasure chest", + PluginConfigBool.AutoCloseChestWindow => "Auto close the loot window when auto opened the chest.", //Rotations PluginConfigBool.DownloadRotations => LocalizationManager.RightLang.ConfigWindow_Rotation_DownloadRotations, @@ -199,6 +201,8 @@ internal static class ConfigTranslation PluginConfigBool.AutoProvokeForTank => LocalizationManager.RightLang.ConfigWindow_Param_AutoProvokeForTankDesc, PluginConfigBool.CanAttackMarkAOE => LocalizationManager.RightLang.ConfigWindow_Param_AttackMarkAOEDesc, PluginConfigBool.MoveTowardsScreenCenter => LocalizationManager.RightLang.ConfigWindow_Param_MoveTowardsScreenDesc, + + PluginConfigBool.AutoOpenChest => "Because of the feature in pandora, there is an issue the treasure chest cannot be opened in some cases, I find the code from roll for loot. Once Pandora fixed that, this feature will be deleted.", _ => string.Empty, }; diff --git a/RotationSolver/UI/RotationConfigWindowNew_Config.cs b/RotationSolver/UI/RotationConfigWindowNew_Config.cs index aa2ad749b..daf95b950 100644 --- a/RotationSolver/UI/RotationConfigWindowNew_Config.cs +++ b/RotationSolver/UI/RotationConfigWindowNew_Config.cs @@ -356,6 +356,10 @@ private static void DrawTarget() new DragFloatRangeSearchPlugin(PluginConfigFloat.StopCastingDelayMin, PluginConfigFloat.StopCastingDelayMin, 0.002f) }), + new CheckBoxSearchPlugin(PluginConfigBool.AutoOpenChest, new ISearchable[] + { + new CheckBoxSearchPlugin(PluginConfigBool.AutoCloseChestWindow), + }), }; private static void DrawExtra() { diff --git a/RotationSolver/UI/SearchableConfigs/Searchable.cs b/RotationSolver/UI/SearchableConfigs/Searchable.cs index 81cbbf1c6..07f9c0591 100644 --- a/RotationSolver/UI/SearchableConfigs/Searchable.cs +++ b/RotationSolver/UI/SearchableConfigs/Searchable.cs @@ -73,7 +73,7 @@ protected void ShowTooltip(Job job, bool showHand = true) } var wholeWidth = ImGui.GetWindowWidth(); - foreach (var tooltip in Tooltips) + if(Tooltips != null) foreach (var tooltip in Tooltips) { RotationConfigWindowNew.DrawLinkDescription(tooltip, wholeWidth, false); } diff --git a/RotationSolver/Updaters/MajorUpdater.cs b/RotationSolver/Updaters/MajorUpdater.cs index 21e4783df..74d2d18d7 100644 --- a/RotationSolver/Updaters/MajorUpdater.cs +++ b/RotationSolver/Updaters/MajorUpdater.cs @@ -1,10 +1,16 @@ using Dalamud.Game; using Dalamud.Game.ClientState.Conditions; +using Dalamud.Game.ClientState.Objects.Enums; using Dalamud.Logging; using ECommons.DalamudServices; using ECommons.GameHelpers; +using ECommons.ImGuiMethods; +using FFXIVClientStructs.FFXIV.Client.Game.Control; +using FFXIVClientStructs.FFXIV.Client.Game.UI; +using FFXIVClientStructs.FFXIV.Component.GUI; using RotationSolver.Commands; using RotationSolver.UI; +using System.Runtime.InteropServices; namespace RotationSolver.Updaters; @@ -93,6 +99,9 @@ private unsafe static void FrameworkUpdate(Framework framework) } MacroUpdater.UpdateMacro(); + + CloseWindow(); + OpenChest(); } catch (Exception ex) { @@ -169,6 +178,84 @@ private static void UpdateWork() _work = false; } + static DateTime _closeWindowTime = DateTime.Now; + private unsafe static void CloseWindow() + { + if (_closeWindowTime < DateTime.Now) return; + + var needGreedWindow = Svc.GameGui.GetAddonByName("NeedGreed", 1); + if (needGreedWindow == IntPtr.Zero) return; + + var notification = (AtkUnitBase*)Svc.GameGui.GetAddonByName("_Notification", 1); + if (notification == null) return; + + var atkValues = (AtkValue*)Marshal.AllocHGlobal(2 * sizeof(AtkValue)); + atkValues[0].Type = atkValues[1].Type = FFXIVClientStructs.FFXIV.Component.GUI.ValueType.Int; + atkValues[0].Int = 0; + atkValues[1].Int = 2; + try + { + notification->FireCallback(2, atkValues); + } + catch (Exception ex) + { + PluginLog.Warning(ex, "Failed to close the window!"); + } + finally + { + Marshal.FreeHGlobal(new IntPtr(atkValues)); + } + } + + static DateTime _nextOpenTime = DateTime.Now; + static uint _lastChest = 0; + private unsafe static void OpenChest() + { + if (!Service.ConfigNew.GetValue(Basic.Configuration.PluginConfigBool.AutoOpenChest)) return; + var player = Player.Object; + + var treasure = Svc.Objects.FirstOrDefault(o => + { + if (o == null) return false; + var dis = Vector3.Distance(player.Position, o.Position) - player.HitboxRadius - o.HitboxRadius; + if (dis > 0.5f) return false; + + var address = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)(void*)o.Address; + if ((ObjectKind)address->ObjectKind != ObjectKind.Treasure) return false; + + //Opened! + foreach (var item in Loot.Instance()->ItemArraySpan) + { + if (item.ChestObjectId == o.ObjectId) return false; + } + + return true; + }); + + if (treasure == null) return; + if (DateTime.Now < _nextOpenTime) return; + if (treasure.ObjectId == _lastChest && DateTime.Now - _nextOpenTime < TimeSpan.FromSeconds(10)) return; + + _nextOpenTime = DateTime.Now.AddSeconds(new Random().NextDouble() + 0.2); + _lastChest = treasure.ObjectId; + + try + { + Svc.Targets.Target =treasure; + + TargetSystem.Instance()->InteractWithObject((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)(void*)treasure.Address); + + Notify.Plain($"Try to open the chest {treasure.Name}"); + } + catch (Exception ex) + { + PluginLog.Error(ex, "Failed to open the chest!"); + } + + if (!Service.ConfigNew.GetValue(Basic.Configuration.PluginConfigBool.AutoOpenChest)) return; + _closeWindowTime = DateTime.Now.AddSeconds(0.1); + } + public static void Dispose() { Svc.Framework.Update -= FrameworkUpdate;