警告!これらのプリセットは未完成です。以下のものは頻繁に変更される可能性があります。また、表示を完全にカバーしていない場合や正しくカバーしていない可能性を含みます。

開幕(サイクロニックブレイク)

[未完成] [スクリプト] 開幕扇範囲

ここを押すとスクリプトが展開/折りたたみされます。
using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Objects.Types;
using ECommons;
using ECommons.DalamudServices;
using ECommons.GameFunctions;
using ECommons.Hooks.ActionEffectTypes;
using ECommons.ImGuiMethods;
using ECommons.MathHelpers;
using ECommons.Schedulers;
using ECommons.Throttlers;
using ImGuiNET;
using Splatoon.SplatoonScripting;
using System.Collections.Generic;
using System.Linq;

namespace SplatoonScriptsOfficial.Duties.Dawntrail.The_Futures_Rewritten;
internal class P1_Cyclonic_Break :SplatoonScript
{
    public override HashSet<uint>? ValidTerritories { get; } = [1238];
    public override Metadata? Metadata => new(2, "Redmoon");

    class PlayerData
    {
        public uint EntityId;
        public float Angle;
        public PlayerData(uint entityId)
        {
            EntityId = entityId;
            Angle = 0;
        }
    }

    const uint _cyclonicBreakCastFireId = 40144;
    const uint _cyclonicBreakCastThunderId = 40148;
    const uint _cyclonicBreakFireId = 40146;
    const uint _cyclonicBreakThunderId = 40149;
    const uint _secondCyclonicBreakCastFireId = 40329;
    const uint _secondCyclonicBreakCastThunderId = 40330;
    //const uint _secondCyclonicBreakFireId = 40146;
    //const uint _secondCyclonicBreakThunderId = 40149;
    List<PlayerData> _playerList = new List<PlayerData>();
    uint _enemyId = 0;
    int _actionCount = 0;
    bool _gimmickStarted = false;
    bool _checked = false;
    bool _isFirst = false;

    public override void OnSetup()
    {
        for (int i = 0; i < 8; i++)
        {
            Controller.RegisterElement($"Cone{i}", new(5) { radius = 20.0f, coneAngleMin = -12, coneAngleMax = 12, refActorComparisonType = 2, includeRotation = true });
        }
    }

    public override void OnStartingCast(uint source, uint castId)
    {
        if (castId == _cyclonicBreakCastFireId || castId == _cyclonicBreakCastThunderId)
        {
            _enemyId = Svc.Objects.FirstOrDefault(x => x.IsTargetable && x.ObjectKind == ObjectKind.BattleNpc && x.DataId == 0x459B).EntityId;
            foreach (var player in FakeParty.Get())
            {
                _playerList.Add(new PlayerData(player.EntityId));
            }
            if (_playerList.Count == 8 && _enemyId != 0u)
            {
                _gimmickStarted = true;
                _isFirst = true;
            }
        }
        if (castId == _secondCyclonicBreakCastFireId || castId == _secondCyclonicBreakCastThunderId)
        {
            _enemyId = Svc.Objects.FirstOrDefault(x => x is IBattleNpc obj && obj.IsCharacterVisible() && obj.ObjectKind == ObjectKind.BattleNpc && obj.DataId == 0x459C).EntityId;
            foreach (var player in FakeParty.Get())
            {
                _playerList.Add(new PlayerData(player.EntityId));
            }
            if (_playerList.Count == 8 && _enemyId != 0u)
            {
                _ = new TickScheduler(delegate { _gimmickStarted = true; _isFirst = true; }, 2000);
            }
        }
        if (castId == 40154 || castId == 40137)
        {
            OnReset();
        }
    }

    public override void OnActionEffectEvent(ActionEffectSet set)
    {
        if (!_gimmickStarted) return;
        if (set.Action == null) return;
        if (set.Action.Value.RowId == _cyclonicBreakCastFireId || set.Action.Value.RowId == _cyclonicBreakCastThunderId ||
            set.Action.Value.RowId == _secondCyclonicBreakCastFireId || set.Action.Value.RowId == _secondCyclonicBreakCastThunderId)
        {
            Hide();
            _isFirst = false;
            foreach (var player in _playerList)
            {
                var obj = player.EntityId.GetObject();
                if (obj != null)
                {
                    player.Angle = MathHelper.GetRelativeAngle(obj.Position, _enemyId.GetObject().Position);
                }
            }
            Show();
            _actionCount++;
        }
        else if (set.Action.Value.RowId == _cyclonicBreakFireId)
        {
            if (_checked) return;
            Hide();
            if (_actionCount == 3)
            {
                OnReset();
                return;
            }
            foreach (var player in _playerList)
            {
                if ((player.Angle + 22.0f) > 360.0f)
                {
                    player.Angle = player.Angle + 22.0f - 360.0f;
                }
                else
                {
                    player.Angle = player.Angle + 22.0f;
                }
            }
            Show();
            _actionCount++;
            _checked = true;
            _ = new TickScheduler(delegate { _checked = false; }, 400);
        }
        else if (set.Action.Value.RowId == 40165)
        {
            this.OnReset();
            return;
        }
    }

    public override void OnUpdate()
    {
        if (!_isFirst || !_gimmickStarted) return;
        DynamicShow();
    }

    public override void OnReset()
    {
        _gimmickStarted = false;
        _isFirst = false;
        _playerList.Clear();
        _actionCount = 0;
        EzThrottler.Reset("CyclonicBreakFire");
        Hide();
    }

    public override void OnSettingsDraw()
    {
        if (ImGuiEx.CollapsingHeader("Debug"))
        {
            ImGui.Text($"Gimmick Started: {_gimmickStarted}");
            ImGui.Text($"Is First: {_isFirst}");
            ImGui.Text($"Enemy: {_enemyId.GetObject().EntityId}");
            ImGui.Text($"Action Count: {_actionCount}");
            int i = 0;
            if (_gimmickStarted || _playerList.Count == 8)
            {
                foreach (var player in _playerList)
                {
                    var obj = player.EntityId.GetObject();
                    if (obj == null) continue;
                    ImGui.Text($"Player {obj.Name.ToString()}: RelativeRotation: {player.Angle}");
                }
            }
        }
    }

    private void Hide()
    {
        Controller.GetRegisteredElements().Each(x => x.Value.Enabled = false);
    }

    private void DynamicShow()
    {
        foreach (var player in _playerList)
        {
            var obj = player.EntityId.GetObject();
            if (obj != null)
            {
                player.Angle = MathHelper.GetRelativeAngle(obj.Position, _enemyId.GetObject().Position);
            }
        }

        for (int i = 0; i < 8; i++)
        {
            var cone = Controller.GetElementByName($"Cone{i}");
            var player = _playerList[i];
            if (cone != null)
            {
                cone.SetRefPosition(_enemyId.GetObject().Position);
                cone.AdditionalRotation = MathHelper.DegToRad(player.Angle);
                cone.Enabled = true;
            }
        }
    }

    private void Show()
    {
        for (int i = 0; i < 8; i++)
        {
            var cone = Controller.GetElementByName($"Cone{i}");
            var player = _playerList[i];
            if (cone != null)
            {
                cone.SetRefPosition(_enemyId.GetObject().Position);
                cone.AdditionalRotation = MathHelper.DegToRad(player.Angle);
                cone.Enabled = true;
            }
        }
    }
}

サイクロニックブレイク

~Lv2~{"Name":"FRU P1_フェイトブレイカー_ サイクロニックブレイク炎","Group":"絶もう1つの未来","ZoneLockH":[1238],"DCond":5,"ElementsL":[{"Name":"サークル","type":1,"radius":5.5,"color":4278190335,"Filled":false,"fillIntensity":0.3,"overlayBGColor":4278190080,"overlayTextColor":4294967295,"overlayVOffset":2.0,"overlayFScale":2.0,"thicc":5.0,"overlayText":"ペア","refActorComparisonType":1,"refActorType":1,"includeRotation":true,"FaceMe":true,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0}],"UseTriggers":true,"Triggers":[{"Type":2,"Duration":10.0,"Match":"(9707>40144)"}]}
~Lv2~{"Name":"FRU P1_フェイトブレイカー_ サイクロニックブレイク雷","Group":"絶もう1つの未来","ZoneLockH":[1238],"DCond":5,"ElementsL":[{"Name":"サークル","type":1,"radius":6.0,"color":4278190335,"fillIntensity":0.3,"overlayBGColor":4278190080,"overlayTextColor":4294967295,"overlayVOffset":2.0,"overlayFScale":2.0,"refActorPlaceholder":["<2>","<3>","<4>","<5>","<6>","<7>","<8>"],"refActorComparisonType":5,"includeRotation":true,"FaceMe":true,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0},{"Name":"テキスト","type":1,"radius":0.0,"Filled":false,"fillIntensity":0.5,"overlayBGColor":4278190080,"overlayTextColor":4294967295,"overlayVOffset":2.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"散開","refActorType":1,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0}],"UseTriggers":true,"Triggers":[{"Type":2,"Duration":10.0,"Match":"(9707>40148)"}],"MaxDistance":7.5,"UseDistanceLimit":true,"DistanceLimitType":1}
~Lv2~{"Name":"FRU P1_フェイトブレイカーの幻影_ サイクロニックブレイク炎","Group":"絶もう1つの未来","ZoneLockH":[1238],"DCond":5,"ElementsL":[{"Name":"サークル","type":1,"radius":5.5,"color":4278190335,"Filled":false,"fillIntensity":0.3,"overlayBGColor":4278190080,"overlayTextColor":4294967295,"overlayVOffset":2.0,"overlayFScale":2.0,"thicc":5.0,"overlayText":"ペア","refActorComparisonType":1,"refActorType":1,"includeRotation":true,"FaceMe":true,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0}],"UseTriggers":true,"Triggers":[{"Type":2,"Duration":8.0,"Match":"(9708>40329)","MatchDelay":2.0}]}
~Lv2~{"Name":"FRU P1_フェイトブレイカーの幻影_ サイクロニックブレイク雷","Group":"絶もう1つの未来","ZoneLockH":[1238],"DCond":5,"ElementsL":[{"Name":"サークル","type":1,"radius":5.5,"color":4278190335,"fillIntensity":0.3,"overlayBGColor":4278190080,"overlayTextColor":4294967295,"overlayVOffset":2.0,"overlayFScale":2.0,"overlayText":"散開","refActorComparisonType":1,"refActorType":1,"includeRotation":true,"FaceMe":true,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0}],"UseTriggers":true,"Triggers":[{"Type":2,"Duration":10.0,"Match":"(9707>40330)"}]}

[未完成] [スクリプト] 連鎖爆印

ここを押すとスクリプトが展開/折りたたみされます。
using Dalamud.Game.ClientState.Objects.SubKinds;
using ECommons.DalamudServices;
using ECommons.GameFunctions;
using ECommons.Hooks.ActionEffectTypes;
using ECommons.ImGuiMethods;
using ECommons.Schedulers;
using ImGuiNET;
using Splatoon.SplatoonScripting;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;

namespace SplatoonScriptsOfficial.Duties.Dawntrail.The_Futures_Rewritten;
internal class P1_Powder_Mark_Trail :SplatoonScript
{
    public override HashSet<uint>? ValidTerritories { get; } = [1238];
    public override Metadata? Metadata => new(1, "Redmoon");

    uint _buffPlayer = 0;
    uint _tooClosePlayer = 0;

    public override void OnSetup()
    {
        Controller.RegisterElement("PowderMark1", new(1) { radius = 10.0f, refActorComparisonType = 2 });
        Controller.RegisterElement("PowderMark2", new(1) { radius = 10.0f, refActorComparisonType = 2 });
    }

    public override void OnActionEffectEvent(ActionEffectSet set)
    {
        if (set.Action == null) return;
        if (set.Action.Value.RowId == 40168)
        {
            _ = new TickScheduler(delegate
            {
                var buffPlayer = FakeParty.Get().FirstOrDefault(x => x is IPlayerCharacter pc && pc.StatusList.Any(y => y.StatusId == 4166));
                if (buffPlayer == null)
                {
                    _ = new TickScheduler(delegate
                    {
                        var buffPlayer = FakeParty.Get().FirstOrDefault(x => x is IPlayerCharacter pc && pc.StatusList.Any(y => y.StatusId == 4166));
                        if (buffPlayer == null) return;
                        _buffPlayer = buffPlayer.EntityId;
                    });
                }
                _buffPlayer = buffPlayer.EntityId;
            });
        }
        if (set.Action.Value.RowId == 40169)
        {
            _buffPlayer = 0;
            _tooClosePlayer = 0;
            Controller.GetElementByName("PowderMark1").Enabled = false;
            Controller.GetElementByName("PowderMark2").Enabled = false;
        }
    }

    public override void OnUpdate()
    {
        if (_buffPlayer == 0) return;
        var pc = _buffPlayer.GetObject() as IPlayerCharacter;
        if (pc == null) return;
        var status = pc.StatusList.Where(x => x.StatusId == 4166 && x.RemainingTime < 6.0f).ToList();
        if (status.Count == 0) return;
        Controller.GetElementByName("PowderMark1").refActorObjectID = _buffPlayer;
        if (_buffPlayer == Svc.ClientState.LocalPlayer.EntityId) Controller.GetElementByName("PowderMark1").Filled = false;
        else Controller.GetElementByName("PowderMark1").Filled = true;
        Controller.GetElementByName("PowderMark1").Enabled = true;

        Vector3 bufferPos = pc.Position;
        uint tooClosePlayer = 0;
        float tooClosePlayerDistance = float.MaxValue;
        var pcList = FakeParty.Get().ToList();
        foreach (var player in pcList)
        {
            if (player.EntityId == _buffPlayer) continue;
            var playerPos = player.Position;
            if (Vector3.Distance(bufferPos, playerPos) < tooClosePlayerDistance)
            {
                tooClosePlayer = player.EntityId;
                tooClosePlayerDistance = Vector3.Distance(bufferPos, playerPos);
            }
        }

        if (_tooClosePlayer == tooClosePlayer) return;

        _tooClosePlayer = tooClosePlayer;
        Controller.GetElementByName("PowderMark2").refActorObjectID = _tooClosePlayer;
        if (_tooClosePlayer == Svc.ClientState.LocalPlayer.EntityId) Controller.GetElementByName("PowderMark2").Filled = false;
        else Controller.GetElementByName("PowderMark2").Filled = true;
        Controller.GetElementByName("PowderMark2").Enabled = true;
    }

    public override void OnReset()
    {
        _buffPlayer = 0;
        _tooClosePlayer = 0;
        Controller.GetElementByName("PowderMark1").Enabled = false;
        Controller.GetElementByName("PowderMark2").Enabled = false;
    }

    public override void OnSettingsDraw()
    {
        if (ImGuiEx.CollapsingHeader("Debug"))
        {
            ImGui.Text($"Buff Player: {_buffPlayer}");
            ImGui.Text($"Too Close Player: {_tooClosePlayer}");
        }
    }
}

連鎖爆印

~Lv2~{"Name":"FRU P1_フェイトブレイカー_ 連鎖爆印","Group":"絶もう1つの未来","ZoneLockH":[1238],"ElementsL":[{"Name":"サークル","type":1,"radius":10.0,"color":4278190335,"fillIntensity":0.3,"refActorRequireBuff":true,"refActorBuffId":[4166],"refActorUseBuffTime":true,"refActorBuffTimeMax":5.0,"refActorComparisonType":1,"includeRotation":true,"FaceMe":true,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0}]}

楽園絶技

楽園絶技

~Lv2~{"Name":"FRU P1_フェイトブレイカー_ 連鎖爆印","Group":"絶もう1つの未来","ZoneLockH":[1238],"ElementsL":[{"Name":"サークル","type":1,"radius":10.0,"color":4278190335,"fillIntensity":0.3,"refActorRequireBuff":true,"refActorBuffId":[4166],"refActorUseBuffTime":true,"refActorBuffTimeMax":5.0,"refActorComparisonType":1,"includeRotation":true,"FaceMe":true,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0}]}
~Lv2~{"Name":"FRU P1_フェイトブレイカー_楽園絶技AOE","Group":"絶もう1つの未来","ZoneLockH":[1238],"ElementsL":[{"Name":"楽園絶技_外村","type":3,"refY":40.0,"radius":8.0,"refActorNPCNameID":9708,"refActorComparisonType":6,"includeRotation":true,"tether":true,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0,"refActorUseTransformation":true,"refActorTransformationID":4}]}
~Lv2~{"Name":"FRU P1_フェイトブレイカー_楽園絶技焔","Group":"絶もう1つの未来","ZoneLockH":[1238],"DCond":5,"ElementsL":[{"Name":"サークル","type":1,"radius":5.5,"color":4278190335,"Filled":false,"fillIntensity":0.3,"overlayBGColor":4278190080,"overlayTextColor":4294967295,"overlayVOffset":2.0,"overlayFScale":2.0,"thicc":5.0,"overlayText":"頭割","refActorPlaceholder":["<h1>","<h2>"],"refActorComparisonType":5,"includeRotation":true,"FaceMe":true,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0}],"UseTriggers":true,"Triggers":[{"Type":2,"Duration":10.0,"Match":"(9707>40154)","MatchDelay":10.0}]}
~Lv2~{"Name":"FRU P1_フェイトブレイカー_楽園絶技雷","Group":"絶もう1つの未来","ZoneLockH":[1238],"DCond":5,"ElementsL":[{"Name":"サークル","type":1,"radius":6.0,"color":4278190335,"fillIntensity":0.3,"overlayBGColor":4278190080,"overlayTextColor":4294967295,"overlayVOffset":2.0,"overlayFScale":2.0,"refActorPlaceholder":["<2>","<3>","<4>","<5>","<6>","<7>","<8>"],"refActorComparisonType":5,"includeRotation":true,"FaceMe":true,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0},{"Name":"テキスト","type":1,"radius":0.0,"fillIntensity":0.5,"overlayBGColor":4278190080,"overlayTextColor":4294967295,"overlayVOffset":2.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"散開","refActorType":1,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0}],"UseTriggers":true,"Triggers":[{"Type":2,"Duration":10.0,"Match":"(9707>40155)","MatchDelay":10.0}],"MaxDistance":7.5,"UseDistanceLimit":true,"DistanceLimitType":1}
~Lv2~{"Name":"FRU P1_フェイトブレイカー_楽園絶技_外周強調","Group":"絶もう1つの未来","ZoneLockH":[1238],"DCond":5,"ElementsL":[{"Name":"外周","refX":100.0,"refY":100.0,"refZ":1.9073486E-06,"radius":20.0,"color":4294908672,"Filled":false,"fillIntensity":0.5,"thicc":10.0,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0}],"UseTriggers":true,"Triggers":[{"Type":2,"Duration":9.0,"Match":"(9707>40154)"},{"Type":2,"Duration":9.0,"Match":"(9707>40155)"}]}

シンフレイム_ロール表示

~Lv2~{"Name":"FRU P1_フェイトブレイカー_ シンフレイム_ロール表示","Group":"絶もう1つの未来","ZoneLockH":[1238],"DCond":5,"ElementsL":[{"Name":"TH","type":1,"radius":0.02,"fillIntensity":0.5,"overlayBGColor":4278190080,"overlayTextColor":4278255376,"overlayVOffset":2.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"TH","refActorPlaceholder":["<t1>","<t2>","<h1>","<h2>"],"refActorRequireBuff":true,"refActorBuffId":[1051],"refActorComparisonType":5,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0},{"Name":"DPS","type":1,"radius":0.02,"fillIntensity":0.5,"overlayBGColor":4278190080,"overlayTextColor":4278190335,"overlayVOffset":2.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"DPS","refActorPlaceholder":["<d1>","<d2>","<d3>","<d4>"],"refActorRequireBuff":true,"refActorBuffId":[1051],"refActorComparisonType":5,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0},{"Name":"サークル","type":1,"radius":6.0,"color":4278190335,"Filled":false,"fillIntensity":0.3,"thicc":5.0,"refActorRequireBuff":true,"refActorBuffId":[4165],"refActorUseBuffTime":true,"refActorBuffTimeMax":6.0,"refActorComparisonType":1,"includeRotation":true,"FaceMe":true,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0}],"UseTriggers":true,"Triggers":[{"Type":2,"Duration":20.0,"Match":"(9708>40163)"}]}

[未完成] [スクリプト] 転臨召

ここを押すとスクリプトが展開/折りたたみされます。
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
using ECommons;
using ECommons.Configuration;
using ECommons.DalamudServices;
using ECommons.ExcelServices;
using ECommons.GameFunctions;
using ECommons.GameHelpers;
using ECommons.Hooks.ActionEffectTypes;
using ECommons.ImGuiMethods;
using ECommons.Logging;
using ECommons.PartyFunctions;
using FFXIVClientStructs.FFXIV.Client.UI.Info;
using ImGuiNET;
using Splatoon.SplatoonScripting;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;

namespace SplatoonScriptsOfficial.Duties.Dawntrail.The_Futures_Rewritten;
internal class P1_Turn_of_the_Heavens :SplatoonScript
{
    public override HashSet<uint>? ValidTerritories { get; } = [1238];
    public override Metadata? Metadata => new(1, "Redmoon");

    Config Conf => Controller.GetConfig<Config>();
    List<IPlayerCharacter> _sortedList = new();
    List<IPlayerCharacter> _stackedList = new();
    bool _mechanicActive = false;

    readonly ImGuiEx.RealtimeDragDrop<Job> DragDrop = new("DragDropJob", x => x.ToString());

    public class Config :IEzConfig
    {
        public bool DebugPrint = false;
        public List<string[]> LeftRightPriorities = new();

        public List<Job> Jobs =
        [
            Job.PLD,
            Job.WAR,
            Job.DRK,
            Job.GNB,
            Job.WHM,
            Job.SCH,
            Job.AST,
            Job.SGE,
            Job.VPR,
            Job.DRG,
            Job.MNK,
            Job.SAM,
            Job.RPR,
            Job.NIN,
            Job.BRD,
            Job.MCH,
            Job.DNC,
            Job.BLM,
            Job.SMN,
            Job.RDM,
            Job.PCT
        ];
    }

    public override void OnSetup()
    {
        Controller.RegisterElement("Stack1", new Splatoon.Element(1) { thicc = 15f, radius = 1.0f, Filled = false, refActorComparisonType = 2 });
        Controller.RegisterElement("Stack2", new Splatoon.Element(1) { thicc = 15f, radius = 1.0f, Filled = false, refActorComparisonType = 2 });
    }

    public override void OnSettingsDraw()
    {
        ImGui.Text("# How to determine left/right priority : ");
        ImGui.SameLine();
        if (ImGui.SmallButton("Test"))
        {
            if (TryGetPriorityList(out var list))
            {
                DuoLog.Information($"Success: priority list {list.Print()}");
            }
            else
            {
                DuoLog.Warning($"Could not get priority list");
            }
        }
        var toRem = -1;
        for (int i = 0; i < Conf.LeftRightPriorities.Count; i++)
        {
            if (DrawPrioList(i))
            {
                toRem = i;
            }
        }
        if (toRem != -1)
        {
            Conf.LeftRightPriorities.RemoveAt(toRem);
        }
        if (ImGui.Button("Create new priority list"))
        {
            Conf.LeftRightPriorities.Add(new string[] { "", "", "", "", "", "", "", "" });
        }

        if (ImGuiEx.CollapsingHeader("Option"))
        {
            DragDrop.Begin();
            foreach (var job in Conf.Jobs)
            {
                DragDrop.NextRow();
                ImGui.Text(job.ToString());
                ImGui.SameLine();

                if (ThreadLoadImageHandler.TryGetIconTextureWrap((uint)job.GetIcon(), false, out var texture))
                {
                    ImGui.Image(texture.ImGuiHandle, new Vector2(24f));
                    ImGui.SameLine();
                }

                ImGui.SameLine();
                DragDrop.DrawButtonDummy(job, Conf.Jobs, Conf.Jobs.IndexOf(job));
            }

            DragDrop.End();
        }

        if (ImGui.CollapsingHeader("Debug"))
        {
            ImGui.Checkbox("DebugPrint", ref Conf.DebugPrint);
            ImGui.Text($"_mechanicActive : {_mechanicActive}");
            ImGui.Text($"_stackedList : {_stackedList.Print()}");
            ImGui.Text($"_sortedList : {_sortedList.Print()}");
            ImGui.Text($"Svc.ClientState.LocalPlayer.Name: {Svc.ClientState.LocalPlayer.Name}");
        }
    }

    public override void OnStartingCast(uint source, uint castId)
    {
        if (source.GetObject() is IBattleChara npc)
        {
            if (castId == 40151)
            {
                if (!TryGetPriorityList(out _sortedList))
                    return;
                _mechanicActive = true;
            }
        }
    }

    public override void OnUpdate()
    {
        if (!_mechanicActive) return;
        if (Controller.GetElementByName("Stack1").Enabled)
        {
            Controller.GetElementByName("Stack1").color = GradientColor.Get(0xFF00FF00.ToVector4(), 0xFF0000FF.ToVector4()).ToUint();
        }

        if (Controller.GetElementByName("Stack2").Enabled)
        {
            Controller.GetElementByName("Stack2").color = GradientColor.Get(0xFF00FF00.ToVector4(), 0xFF0000FF.ToVector4()).ToUint();
        }
    }

    public override void OnActionEffectEvent(ActionEffectSet set)
    {
        if (!_mechanicActive || set.Action == null)
            return;

        if (set.Action.Value.RowId == 40165)
        {
            this.OnReset();
            return;
        }
    }

    public override void OnTetherCreate(uint source, uint target, uint data2, uint data3, uint data5)
    {
        if (!_mechanicActive) return;
        if (data2 != 0 || data3 != 249 || data5 != 15) return;

        try
        {
            DebugLog($"StackMarker: {target.GetObject().Name}");
            if (target.GetObject() is not IPlayerCharacter pcObj)
                return;

            _stackedList.Add(pcObj);
            if (_stackedList.Count == 1)
            {
                Controller.GetElementByName("Stack1").refActorObjectID = target;
            }
            else if (_stackedList.Count == 2)
            {
                Controller.GetElementByName("Stack2").refActorObjectID = target;
            }
            DebugLog($"_stackedList: {_stackedList.Print()}");
            if (_stackedList.Count == 2)
            {
                if (!_stackedList.Exists(x => x.Address == Svc.ClientState.LocalPlayer.Address))
                {
                    DebugLog("Non stacker");
                    // non stacker show element
                    List<IPlayerCharacter> noneStackers = _sortedList.Where(x => !_stackedList.Contains(x)).ToList();
                    int myIndex = noneStackers.IndexOf(Svc.ClientState.LocalPlayer);
                    if (myIndex == -1)
                    {
                        DuoLog.Warning($"Could not find player in priority list");
                        _mechanicActive = false;
                        this.OnReset();
                        return;
                    }
                    string myNum = myIndex < 3 ? "1" : "2";

                    Controller.GetElementByName($"Stack{myNum}").Enabled = true;
                    Controller.GetElementByName($"Stack{myNum}").tether = true;

                    //Debug
                    IPlayerCharacter myStacker = _stackedList.First();
                    IPlayerCharacter otherStacker = _stackedList.Last();
                    myIndex = _sortedList.IndexOf(myStacker);
                    int otherIndex = _sortedList.IndexOf(otherStacker);
                    if (myIndex == -1 || otherIndex == -1)
                    {
                        DuoLog.Warning($"Could not find player in priority list");
                        _mechanicActive = false;
                        this.OnReset();
                        return;
                    }
                    myNum = myIndex < otherIndex ? "1" : "2";
                    string otherPos = myIndex < otherIndex ? "2" : "1";
                    DebugLog($"FirstStacker: {myStacker.Name} {myNum}, LastStacker: {otherStacker.Name} {otherPos}");

                    foreach (var x in noneStackers)
                    {
                        var dpos = noneStackers.IndexOf(x) < 3 ? "1" : "2";
                        DebugLog($"noneStacker: {x.Name} {dpos}");
                    }
                }
            }
        }
        catch (Exception e)
        {
            DuoLog.Error(e.Message);
        }
    }

    public override void OnReset()
    {
        Controller.GetRegisteredElements().Each(x => x.Value.Enabled = false);
        _stackedList.Clear();
        _mechanicActive = false;
    }

    private bool TryGetPriorityList([NotNullWhen(true)] out List<IPlayerCharacter> values)
    {
        foreach (var p in Conf.LeftRightPriorities)
        {
            var valid = true;
            var l = FakeParty.Get().Select(x => x.Name.ToString()).ToHashSet();
            foreach (var x in p)
            {
                if (!l.Remove(x))
                {
                    valid = false;
                    break;
                }
            }
            if (valid)
            {
                values = FakeParty.Get().ToList().OrderBy(x => Array.IndexOf(p, x.Name.ToString())).ToList();
                return true;
            }
        }
        values = new();
        return false;
    }

    private unsafe bool DrawPrioList(int num)
    {
        var prio = Conf.LeftRightPriorities[num];
        ImGuiEx.Text($"# Priority list {num + 1}");
        ImGui.PushID($"prio{num}");
        ImGuiEx.Text($"    NorthWest");
        for (int i = 0; i < prio.Length; i++)
        {
            ImGui.PushID($"prio{num}element{i}");
            ImGui.SetNextItemWidth(200);
            ImGui.InputText($"Player {i + 1}", ref prio[i], 50);
            ImGui.SameLine();
            ImGui.SetNextItemWidth(150);
            if (ImGui.BeginCombo("##partysel", "Select from party"))
            {
                foreach (var x in FakeParty.Get().Select(x => x.Name.ToString())
                             .Union(UniversalParty.Members.Select(x => x.Name)).ToHashSet())
                    if (ImGui.Selectable(x))
                        prio[i] = x;
                ImGui.EndCombo();
            }
            ImGui.PopID();
        }
        ImGuiEx.Text($"    NorthEast");
        if (ImGui.Button("Delete this list (ctrl+click)") && ImGui.GetIO().KeyCtrl)
        {
            return true;
        }

        ImGui.SameLine();
        if (ImGui.Button("Fill by job"))
        {
            HashSet<(string, Job)> party = [];
            foreach (var x in FakeParty.Get())
                party.Add((x.Name.ToString(), x.GetJob()));

            var proxy = InfoProxyCrossRealm.Instance();
            for (var i = 0; i < proxy->GroupCount; i++)
            {
                var group = proxy->CrossRealmGroups[i];
                for (var c = 0; c < proxy->CrossRealmGroups[i].GroupMemberCount; c++)
                {
                    var x = group.GroupMembers[c];
                    party.Add((x.Name.Read(), (Job)x.ClassJobId));
                }
            }

            var index = 0;
            foreach (var job in Conf.Jobs.Where(job => party.Any(x => x.Item2 == job)))
            {
                prio[index] = party.First(x => x.Item2 == job).Item1;
                index++;
            }

            for (var i = index; i < prio.Length; i++)
                prio[i] = "";
        }
        ImGuiEx.Tooltip("The list is populated based on the job.\nYou can adjust the priority from the option header.");

        ImGui.PopID();
        return false;
    }

    private void DebugLog(string log, [CallerLineNumber] int lineNum = 0)
    {
        if (Conf.DebugPrint)
            DuoLog.Information(log + $" : L({lineNum})");
    }
}

転輪召リマインダー

~Lv2~{"Name":"FRU P1_フェイトブレイカーの幻影_ 転輪召(炎)_リマインダー","Group":"絶もう1つの未来","ZoneLockH":[1238],"DCond":5,"ElementsL":[{"Name":"OverlayText","type":1,"radius":0.0,"overlayBGColor":4278190080,"overlayTextColor":4294944000,"overlayVOffset":3.0,"overlayFScale":2.0,"overlayText":"青安置","refActorType":1,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0}],"UseTriggers":true,"Triggers":[{"Type":2,"Duration":7.0,"Match":"(9708>40150)","MatchDelay":5.0}]}
~Lv2~{"Name":"FRU P1_フェイトブレイカーの幻影_ 転輪召(雷)_リマインダー","Group":"絶もう1つの未来","ZoneLockH":[1238],"DCond":5,"ElementsL":[{"Name":"OverlayText","type":1,"radius":0.0,"fillIntensity":0.5,"overlayBGColor":4278190080,"overlayTextColor":4278190335,"overlayVOffset":3.0,"overlayFScale":2.0,"overlayText":"赤安置","refActorType":1,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0}],"UseTriggers":true,"Triggers":[{"Type":2,"TimeBegin":3.0,"Duration":7.0,"Match":"(9708>40151)","MatchDelay":5.0}]}

バーンストライク

~Lv2~{"Name":"FRU P1_フェイトブレイカー_ バーンストライク","Group":"絶もう1つの未来","ZoneLockH":[1238],"ElementsL":[{"Name":"雷","type":3,"refY":20.0,"offY":-20.0,"radius":10.0,"color":4278190335,"fillIntensity":0.3,"castAnimation":3,"refActorNPCNameID":9707,"refActorRequireCast":true,"refActorCastId":[40133],"refActorUseCastTime":true,"refActorCastTimeMin":4.0,"refActorCastTimeMax":10.0,"refActorUseOvercast":true,"refActorComparisonType":6,"includeRotation":true,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0,"FillStep":2.0},{"Name":"炎","type":3,"refY":20.0,"offY":-20.0,"radius":5.0,"color":4278190335,"fillIntensity":0.3,"refActorNPCNameID":9707,"refActorRequireCast":true,"refActorCastId":[40129],"refActorUseCastTime":true,"refActorCastTimeMax":10.0,"refActorComparisonType":6,"includeRotation":true,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0,"FillStep":2.0},{"Name":"炎 ノックバックライン","type":3,"refY":20.0,"offY":-20.0,"radius":0.1,"color":4278251263,"fillIntensity":0.3,"refActorNPCNameID":9707,"refActorRequireCast":true,"refActorCastId":[40129],"refActorUseCastTime":true,"refActorCastTimeMin":7.8,"refActorCastTimeMax":10.5,"refActorUseOvercast":true,"refActorComparisonType":6,"includeRotation":true,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0,"FillStep":2.0}]}
~Lv2~{"Name":"FRU P1_フェイトブレイカーの幻影_ バーンストライク","Group":"絶もう1つの未来","ZoneLockH":[1238],"ElementsL":[{"Name":"雷","type":3,"refY":50.0,"radius":10.0,"color":4278190335,"fillIntensity":0.3,"refActorNPCNameID":9708,"refActorRequireCast":true,"refActorCastId":[40163],"refActorUseCastTime":true,"refActorCastTimeMax":10.0,"refActorUseOvercast":true,"refActorComparisonType":6,"includeRotation":true,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0,"FillStep":2.0},{"Name":"炎","type":3,"refY":50.0,"radius":5.0,"color":4278190335,"fillIntensity":0.3,"refActorNPCNameID":9708,"refActorRequireCast":true,"refActorCastId":[40161],"refActorUseCastTime":true,"refActorCastTimeMin":4.0,"refActorCastTimeMax":10.0,"refActorComparisonType":6,"includeRotation":true,"refActorTetherTimeMin":0.0,"refActorTetherTimeMax":0.0,"FillStep":2.0}]}

シンソイルセヴァー

[未完成] [スクリプト] シンソイルセヴァー