From df1374338dba4741af44dd9eadc4acea97a0f7b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E6=B0=B4?= <1123993881@qq.com> Date: Wed, 6 Mar 2024 11:36:37 +0800 Subject: [PATCH] feat: timeline drawing first commit. --- .../Timeline/CastingOmenConfig.cs | 8 - .../Configuration/Timeline/DrawingTimeline.cs | 153 +----------------- .../ITimelineConditionConverter.cs | 17 ++ .../TimelineCondition/ObjectGetter.cs | 13 ++ .../TimelineDrawing/ActionDrawingGetter.cs | 78 +++++++++ .../TimelineDrawing/IDrawingGetter.cs | 5 + .../IDrawingGetterConverter.cs | 25 +++ .../TimelineDrawing/ObjectDrawingGetter.cs | 70 ++++++++ .../TimelineDrawing/StaticDrawingGetter.cs | 20 +++ .../Timeline/TimelineDrawing/TextDrawing.cs | 45 ++++++ RotationSolver.Basic/Data/TimelineItem.cs | 55 +++++-- RotationSolver/RotationSolverPlugin.cs | 20 +-- RotationSolver/UI/RotationConfigWindow.cs | 93 ++++++++++- RotationSolver/Updaters/ActionUpdater.cs | 4 - RotationSolver/Watcher.cs | 3 - XIVPainter | 2 +- 16 files changed, 415 insertions(+), 196 deletions(-) delete mode 100644 RotationSolver.Basic/Configuration/Timeline/CastingOmenConfig.cs create mode 100644 RotationSolver.Basic/Configuration/Timeline/TimelineCondition/ITimelineConditionConverter.cs create mode 100644 RotationSolver.Basic/Configuration/Timeline/TimelineCondition/ObjectGetter.cs create mode 100644 RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/ActionDrawingGetter.cs create mode 100644 RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/IDrawingGetter.cs create mode 100644 RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/IDrawingGetterConverter.cs create mode 100644 RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/ObjectDrawingGetter.cs create mode 100644 RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/StaticDrawingGetter.cs create mode 100644 RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/TextDrawing.cs diff --git a/RotationSolver.Basic/Configuration/Timeline/CastingOmenConfig.cs b/RotationSolver.Basic/Configuration/Timeline/CastingOmenConfig.cs deleted file mode 100644 index 9cb9c830e..000000000 --- a/RotationSolver.Basic/Configuration/Timeline/CastingOmenConfig.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace RotationSolver.Basic.Configuration.Timeline; -public struct CastingOmenConfig -{ - public string? OmenPath { get; set; } - public float? X { get; set; } - public float? Y { get; set; } - public float? Rotation { get; set; } -} diff --git a/RotationSolver.Basic/Configuration/Timeline/DrawingTimeline.cs b/RotationSolver.Basic/Configuration/Timeline/DrawingTimeline.cs index fce012737..8613f7e5b 100644 --- a/RotationSolver.Basic/Configuration/Timeline/DrawingTimeline.cs +++ b/RotationSolver.Basic/Configuration/Timeline/DrawingTimeline.cs @@ -1,11 +1,5 @@ -using ECommons.Configuration; -using ECommons.DalamudServices; -using ECommons.GameFunctions; -using RotationSolver.Basic.Configuration.Timeline.TimelineCondition; -using XIVPainter; -using XIVPainter.Element; -using XIVPainter.Vfx; -using Action = Lumina.Excel.GeneratedSheets.Action; +using RotationSolver.Basic.Configuration.Timeline.TimelineCondition; +using RotationSolver.Basic.Configuration.Timeline.TimelineDrawing; namespace RotationSolver.Basic.Configuration.Timeline; @@ -13,15 +7,11 @@ namespace RotationSolver.Basic.Configuration.Timeline; [Description("Drawing Timeline")] internal class DrawingTimeline : BaseTimelineItem { - private IDisposable[] _drawings = []; public ITimelineCondition Condition { get; set; } = new TrueTimelineCondition(); - public StaticVfxConfig StaticVfxConfig { get; set; } - public ObjectVfxConfig ObjectConfig { get; set; } - public ActionVfxConfig ActionConfig { get; set; } - public ObjectGetter ObjectGetter { get; set; } = new(); - public DrawingType Type { get; set; } + public List DrawingGetters { get; set; } = []; + + private IDisposable[] _drawings = []; - public uint ActionID { get; set; } public DrawingTimeline() { Time = 5; @@ -45,7 +35,8 @@ protected override void OnEnable() { item.Dispose(); } - _drawings = CreateDrawing(); + + _drawings = [.. DrawingGetters.SelectMany(i => i.GetDrawing())]; #if DEBUG //Svc.Log.Debug($"Added the state {item2.State} to timeline."); @@ -62,134 +53,4 @@ protected override void OnDisable() _drawings = []; base.OnDisable(); } - - private IDisposable[] CreateDrawing() - { - switch (Type) - { - case DrawingType.Ground: - if (string.IsNullOrEmpty(StaticVfxConfig.Path)) break; - - return [new StaticVfx(StaticVfxConfig.Path, StaticVfxConfig.Position, StaticVfxConfig.Rotation, StaticVfxConfig.Scale)]; - - case DrawingType.Object: - return [..ObjectGetter.GetObjects().Select(GetObjectDrawing)]; - - case DrawingType.Action: - return [.. ObjectGetter.GetObjects().Select(GetActionDrawing)]; - } - return []; - } - - private IDisposable? GetObjectDrawing(GameObject obj) - { - switch (ObjectConfig.Type) - { - case ObjectVfxConfig.ObjectType.Single: - return new Single1(obj, ObjectConfig.Radius); - - case ObjectVfxConfig.ObjectType.Stack2: - return new Share2(obj, ObjectConfig.Radius); - - case ObjectVfxConfig.ObjectType.Stack4: - return new Share4(obj, ObjectConfig.Radius); - - case ObjectVfxConfig.ObjectType.General: - if (string.IsNullOrEmpty(StaticVfxConfig.Path)) break; - - var result = new StaticVfx(StaticVfxConfig.Path, obj, StaticVfxConfig.Scale) - { - LocationOffset = StaticVfxConfig.Position, - RotateAddition = StaticVfxConfig.Rotation, - }; - if (ObjectConfig.TargetOnTarget) - { - result.Target = obj.TargetObject; - } - return result; - } - return null; - } - - private IDisposable? GetActionDrawing(GameObject obj) - { - if (ActionID == 0) return null; - var action = Svc.Data.GetExcelSheet()?.GetRow(ActionID); - if (action == null) return null; - var omen = action.Omen.Value?.Path?.RawString; - omen = string.IsNullOrEmpty(omen) ? StaticVfxConfig.Path : omen.Omen(); - - var x = ActionConfig.X ?? (action.XAxisModifier > 0 ? action.XAxisModifier / 2 : action.EffectRange); - var y = ActionConfig.Y ?? action.EffectRange; - var scale = new Vector3(x, XIVPainterMain.HeightScale, y); - - if (action.TargetArea) - { - var location = StaticVfxConfig.Position; - if (obj is BattleChara battle) - { - unsafe - { - var info = battle.Struct()->GetCastInfo; - if (info->IsCasting != 0) - { - location = info->CastLocation; - } - } - } - return new StaticVfx(omen, location, 0, scale); - } - else - { - return new StaticVfx(omen, obj, scale) - { - RotateAddition = StaticVfxConfig.Rotation / 180 * MathF.PI, - LocationOffset = StaticVfxConfig.Position, - }; - } - } -} - -public class ObjectGetter -{ - public GameObject[] GetObjects() - { - return []; - } -} - -public struct ActionVfxConfig -{ - public float? X { get; set; } - public float? Y { get; set; } -} - -public struct ObjectVfxConfig -{ - public enum ObjectType - { - Single, - Stack2, - Stack4, - General, - } - - public float Radius { get; set; } - public bool TargetOnTarget { get; set; } - public ObjectType Type { get; set; } -} - -public struct StaticVfxConfig -{ - public string Path { get; set; } - public Vector3 Position { get; set; } - public float Rotation { get; set; } - public Vector3 Scale { get; set; } -} - -public enum DrawingType -{ - Ground, - Object, - Action, } diff --git a/RotationSolver.Basic/Configuration/Timeline/TimelineCondition/ITimelineConditionConverter.cs b/RotationSolver.Basic/Configuration/Timeline/TimelineCondition/ITimelineConditionConverter.cs new file mode 100644 index 000000000..5b5715d9e --- /dev/null +++ b/RotationSolver.Basic/Configuration/Timeline/TimelineCondition/ITimelineConditionConverter.cs @@ -0,0 +1,17 @@ +using Newtonsoft.Json.Linq; +using RotationSolver.Basic.Configuration.Conditions; +using RotationSolver.Basic.Configuration.Timeline.TimelineDrawing; + +namespace RotationSolver.Basic.Configuration.Timeline.TimelineCondition; +internal class ITimelineConditionConverter : JsonCreationConverter +{ + protected override ITimelineCondition? Create(JObject jObject) + { + if (FieldExists(nameof(ActionDrawingGetter.ActionID), jObject)) + { + //return new ActionDrawingGetter(); + } + + return new TrueTimelineCondition(); + } +} diff --git a/RotationSolver.Basic/Configuration/Timeline/TimelineCondition/ObjectGetter.cs b/RotationSolver.Basic/Configuration/Timeline/TimelineCondition/ObjectGetter.cs new file mode 100644 index 000000000..95aa06c92 --- /dev/null +++ b/RotationSolver.Basic/Configuration/Timeline/TimelineCondition/ObjectGetter.cs @@ -0,0 +1,13 @@ +namespace RotationSolver.Basic.Configuration.Timeline.TimelineCondition; +public class ObjectGetter +{ + public bool CanGet(GameObject obj) + { + return true; + } + + public GameObject[] TargetGetter(GameObject obj) + { + return []; + } +} \ No newline at end of file diff --git a/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/ActionDrawingGetter.cs b/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/ActionDrawingGetter.cs new file mode 100644 index 000000000..41d344713 --- /dev/null +++ b/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/ActionDrawingGetter.cs @@ -0,0 +1,78 @@ +using ECommons.DalamudServices; +using ECommons.GameFunctions; +using RotationSolver.Basic.Configuration.Timeline.TimelineCondition; +using XIVPainter; +using XIVPainter.Vfx; +using Action = Lumina.Excel.GeneratedSheets.Action; + +namespace RotationSolver.Basic.Configuration.Timeline.TimelineDrawing; + +[Description("Action Drawing")] +internal class ActionDrawingGetter : IDrawingGetter +{ + public uint ActionID { get; set; } + public string Path { get; set; } = ""; + public float? X { get; set; } + public float? Y { get; set; } + public Vector3 Position { get; set; } + public float Rotation { get; set; } + public ObjectGetter ObjectGetter { get; set; } = new(); + + public IDisposable[] GetDrawing() + { + var objs = Svc.Objects.Where(ObjectGetter.CanGet); + if (objs.Any()) + { + return [.. objs.Select(GetActionDrawing).OfType()]; + } + + var item = GetActionDrawing(null); + if (item == null) return []; + return [item]; + } + + private IDisposable? GetActionDrawing(GameObject? obj) + { + if (ActionID == 0) return null; + var action = Svc.Data.GetExcelSheet()?.GetRow(ActionID); + if (action == null) return null; + var omen = action.Omen.Value?.Path?.RawString; + omen = string.IsNullOrEmpty(omen) ? Path : omen.Omen(); + + var x = X ?? (action.XAxisModifier > 0 ? action.XAxisModifier / 2 : action.EffectRange); + var y = Y ?? action.EffectRange; + var scale = new Vector3(x, XIVPainterMain.HeightScale, y); + + if (action.TargetArea) + { + var location = Position; + if (obj is BattleChara battle) + { + unsafe + { + var info = battle.Struct()->GetCastInfo; + if (info->IsCasting != 0) + { + location = info->CastLocation; + } + } + } + return new StaticVfx(omen, location, 0, scale); + } + else + { + if(obj != null) + { + return new StaticVfx(omen, obj, scale) + { + RotateAddition = Rotation / 180 * MathF.PI, + LocationOffset = Position, + }; + } + else + { + return new StaticVfx(omen, Position, Rotation, scale); + } + } + } +} diff --git a/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/IDrawingGetter.cs b/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/IDrawingGetter.cs new file mode 100644 index 000000000..7d8951176 --- /dev/null +++ b/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/IDrawingGetter.cs @@ -0,0 +1,5 @@ +namespace RotationSolver.Basic.Configuration.Timeline.TimelineDrawing; +internal interface IDrawingGetter +{ + IDisposable[] GetDrawing(); +} diff --git a/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/IDrawingGetterConverter.cs b/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/IDrawingGetterConverter.cs new file mode 100644 index 000000000..a93725559 --- /dev/null +++ b/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/IDrawingGetterConverter.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json.Linq; +using RotationSolver.Basic.Configuration.Conditions; + +namespace RotationSolver.Basic.Configuration.Timeline.TimelineDrawing; + +internal class IDrawingGetterConverter : JsonCreationConverter +{ + protected override IDrawingGetter? Create(JObject jObject) + { + if (FieldExists(nameof(ActionDrawingGetter.ActionID), jObject)) + { + return new ActionDrawingGetter(); + } + else if (FieldExists(nameof(ObjectDrawingGetter.IsActorEffect), jObject)) + { + return new ObjectDrawingGetter(); + } + else if (FieldExists(nameof(StaticDrawingGetter.Text), jObject)) + { + return new StaticDrawingGetter(); + } + + return null; + } +} diff --git a/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/ObjectDrawingGetter.cs b/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/ObjectDrawingGetter.cs new file mode 100644 index 000000000..d6b22489c --- /dev/null +++ b/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/ObjectDrawingGetter.cs @@ -0,0 +1,70 @@ +using ECommons.DalamudServices; +using RotationSolver.Basic.Configuration.Timeline.TimelineCondition; +using XIVPainter.Vfx; + +namespace RotationSolver.Basic.Configuration.Timeline.TimelineDrawing; + +[Description("Object Drawing")] +internal class ObjectDrawingGetter : IDrawingGetter +{ + public string Path { get; set; } = GroundOmenHostile.Circle.Omen(); + public bool IsActorEffect { get; set; } = false; + public Vector3 Position { get; set; } + public float Rotation { get; set; } + public Vector3 Scale { get; set; } + public ObjectGetter ObjectGetter { get; set; } = new(); + public TextDrawing ObjectText { get; set; } = new(); + public TextDrawing TargetText { get; set; } = new(); + + public IDisposable[] GetDrawing() + { + var objs = Svc.Objects.Where(ObjectGetter.CanGet); + return [..objs.SelectMany(GetTextDrawing), + ..objs.SelectMany(GetObjectDrawing)]; + } + + private IDisposable[] GetTextDrawing(GameObject obj) + { + return [..ObjectGetter.TargetGetter(obj).Select(TargetText.GetText) + .Append(ObjectText.GetText(obj)) + .OfType()]; + } + + private IDisposable[] GetObjectDrawing(GameObject obj) + { + if (string.IsNullOrEmpty(Path)) return []; + + var targets = ObjectGetter.TargetGetter(obj); + if (IsActorEffect) + { + if (targets.Length > 0) + { + return [.. targets.Select(t => new ActorVfx(Path, obj, t))]; + } + else + { + return [new ActorVfx(Path, obj, obj)]; + } + } + else + { + if (targets.Length > 0) + { + return [.. targets.Select(t => new StaticVfx(Path, obj, Scale) + { + LocationOffset = Position, + RotateAddition = Rotation, + Target = t, + })]; + } + else + { + return [new StaticVfx(Path, obj, Scale) + { + LocationOffset = Position, + RotateAddition = Rotation, + }]; + } + } + } +} \ No newline at end of file diff --git a/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/StaticDrawingGetter.cs b/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/StaticDrawingGetter.cs new file mode 100644 index 000000000..ac07ebdb5 --- /dev/null +++ b/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/StaticDrawingGetter.cs @@ -0,0 +1,20 @@ +using XIVPainter.Vfx; + +namespace RotationSolver.Basic.Configuration.Timeline.TimelineDrawing; + +[Description("Static Drawing")] +internal class StaticDrawingGetter : IDrawingGetter +{ + public string Path { get; set; } = GroundOmenHostile.Circle.Omen(); + public Vector3 Position { get; set; } + public float Rotation { get; set; } + public Vector3 Scale { get; set; } + public TextDrawing Text { get; set; } = new(); + public IDisposable[] GetDrawing() + { + if (string.IsNullOrEmpty(Path)) return []; + var item = new StaticVfx(Path, Position, Rotation, Scale); + var text = Text.GetText(Position); + return text == null ? [item] : [item, text]; + } +} \ No newline at end of file diff --git a/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/TextDrawing.cs b/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/TextDrawing.cs new file mode 100644 index 000000000..b3f4520f9 --- /dev/null +++ b/RotationSolver.Basic/Configuration/Timeline/TimelineDrawing/TextDrawing.cs @@ -0,0 +1,45 @@ +using XIVPainter.Element3D; + +namespace RotationSolver.Basic.Configuration.Timeline.TimelineDrawing; +internal class TextDrawing +{ + public string? Text { get; set; } + public Vector3 PositionOffset { get; set; } + + public Vector2 Padding { get; set; } = Vector2.One * 5; + + public float Scale { get; set; } = 1; + + public uint BackgroundColor { get; set; } = 0x00000080; + + public uint Color { get; set; } = uint.MaxValue; + + /// + /// The corner of the background. + /// + public float Corner { get; set; } = 5; + + public Drawing3DText? GetText(Vector3 position) + { + if (string.IsNullOrEmpty(Text)) return null; + return new(Text, position + PositionOffset) + { + HideIfInvisible = false, + Padding = Padding, + BackgroundColor = BackgroundColor, + Color = Color, + Scale = Scale, + }; + } + + public Drawing3DText? GetText(GameObject obj) + { + var text = GetText(obj.Position); + if (text == null) return null; + text.UpdateEveryFrame += () => + { + text.Position = obj.Position + PositionOffset; + }; + return text; + } +} diff --git a/RotationSolver.Basic/Data/TimelineItem.cs b/RotationSolver.Basic/Data/TimelineItem.cs index fe69ffb83..003bd319c 100644 --- a/RotationSolver.Basic/Data/TimelineItem.cs +++ b/RotationSolver.Basic/Data/TimelineItem.cs @@ -15,9 +15,34 @@ internal enum TimelineType : byte AddedCombatant, } -internal readonly struct TimelineItem(float time, string name, TimelineType type, JObject? obj, RaidLangs langs, float? jumpTime, float windowMin, float windowMax) +internal struct TimelineItem(float time, string name, TimelineType type, JObject? obj, RaidLangs langs, float? jumpTime, float windowMin, float windowMax) { - private RaidLangs.Lang Lang + private uint[]? ids = null; + public uint[] ActionIDs => ids ??= GetActionIds(); + private readonly uint[] GetActionIds() + { + if (Type is not TimelineType.Ability and not TimelineType.StartsUsing) return []; + var idsRaw = this["id"]; + + if (idsRaw == null || idsRaw.Length == 0) return []; + + var regex = idsRaw.Select(id => new Regex(id)); + + var count = Svc.Data.GetExcelSheet()?.RowCount ?? ushort.MaxValue; + + List reuslt = []; + for (uint i = 0; i < count; i++) + { + var text = i.ToString("X"); + if (regex.Any(i => i.IsMatch(text))) + { + reuslt.Add(i); + } + } + return [.. reuslt]; + } + + private readonly RaidLangs.Lang Lang { get { @@ -35,15 +60,15 @@ private RaidLangs.Lang Lang return new RaidLangs.Lang(); } } - public TimelineType Type => type; + public readonly TimelineType Type => type; - public float Time => time; + public readonly float Time => time; - public float WindowMin => windowMin; - public float WindowMax => windowMax; - public JObject? Object => obj; + public readonly float WindowMin => windowMin; + public readonly float WindowMax => windowMax; + public readonly JObject? Object => obj; - public string Name + public readonly string Name { get { @@ -52,14 +77,14 @@ public string Name } } - public bool IsInWindow => DataCenter.RaidTimeRaw >= Time - WindowMin && DataCenter.RaidTimeRaw <= Time + WindowMax; + public readonly bool IsInWindow => DataCenter.RaidTimeRaw >= Time - WindowMin && DataCenter.RaidTimeRaw <= Time + WindowMax; - public bool IsShown => Name is not "--Reset--" and not "--sync--"; + public readonly bool IsShown => Name is not "--Reset--" and not "--sync--"; - public bool this[string propertyName, uint matchValue] + public readonly bool this[string propertyName, uint matchValue] => this[propertyName, matchValue.ToString("X")]; - public bool this[string propertyName, string matchString] + public readonly bool this[string propertyName, string matchString] { get { @@ -80,7 +105,7 @@ public string Name } } - public string[] this[string propertyName] + public readonly string[] this[string propertyName] { get { @@ -159,7 +184,7 @@ private static TimelineType GetTypeFromName(string type) } } - public void UpdateRaidTimeOffset() + public readonly void UpdateRaidTimeOffset() { if (Name == "--Reset--") { @@ -178,7 +203,7 @@ public void UpdateRaidTimeOffset() } } - public override string ToString() + public readonly override string ToString() { return $""" IsShown: {IsShown}, diff --git a/RotationSolver/RotationSolverPlugin.cs b/RotationSolver/RotationSolverPlugin.cs index 54303b3c1..c93d95b5d 100644 --- a/RotationSolver/RotationSolverPlugin.cs +++ b/RotationSolver/RotationSolverPlugin.cs @@ -8,6 +8,8 @@ using ECommons.ImGuiMethods; using RotationSolver.Basic.Configuration; using RotationSolver.Basic.Configuration.Timeline; +using RotationSolver.Basic.Configuration.Timeline.TimelineCondition; +using RotationSolver.Basic.Configuration.Timeline.TimelineDrawing; using RotationSolver.Commands; using RotationSolver.Data; using RotationSolver.Helpers; @@ -15,7 +17,6 @@ using RotationSolver.UI; using RotationSolver.Updaters; using XIVPainter; -using XIVPainter.Element; namespace RotationSolver; @@ -43,7 +44,8 @@ public RotationSolverPlugin(DalamudPluginInterface pluginInterface) try { Service.Config = JsonConvert.DeserializeObject( - File.ReadAllText(Svc.PluginInterface.ConfigFile.FullName), new ITimelineItemConverter()) + File.ReadAllText(Svc.PluginInterface.ConfigFile.FullName), + new ITimelineItemConverter(), new IDrawingGetterConverter(), new ITimelineConditionConverter()) ?? new Configs(); } catch (Exception ex) @@ -95,20 +97,6 @@ public RotationSolverPlugin(DalamudPluginInterface pluginInterface) if (Player.Available) { _ = XIVPainterMain.ShowOff(); - //_ = new StaticVfx($"vfx/omen/eff/{GroundOmenFriendly.Circle}.avfx", Player.Object, new Vector3(1, 1, 3)) - //{ - // RotateAddition = MathF.PI / 4, - // LocationOffset = new Vector3(1, 0, 2), - //}; - - //Task.Run(async () => - //{ - // while(true) - // { - // new Share2(Player.Object, 3); - // await Task.Delay(6000); - // } - //}); } #endif } diff --git a/RotationSolver/UI/RotationConfigWindow.cs b/RotationSolver/UI/RotationConfigWindow.cs index 36be344cb..69037e6c2 100644 --- a/RotationSolver/UI/RotationConfigWindow.cs +++ b/RotationSolver/UI/RotationConfigWindow.cs @@ -16,6 +16,9 @@ using Lumina.Excel.GeneratedSheets; using RotationSolver.Basic.Configuration; using RotationSolver.Basic.Configuration.Timeline; +using RotationSolver.Basic.Configuration.Timeline.TimelineCondition; +using RotationSolver.Basic.Configuration.Timeline.TimelineDrawing; +using RotationSolver.Basic.Data; using RotationSolver.Data; using RotationSolver.Helpers; using RotationSolver.Localization; @@ -188,7 +191,7 @@ void DeleteFile() } ImGuiHelper.ExecuteHotKeysPopup(key, string.Empty, string.Empty, false, - (DeleteFile, [Dalamud.Game.ClientState.Keys.VirtualKey.DELETE])); + (DeleteFile, [VirtualKey.DELETE])); } } @@ -701,7 +704,8 @@ static string GetName(TerritoryType? territory) var str = ImGui.GetClipboardText(); try { - var set = JsonConvert.DeserializeObject>>(str, new ITimelineItemConverter())!; + var set = JsonConvert.DeserializeObject>>(str, + new ITimelineItemConverter(), new IDrawingGetterConverter(), new ITimelineConditionConverter())!; Service.Config.Timeline[_territoryId] = timeLine = set; } catch (Exception ex) @@ -843,7 +847,7 @@ void Down() } else if(timeLineItem is DrawingTimeline drawingItem) { - //TODO: the drawing thing in the config window. + DrawDrawingTimeline(drawingItem); } } @@ -876,6 +880,89 @@ void AddOneCondition() where T : BaseTimelineItem } } } + + private static void DrawDrawingTimeline(DrawingTimeline drawingItem) + { + AddButton(); + + for (int i = 0; i < drawingItem.DrawingGetters.Count; i++) + { + var item = drawingItem.DrawingGetters[i]; + + void Delete() + { + drawingItem.DrawingGetters.RemoveAt(i); + }; + + void Up() + { + drawingItem.DrawingGetters.RemoveAt(i); + drawingItem.DrawingGetters.Insert(Math.Max(0, i - 1), item); + }; + + void Down() + { + drawingItem.DrawingGetters.RemoveAt(i); + drawingItem.DrawingGetters.Insert(Math.Min(drawingItem.DrawingGetters.Count, i + 1), item); + } + + var key = $"DrawingItem Pop Up: {item.GetHashCode()}"; + + ImGuiHelper.DrawHotKeysPopup(key, string.Empty, + (UiString.ConfigWindow_List_Remove.Local(), Delete, ["Delete"]), + (UiString.ConfigWindow_Actions_MoveUp.Local(), Up, ["↑"]), + (UiString.ConfigWindow_Actions_MoveDown.Local(), Down, ["↓"])); + + if (IconSet.GetTexture(30, out var texture)) + { + ImGui.Image(texture.ImGuiHandle, ConditionDrawer.IconSize * Vector2.One); + } + + ImGuiHelper.ExecuteHotKeysPopup(key, string.Empty, string.Empty, true, + (Delete, [VirtualKey.DELETE]), + (Up, [VirtualKey.UP]), + (Down, [VirtualKey.DOWN])); + + DrawingGetterDraw(item); + } + + TimelineConditionDraw(drawingItem.Condition); + + void AddButton() + { + if (ImGuiEx.IconButton(FontAwesomeIcon.Plus, "AddDrawingButton" + drawingItem.GetHashCode())) + { + ImGui.OpenPopup("PopupDrawingButton" + drawingItem.GetHashCode()); + } + + using var popUp = ImRaii.Popup("PopupDrawingButton" + drawingItem.GetHashCode()); + if (popUp) + { + AddOneCondition(); + AddOneCondition(); + AddOneCondition(); + } + + void AddOneCondition() where T : IDrawingGetter + { + if (ImGui.Selectable(typeof(T).Local())) + { + drawingItem.DrawingGetters.Add(Activator.CreateInstance()); + ImGui.CloseCurrentPopup(); + } + } + } + } + + private static void TimelineConditionDraw(ITimelineCondition condition) + { + //TODO: the condition drawing in the config window. + } + + private static void DrawingGetterDraw(IDrawingGetter drawing) + { + + } #endregion #region About diff --git a/RotationSolver/Updaters/ActionUpdater.cs b/RotationSolver/Updaters/ActionUpdater.cs index 005eab3cf..fffc54dd6 100644 --- a/RotationSolver/Updaters/ActionUpdater.cs +++ b/RotationSolver/Updaters/ActionUpdater.cs @@ -2,13 +2,9 @@ using Dalamud.Game.ClientState.Objects.SubKinds; using ECommons.DalamudServices; using ECommons.GameHelpers; -using ExCSS; using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.UI.Agent; using RotationSolver.Commands; -using System.Text.RegularExpressions; -using System.Windows.Forms; -using XIVPainter.Enum; using XIVPainter.Vfx; namespace RotationSolver.Updaters; diff --git a/RotationSolver/Watcher.cs b/RotationSolver/Watcher.cs index 0706f7c00..1870c4341 100644 --- a/RotationSolver/Watcher.cs +++ b/RotationSolver/Watcher.cs @@ -1,7 +1,6 @@ using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Hooking; using Dalamud.Plugin.Ipc; -using Dalamud.Utility; using ECommons.DalamudServices; using ECommons.GameHelpers; using ECommons.Hooks; @@ -10,8 +9,6 @@ using Lumina.Excel.GeneratedSheets; using RotationSolver.Basic.Configuration; using System.Text.RegularExpressions; -using XIVPainter.Enum; -using XIVPainter.Vfx; using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject; namespace RotationSolver; diff --git a/XIVPainter b/XIVPainter index 0ca5edfe2..fe3abe1fb 160000 --- a/XIVPainter +++ b/XIVPainter @@ -1 +1 @@ -Subproject commit 0ca5edfe2f635e0cf412b546f15b75e5ca2447f9 +Subproject commit fe3abe1fb9b93299aa72a3fff322f113205f63d5