diff --git a/Resources/HostileCastingArea.json b/Resources/HostileCastingArea.json index b57da9939..3160eacdb 100644 --- a/Resources/HostileCastingArea.json +++ b/Resources/HostileCastingArea.json @@ -427,5 +427,8 @@ 35274, 35268, 35284, - 35279 + 35279, + 35312, + 35280, + 35269 ] \ No newline at end of file diff --git a/Resources/RotationSolverRecord.json b/Resources/RotationSolverRecord.json index aec22dc17..9dfab7476 100644 --- a/Resources/RotationSolverRecord.json +++ b/Resources/RotationSolverRecord.json @@ -1,4 +1,4 @@ { - "ClickingCount": 15952, + "ClickingCount": 17595, "SaidUsers": [] } \ No newline at end of file diff --git a/RotationSolver.Basic/Configuration/Conditions/ActionCondition.cs b/RotationSolver.Basic/Configuration/Conditions/ActionCondition.cs new file mode 100644 index 000000000..de35d767b --- /dev/null +++ b/RotationSolver.Basic/Configuration/Conditions/ActionCondition.cs @@ -0,0 +1,80 @@ +namespace RotationSolver.ActionSequencer; + +internal class ActionCondition : DelayCondition +{ + internal IBaseAction _action; + + public ActionID ID { get; set; } = ActionID.None; + + public ActionConditionType ActionConditionType = ActionConditionType.Elapsed; + + public bool Condition { get; set; } + + public int Param1; + public int Param2; + public float Time; + + public override bool CheckBefore(ICustomRotation rotation) + { + return CheckBaseAction(rotation, ID, ref _action) && base.CheckBefore(rotation); + } + + public override bool IsTrueInside(ICustomRotation rotation) + { + var result = false; + + switch (ActionConditionType) + { + case ActionConditionType.Elapsed: + result = _action.ElapsedOneChargeAfter(Time); // Bigger + break; + + case ActionConditionType.ElapsedGCD: + result = _action.ElapsedOneChargeAfterGCD((uint)Param1, Param2); // Bigger + break; + + case ActionConditionType.Remain: + result = !_action.WillHaveOneCharge(Time); //Smaller + break; + + case ActionConditionType.RemainGCD: + result = !_action.WillHaveOneChargeGCD((uint)Param1, Param2); // Smaller + break; + + case ActionConditionType.CanUse: + result = _action.CanUse(out _, (CanUseOption)Param1, (byte)Param2); + break; + + case ActionConditionType.EnoughLevel: + result = _action.EnoughLevel; + break; + + case ActionConditionType.IsCoolDown: + result = _action.IsCoolingDown; + break; + + case ActionConditionType.CurrentCharges: + result = _action.CurrentCharges > Param1; + break; + + case ActionConditionType.MaxCharges: + result = _action.MaxCharges > Param1; + break; + } + + return Condition ? !result : result; + } +} + +internal enum ActionConditionType : byte +{ + Elapsed, + ElapsedGCD, + Remain, + RemainGCD, + CanUse, + EnoughLevel, + IsCoolDown, + CurrentCharges, + MaxCharges, +} diff --git a/RotationSolver.Basic/Configuration/Conditions/ConditionSet.cs b/RotationSolver.Basic/Configuration/Conditions/ConditionSet.cs new file mode 100644 index 000000000..2ad493a2f --- /dev/null +++ b/RotationSolver.Basic/Configuration/Conditions/ConditionSet.cs @@ -0,0 +1,30 @@ +namespace RotationSolver.ActionSequencer; + +internal class ConditionSet : DelayCondition +{ + public List Conditions { get; set; } = new List(); + + public LogicalType Type; + + public override bool IsTrueInside(ICustomRotation rotation) + { + if (Conditions.Count == 0) return false; + + return Type switch + { + LogicalType.And => Conditions.All(c => c.IsTrue(rotation)), + LogicalType.Or => Conditions.Any(c => c.IsTrue(rotation)), + LogicalType.NotAnd => !Conditions.All(c => c.IsTrue(rotation)), + LogicalType.NotOr => !Conditions.Any(c => c.IsTrue(rotation)), + _ => false, + }; + } +} + +internal enum LogicalType: byte +{ + And, + Or, + NotAnd, + NotOr, +} diff --git a/RotationSolver.Basic/Configuration/Conditions/DelayCondition.cs b/RotationSolver.Basic/Configuration/Conditions/DelayCondition.cs new file mode 100644 index 000000000..0f183e84e --- /dev/null +++ b/RotationSolver.Basic/Configuration/Conditions/DelayCondition.cs @@ -0,0 +1,63 @@ +using ECommons.GameHelpers; + +namespace RotationSolver.ActionSequencer; + +internal abstract class DelayCondition : ICondition +{ + public float DelayMin = 0; + public float DelayMax = 0; + + RandomDelay _delay = default; + + public bool IsTrue(ICustomRotation rotation) + { + if(_delay.GetRange == null) + { + _delay = new(() => (DelayMin, DelayMax)); + } + + return _delay.Delay(CheckBefore(rotation) && IsTrueInside(rotation)); + } + + public abstract bool IsTrueInside(ICustomRotation rotation); + + public virtual bool CheckBefore(ICustomRotation rotation) + { + return Player.Available; + } + + internal static bool CheckBaseAction(ICustomRotation rotation, ActionID id, ref IBaseAction action) + { + if (id != ActionID.None && (action == null || (ActionID)action.ID != id)) + { + action = rotation.AllBaseActions.FirstOrDefault(a => (ActionID)a.ID == id); + } + if (action == null) return false; + return true; + } + + internal static bool CheckMemberInfo(ICustomRotation rotation, ref string name, ref T value) where T : MemberInfo + { + if (!string.IsNullOrEmpty(name) && (value == null || value.Name != name)) + { + var memberName = name; + if (typeof(T).IsAssignableFrom(typeof(PropertyInfo))) + { + value = (T)GetAllMethods(rotation.GetType(), RuntimeReflectionExtensions.GetRuntimeProperties).FirstOrDefault(m => m.Name == memberName); + } + else if (typeof(T).IsAssignableFrom(typeof(MethodInfo))) + { + value = (T)GetAllMethods(rotation.GetType(), RuntimeReflectionExtensions.GetRuntimeMethods).FirstOrDefault(m => m.Name == memberName); + } + } + return true; + } + + private static IEnumerable GetAllMethods(Type type, Func> getFunc) + { + if (type == null || getFunc == null) return Array.Empty(); + + var methods = getFunc(type); + return methods.Union(GetAllMethods(type.BaseType, getFunc)); + } +} diff --git a/RotationSolver/ActionSequencer/ICondition.cs b/RotationSolver.Basic/Configuration/Conditions/ICondition.cs similarity index 71% rename from RotationSolver/ActionSequencer/ICondition.cs rename to RotationSolver.Basic/Configuration/Conditions/ICondition.cs index 53ae37cf8..326728b3a 100644 --- a/RotationSolver/ActionSequencer/ICondition.cs +++ b/RotationSolver.Basic/Configuration/Conditions/ICondition.cs @@ -3,5 +3,5 @@ internal interface ICondition { bool IsTrue(ICustomRotation rotation); - void Draw(ICustomRotation rotation); + bool CheckBefore(ICustomRotation rotation); } \ No newline at end of file diff --git a/RotationSolver.Basic/Configuration/Conditions/RotationCondition.cs b/RotationSolver.Basic/Configuration/Conditions/RotationCondition.cs new file mode 100644 index 000000000..008761bb3 --- /dev/null +++ b/RotationSolver.Basic/Configuration/Conditions/RotationCondition.cs @@ -0,0 +1,112 @@ +namespace RotationSolver.ActionSequencer; + +internal class RotationCondition : DelayCondition +{ + public ComboConditionType ComboConditionType = ComboConditionType.Float; + internal PropertyInfo _prop; + public string PropertyName = nameof(CustomRotation.CombatTime); + + MethodInfo _method; + public string MethodName = string.Empty; + + internal IBaseAction _action; + public ActionID ID { get; set; } = ActionID.None; + + public int Condition; + + public int Param1; + public float Param2; + + + public override bool CheckBefore(ICustomRotation rotation) + { + return CheckBaseAction(rotation, ID, ref _action) + && CheckMemberInfo(rotation, ref PropertyName, ref _prop) + && CheckMemberInfo(rotation, ref MethodName, ref _method) + && base.CheckBefore(rotation); + } + + public override bool IsTrueInside(ICustomRotation rotation) + { + switch (ComboConditionType) + { + case ComboConditionType.Bool: + if (_prop == null) return false; + if (_prop.GetValue(rotation) is bool b) + { + return Condition > 0 ? !b : b; + } + return false; + + case ComboConditionType.Integer: + if (_prop == null) return false; + + var value = _prop.GetValue(rotation); + if (value is byte by) + { + switch (Condition) + { + case 0: + return by > Param1; + case 1: + return by < Param1; + case 2: + return by == Param1; + } + } + else if (value is int i) + { + switch (Condition) + { + case 0: + return i > Param1; + case 1: + return i < Param1; + case 2: + return i == Param1; + } + } + return false; + + case ComboConditionType.Float: + if (_prop == null) return false; + if (_prop.GetValue(rotation) is float fl) + { + switch (Condition) + { + case 0: + return fl > Param2; + case 1: + return fl < Param2; + case 2: + return fl == Param2; + } + } + return false; + + case ComboConditionType.Last: + try + { + if (_method?.Invoke(rotation, new object[] { Param1 > 0, new IAction[] { _action } }) is bool boo) + { + return Condition > 0 ? !boo : boo; + } + return false; + } + catch + { + return false; + } + } + + return false; + } +} + +internal enum ComboConditionType : byte +{ + Bool, + Integer, + Float, + Last, +} diff --git a/RotationSolver.Basic/Configuration/Conditions/TargetCondition.cs b/RotationSolver.Basic/Configuration/Conditions/TargetCondition.cs new file mode 100644 index 000000000..89842a286 --- /dev/null +++ b/RotationSolver.Basic/Configuration/Conditions/TargetCondition.cs @@ -0,0 +1,128 @@ +using ECommons.DalamudServices; +using ECommons.GameHelpers; +using Lumina.Excel.GeneratedSheets; + +namespace RotationSolver.ActionSequencer; + +internal class TargetCondition : DelayCondition +{ + internal IBaseAction _action; + public ActionID ID { get; set; } = ActionID.None; + + public bool Condition; + public bool FromSelf; + internal Status Status; + public StatusID StatusId { get; set; } + public bool IsTarget; + public TargetConditionType TargetConditionType; + + public float DistanceOrTime; + public int GCD; + + public string CastingActionName = string.Empty; + + public override bool IsTrueInside(ICustomRotation rotation) + { + BattleChara tar; + if (_action != null) + { + _action.CanUse(out _, CanUseOption.EmptyOrSkipCombo | CanUseOption.MustUse + | CanUseOption.IgnoreTarget); + tar = _action.Target; + } + else + { + tar = IsTarget ? Svc.Targets.Target as BattleChara : Player.Object; + tar ??= Player.Object; + } + + if (tar == null) return false; + + var result = false; + + switch (TargetConditionType) + { + case TargetConditionType.HasStatus: + result = tar.HasStatus(FromSelf, StatusId); + break; + + case TargetConditionType.IsBoss: + result = tar.IsBoss(); + break; + + case TargetConditionType.IsDying: + result = tar.IsDying(); + break; + + case TargetConditionType.InCombat: + result = tar.InCombat(); + break; + + case TargetConditionType.Distance: + result = tar.DistanceToPlayer() > DistanceOrTime; + break; + + case TargetConditionType.StatusEnd: + result = !tar.WillStatusEnd(DistanceOrTime, FromSelf, StatusId); + break; + + case TargetConditionType.StatusEndGCD: + result = !tar.WillStatusEndGCD((uint)GCD, DistanceOrTime, FromSelf, StatusId); + break; + + case TargetConditionType.TimeToKill: + result = tar.GetTimeToKill() > DistanceOrTime; + break; + + case TargetConditionType.CastingAction: + if (string.IsNullOrEmpty(CastingActionName) || tar.CastActionId == 0) + { + result = false; + break; + } + + var castName = Service.GetSheet().GetRow(tar.CastActionId)?.Name.ToString(); + + result = CastingActionName == castName; + break; + + case TargetConditionType.CastingActionTimeUntil: + + if (!tar.IsCasting || tar.CastActionId == 0) + { + result = false; + break; + } + + float castTime = tar.TotalCastTime - tar.CurrentCastTime; + result = castTime > DistanceOrTime + DataCenter.WeaponRemain; + break; + + case TargetConditionType.HP: + result = tar.CurrentHp > GCD; + break; + + case TargetConditionType.MP: + result = tar.CurrentMp > GCD; + break; + } + + return Condition ? !result : result; + } +} + +internal enum TargetConditionType : byte +{ + HasStatus, + IsDying, + IsBoss, + InCombat, + Distance, + StatusEnd, + StatusEndGCD, + CastingAction, + CastingActionTimeUntil, + TimeToKill, + HP, + MP, +} \ No newline at end of file diff --git a/RotationSolver.Basic/Configuration/Conditions/TraitCondition.cs b/RotationSolver.Basic/Configuration/Conditions/TraitCondition.cs new file mode 100644 index 000000000..3089ff171 --- /dev/null +++ b/RotationSolver.Basic/Configuration/Conditions/TraitCondition.cs @@ -0,0 +1,28 @@ +using ECommons.GameHelpers; +using RotationSolver.Basic.Traits; + +namespace RotationSolver.ActionSequencer; + +internal class TraitCondition : DelayCondition +{ + public uint TraitID { get; set; } = 0; + internal IBaseTrait _trait; + public bool Condition { get; set; } + + public override bool CheckBefore(ICustomRotation rotation) + { + if (TraitID != 0 && (_trait == null || _trait.ID != TraitID)) + { + _trait = rotation.AllTraits.FirstOrDefault(a => a.ID == TraitID); + } + return base.CheckBefore(rotation); + } + + public override bool IsTrueInside(ICustomRotation rotation) + { + if (_trait == null || !Player.Available) return false; + + var result = _trait.EnoughLevel; + return Condition ? !result : result; + } +} diff --git a/RotationSolver.Basic/Configuration/OtherConfiguration.cs b/RotationSolver.Basic/Configuration/OtherConfiguration.cs index d19bc58c2..b1bc6fd5e 100644 --- a/RotationSolver.Basic/Configuration/OtherConfiguration.cs +++ b/RotationSolver.Basic/Configuration/OtherConfiguration.cs @@ -221,7 +221,7 @@ private static void InitOne(ref T value, string name, bool download = true) { try { - var client = new HttpClient(); + using var client = new HttpClient(); var str = client.GetStringAsync($"https://raw.githubusercontent.com/{Service.USERNAME}/{Service.REPO}/main/Resources/{name}.json").Result; File.WriteAllText(path, str); diff --git a/RotationSolver/ActionSequencer/ActionCondition.cs b/RotationSolver/ActionSequencer/ActionCondition.cs deleted file mode 100644 index e1cc02ab4..000000000 --- a/RotationSolver/ActionSequencer/ActionCondition.cs +++ /dev/null @@ -1,211 +0,0 @@ -using Dalamud.Utility; -using RotationSolver.Localization; -using RotationSolver.UI; - -namespace RotationSolver.ActionSequencer; - -internal class ActionCondition : BaseCondition -{ - private IBaseAction _action; - - public ActionID ID { get; set; } = ActionID.None; - - public ActionConditionType ActionConditionType = ActionConditionType.Elapsed; - - public bool Condition { get; set; } - - public int Param1; - public int Param2; - public float Time; - - public override bool IsTrueInside(ICustomRotation rotation) - { - if (!ConditionHelper.CheckBaseAction(rotation, ID, ref _action)) return false; - - var result = false; - - switch (ActionConditionType) - { - case ActionConditionType.Elapsed: - result = _action.ElapsedOneChargeAfter(Time); // Bigger - break; - - case ActionConditionType.ElapsedGCD: - result = _action.ElapsedOneChargeAfterGCD((uint)Param1, Param2); // Bigger - break; - - case ActionConditionType.Remain: - result = !_action.WillHaveOneCharge(Time); //Smaller - break; - - case ActionConditionType.RemainGCD: - result = !_action.WillHaveOneChargeGCD((uint)Param1, Param2); // Smaller - break; - - case ActionConditionType.CanUse: - result = _action.CanUse(out _, (CanUseOption)Param1, (byte)Param2); - break; - - case ActionConditionType.EnoughLevel: - result = _action.EnoughLevel; - break; - - case ActionConditionType.IsCoolDown: - result = _action.IsCoolingDown; - break; - - case ActionConditionType.CurrentCharges: - result = _action.CurrentCharges > Param1; - break; - - case ActionConditionType.MaxCharges: - result = _action.MaxCharges > Param1; - break; - } - - return Condition ? !result : result; - } - - private readonly CollapsingHeaderGroup _actionsList = new() - { - HeaderSize = 12, - }; - - public override void DrawInside(ICustomRotation rotation) - { - ConditionHelper.CheckBaseAction(rotation, ID, ref _action); - - var name = _action?.Name ?? string.Empty; - - var popUpKey = "Action Condition Pop Up" + GetHashCode().ToString(); - - ConditionHelper.ActionSelectorPopUp(popUpKey, _actionsList, rotation, item => ID = (ActionID)item.ID); - - if (_action?.GetTexture(out var icon) ?? false || IconSet.GetTexture(4, out icon)) - { - var cursor = ImGui.GetCursorPos(); - if (ImGuiHelper.NoPaddingNoColorImageButton(icon.ImGuiHandle, Vector2.One * ConditionHelper.IconSize, GetHashCode().ToString())) - { - if(!ImGui.IsPopupOpen(popUpKey)) ImGui.OpenPopup(popUpKey); - } - ImGuiHelper.DrawActionOverlay(cursor, ConditionHelper.IconSize, 1); - ImguiTooltips.HoveredTooltip(name); - } - - ImGui.SameLine(); - - ConditionHelper.DrawByteEnum($"##Category{GetHashCode()}", ref ActionConditionType, EnumTranslations.ToName); - - var condition = Condition ? 1 : 0; - var combos = Array.Empty(); - switch (ActionConditionType) - { - case ActionConditionType.ElapsedGCD: - case ActionConditionType.RemainGCD: - case ActionConditionType.Elapsed: - case ActionConditionType.Remain: - case ActionConditionType.CurrentCharges: - case ActionConditionType.MaxCharges: - combos = new string[] { ">", "<=" }; - break; - - case ActionConditionType.CanUse: - combos = new string[] - { - LocalizationManager.RightLang.ActionSequencer_Can, - LocalizationManager.RightLang.ActionSequencer_Cannot, - }; - break; - - case ActionConditionType.EnoughLevel: - case ActionConditionType.IsCoolDown: - combos = new string[] - { - LocalizationManager.RightLang.ActionSequencer_Is, - LocalizationManager.RightLang.ActionSequencer_Isnot, - }; - break; - } - ImGui.SameLine(); - - if(ImGuiHelper.SelectableCombo($"##Comparation{GetHashCode()}", combos, ref condition)) - { - Condition = condition > 0; - } - - - switch (ActionConditionType) - { - case ActionConditionType.Elapsed: - case ActionConditionType.Remain: - ConditionHelper.DrawDragFloat($"s##Seconds{GetHashCode()}", ref Time); - break; - - case ActionConditionType.ElapsedGCD: - case ActionConditionType.RemainGCD: - if (ConditionHelper.DrawDragInt($"GCD##GCD{GetHashCode()}", ref Param1)) - { - Param1 = Math.Max(0, Param1); - } - if (ConditionHelper.DrawDragInt($"{LocalizationManager.RightLang.ActionSequencer_TimeOffset}##Ability{GetHashCode()}", ref Param2)) - { - Param2 = Math.Max(0, Param2); - } - break; - - case ActionConditionType.CanUse: - var popUpId = "Can Use Id" + GetHashCode().ToString(); - var option = (CanUseOption)Param1; - - if (ImGui.Selectable($"{option}##CanUse{GetHashCode()}")) - { - if (!ImGui.IsPopupOpen(popUpId)) ImGui.OpenPopup(popUpId); - } - - if (ImGui.BeginPopup(popUpId)) - { - var showedValues = Enum.GetValues().Where(i => i.GetAttribute() == null); - - foreach (var value in showedValues) - { - var b = option.HasFlag(value); - if(ImGui.Checkbox(value.ToString(), ref b)) - { - option ^= value; - Param1 = (int)option; - } - } - - ImGui.EndPopup(); - } - - if (ConditionHelper.DrawDragInt($"{LocalizationManager.RightLang.ActionSequencer_AOECount}##AOECount{GetHashCode()}", ref Param2)) - { - Param2 = Math.Max(0, Param2); - } - break; - - case ActionConditionType.CurrentCharges: - case ActionConditionType.MaxCharges: - if (ConditionHelper.DrawDragInt($"{LocalizationManager.RightLang.ActionSequencer_Charges}##Charges{GetHashCode()}", ref Param1)) - { - Param1 = Math.Max(0, Param1); - } - break; - } - } - -} - -public enum ActionConditionType : byte -{ - Elapsed, - ElapsedGCD, - Remain, - RemainGCD, - CanUse, - EnoughLevel, - IsCoolDown, - CurrentCharges, - MaxCharges, -} diff --git a/RotationSolver/ActionSequencer/BaseCondition.cs b/RotationSolver/ActionSequencer/BaseCondition.cs deleted file mode 100644 index d1dd51210..000000000 --- a/RotationSolver/ActionSequencer/BaseCondition.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Dalamud.Interface.Utility; -using RotationSolver.Localization; -using RotationSolver.UI; - -namespace RotationSolver.ActionSequencer; - -internal abstract class BaseCondition : ICondition -{ - public float DelayMin = 0; - public float DelayMax = 0; - - RandomDelay _delay = default; - - [JsonIgnore] - private const float MIN = 0, MAX = 60; - - public bool IsTrue(ICustomRotation rotation) - { - if(_delay.GetRange == null) - { - _delay = new(() => (DelayMin, DelayMax)); - } - return _delay.Delay(IsTrueInside(rotation)); - } - - public abstract bool IsTrueInside(ICustomRotation rotation); - - public void Draw(ICustomRotation rotation) - { - BeforeDraw(); - ImGui.SetNextItemWidth(80 * ImGuiHelpers.GlobalScale); - if(ImGui.DragFloatRange2($"##Random Delay {GetHashCode()}", ref DelayMin, ref DelayMax, 0.1f, MIN, MAX)) - { - DelayMin = Math.Max(Math.Min(DelayMin, DelayMax), MIN); - DelayMax = Math.Min(Math.Max(DelayMin, DelayMax), MAX); - } - ImguiTooltips.HoveredTooltip(LocalizationManager.RightLang.ActionSequencer_Delay_Description); - - ImGui.SameLine(); - DrawInside(rotation); - } - - public virtual void BeforeDraw() - { - - } - public abstract void DrawInside(ICustomRotation rotation); -} diff --git a/RotationSolver/ActionSequencer/ConditionHelper.cs b/RotationSolver/ActionSequencer/ConditionHelper.cs index 71a289b7f..67874b78a 100644 --- a/RotationSolver/ActionSequencer/ConditionHelper.cs +++ b/RotationSolver/ActionSequencer/ConditionHelper.cs @@ -1,22 +1,42 @@ -using Dalamud.Interface.Utility; -using Dalamud.Logging; -using ECommons.GameHelpers; +using Dalamud.Game.ClientState.Keys; +using Dalamud.Interface.Utility; +using Dalamud.Utility; +using ECommons.ImGuiMethods; +using ExCSS; +using Lumina.Excel.GeneratedSheets; using RotationSolver.Localization; using RotationSolver.UI; using RotationSolver.Updaters; +using static Dalamud.Interface.Utility.Raii.ImRaii; +using System.Reflection; +using Action = System.Action; +using RotationSolver.Basic.Data; +using System; namespace RotationSolver.ActionSequencer; internal static class ConditionHelper { - public static bool CheckBaseAction(ICustomRotation rotation, ActionID id, ref IBaseAction action) + internal static void DrawCondition(bool? tag) { - if (id != ActionID.None && (action == null || (ActionID)action.ID != id)) + float size = ConditionHelper.IconSize * (1 + 8 / 82); + + if (!tag.HasValue) { - action = rotation.AllBaseActions.FirstOrDefault(a => (ActionID)a.ID == id); + if (IconSet.GetTexture("ui/uld/image2.tex", out var texture) || IconSet.GetTexture(0u, out texture)) + { + ImGui.Image(texture.ImGuiHandle, Vector2.One * size); + } + } + else + { + if (IconSet.GetTexture("ui/uld/readycheck_hr1.tex", out var texture)) + { + ImGui.Image(texture.ImGuiHandle, Vector2.One * size, + new Vector2(tag.Value ? 0 : 0.5f, 0), + new Vector2(tag.Value ? 0.5f : 1, 1)); + } } - if (action == null || !Player.Available) return false; - return true; } public static void CheckMemberInfo(ICustomRotation rotation, ref string name, ref T value) where T : MemberInfo @@ -162,4 +182,661 @@ public static void ActionSelectorPopUp(string popUpId, CollapsingHeaderGroup gro ImGui.EndPopup(); } } + + #region Draw + public static void Draw(this ICondition condition, ICustomRotation rotation) + { + condition.CheckBefore(rotation); + + condition.DrawBefore(); + + if (condition is DelayCondition delay) delay.DrawDelay(); + + ImGui.SameLine(); + + condition.DrawAfter(rotation); + } + + private static void DrawDelay(this DelayCondition condition) + { + const float MIN = 0, MAX = 60; + + ImGui.SetNextItemWidth(80 * ImGuiHelpers.GlobalScale); + if (ImGui.DragFloatRange2($"##Random Delay {condition.GetHashCode()}", ref condition.DelayMin, ref condition.DelayMax, 0.1f, MIN, MAX)) + { + condition.DelayMin = Math.Max(Math.Min(condition.DelayMin, condition.DelayMax), MIN); + condition.DelayMax = Math.Min(Math.Max(condition.DelayMin, condition.DelayMax), MAX); + } + ImguiTooltips.HoveredTooltip(LocalizationManager.RightLang.ActionSequencer_Delay_Description); + } + + private static void DrawBefore(this ICondition condition) + { + if(condition is ConditionSet) + { + ImGui.BeginGroup(); + } + } + + private static void DrawAfter(this ICondition condition, ICustomRotation rotation) + { + switch (condition) + { + case TraitCondition traitCondition: + traitCondition.DrawAfter(rotation); + break; + + case ActionCondition actionCondition: + actionCondition.DrawAfter(rotation); + break; + + case ConditionSet conditionSet: + conditionSet.DrawAfter(rotation); + break; + + case RotationCondition rotationCondition: + rotationCondition.DrawAfter(rotation); + break; + + case TargetCondition targetCondition: + targetCondition.DrawAfter(rotation); + break; + } + } + + private static void DrawAfter(this TraitCondition traitCondition, ICustomRotation rotation) + { + var name = traitCondition._trait?.Name ?? string.Empty; + var popUpKey = "Trait Condition Pop Up" + traitCondition.GetHashCode().ToString(); + + if (ImGui.BeginPopup(popUpKey)) + { + var index = 0; + foreach (var trait in rotation.AllTraits) + { + if (!trait.GetTexture(out var traitIcon)) continue; + + if (index++ % count != 0) + { + ImGui.SameLine(); + } + + ImGui.BeginGroup(); + var cursor = ImGui.GetCursorPos(); + if (ImGuiHelper.NoPaddingNoColorImageButton(traitIcon.ImGuiHandle, Vector2.One * ConditionHelper.IconSize, trait.GetHashCode().ToString())) + { + traitCondition.TraitID = trait.ID; + ImGui.CloseCurrentPopup(); + } + ImGuiHelper.DrawActionOverlay(cursor, ConditionHelper.IconSize, -1); + ImGui.EndGroup(); + + var tooltip = trait.Name; + if (!string.IsNullOrEmpty(tooltip)) ImguiTooltips.HoveredTooltip(tooltip); + + } + ImGui.EndPopup(); + } + + if (traitCondition._trait?.GetTexture(out var icon) ?? false || IconSet.GetTexture(4, out icon)) + { + var cursor = ImGui.GetCursorPos(); + if (ImGuiHelper.NoPaddingNoColorImageButton(icon.ImGuiHandle, Vector2.One * ConditionHelper.IconSize, traitCondition.GetHashCode().ToString())) + { + if (!ImGui.IsPopupOpen(popUpKey)) ImGui.OpenPopup(popUpKey); + } + ImGuiHelper.DrawActionOverlay(cursor, ConditionHelper.IconSize, -1); + ImguiTooltips.HoveredTooltip(name); + } + + ImGui.SameLine(); + var i = 0; + ImGuiHelper.SelectableCombo($"##Category{traitCondition.GetHashCode()}", new string[] + { + LocalizationManager.RightLang.ActionConditionType_EnoughLevel + }, ref i); + ImGui.SameLine(); + + var condition = traitCondition.Condition ? 1 : 0; + if (ImGuiHelper.SelectableCombo($"##Comparation{traitCondition.GetHashCode()}", new string[] + { + LocalizationManager.RightLang.ActionSequencer_Is, + LocalizationManager.RightLang.ActionSequencer_Isnot, + }, ref condition)) + { + traitCondition.Condition = condition > 0; + } + + } + + private static readonly CollapsingHeaderGroup _actionsList = new() + { + HeaderSize = 12, + }; + static string searchTxt = string.Empty; + + private static void DrawAfter(this ActionCondition actionCondition, ICustomRotation rotation) + { + var name = actionCondition._action?.Name ?? string.Empty; + var popUpKey = "Action Condition Pop Up" + actionCondition.GetHashCode().ToString(); + + ActionSelectorPopUp(popUpKey, _actionsList, rotation, item => actionCondition.ID = (ActionID)item.ID); + + if (actionCondition._action?.GetTexture(out var icon) ?? false || IconSet.GetTexture(4, out icon)) + { + var cursor = ImGui.GetCursorPos(); + if (ImGuiHelper.NoPaddingNoColorImageButton(icon.ImGuiHandle, Vector2.One * IconSize, actionCondition.GetHashCode().ToString())) + { + if (!ImGui.IsPopupOpen(popUpKey)) ImGui.OpenPopup(popUpKey); + } + ImGuiHelper.DrawActionOverlay(cursor, IconSize, 1); + ImguiTooltips.HoveredTooltip(name); + } + + ImGui.SameLine(); + + DrawByteEnum($"##Category{actionCondition.GetHashCode()}", ref actionCondition.ActionConditionType, EnumTranslations.ToName); + + var condition = actionCondition.Condition ? 1 : 0; + var combos = Array.Empty(); + switch (actionCondition.ActionConditionType) + { + case ActionConditionType.ElapsedGCD: + case ActionConditionType.RemainGCD: + case ActionConditionType.Elapsed: + case ActionConditionType.Remain: + case ActionConditionType.CurrentCharges: + case ActionConditionType.MaxCharges: + combos = new string[] { ">", "<=" }; + break; + + case ActionConditionType.CanUse: + combos = new string[] + { + LocalizationManager.RightLang.ActionSequencer_Can, + LocalizationManager.RightLang.ActionSequencer_Cannot, + }; + break; + + case ActionConditionType.EnoughLevel: + case ActionConditionType.IsCoolDown: + combos = new string[] + { + LocalizationManager.RightLang.ActionSequencer_Is, + LocalizationManager.RightLang.ActionSequencer_Isnot, + }; + break; + } + ImGui.SameLine(); + + if (ImGuiHelper.SelectableCombo($"##Comparation{actionCondition.GetHashCode()}", combos, ref condition)) + { + actionCondition.Condition = condition > 0; + } + + + switch (actionCondition.ActionConditionType) + { + case ActionConditionType.Elapsed: + case ActionConditionType.Remain: + DrawDragFloat($"s##Seconds{actionCondition.GetHashCode()}", ref actionCondition.Time); + break; + + case ActionConditionType.ElapsedGCD: + case ActionConditionType.RemainGCD: + if (DrawDragInt($"GCD##GCD{actionCondition.GetHashCode()}", ref actionCondition.Param1)) + { + actionCondition.Param1 = Math.Max(0, actionCondition.Param1); + } + if (ConditionHelper.DrawDragInt($"{LocalizationManager.RightLang.ActionSequencer_TimeOffset}##Ability{actionCondition.GetHashCode()}", ref actionCondition.Param2)) + { + actionCondition.Param2 = Math.Max(0, actionCondition.Param2); + } + break; + + case ActionConditionType.CanUse: + var popUpId = "Can Use Id" + actionCondition.GetHashCode().ToString(); + var option = (CanUseOption)actionCondition.Param1; + + if (ImGui.Selectable($"{option}##CanUse{actionCondition.GetHashCode()}")) + { + if (!ImGui.IsPopupOpen(popUpId)) ImGui.OpenPopup(popUpId); + } + + if (ImGui.BeginPopup(popUpId)) + { + var showedValues = Enum.GetValues().Where(i => i.GetAttribute() == null); + + foreach (var value in showedValues) + { + var b = option.HasFlag(value); + if (ImGui.Checkbox(value.ToString(), ref b)) + { + option ^= value; + actionCondition.Param1 = (int)option; + } + } + + ImGui.EndPopup(); + } + + if (DrawDragInt($"{LocalizationManager.RightLang.ActionSequencer_AOECount}##AOECount{actionCondition.GetHashCode()}", ref actionCondition.Param2)) + { + actionCondition.Param2 = Math.Max(0, actionCondition.Param2); + } + break; + + case ActionConditionType.CurrentCharges: + case ActionConditionType.MaxCharges: + if (ConditionHelper.DrawDragInt($"{LocalizationManager.RightLang.ActionSequencer_Charges}##Charges{actionCondition.GetHashCode()}", ref actionCondition.Param1)) + { + actionCondition.Param1 = Math.Max(0, actionCondition.Param1); + } + break; + } + + } + + private static void DrawAfter(this ConditionSet conditionSet, ICustomRotation rotation) + { + AddButton(); + + ImGui.SameLine(); + + DrawByteEnum($"##Rule{conditionSet.GetHashCode()}", ref conditionSet.Type, t => t switch + { + LogicalType.And => "&&", + LogicalType.Or => " | | ", + LogicalType.NotAnd => "! &&", + LogicalType.NotOr => "! | | ", + _ => string.Empty, + }); + + ImGui.Spacing(); + + for (int i = 0; i < conditionSet.Conditions.Count; i++) + { + ICondition condition = conditionSet.Conditions[i]; + + void Delete() + { + conditionSet.Conditions.RemoveAt(i); + }; + + void Up() + { + conditionSet.Conditions.RemoveAt(i); + conditionSet.Conditions.Insert(Math.Max(0, i - 1), condition); + }; + void Down() + { + conditionSet.Conditions.RemoveAt(i); + conditionSet.Conditions.Insert(Math.Min(conditionSet.Conditions.Count, i + 1), condition); + } + + var key = $"Condition Pop Up: {condition.GetHashCode()}"; + + ImGuiHelper.DrawHotKeysPopup(key, string.Empty, + (LocalizationManager.RightLang.ConfigWindow_List_Remove, Delete, new string[] { "Delete" }), + (LocalizationManager.RightLang.ConfigWindow_Actions_MoveUp, Up, new string[] { "↑" }), + (LocalizationManager.RightLang.ConfigWindow_Actions_MoveDown, Down, new string[] { "↓" })); + + DrawCondition(condition.IsTrue(rotation)); + + ImGuiHelper.ExecuteHotKeysPopup(key, string.Empty, string.Empty, true, + (Delete, new VirtualKey[] { VirtualKey.DELETE }), + (Up, new VirtualKey[] { VirtualKey.UP }), + (Down, new VirtualKey[] { VirtualKey.DOWN })); + + ImGui.SameLine(); + + condition.Draw(rotation); + } + + ImGui.EndGroup(); + + void AddButton() + { + if (ImGuiEx.IconButton(FontAwesomeIcon.Plus, "AddButton" + conditionSet.GetHashCode().ToString())) + { + ImGui.OpenPopup("Popup" + conditionSet.GetHashCode().ToString()); + } + + if (ImGui.BeginPopup("Popup" + conditionSet.GetHashCode().ToString())) + { + AddOneCondition(LocalizationManager.RightLang.ActionSequencer_ConditionSet); + AddOneCondition(LocalizationManager.RightLang.ActionSequencer_ActionCondition); + AddOneCondition(LocalizationManager.RightLang.ActionSequencer_TraitCondition); + AddOneCondition(LocalizationManager.RightLang.ActionSequencer_TargetCondition); + AddOneCondition(LocalizationManager.RightLang.ActionSequencer_RotationCondition); + + ImGui.EndPopup(); + } + + void AddOneCondition(string name) where T : ICondition + { + if (ImGui.Selectable(name)) + { + conditionSet.Conditions.Add(Activator.CreateInstance()); + ImGui.CloseCurrentPopup(); + } + } + } + } + + private static void DrawAfter(this RotationCondition rotationCondition, ICustomRotation rotation) + { + DrawByteEnum($"##Category{rotationCondition.GetHashCode()}", ref rotationCondition.ComboConditionType, EnumTranslations.ToName); + + switch (rotationCondition.ComboConditionType) + { + case ComboConditionType.Bool: + ImGui.SameLine(); + SearchItemsReflection($"##Comparation{rotationCondition.GetHashCode()}", rotationCondition._prop?.GetMemberName(), ref searchTxt, rotation.AllBools, i => + { + rotationCondition._prop = i; + rotationCondition.PropertyName = i.Name; + }); + ImGui.SameLine(); + + ImGuiHelper.SelectableCombo($"##IsOrNot{rotationCondition.GetHashCode()}", new string[] + { + LocalizationManager.RightLang.ActionSequencer_Is, + LocalizationManager.RightLang.ActionSequencer_Isnot, + }, ref rotationCondition.Condition); + + break; + + case ComboConditionType.Integer: + ImGui.SameLine(); + ConditionHelper.SearchItemsReflection($"##ByteChoice{rotationCondition.GetHashCode()}", rotationCondition._prop?.GetMemberName(), ref searchTxt, rotation.AllBytesOrInt, i => + { + rotationCondition._prop = i; + rotationCondition.PropertyName = i.Name; + }); + + ImGui.SameLine(); + + ImGuiHelper.SelectableCombo($"##Comparation{rotationCondition.GetHashCode()}", new string[] { ">", "<", "=" }, ref rotationCondition.Condition); + + ImGui.SameLine(); + ImGui.SetNextItemWidth(50); + + ImGui.DragInt($"##Value{rotationCondition.GetHashCode()}", ref rotationCondition.Param1); + + break; + case ComboConditionType.Float: + ImGui.SameLine(); + SearchItemsReflection($"##FloatChoice{rotationCondition.GetHashCode()}", rotationCondition._prop?.GetMemberName(), ref searchTxt, rotation.AllFloats, i => + { + rotationCondition._prop = i; + rotationCondition.PropertyName = i.Name; + }); + + ImGui.SameLine(); + ImGuiHelper.SelectableCombo($"##Comparation{rotationCondition.GetHashCode()}", new string[] { ">", "<", "=" }, ref rotationCondition.Condition); + + ImGui.SameLine(); + ImGui.SetNextItemWidth(50); + + ImGui.DragFloat($"##Value{rotationCondition.GetHashCode()}", ref rotationCondition.Param2); + + break; + + case ComboConditionType.Last: + ImGui.SameLine(); + + var names = new string[] + { + nameof(CustomRotation.IsLastGCD), + nameof(CustomRotation.IsLastAction), + nameof(CustomRotation.IsLastAbility), + }; + var index = Math.Max(0, Array.IndexOf(names, rotationCondition.MethodName)); + if (ImGuiHelper.SelectableCombo($"##Last{rotationCondition.GetHashCode()}", names, ref index)) + { + rotationCondition.MethodName = names[index]; + } + + ImGui.SameLine(); + + ImGuiHelper.SelectableCombo($"##IsNot{rotationCondition.GetHashCode()}", new string[] + { + LocalizationManager.RightLang.ActionSequencer_Is, + LocalizationManager.RightLang.ActionSequencer_Isnot, + }, ref rotationCondition.Condition); + + ImGui.SameLine(); + + var name = rotationCondition._action?.Name ?? string.Empty; + + var popUpKey = "Rotation Condition Pop Up" + rotationCondition.GetHashCode().ToString(); + + ActionSelectorPopUp(popUpKey, _actionsList, rotation, item => rotationCondition.ID = (ActionID)item.ID); + + if (rotationCondition._action?.GetTexture(out var icon) ?? false || IconSet.GetTexture(4, out icon)) + { + var cursor = ImGui.GetCursorPos(); + if (ImGuiHelper.NoPaddingNoColorImageButton(icon.ImGuiHandle, Vector2.One * IconSize, rotationCondition.GetHashCode().ToString())) + { + if (!ImGui.IsPopupOpen(popUpKey)) ImGui.OpenPopup(popUpKey); + } + ImGuiHelper.DrawActionOverlay(cursor, IconSize, 1); + } + + ImGui.SameLine(); + ImGuiHelper.SelectableCombo($"##Adjust{rotationCondition.GetHashCode()}", new string[] + { + LocalizationManager.RightLang.ActionSequencer_Original, + LocalizationManager.RightLang.ActionSequencer_Adjusted, + }, ref rotationCondition.Param1); + break; + } + } + + private static Status[] _allStatus = null; + private static Status[] AllStatus + { + get + { + _allStatus ??= Enum.GetValues().Select(id => Service.GetSheet().GetRow((uint)id)).ToArray(); + return _allStatus; + } + } + private static void DrawAfter(this TargetCondition targetCondition, ICustomRotation rotation) + { + DelayCondition.CheckBaseAction(rotation, targetCondition.ID, ref targetCondition._action); + + if (targetCondition.StatusId != StatusID.None && + (targetCondition.Status == null || targetCondition.Status.RowId != (uint)targetCondition.StatusId)) + { + targetCondition.Status = AllStatus.FirstOrDefault(a => a.RowId == (uint)targetCondition.StatusId); + } + + var popUpKey = "Target Condition Pop Up" + targetCondition.GetHashCode().ToString(); + + ActionSelectorPopUp(popUpKey, _actionsList, rotation, item => targetCondition.ID = (ActionID)item.ID, () => + { + if (ImGui.Selectable(LocalizationManager.RightLang.ActionSequencer_Target)) + { + targetCondition._action = null; + targetCondition.ID = ActionID.None; + targetCondition.IsTarget = true; + } + + if (ImGui.Selectable(LocalizationManager.RightLang.ActionSequencer_Player)) + { + targetCondition._action = null; + targetCondition.ID = ActionID.None; + targetCondition.IsTarget = false; + } + }); + + if (targetCondition._action != null ? (targetCondition._action.GetTexture(out var icon) || IconSet.GetTexture(4, out icon)) + : IconSet.GetTexture(targetCondition.IsTarget ? 16u : 18u, out icon)) + { + var cursor = ImGui.GetCursorPos(); + if (ImGuiHelper.NoPaddingNoColorImageButton(icon.ImGuiHandle, Vector2.One * IconSize, targetCondition.GetHashCode().ToString())) + { + if (!ImGui.IsPopupOpen(popUpKey)) ImGui.OpenPopup(popUpKey); + } + ImGuiHelper.DrawActionOverlay(cursor, IconSize, 1); + + var description = targetCondition._action != null ? string.Format(LocalizationManager.RightLang.ActionSequencer_ActionTarget, targetCondition._action.Name) + : targetCondition.IsTarget + ? LocalizationManager.RightLang.ActionSequencer_Target + : LocalizationManager.RightLang.ActionSequencer_Player; + ImguiTooltips.HoveredTooltip(description); + } + + ImGui.SameLine(); + DrawByteEnum($"##Category{targetCondition.GetHashCode()}", ref targetCondition.TargetConditionType, EnumTranslations.ToName); + + var condition = targetCondition.Condition ? 1 : 0; + var combos = Array.Empty(); + switch (targetCondition.TargetConditionType) + { + case TargetConditionType.HasStatus: + combos = new string[] + { + LocalizationManager.RightLang.ActionSequencer_Has, + LocalizationManager.RightLang.ActionSequencer_HasNot, + }; + break; + case TargetConditionType.IsDying: + case TargetConditionType.IsBoss: + case TargetConditionType.InCombat: + case TargetConditionType.CastingAction: + combos = new string[] + { + LocalizationManager.RightLang.ActionSequencer_Is, + LocalizationManager.RightLang.ActionSequencer_Isnot, + }; + break; + + case TargetConditionType.CastingActionTimeUntil: + case TargetConditionType.Distance: + case TargetConditionType.StatusEnd: + case TargetConditionType.TimeToKill: + case TargetConditionType.HP: + case TargetConditionType.MP: + combos = new string[] { ">", "<=" }; + break; + } + + ImGui.SameLine(); + + if (ImGuiHelper.SelectableCombo($"##Comparation{targetCondition.GetHashCode()}", combos, ref condition)) + { + targetCondition.Condition = condition > 0; + } + + var popupId = "Status Finding Popup" + targetCondition.GetHashCode().ToString(); + + RotationConfigWindow.StatusPopUp(popupId, AllStatus, ref searchTxt, status => + { + targetCondition.Status = status; + targetCondition.StatusId = (StatusID)targetCondition.Status.RowId; + }, size: IconSizeRaw); + + void DrawStatusIcon() + { + if (IconSet.GetTexture(targetCondition.Status?.Icon ?? 16220, out var icon) + || IconSet.GetTexture(16220, out icon)) + { + if (ImGuiHelper.NoPaddingNoColorImageButton(icon.ImGuiHandle, new Vector2(IconSize * 3 / 4, IconSize) * ImGuiHelpers.GlobalScale, targetCondition.GetHashCode().ToString())) + { + if (!ImGui.IsPopupOpen(popupId)) ImGui.OpenPopup(popupId); + } + ImguiTooltips.HoveredTooltip(targetCondition.Status?.Name ?? string.Empty); + } + } + + switch (targetCondition.TargetConditionType) + { + case TargetConditionType.HasStatus: + ImGui.SameLine(); + DrawStatusIcon(); + + ImGui.SameLine(); + + var check = targetCondition.FromSelf ? 1 : 0; + if (ImGuiHelper.SelectableCombo($"From Self {targetCondition.GetHashCode()}", new string[] + { + LocalizationManager.RightLang.ActionSequencer_StatusAll, + LocalizationManager.RightLang.ActionSequencer_StatusSelf, + }, ref check)) + { + targetCondition.FromSelf = check != 0; + } + break; + + case TargetConditionType.StatusEnd: + ImGui.SameLine(); + DrawStatusIcon(); + + ImGui.SameLine(); + + check = targetCondition.FromSelf ? 1 : 0; + if (ImGuiHelper.SelectableCombo($"From Self {targetCondition.GetHashCode()}", new string[] + { + LocalizationManager.RightLang.ActionSequencer_StatusAll, + LocalizationManager.RightLang.ActionSequencer_StatusSelf, + }, ref check)) + { + targetCondition.FromSelf = check != 0; + } + + ConditionHelper.DrawDragFloat($"s##Seconds{targetCondition.GetHashCode()}", ref targetCondition.DistanceOrTime); + break; + + + case TargetConditionType.StatusEndGCD: + ImGui.SameLine(); + DrawStatusIcon(); + + ImGui.SameLine(); + + check = targetCondition.FromSelf ? 1 : 0; + if (ImGuiHelper.SelectableCombo($"From Self {targetCondition.GetHashCode()}", new string[] + { + LocalizationManager.RightLang.ActionSequencer_StatusAll, + LocalizationManager.RightLang.ActionSequencer_StatusSelf, + }, ref check)) + { + targetCondition.FromSelf = check != 0; + } + + DrawDragInt($"GCD##GCD{targetCondition.GetHashCode()}", ref targetCondition.GCD); + DrawDragFloat($"{LocalizationManager.RightLang.ActionSequencer_TimeOffset}##Ability{targetCondition.GetHashCode()}", ref targetCondition.DistanceOrTime); + break; + + case TargetConditionType.Distance: + if (DrawDragFloat($"yalm##yalm{targetCondition.GetHashCode()}", ref targetCondition.DistanceOrTime)) + { + targetCondition.DistanceOrTime = Math.Max(0, targetCondition.DistanceOrTime); + } + break; + + case TargetConditionType.CastingAction: + ImGui.SameLine(); + ImGuiHelper.SetNextWidthWithName(targetCondition.CastingActionName); + ImGui.InputText($"Ability name##CastingActionName{targetCondition.GetHashCode()}", ref targetCondition.CastingActionName, 128); + break; + + case TargetConditionType.CastingActionTimeUntil: + ImGui.SameLine(); + ImGui.SetNextItemWidth(Math.Max(150 * ImGuiHelpers.GlobalScale, ImGui.CalcTextSize(targetCondition.DistanceOrTime.ToString()).X)); + ImGui.DragFloat($"s##CastingActionTimeUntil{targetCondition.GetHashCode()}", ref targetCondition.DistanceOrTime, .1f); + break; + + case TargetConditionType.MP: + case TargetConditionType.HP: + ImGui.SameLine(); + ImGui.SetNextItemWidth(Math.Max(150 * ImGuiHelpers.GlobalScale, ImGui.CalcTextSize(targetCondition.GCD.ToString()).X)); + ImGui.DragInt($"##HPorMP{targetCondition.GetHashCode()}", ref targetCondition.GCD, .1f); + break; + } + } + #endregion } diff --git a/RotationSolver/ActionSequencer/ConditionSet.cs b/RotationSolver/ActionSequencer/ConditionSet.cs deleted file mode 100644 index ff669901e..000000000 --- a/RotationSolver/ActionSequencer/ConditionSet.cs +++ /dev/null @@ -1,150 +0,0 @@ -using Dalamud.Game.ClientState.Keys; -using ECommons.ImGuiMethods; -using RotationSolver.Localization; -using RotationSolver.UI; - -namespace RotationSolver.ActionSequencer; - -internal class ConditionSet : BaseCondition -{ - public override bool IsTrueInside(ICustomRotation rotation) - { - if (Conditions.Count == 0) return false; - switch (Type) - { - case LogicalType.And: - return Conditions.All(c => c.IsTrue(rotation)); - case LogicalType.Or: - return Conditions.Any(c => c.IsTrue(rotation)); - case LogicalType.NotAnd: - return !Conditions.All(c => c.IsTrue(rotation)); - case LogicalType.NotOr: - return !Conditions.Any(c => c.IsTrue(rotation)); - } - return false; - } - public List Conditions { get; set; } = new List(); - public LogicalType Type; - - public override void BeforeDraw() - { - ImGui.BeginGroup(); - } - - public override void DrawInside(ICustomRotation rotation) - { - AddButton(); - - ImGui.SameLine(); - - ConditionHelper.DrawByteEnum($"##Rule{GetHashCode()}", ref Type, t => t switch - { - LogicalType.And => "&&", - LogicalType.Or => " | | ", - LogicalType.NotAnd => "! &&", - LogicalType.NotOr => "! | | ", - _ => string.Empty, - }); - - ImGui.Spacing(); - - for(int i = 0; i < Conditions.Count; i++) - { - ICondition condition = Conditions[i]; - - void Delete() - { - Conditions.RemoveAt(i); - }; - - void Up() - { - Conditions.RemoveAt(i); - Conditions.Insert(Math.Max(0, i - 1), condition); - }; - void Down() - { - Conditions.RemoveAt(i); - Conditions.Insert(Math.Min(Conditions.Count, i + 1), condition); - } - - var key = $"Condition Pop Up: {condition.GetHashCode()}"; - - ImGuiHelper.DrawHotKeysPopup(key, string.Empty, - (LocalizationManager.RightLang.ConfigWindow_List_Remove, Delete, new string[] { "Delete" }), - (LocalizationManager.RightLang.ConfigWindow_Actions_MoveUp, Up, new string[] { "↑" }), - (LocalizationManager.RightLang.ConfigWindow_Actions_MoveDown, Down, new string[] { "↓" })); - - DrawCondition(condition.IsTrue(rotation)); - - ImGuiHelper.ExecuteHotKeysPopup(key, string.Empty, string.Empty, true, - (Delete, new VirtualKey[] { VirtualKey.DELETE }), - (Up, new VirtualKey[] { VirtualKey.UP }), - (Down, new VirtualKey[] { VirtualKey.DOWN })); - - ImGui.SameLine(); - - condition.Draw(rotation); - } - - ImGui.EndGroup(); - } - - private void AddButton() - { - if (ImGuiEx.IconButton(FontAwesomeIcon.Plus, "AddButton" + GetHashCode().ToString())) - { - ImGui.OpenPopup("Popup" + GetHashCode().ToString()); - } - - if (ImGui.BeginPopup("Popup" + GetHashCode().ToString())) - { - AddOneCondition(LocalizationManager.RightLang.ActionSequencer_ConditionSet); - AddOneCondition(LocalizationManager.RightLang.ActionSequencer_ActionCondition); - AddOneCondition(LocalizationManager.RightLang.ActionSequencer_TraitCondition); - AddOneCondition(LocalizationManager.RightLang.ActionSequencer_TargetCondition); - AddOneCondition(LocalizationManager.RightLang.ActionSequencer_RotationCondition); - - ImGui.EndPopup(); - } - } - - private void AddOneCondition(string name) where T : ICondition - { - if (ImGui.Selectable(name)) - { - Conditions.Add(Activator.CreateInstance()); - ImGui.CloseCurrentPopup(); - } - } - - internal static void DrawCondition(bool? tag) - { - float size = ConditionHelper.IconSize * (1 + 8 / 82); - - if (!tag.HasValue) - { - if (IconSet.GetTexture("ui/uld/image2.tex", out var texture) || IconSet.GetTexture(0u, out texture)) - { - ImGui.Image(texture.ImGuiHandle, Vector2.One * size); - } - } - else - { - if (IconSet.GetTexture("ui/uld/readycheck_hr1.tex", out var texture)) - { - ImGui.Image(texture.ImGuiHandle, Vector2.One * size, - new Vector2(tag.Value ? 0 : 0.5f, 0), - new Vector2(tag.Value ? 0.5f : 1, 1)); - } - } - } -} - -public enum LogicalType: byte -{ - And, - Or, - NotAnd, - NotOr, -} diff --git a/RotationSolver/ActionSequencer/MajorConditionSet.cs b/RotationSolver/ActionSequencer/MajorConditionSet.cs index 3a28dce88..56a7856b5 100644 --- a/RotationSolver/ActionSequencer/MajorConditionSet.cs +++ b/RotationSolver/ActionSequencer/MajorConditionSet.cs @@ -1,6 +1,4 @@ using ECommons.DalamudServices; -using Lumina.Data.Parsing; -using static FFXIVClientStructs.FFXIV.Client.UI.AddonAOZNotebook; namespace RotationSolver.ActionSequencer; @@ -16,7 +14,6 @@ internal class MajorConditionSet public string Name; public void DrawCondition(uint id, ICustomRotation rotation) { - if (!Conditions.TryGetValue(id, out var conditionSet)) { conditionSet = Conditions[id] = new ConditionSet(); @@ -24,7 +21,7 @@ public void DrawCondition(uint id, ICustomRotation rotation) if (conditionSet == null) return; - ConditionSet.DrawCondition(conditionSet.IsTrue(rotation)); + ConditionHelper.DrawCondition(conditionSet.IsTrue(rotation)); ImGui.SameLine(); conditionSet?.Draw(rotation); } @@ -37,7 +34,7 @@ public void DrawDisabledCondition(uint id, ICustomRotation rotation) } if (conditionSet == null) return; - ConditionSet.DrawCondition(conditionSet.IsTrue(rotation)); + ConditionHelper.DrawCondition(conditionSet.IsTrue(rotation)); ImGui.SameLine(); conditionSet?.Draw(rotation); } diff --git a/RotationSolver/ActionSequencer/RotationCondition.cs b/RotationSolver/ActionSequencer/RotationCondition.cs deleted file mode 100644 index 6a4e41119..000000000 --- a/RotationSolver/ActionSequencer/RotationCondition.cs +++ /dev/null @@ -1,236 +0,0 @@ -using Dalamud.Logging; -using ECommons.GameHelpers; -using RotationSolver.Localization; -using RotationSolver.UI; - -namespace RotationSolver.ActionSequencer; - -internal class RotationCondition : BaseCondition -{ - public ComboConditionType ComboConditionType = ComboConditionType.Float; - PropertyInfo _prop; - public string PropertyName = nameof(CustomRotation.CombatTime); - - MethodInfo _method; - public string MethodName = string.Empty; - - IBaseAction _action; - public ActionID ID { get; set; } = ActionID.None; - - public int Condition; - - public int Param1; - public float Param2; - - private void UpdateInfo(ICustomRotation rotation) - { - ConditionHelper.CheckBaseAction(rotation, ID, ref _action); - ConditionHelper.CheckMemberInfo(rotation, ref PropertyName, ref _prop); - ConditionHelper.CheckMemberInfo(rotation, ref MethodName, ref _method); - } - - public override bool IsTrueInside(ICustomRotation rotation) - { - if (!Player.Available) return false; - UpdateInfo(rotation); - - switch (ComboConditionType) - { - case ComboConditionType.Bool: - if (_prop == null) return false; - if (_prop.GetValue(rotation) is bool b) - { - return Condition > 0 ? !b : b; - } - return false; - - case ComboConditionType.Integer: - if (_prop == null) return false; - - var value = _prop.GetValue(rotation); - if (value is byte by) - { - switch (Condition) - { - case 0: - return by > Param1; - case 1: - return by < Param1; - case 2: - return by == Param1; - } - } - else if (value is int i) - { - switch (Condition) - { - case 0: - return i > Param1; - case 1: - return i < Param1; - case 2: - return i == Param1; - } - } - return false; - - case ComboConditionType.Float: - if (_prop == null) return false; - if (_prop.GetValue(rotation) is float fl) - { - switch (Condition) - { - case 0: - return fl > Param2; - case 1: - return fl < Param2; - case 2: - return fl == Param2; - } - } - return false; - - case ComboConditionType.Last: - try - { - if (_method?.Invoke(rotation, new object[] { Param1 > 0, new IAction[] { _action } }) is bool boo) - { - return Condition > 0 ? !boo : boo; - } - return false; - } - catch - { - return false; - } - } - - return false; - } - - string searchTxt = string.Empty; - - private readonly CollapsingHeaderGroup _actionsList = new() - { - HeaderSize = 12, - }; - public override void DrawInside(ICustomRotation rotation) - { - UpdateInfo(rotation); - - ConditionHelper.DrawByteEnum($"##Category{GetHashCode()}", ref ComboConditionType, EnumTranslations.ToName); - - switch (ComboConditionType) - { - case ComboConditionType.Bool: - ImGui.SameLine(); - ConditionHelper.SearchItemsReflection($"##Comparation{GetHashCode()}", _prop?.GetMemberName(), ref searchTxt, rotation.AllBools, i => - { - _prop = i; - PropertyName = i.Name; - }); - ImGui.SameLine(); - - ImGuiHelper.SelectableCombo($"##IsOrNot{GetHashCode()}", new string[] - { - LocalizationManager.RightLang.ActionSequencer_Is, - LocalizationManager.RightLang.ActionSequencer_Isnot, - }, ref Condition); - - break; - - case ComboConditionType.Integer: - ImGui.SameLine(); - ConditionHelper.SearchItemsReflection($"##ByteChoice{GetHashCode()}", _prop?.GetMemberName(), ref searchTxt, rotation.AllBytesOrInt, i => - { - _prop = i; - PropertyName = i.Name; - }); - - ImGui.SameLine(); - - ImGuiHelper.SelectableCombo($"##Comparation{GetHashCode()}", new string[] { ">", "<", "=" }, ref Condition); - - ImGui.SameLine(); - ImGui.SetNextItemWidth(50); - - ImGui.DragInt($"##Value{GetHashCode()}", ref Param1); - - break; - case ComboConditionType.Float: - ImGui.SameLine(); - ConditionHelper.SearchItemsReflection($"##FloatChoice{GetHashCode()}", _prop?.GetMemberName(), ref searchTxt, rotation.AllFloats, i => - { - _prop = i; - PropertyName = i.Name; - }); - - ImGui.SameLine(); - ImGuiHelper.SelectableCombo($"##Comparation{GetHashCode()}", new string[] { ">", "<", "=" }, ref Condition); - - ImGui.SameLine(); - ImGui.SetNextItemWidth(50); - - ImGui.DragFloat($"##Value{GetHashCode()}", ref Param2); - - break; - - case ComboConditionType.Last: - ImGui.SameLine(); - - var names = new string[] - { - nameof(CustomRotation.IsLastGCD), - nameof(CustomRotation.IsLastAction), - nameof(CustomRotation.IsLastAbility), - }; - var index = Math.Max(0, Array.IndexOf(names, MethodName)); - if(ImGuiHelper.SelectableCombo($"##Last{GetHashCode()}", names, ref index)) - { - MethodName = names[index]; - } - - ImGui.SameLine(); - - ImGuiHelper.SelectableCombo($"##IsNot{GetHashCode()}", new string[] - { - LocalizationManager.RightLang.ActionSequencer_Is, - LocalizationManager.RightLang.ActionSequencer_Isnot, - }, ref Condition); - - ImGui.SameLine(); - - var name = _action?.Name ?? string.Empty; - - var popUpKey = "Rotation Condition Pop Up" + GetHashCode().ToString(); - - ConditionHelper.ActionSelectorPopUp(popUpKey, _actionsList, rotation, item => ID = (ActionID)item.ID); - - if (_action?.GetTexture(out var icon) ?? false || IconSet.GetTexture(4, out icon)) - { - var cursor = ImGui.GetCursorPos(); - if (ImGuiHelper.NoPaddingNoColorImageButton(icon.ImGuiHandle, Vector2.One * ConditionHelper.IconSize, GetHashCode().ToString())) - { - if (!ImGui.IsPopupOpen(popUpKey)) ImGui.OpenPopup(popUpKey); - } - ImGuiHelper.DrawActionOverlay(cursor, ConditionHelper.IconSize, 1); - } - - ImGui.SameLine(); - ImGuiHelper.SelectableCombo($"##Adjust{GetHashCode()}", new string[] - { - LocalizationManager.RightLang.ActionSequencer_Original, - LocalizationManager.RightLang.ActionSequencer_Adjusted, - }, ref Param1); - break; - } - } -} - -public enum ComboConditionType : byte -{ - Bool, - Integer, - Float, - Last, -} diff --git a/RotationSolver/ActionSequencer/TargetCondition.cs b/RotationSolver/ActionSequencer/TargetCondition.cs deleted file mode 100644 index 0b5155881..000000000 --- a/RotationSolver/ActionSequencer/TargetCondition.cs +++ /dev/null @@ -1,344 +0,0 @@ -using Dalamud.Interface.Utility; -using ECommons.DalamudServices; -using ECommons.GameHelpers; -using Lumina.Excel.GeneratedSheets; -using RotationSolver.Localization; -using RotationSolver.UI; - -namespace RotationSolver.ActionSequencer; - -internal class TargetCondition : BaseCondition -{ - private static Status[] _allStatus = null; - private static Status[] AllStatus - { - get - { - _allStatus ??= Enum.GetValues().Select(id => Service.GetSheet().GetRow((uint)id)).ToArray(); - return _allStatus; - } - } - - private IBaseAction _action; - public ActionID ID { get; set; } = ActionID.None; - - public bool Condition; - public bool FromSelf; - private Status Status { get; set; } - public StatusID StatusId { get; set; } - public bool IsTarget; - public TargetConditionType TargetConditionType; - - public float DistanceOrTime; - public int GCD; - - public string CastingActionName = string.Empty; - - public override bool IsTrueInside(ICustomRotation rotation) - { - if (!Player.Available) return false; - - BattleChara tar; - if (_action != null) - { - _action.CanUse(out _, CanUseOption.EmptyOrSkipCombo | CanUseOption.MustUse - | CanUseOption.IgnoreTarget); - tar = _action.Target; - } - else - { - tar = IsTarget ? Svc.Targets.Target as BattleChara : Player.Object; - tar ??= Player.Object; - } - - if (tar == null) return false; - - var result = false; - - switch (TargetConditionType) - { - case TargetConditionType.HasStatus: - result = tar.HasStatus(FromSelf, StatusId); - break; - - case TargetConditionType.IsBoss: - result = tar.IsBoss(); - break; - - case TargetConditionType.IsDying: - result = tar.IsDying(); - break; - - case TargetConditionType.InCombat: - result = tar.InCombat(); - break; - - case TargetConditionType.Distance: - result = tar.DistanceToPlayer() > DistanceOrTime; - break; - - case TargetConditionType.StatusEnd: - result = !tar.WillStatusEnd(DistanceOrTime, FromSelf, StatusId); - break; - - case TargetConditionType.StatusEndGCD: - result = !tar.WillStatusEndGCD((uint)GCD, DistanceOrTime, FromSelf, StatusId); - break; - - case TargetConditionType.TimeToKill: - result = tar.GetTimeToKill() > DistanceOrTime; - break; - - case TargetConditionType.CastingAction: - if (string.IsNullOrEmpty(CastingActionName) || tar.CastActionId == 0) - { - result = false; - break; - } - - var castName = Service.GetSheet().GetRow(tar.CastActionId)?.Name.ToString(); - - result = CastingActionName == castName; - break; - - case TargetConditionType.CastingActionTimeUntil: - - if (!tar.IsCasting || tar.CastActionId == 0) - { - result = false; - break; - } - - float castTime = tar.TotalCastTime - tar.CurrentCastTime; - result = castTime > DistanceOrTime + DataCenter.WeaponRemain; - break; - - case TargetConditionType.HP: - result = tar.CurrentHp > GCD; - break; - - case TargetConditionType.MP: - result = tar.CurrentMp > GCD; - break; - } - - return Condition ? !result : result; - } - - string searchTxt = string.Empty; - private readonly CollapsingHeaderGroup _actionsList = new() - { - HeaderSize = 12, - }; - - public override void DrawInside(ICustomRotation rotation) - { - ConditionHelper.CheckBaseAction(rotation, ID, ref _action); - - if (StatusId != StatusID.None && (Status == null || Status.RowId != (uint)StatusId)) - { - Status = AllStatus.FirstOrDefault(a => a.RowId == (uint) StatusId); - } - - var popUpKey = "Target Condition Pop Up" + GetHashCode().ToString(); - - ConditionHelper.ActionSelectorPopUp(popUpKey, _actionsList, rotation, item => ID = (ActionID)item.ID, ()=> - { - if (ImGui.Selectable(LocalizationManager.RightLang.ActionSequencer_Target)) - { - _action = null; - ID = ActionID.None; - IsTarget = true; - } - - if (ImGui.Selectable(LocalizationManager.RightLang.ActionSequencer_Player)) - { - _action = null; - ID = ActionID.None; - IsTarget = false; - } - }); - - if (_action != null ? ( _action.GetTexture(out var icon) || IconSet.GetTexture(4, out icon)) - : IconSet.GetTexture(IsTarget ? 16u : 18u, out icon)) - { - var cursor = ImGui.GetCursorPos(); - if (ImGuiHelper.NoPaddingNoColorImageButton(icon.ImGuiHandle, Vector2.One * ConditionHelper.IconSize, GetHashCode().ToString())) - { - if (!ImGui.IsPopupOpen(popUpKey)) ImGui.OpenPopup(popUpKey); - } - ImGuiHelper.DrawActionOverlay(cursor, ConditionHelper.IconSize, 1); - - var description = _action != null ? string.Format(LocalizationManager.RightLang.ActionSequencer_ActionTarget, _action.Name) - : IsTarget - ? LocalizationManager.RightLang.ActionSequencer_Target - : LocalizationManager.RightLang.ActionSequencer_Player; - ImguiTooltips.HoveredTooltip(description); - } - - ImGui.SameLine(); - ConditionHelper.DrawByteEnum($"##Category{GetHashCode()}", ref TargetConditionType, EnumTranslations.ToName); - - var condition = Condition ? 1 : 0; - var combos = Array.Empty(); - switch (TargetConditionType) - { - case TargetConditionType.HasStatus: - combos = new string[] - { - LocalizationManager.RightLang.ActionSequencer_Has, - LocalizationManager.RightLang.ActionSequencer_HasNot, - }; - break; - case TargetConditionType.IsDying: - case TargetConditionType.IsBoss: - case TargetConditionType.InCombat: - case TargetConditionType.CastingAction: - combos = new string[] - { - LocalizationManager.RightLang.ActionSequencer_Is, - LocalizationManager.RightLang.ActionSequencer_Isnot, - }; - break; - - case TargetConditionType.CastingActionTimeUntil: - case TargetConditionType.Distance: - case TargetConditionType.StatusEnd: - case TargetConditionType.TimeToKill: - case TargetConditionType.HP: - case TargetConditionType.MP: - combos = new string[] { ">", "<=" }; - break; - } - - ImGui.SameLine(); - - if(ImGuiHelper.SelectableCombo($"##Comparation{GetHashCode()}", combos, ref condition)) - { - Condition = condition > 0; - } - - var popupId = "Status Finding Popup" + GetHashCode().ToString(); - - RotationConfigWindow.StatusPopUp(popupId, AllStatus, ref searchTxt, status => - { - Status = status; - StatusId = (StatusID)Status.RowId; - }, size: ConditionHelper.IconSizeRaw); - - void DrawStatusIcon() - { - if (IconSet.GetTexture(Status?.Icon ?? 16220, out var icon) - || IconSet.GetTexture(16220, out icon)) - { - if (ImGuiHelper.NoPaddingNoColorImageButton(icon.ImGuiHandle, new Vector2(ConditionHelper.IconSize * 3 / 4, ConditionHelper.IconSize) * ImGuiHelpers.GlobalScale, GetHashCode().ToString())) - { - if (!ImGui.IsPopupOpen(popupId)) ImGui.OpenPopup(popupId); - } - ImguiTooltips.HoveredTooltip(Status?.Name ?? string.Empty); - } - } - - switch (TargetConditionType) - { - case TargetConditionType.HasStatus: - ImGui.SameLine(); - DrawStatusIcon(); - - ImGui.SameLine(); - - var check = FromSelf ? 1 : 0; - if(ImGuiHelper.SelectableCombo($"From Self {GetHashCode()}", new string[] - { - LocalizationManager.RightLang.ActionSequencer_StatusAll, - LocalizationManager.RightLang.ActionSequencer_StatusSelf, - }, ref check)) - { - FromSelf = check != 0; - } - break; - - case TargetConditionType.StatusEnd: - ImGui.SameLine(); - DrawStatusIcon(); - - ImGui.SameLine(); - - check = FromSelf ? 1 : 0; - if(ImGuiHelper.SelectableCombo($"From Self {GetHashCode()}", new string[] - { - LocalizationManager.RightLang.ActionSequencer_StatusAll, - LocalizationManager.RightLang.ActionSequencer_StatusSelf, - }, ref check)) - { - FromSelf = check != 0; - } - - ConditionHelper.DrawDragFloat($"s##Seconds{GetHashCode()}", ref DistanceOrTime); - break; - - - case TargetConditionType.StatusEndGCD: - ImGui.SameLine(); - DrawStatusIcon(); - - ImGui.SameLine(); - - check = FromSelf ? 1 : 0; - if(ImGuiHelper.SelectableCombo($"From Self {GetHashCode()}", new string[] - { - LocalizationManager.RightLang.ActionSequencer_StatusAll, - LocalizationManager.RightLang.ActionSequencer_StatusSelf, - }, ref check)) - { - FromSelf = check != 0; - } - - ConditionHelper.DrawDragInt($"GCD##GCD{GetHashCode()}", ref GCD); - ConditionHelper.DrawDragFloat($"{LocalizationManager.RightLang.ActionSequencer_TimeOffset}##Ability{GetHashCode()}", ref DistanceOrTime); - break; - - case TargetConditionType.Distance: - if (ConditionHelper.DrawDragFloat($"yalm##yalm{GetHashCode()}", ref DistanceOrTime)) - { - DistanceOrTime = Math.Max(0, DistanceOrTime); - } - break; - - case TargetConditionType.CastingAction: - ImGui.SameLine(); - ImGuiHelper.SetNextWidthWithName(CastingActionName); - ImGui.InputText($"Ability name##CastingActionName{GetHashCode()}", ref CastingActionName, 128); - break; - - case TargetConditionType.CastingActionTimeUntil: - ImGui.SameLine(); - ImGui.SetNextItemWidth(Math.Max(150 * ImGuiHelpers.GlobalScale, ImGui.CalcTextSize(DistanceOrTime.ToString()).X)); - ImGui.DragFloat($"s##CastingActionTimeUntil{GetHashCode()}", ref DistanceOrTime, .1f); - break; - - case TargetConditionType.MP: - case TargetConditionType.HP: - ImGui.SameLine(); - ImGui.SetNextItemWidth(Math.Max(150 * ImGuiHelpers.GlobalScale, ImGui.CalcTextSize(GCD.ToString()).X)); - ImGui.DragInt($"##HPorMP{GetHashCode()}", ref GCD, .1f); - break; - } - } -} - -public enum TargetConditionType : byte -{ - HasStatus, - IsDying, - IsBoss, - InCombat, - Distance, - StatusEnd, - StatusEndGCD, - CastingAction, - CastingActionTimeUntil, - TimeToKill, - HP, - MP, -} \ No newline at end of file diff --git a/RotationSolver/ActionSequencer/TraitCondition.cs b/RotationSolver/ActionSequencer/TraitCondition.cs deleted file mode 100644 index a941082c1..000000000 --- a/RotationSolver/ActionSequencer/TraitCondition.cs +++ /dev/null @@ -1,97 +0,0 @@ -using ECommons.GameHelpers; -using RotationSolver.Basic.Traits; -using RotationSolver.Localization; -using RotationSolver.UI; - -namespace RotationSolver.ActionSequencer; - -internal class TraitCondition : BaseCondition -{ - public uint TraitID { get; set; } = 0; - private IBaseTrait _trait; - public bool Condition { get; set; } - - public override bool IsTrueInside(ICustomRotation rotation) - { - CheckBaseTrait(rotation); - if (_trait == null || !Player.Available) return false; - - var result = _trait.EnoughLevel; - return Condition ? !result : result; - } - - private const int count = 8; - public override void DrawInside(ICustomRotation rotation) - { - CheckBaseTrait(rotation); - - var name = _trait?.Name ?? string.Empty; - var popUpKey = "Trait Condition Pop Up" + GetHashCode().ToString(); - - if (ImGui.BeginPopup(popUpKey)) - { - var index = 0; - foreach (var trait in rotation.AllTraits) - { - if (!trait.GetTexture(out var traitIcon)) continue; - - if (index++ % count != 0) - { - ImGui.SameLine(); - } - - ImGui.BeginGroup(); - var cursor = ImGui.GetCursorPos(); - if (ImGuiHelper.NoPaddingNoColorImageButton(traitIcon.ImGuiHandle, Vector2.One * ConditionHelper.IconSize, trait.GetHashCode().ToString())) - { - TraitID = trait.ID; - ImGui.CloseCurrentPopup(); - } - ImGuiHelper.DrawActionOverlay(cursor, ConditionHelper.IconSize, -1); - ImGui.EndGroup(); - - var tooltip = trait.Name; - if (!string.IsNullOrEmpty(tooltip)) ImguiTooltips.HoveredTooltip(tooltip); - - } - ImGui.EndPopup(); - } - - if (_trait?.GetTexture(out var icon) ?? false || IconSet.GetTexture(4, out icon)) - { - var cursor = ImGui.GetCursorPos(); - if (ImGuiHelper.NoPaddingNoColorImageButton(icon.ImGuiHandle, Vector2.One * ConditionHelper.IconSize, GetHashCode().ToString())) - { - if (!ImGui.IsPopupOpen(popUpKey)) ImGui.OpenPopup(popUpKey); - } - ImGuiHelper.DrawActionOverlay(cursor, ConditionHelper.IconSize, -1); - ImguiTooltips.HoveredTooltip(name); - } - - ImGui.SameLine(); - var i = 0; - ImGuiHelper.SelectableCombo($"##Category{GetHashCode()}", new string[] - { - LocalizationManager.RightLang.ActionConditionType_EnoughLevel - }, ref i); - ImGui.SameLine(); - - var condition = Condition ? 1 : 0; - if (ImGuiHelper.SelectableCombo($"##Comparation{GetHashCode()}", new string[] - { - LocalizationManager.RightLang.ActionSequencer_Is, - LocalizationManager.RightLang.ActionSequencer_Isnot, - }, ref condition)) - { - Condition = condition > 0; - } - } - - private void CheckBaseTrait(ICustomRotation rotation) - { - if (TraitID != 0 && (_trait == null || _trait.ID != TraitID)) - { - _trait = rotation.AllTraits.FirstOrDefault(a => a.ID == TraitID); - } - } -} diff --git a/RotationSolver/UI/RotationConfigWindow.cs b/RotationSolver/UI/RotationConfigWindow.cs index 6c783cf0b..dcf961d16 100644 --- a/RotationSolver/UI/RotationConfigWindow.cs +++ b/RotationSolver/UI/RotationConfigWindow.cs @@ -1250,7 +1250,6 @@ private static unsafe void DrawActions() } } - if (_activeAction != null) { var enable = _activeAction.IsEnabled; diff --git a/RotationSolver/Updaters/ActionSequencerUpdater.cs b/RotationSolver/Updaters/ActionSequencerUpdater.cs index 4d9d2e323..e62620ff7 100644 --- a/RotationSolver/Updaters/ActionSequencerUpdater.cs +++ b/RotationSolver/Updaters/ActionSequencerUpdater.cs @@ -1,12 +1,9 @@ using Dalamud.Interface.Colors; -using ECommons.DalamudServices; using ECommons.ImGuiMethods; using RotationSolver.ActionSequencer; using RotationSolver.Basic.Configuration; using RotationSolver.Localization; using RotationSolver.UI; -using System.Diagnostics; -using System.Windows.Forms; namespace RotationSolver.Updaters;