From f00e614552c3cc678b667c0f00fe94301d4e1213 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=A7=8B=E6=B0=B4?= <1123993881@qq.com>
Date: Fri, 20 Jan 2023 11:34:00 +0800
Subject: [PATCH] refactor: change for the interface.
---
.../BaseAction/BaseAction_ActionInfo.cs | 24 +-
.../BaseAction/BaseAction_BasicInfo.cs | 2 +-
.../Actions/BaseAction/BaseAction_Cooldown.cs | 14 +-
.../Actions/BaseAction/BaseAction_Target.cs | 8 +-
RotationSolver/Actions/BaseItem.cs | 4 -
RotationSolver/Actions/IAction.cs | 2 +-
RotationSolver/Actions/IBaseAction.cs | 38 +-
RotationSolver/Actions/IBaseItem.cs | 1 +
RotationSolver/Helpers/ImguiHelper.cs | 27 +-
RotationSolver/ITexture.cs | 2 +-
RotationSolver/Interfaces.cd | 12 +-
.../{ASTRotation_Base.cs => AST_Base.cs} | 70 +-
.../{BLMRotation_Base.cs => BLM_Base.cs} | 64 +-
.../Rotations/Basic/BLURotation_Base.cs | 741 -----------------
RotationSolver/Rotations/Basic/BLU_Base.cs | 746 ++++++++++++++++++
.../{BRDRotation_Base.cs => BRD_Base.cs} | 52 +-
.../{DNCRotation_Base.cs => DNC_Base.cs} | 102 +--
.../{DRGRotation_Base.cs => DRG_Base.cs} | 63 +-
.../{DRKRotation_Base.cs => DRK_Base.cs} | 58 +-
.../{GNBRotation_Base.cs => GNB_Base.cs} | 62 +-
.../{MCHRotation_Base.cs => MCH_Base.cs} | 41 +-
.../{MNKRotation_Base.cs => MNK_Base.cs} | 62 +-
.../Rotations/Basic/NINRotation_Base.cs | 312 --------
RotationSolver/Rotations/Basic/NIN_Base.cs | 316 ++++++++
.../{PLDRotation_Base.cs => PLD_Base.cs} | 66 +-
.../{RDMRotation_Base.cs => RDM_Base.cs} | 83 +-
.../{RPRRotation_Base.cs => RPR_Base.cs} | 98 +--
.../{SAMRotation_Base.cs => SAM_Base.cs} | 68 +-
.../{SCHRotation_Base.cs => SCH_Base.cs} | 63 +-
.../{SGERotation_Base.cs => SGE_Base.cs} | 78 +-
.../{SMNRotation_Base.cs => SMN_Base.cs} | 73 +-
.../{WARRotation_Base.cs => WAR_Base.cs} | 58 +-
.../{WHMRotation_Base.cs => WHM_Base.cs} | 55 +-
.../CustomRotation/CustomRotation_Actions.cs | 54 +-
.../CustomRotation_BasicInfo.cs | 2 +-
.../CustomRotation_BreakItems.cs | 2 +-
.../CustomRotation/ICustomRotation.cs | 2 +-
.../Rotations/Healer/AST/AST_Default.cs | 2 +-
.../Rotations/Healer/SCH/SCH_Default.cs | 2 +-
.../Rotations/Healer/SGE/SGE_Default.cs | 2 +-
.../Rotations/Healer/WHM/WHM_Default.cs | 2 +-
.../Rotations/Melee/DRG/DRG_Default.cs | 2 +-
.../Rotations/Melee/MNK/MNK_Default.cs | 2 +-
.../Rotations/Melee/NIN/NIN_Default.cs | 4 +-
.../Rotations/Melee/RPR/RPR_Default.cs | 2 +-
.../Rotations/Melee/SAM/SAM_Default.cs | 2 +-
.../RangedMagicial/BLM/BLM_Default.cs | 2 +-
.../RangedMagicial/BLU/BLU_Default.cs | 2 +-
.../RangedMagicial/RDM/RDM_Default.cs | 2 +-
.../RangedMagicial/SMN/SMN_Default.cs | 2 +-
.../RangedPhysicial/BRD/BRD_Default.cs | 2 +-
.../RangedPhysicial/DNC/DNC_Default.cs | 2 +-
.../RangedPhysicial/MCH/MCH_Default.cs | 2 +-
.../Rotations/Tank/DRK/DRK_Default.cs | 2 +-
.../Rotations/Tank/GNB/GNB_Default.cs | 2 +-
.../Rotations/Tank/PLD/PLD_Default.cs | 2 +-
.../Rotations/Tank/WAR/WAR_Default.cs | 2 +-
57 files changed, 1800 insertions(+), 1767 deletions(-)
rename RotationSolver/Rotations/Basic/{ASTRotation_Base.cs => AST_Base.cs} (61%)
rename RotationSolver/Rotations/Basic/{BLMRotation_Base.cs => BLM_Base.cs} (69%)
delete mode 100644 RotationSolver/Rotations/Basic/BLURotation_Base.cs
create mode 100644 RotationSolver/Rotations/Basic/BLU_Base.cs
rename RotationSolver/Rotations/Basic/{BRDRotation_Base.cs => BRD_Base.cs} (64%)
rename RotationSolver/Rotations/Basic/{DNCRotation_Base.cs => DNC_Base.cs} (60%)
rename RotationSolver/Rotations/Basic/{DRGRotation_Base.cs => DRG_Base.cs} (51%)
rename RotationSolver/Rotations/Basic/{DRKRotation_Base.cs => DRK_Base.cs} (60%)
rename RotationSolver/Rotations/Basic/{GNBRotation_Base.cs => GNB_Base.cs} (59%)
rename RotationSolver/Rotations/Basic/{MCHRotation_Base.cs => MCH_Base.cs} (65%)
rename RotationSolver/Rotations/Basic/{MNKRotation_Base.cs => MNK_Base.cs} (50%)
delete mode 100644 RotationSolver/Rotations/Basic/NINRotation_Base.cs
create mode 100644 RotationSolver/Rotations/Basic/NIN_Base.cs
rename RotationSolver/Rotations/Basic/{PLDRotation_Base.cs => PLD_Base.cs} (54%)
rename RotationSolver/Rotations/Basic/{RDMRotation_Base.cs => RDM_Base.cs} (53%)
rename RotationSolver/Rotations/Basic/{RPRRotation_Base.cs => RPR_Base.cs} (58%)
rename RotationSolver/Rotations/Basic/{SAMRotation_Base.cs => SAM_Base.cs} (63%)
rename RotationSolver/Rotations/Basic/{SCHRotation_Base.cs => SCH_Base.cs} (58%)
rename RotationSolver/Rotations/Basic/{SGERotation_Base.cs => SGE_Base.cs} (59%)
rename RotationSolver/Rotations/Basic/{SMNRotation_Base.cs => SMN_Base.cs} (64%)
rename RotationSolver/Rotations/Basic/{WARRotation_Base.cs => WAR_Base.cs} (55%)
rename RotationSolver/Rotations/Basic/{WHMRotation_Base.cs => WHM_Base.cs} (55%)
diff --git a/RotationSolver/Actions/BaseAction/BaseAction_ActionInfo.cs b/RotationSolver/Actions/BaseAction/BaseAction_ActionInfo.cs
index cbb3c078f..bc482ca56 100644
--- a/RotationSolver/Actions/BaseAction/BaseAction_ActionInfo.cs
+++ b/RotationSolver/Actions/BaseAction/BaseAction_ActionInfo.cs
@@ -18,32 +18,32 @@ internal partial class BaseAction
///
/// 如果之前是这些ID,那么就不会执行。
///
- internal ActionID[] OtherIDsNot { private get; set; } = null;
+ public ActionID[] OtherIDsNot { private get; set; } = null;
///
/// 如果之前不是这些ID中的某个,那么就不会执行。
///
- internal ActionID[] OtherIDsCombo { private get; set; } = null;
+ public ActionID[] OtherIDsCombo { private get; set; } = null;
///
/// 使用了这个技能会得到的Buff,如果有这些Buff中的一种,那么就不会执行,这个buff是自己提供的。
///
- internal StatusID[] BuffsProvide { get; set; } = null;
+ public StatusID[] StatusProvide { get; set; } = null;
///
/// 使用这个技能需要的前置Buff,有任何一个就好。
///
- internal virtual StatusID[] BuffsNeed { get; set; } = null;
+ public virtual StatusID[] StatusNeed { get; set; } = null;
///
/// 如果有一些别的需要判断的,可以写在这里。True表示可以使用这个技能。
///
- internal Func ActionCheck { get; set; } = null;
+ public Func ActionCheck { get; set; } = null;
///
/// 如果有一些别的需要判断的,可以写在这里。True表示可以使用这个技能。
///
- internal Func ComboCheck { get; set; } = null;
+ public Func ComboCheck { get; set; } = null;
private bool WillCooldown
{
@@ -77,7 +77,7 @@ private bool WillCooldown
/// 判断是否需要使用这个技能
///
/// 返回的技能
- /// 必须使用,不判断提供的Buff和是否已提供,不判断AOE技能的敌人数量是否达标.
+ /// 必须使用,不判断提供的Buff和是否已提供,不判断AOE技能的敌人数量是否达标.
/// 如果有层数,放完所有层数,不判断是否为Combo
/// 这个技能能不能用
public unsafe virtual bool ShouldUse(out IAction act, bool mustUse = false, bool emptyOrSkipCombo = false, bool skipDisable = false)
@@ -102,15 +102,15 @@ public unsafe virtual bool ShouldUse(out IAction act, bool mustUse = false, bool
if (Service.ClientState.LocalPlayer.CurrentMp < MPNeed) return false;
//没有前置Buff
- if (BuffsNeed != null)
+ if (StatusNeed != null)
{
- if (!Service.ClientState.LocalPlayer.HasStatus(true, BuffsNeed)) return false;
+ if (!Service.ClientState.LocalPlayer.HasStatus(true, StatusNeed)) return false;
}
//已有提供的Buff的任何一种
- if (BuffsProvide != null && !mustUse)
+ if (StatusProvide != null && !mustUse)
{
- if (Service.ClientState.LocalPlayer.HasStatus(true, BuffsProvide)) return false;
+ if (Service.ClientState.LocalPlayer.HasStatus(true, StatusProvide)) return false;
}
//还冷却不下来呢,来不及。
@@ -148,7 +148,7 @@ public unsafe virtual bool ShouldUse(out IAction act, bool mustUse = false, bool
//如果是个法术需要咏唱,并且还在移动,也没有即刻相关的技能。
if (CastTime > 0 && MovingUpdater.IsMoving)
{
- if (!player.HasStatus(true, CustomRotation.Swiftcast.BuffsProvide))
+ if (!player.HasStatus(true, CustomRotation.Swiftcast.StatusProvide))
{
return false;
}
diff --git a/RotationSolver/Actions/BaseAction/BaseAction_BasicInfo.cs b/RotationSolver/Actions/BaseAction/BaseAction_BasicInfo.cs
index 53f6c2b37..9b58cb6c2 100644
--- a/RotationSolver/Actions/BaseAction/BaseAction_BasicInfo.cs
+++ b/RotationSolver/Actions/BaseAction/BaseAction_BasicInfo.cs
@@ -20,7 +20,7 @@ internal partial class BaseAction : IBaseAction
///
/// 玩家当前等级是否大于等于技能可用等级
///
- internal bool EnoughLevel => Service.ClientState.LocalPlayer.Level >= _action.ClassJobLevel;
+ public bool EnoughLevel => Service.ClientState.LocalPlayer.Level >= _action.ClassJobLevel;
public string Name => _action.Name;
public string Description => string.Empty;
diff --git a/RotationSolver/Actions/BaseAction/BaseAction_Cooldown.cs b/RotationSolver/Actions/BaseAction/BaseAction_Cooldown.cs
index 21379f068..5f672b13b 100644
--- a/RotationSolver/Actions/BaseAction/BaseAction_Cooldown.cs
+++ b/RotationSolver/Actions/BaseAction/BaseAction_Cooldown.cs
@@ -14,7 +14,7 @@ internal partial class BaseAction
/// 已经运转了多少个完整的GCD
/// 再多少个能力技之后
/// 是否已经冷却了这么久了(不在冷却会返回false)
- internal bool ElapsedAfterGCD(uint gcdCount = 0, uint abilityCount = 0)
+ public bool ElapsedAfterGCD(uint gcdCount = 0, uint abilityCount = 0)
{
if (!IsCoolDown) return false;
var elapsed = RecastTimeElapsedOneCharge;
@@ -26,7 +26,7 @@ internal bool ElapsedAfterGCD(uint gcdCount = 0, uint abilityCount = 0)
///
/// 已经进行了多少秒了
/// 是否已经冷却了这么久了(不在冷却会返回false)
- internal bool ElapsedAfter(float gcdelapsed)
+ public bool ElapsedAfter(float gcdelapsed)
{
if (!IsCoolDown) return false;
var elapsed = RecastTimeElapsedOneCharge;
@@ -39,7 +39,7 @@ internal bool ElapsedAfter(float gcdelapsed)
/// 要隔着多少个完整的GCD
/// 再多少个能力技之后
/// 这个时间点是否起码有一层可以用
- internal bool WillHaveOneChargeGCD(uint gcdCount = 0, uint abilityCount = 0)
+ public bool WillHaveOneChargeGCD(uint gcdCount = 0, uint abilityCount = 0)
{
if (HaveOneCharge) return true;
var recast = RecastTimeRemainOneCharge;
@@ -51,7 +51,7 @@ internal bool WillHaveOneChargeGCD(uint gcdCount = 0, uint abilityCount = 0)
///
/// 要多少秒呢
/// 这个时间点是否起码有一层可以用
- internal bool WillHaveOneCharge(float remain)
+ public bool WillHaveOneCharge(float remain)
{
return WillHaveOneCharge(remain, true);
}
@@ -78,7 +78,7 @@ private bool WillHaveOneCharge(float remain, bool addWeaponRemain)
///
/// 是否正在冷却中
///
- internal unsafe bool IsCoolDown => CoolDownDetail->IsActive != 0;
+ public unsafe bool IsCoolDown => CoolDownDetail->IsActive != 0;
///
/// 复唱剩余时间
@@ -88,7 +88,7 @@ private bool WillHaveOneCharge(float remain, bool addWeaponRemain)
///
/// 技能的最大层数
///
- internal unsafe ushort MaxCharges => Math.Max(ActionManager.GetMaxCharges(AdjustedID, Service.ClientState.LocalPlayer.Level), (ushort)1);
+ public unsafe ushort MaxCharges => Math.Max(ActionManager.GetMaxCharges(AdjustedID, Service.ClientState.LocalPlayer.Level), (ushort)1);
///
/// 是否起码有一层技能
///
@@ -96,7 +96,7 @@ private bool WillHaveOneCharge(float remain, bool addWeaponRemain)
///
/// 当前技能层数
///
- internal ushort CurrentCharges => IsCoolDown ? (ushort)(RecastTimeElapsed / RecastTimeOneCharge) : MaxCharges;
+ public ushort CurrentCharges => IsCoolDown ? (ushort)(RecastTimeElapsed / RecastTimeOneCharge) : MaxCharges;
private float RecastTimeOneCharge => ActionManager.GetAdjustedRecastTime(ActionType.Spell, AdjustedID) / 1000f;
diff --git a/RotationSolver/Actions/BaseAction/BaseAction_Target.cs b/RotationSolver/Actions/BaseAction/BaseAction_Target.cs
index 2ebde7aba..4859c1707 100644
--- a/RotationSolver/Actions/BaseAction/BaseAction_Target.cs
+++ b/RotationSolver/Actions/BaseAction/BaseAction_Target.cs
@@ -13,7 +13,7 @@ namespace RotationSolver.Actions.BaseAction;
internal partial class BaseAction
{
- internal bool IsTargetDying
+ public bool IsTargetDying
{
get
{
@@ -22,7 +22,7 @@ internal bool IsTargetDying
}
}
- internal bool IsTargetBoss
+ public bool IsTargetBoss
{
get
{
@@ -31,7 +31,7 @@ internal bool IsTargetBoss
}
}
- internal BattleChara Target { get; private set; } = Service.ClientState.LocalPlayer;
+ public BattleChara Target { get; private set; } = Service.ClientState.LocalPlayer;
private Vector3 _position = default;
private Func, bool, BattleChara> _choiceTarget = null;
@@ -50,7 +50,7 @@ private get
///
/// 给敌人造成的Debuff,如果有这些Debuff,那么不会执行,这个status是玩家赋予的。
///
- internal StatusID[] TargetStatus { get; set; } = null;
+ public StatusID[] TargetStatus { get; set; } = null;
internal static bool TankDefenseSelf(BattleChara chara)
{
diff --git a/RotationSolver/Actions/BaseItem.cs b/RotationSolver/Actions/BaseItem.cs
index f0da7078c..e83c4a932 100644
--- a/RotationSolver/Actions/BaseItem.cs
+++ b/RotationSolver/Actions/BaseItem.cs
@@ -18,9 +18,6 @@ internal class BaseItem : IBaseItem
InventoryManager.Instance()->GetInventoryItemCount(_item.RowId, true) > 0;
public uint IconID { get; }
- public bool IsEnabled { get; set; }
- public string Description => string.Empty;
- public string Author => string.Empty;
public string Name => _item.Name;
@@ -30,7 +27,6 @@ public BaseItem(uint row, uint a4 = 0)
{
_item = Service.DataManager.GetExcelSheet- ().GetRow(row);
IconID = _item.Icon;
-
A4 = a4;
}
diff --git a/RotationSolver/Actions/IAction.cs b/RotationSolver/Actions/IAction.cs
index 8758ac98e..4788ea1fb 100644
--- a/RotationSolver/Actions/IAction.cs
+++ b/RotationSolver/Actions/IAction.cs
@@ -1,6 +1,6 @@
namespace RotationSolver.Actions;
-public interface IAction : IEnableTexture
+public interface IAction : ITexture
{
bool Use();
uint ID { get; }
diff --git a/RotationSolver/Actions/IBaseAction.cs b/RotationSolver/Actions/IBaseAction.cs
index 43719536d..16adb04fe 100644
--- a/RotationSolver/Actions/IBaseAction.cs
+++ b/RotationSolver/Actions/IBaseAction.cs
@@ -1,4 +1,6 @@
-using System;
+using Dalamud.Game.ClientState.Objects.Types;
+using RotationSolver.Data;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -6,7 +8,39 @@
namespace RotationSolver.Actions
{
- internal interface IBaseAction : IAction
+ internal interface IBaseAction : IAction, IEnable
{
+ Func ActionCheck { get; set; }
+ Func ComboCheck { get; set; }
+ StatusID[] StatusProvide { get; set; }
+
+ StatusID[] StatusNeed { get; set; }
+
+ bool EnoughLevel { get; }
+
+ bool ShouldUse(out IAction act, bool mustUse = false, bool emptyOrSkipCombo = false, bool skipDisable = false);
+
+ #region CoolDown
+ bool IsCoolDown { get; }
+
+ ushort CurrentCharges { get; }
+ ushort MaxCharges { get; }
+ bool ElapsedAfterGCD(uint gcdCount = 0, uint abilityCount = 0);
+
+ bool ElapsedAfter(float gcdelapsed);
+
+ bool WillHaveOneChargeGCD(uint gcdCount = 0, uint abilityCount = 0);
+
+ bool WillHaveOneCharge(float remain);
+ #endregion
+
+ #region Target
+ StatusID[] TargetStatus { get; set; }
+
+ BattleChara Target { get; }
+
+ bool IsTargetBoss { get; }
+ bool IsTargetDying { get; }
+ #endregion
}
}
diff --git a/RotationSolver/Actions/IBaseItem.cs b/RotationSolver/Actions/IBaseItem.cs
index f91425fe5..1b76f6cd0 100644
--- a/RotationSolver/Actions/IBaseItem.cs
+++ b/RotationSolver/Actions/IBaseItem.cs
@@ -8,5 +8,6 @@ namespace RotationSolver.Actions
{
internal interface IBaseItem : IAction
{
+ bool ShoudUseItem(out IAction item);
}
}
diff --git a/RotationSolver/Helpers/ImguiHelper.cs b/RotationSolver/Helpers/ImguiHelper.cs
index 00f633f3a..e3abdb785 100644
--- a/RotationSolver/Helpers/ImguiHelper.cs
+++ b/RotationSolver/Helpers/ImguiHelper.cs
@@ -15,14 +15,16 @@ namespace RotationSolver.Helpers
internal static class ImGuiHelper
{
public static void DrawEnableTexture(this T texture, bool isSelected, Action selected,
- Action additonalHeader = null, Action otherThing = null) where T : class, IEnableTexture
+ Action additonalHeader = null, Action otherThing = null) where T : class, ITexture
{
ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, new Vector2(3f, 3f));
var t = texture.GetTexture();
ImGui.Image(t.ImGuiHandle, new Vector2(t.Width, t.Height));
- var desc = texture.Description;
+ var able = texture as IEnable;
+
+ var desc = able?.Description;
HoveredString(desc);
ImGui.SameLine();
Spacing();
@@ -34,16 +36,21 @@ public static void DrawEnableTexture(this T texture, bool isSelected, Action
}
HoveredString(desc);
- ImGui.SameLine();
- Spacing();
-
- bool enable = texture.IsEnabled;
- if (ImGui.Checkbox("##" + texture.Name, ref enable))
+ bool enable = false;
+ if (able != null)
{
- texture.IsEnabled = enable;
- Service.Configuration.Save();
+ ImGui.SameLine();
+ Spacing();
+
+ enable = able.IsEnabled;
+ if (ImGui.Checkbox("##" + texture.Name, ref enable))
+ {
+ able.IsEnabled = enable;
+ Service.Configuration.Save();
+ }
+ HoveredString(desc);
}
- HoveredString(desc);
+
additonalHeader?.Invoke();
diff --git a/RotationSolver/ITexture.cs b/RotationSolver/ITexture.cs
index b2b1f9b88..80ebc73b1 100644
--- a/RotationSolver/ITexture.cs
+++ b/RotationSolver/ITexture.cs
@@ -1,6 +1,6 @@
namespace RotationSolver;
-public interface IEnableTexture : ITexture
+public interface IEnable
{
string Description { get; }
diff --git a/RotationSolver/Interfaces.cd b/RotationSolver/Interfaces.cd
index e95a07dc5..2c5fd3633 100644
--- a/RotationSolver/Interfaces.cd
+++ b/RotationSolver/Interfaces.cd
@@ -1,21 +1,21 @@
-
-
+
+
AAAAAAAAAAAgAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAA=
ITexture.cs
-
+
AAAAAAAAAAAAAAgAAAAAAAQAAAAAAAAAAAAAAAAAAAA=
ITexture.cs
-
+
AAAAAAAAAAAAgABAAAAAAQAAAAAEAAAAAAAAAgAAAAA=
Actions\IAction.cs
@@ -31,12 +31,12 @@
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAA=
Actions\IBaseItem.cs
-
+
EAgAAAAAAEAAEAAAAAAIAQAAgAACAAAAABACCIBAAEE=
Rotations\CustomRotation\ICustomRotation.cs
diff --git a/RotationSolver/Rotations/Basic/ASTRotation_Base.cs b/RotationSolver/Rotations/Basic/AST_Base.cs
similarity index 61%
rename from RotationSolver/Rotations/Basic/ASTRotation_Base.cs
rename to RotationSolver/Rotations/Basic/AST_Base.cs
index a79e15d7e..ae7b35f43 100644
--- a/RotationSolver/Rotations/Basic/ASTRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/AST_Base.cs
@@ -30,22 +30,22 @@ internal abstract class ASTRotation_Base : CustomRotation.CustomRotation
public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Astrologian };
- private sealed protected override BaseAction Raise => Ascend;
+ private sealed protected override IBaseAction Raise => Ascend;
///
/// 生辰
///
- public static BaseAction Ascend { get; } = new(ActionID.Ascend, true);
+ public static IBaseAction Ascend { get; } = new BaseAction(ActionID.Ascend, true);
///
/// 凶星
///
- public static BaseAction Malefic { get; } = new(ActionID.Malefic);
+ public static IBaseAction Malefic { get; } = new BaseAction(ActionID.Malefic);
///
/// 烧灼
///
- public static BaseAction Combust { get; } = new(ActionID.Combust, isEot: true)
+ public static IBaseAction Combust { get; } = new BaseAction(ActionID.Combust, isEot: true)
{
TargetStatus = new StatusID[]
{
@@ -59,22 +59,22 @@ internal abstract class ASTRotation_Base : CustomRotation.CustomRotation
///
/// 重力
///
- public static BaseAction Gravity { get; } = new(ActionID.Gravity);
+ public static IBaseAction Gravity { get; } = new BaseAction(ActionID.Gravity);
///
/// 吉星
///
- public static BaseAction Benefic { get; } = new(ActionID.Benefic, true, isTimeline: true);
+ public static IBaseAction Benefic { get; } = new BaseAction(ActionID.Benefic, true, isTimeline: true);
///
/// 福星
///
- public static BaseAction Benefic2 { get; } = new(ActionID.Benefic2, true, isTimeline: true);
+ public static IBaseAction Benefic2 { get; } = new BaseAction(ActionID.Benefic2, true, isTimeline: true);
///
/// 吉星相位
///
- public static BaseAction AspectedBenefic { get; } = new(ActionID.AspectedBenefic, true, isEot: true, isTimeline: true)
+ public static IBaseAction AspectedBenefic { get; } = new BaseAction(ActionID.AspectedBenefic, true, isEot: true, isTimeline: true)
{
TargetStatus = new StatusID[] { StatusID.AspectedBenefic },
};
@@ -82,17 +82,17 @@ internal abstract class ASTRotation_Base : CustomRotation.CustomRotation
///
/// 先天禀赋
///
- public static BaseAction EssentialDignity { get; } = new(ActionID.EssentialDignity, true, isTimeline: true);
+ public static IBaseAction EssentialDignity { get; } = new BaseAction(ActionID.EssentialDignity, true, isTimeline: true);
///
/// 星位合图
///
- public static BaseAction Synastry { get; } = new(ActionID.Synastry, true, isTimeline: true);
+ public static IBaseAction Synastry { get; } = new BaseAction(ActionID.Synastry, true, isTimeline: true);
///
/// 天星交错
///
- public static BaseAction CelestialIntersection { get; } = new(ActionID.CelestialIntersection, true, isTimeline: true)
+ public static IBaseAction CelestialIntersection { get; } = new BaseAction(ActionID.CelestialIntersection, true, isTimeline: true)
{
ChoiceTarget = TargetFilter.FindAttackedTarget,
@@ -102,7 +102,7 @@ internal abstract class ASTRotation_Base : CustomRotation.CustomRotation
///
/// 擢升
///
- public static BaseAction Exaltation { get; } = new(ActionID.Exaltation, true, isTimeline: true)
+ public static IBaseAction Exaltation { get; } = new BaseAction(ActionID.Exaltation, true, isTimeline: true)
{
ChoiceTarget = TargetFilter.FindAttackedTarget,
};
@@ -110,55 +110,55 @@ internal abstract class ASTRotation_Base : CustomRotation.CustomRotation
///
/// 阳星
///
- public static BaseAction Helios { get; } = new(ActionID.Helios, true, isTimeline: true);
+ public static IBaseAction Helios { get; } = new BaseAction(ActionID.Helios, true, isTimeline: true);
///
/// 阳星相位
///
- public static BaseAction AspectedHelios { get; } = new(ActionID.AspectedHelios, true, isEot: true, isTimeline: true)
+ public static IBaseAction AspectedHelios { get; } = new BaseAction(ActionID.AspectedHelios, true, isEot: true, isTimeline: true)
{
- BuffsProvide = new StatusID[] { StatusID.AspectedHelios },
+ StatusProvide = new StatusID[] { StatusID.AspectedHelios },
};
///
/// 天星冲日
///
- public static BaseAction CelestialOpposition { get; } = new(ActionID.CelestialOpposition, true, isTimeline: true);
+ public static IBaseAction CelestialOpposition { get; } = new BaseAction(ActionID.CelestialOpposition, true, isTimeline: true);
///
/// 地星
///
- public static BaseAction EarthlyStar { get; } = new(ActionID.EarthlyStar, true, isTimeline: true);
+ public static IBaseAction EarthlyStar { get; } = new BaseAction(ActionID.EarthlyStar, true, isTimeline: true);
///
/// 命运之轮 减伤,手动放。
///
- public static BaseAction CollectiveUnconscious { get; } = new(ActionID.CollectiveUnconscious, true, isTimeline: true);
+ public static IBaseAction CollectiveUnconscious { get; } = new BaseAction(ActionID.CollectiveUnconscious, true, isTimeline: true);
///
/// 天宫图
///
- public static BaseAction Horoscope { get; } = new(ActionID.Horoscope, true, isTimeline: true);
+ public static IBaseAction Horoscope { get; } = new BaseAction(ActionID.Horoscope, true, isTimeline: true);
///
/// 光速
///
- public static BaseAction Lightspeed { get; } = new(ActionID.Lightspeed);
+ public static IBaseAction Lightspeed { get; } = new BaseAction(ActionID.Lightspeed);
///
/// 中间学派
///
- public static BaseAction NeutralSect { get; } = new(ActionID.NeutralSect, isTimeline: true);
+ public static IBaseAction NeutralSect { get; } = new BaseAction(ActionID.NeutralSect, isTimeline: true);
///
/// 大宇宙
///
- public static BaseAction Macrocosmos { get; } = new(ActionID.Macrocosmos, isTimeline: true);
+ public static IBaseAction Macrocosmos { get; } = new BaseAction(ActionID.Macrocosmos, isTimeline: true);
///
/// 星力
///
- public static BaseAction Astrodyne { get; } = new(ActionID.Astrodyne)
+ public static IBaseAction Astrodyne { get; } = new BaseAction(ActionID.Astrodyne)
{
ActionCheck = b =>
{
@@ -171,12 +171,12 @@ internal abstract class ASTRotation_Base : CustomRotation.CustomRotation
///
/// 占卜
///
- public static BaseAction Divination { get; } = new(ActionID.Divination, true);
+ public static IBaseAction Divination { get; } = new BaseAction(ActionID.Divination, true);
///
/// 抽卡
///
- public static BaseAction Draw { get; } = new(ActionID.Draw)
+ public static IBaseAction Draw { get; } = new BaseAction(ActionID.Draw)
{
ActionCheck = b => DrawnCard == CardType.NONE,
};
@@ -184,16 +184,16 @@ internal abstract class ASTRotation_Base : CustomRotation.CustomRotation
///
/// 重抽
///
- public static BaseAction Redraw { get; } = new(ActionID.Redraw)
+ public static IBaseAction Redraw { get; } = new BaseAction(ActionID.Redraw)
{
- BuffsNeed = new[] { StatusID.ClarifyingDraw },
+ StatusNeed = new[] { StatusID.ClarifyingDraw },
ActionCheck = b => DrawnCard != CardType.NONE && Seals.Contains(GetCardSeal(DrawnCard)),
};
///
/// 小奥秘卡
///
- public static BaseAction MinorArcana { get; } = new(ActionID.MinorArcana)
+ public static IBaseAction MinorArcana { get; } = new BaseAction(ActionID.MinorArcana)
{
ActionCheck = b => InCombat && DrawnCrownCard == CardType.NONE,
};
@@ -201,7 +201,7 @@ internal abstract class ASTRotation_Base : CustomRotation.CustomRotation
///
/// 出王冠卡
///
- public static BaseAction CrownPlay { get; } = new(ActionID.CrownPlay)
+ public static IBaseAction CrownPlay { get; } = new BaseAction(ActionID.CrownPlay)
{
ActionCheck = b => DrawnCrownCard is CardType.LADY or CardType.LORD,
};
@@ -209,7 +209,7 @@ internal abstract class ASTRotation_Base : CustomRotation.CustomRotation
///
/// 太阳神之衡
///
- private static BaseAction Balance { get; } = new(ActionID.Balance)
+ private static IBaseAction Balance { get; } = new BaseAction(ActionID.Balance)
{
ChoiceTarget = TargetFilter.ASTMeleeTarget,
ActionCheck = b => DrawnCard == CardType.BALANCE,
@@ -218,7 +218,7 @@ internal abstract class ASTRotation_Base : CustomRotation.CustomRotation
///
/// 放浪神之箭
///
- private static BaseAction Arrow { get; } = new(ActionID.Arrow)
+ private static IBaseAction Arrow { get; } = new BaseAction(ActionID.Arrow)
{
ChoiceTarget = TargetFilter.ASTMeleeTarget,
ActionCheck = b => DrawnCard == CardType.ARROW,
@@ -227,7 +227,7 @@ internal abstract class ASTRotation_Base : CustomRotation.CustomRotation
///
/// 战争神之枪
///
- private static BaseAction Spear { get; } = new(ActionID.Spear)
+ private static IBaseAction Spear { get; } = new BaseAction(ActionID.Spear)
{
ChoiceTarget = TargetFilter.ASTMeleeTarget,
ActionCheck = b => DrawnCard == CardType.SPEAR,
@@ -236,7 +236,7 @@ internal abstract class ASTRotation_Base : CustomRotation.CustomRotation
///
/// 世界树之干
///
- private static BaseAction Bole { get; } = new(ActionID.Bole)
+ private static IBaseAction Bole { get; } = new BaseAction(ActionID.Bole)
{
ChoiceTarget = TargetFilter.ASTRangeTarget,
ActionCheck = b => DrawnCard == CardType.BOLE,
@@ -245,7 +245,7 @@ internal abstract class ASTRotation_Base : CustomRotation.CustomRotation
///
/// 河流神之瓶
///
- private static BaseAction Ewer { get; } = new(ActionID.Ewer)
+ private static IBaseAction Ewer { get; } = new BaseAction(ActionID.Ewer)
{
ChoiceTarget = TargetFilter.ASTRangeTarget,
ActionCheck = b => DrawnCard == CardType.EWER,
@@ -255,7 +255,7 @@ internal abstract class ASTRotation_Base : CustomRotation.CustomRotation
///
/// 建筑神之塔
///
- private static BaseAction Spire { get; } = new(ActionID.Spire)
+ private static IBaseAction Spire { get; } = new BaseAction(ActionID.Spire)
{
ChoiceTarget = TargetFilter.ASTRangeTarget,
ActionCheck = b => DrawnCard == CardType.SPIRE,
diff --git a/RotationSolver/Rotations/Basic/BLMRotation_Base.cs b/RotationSolver/Rotations/Basic/BLM_Base.cs
similarity index 69%
rename from RotationSolver/Rotations/Basic/BLMRotation_Base.cs
rename to RotationSolver/Rotations/Basic/BLM_Base.cs
index 6b0c23d32..69d9ba5af 100644
--- a/RotationSolver/Rotations/Basic/BLMRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/BLM_Base.cs
@@ -148,75 +148,75 @@ public override bool ShouldUse(out IAction act, bool mustUse = false, bool empty
///
/// 闪雷
///
- public static BaseAction Thunder { get; } = new ThunderAction(ActionID.Thunder, isDot: true);
+ public static IBaseAction Thunder { get; } = new ThunderAction(ActionID.Thunder, isDot: true);
///
/// 暴雷
///
- public static BaseAction Thunder3 { get; } = new ThunderAction(ActionID.Thunder3, isDot: true);
+ public static IBaseAction Thunder3 { get; } = new ThunderAction(ActionID.Thunder3, isDot: true);
///
/// 震雷
///
- public static BaseAction Thunder2 { get; } = new ThunderAction(ActionID.Thunder2, isDot: true);
+ public static IBaseAction Thunder2 { get; } = new ThunderAction(ActionID.Thunder2, isDot: true);
///
/// 星灵移位
///
- public static BaseAction Transpose { get; } = new(ActionID.Transpose) { ActionCheck = b => ActionUpdater.AbilityRemain.IsLessThan(JobGauge.ElementTimeRemaining / 1000f) };
+ public static IBaseAction Transpose { get; } = new BaseAction(ActionID.Transpose) { ActionCheck = b => ActionUpdater.AbilityRemain.IsLessThan(JobGauge.ElementTimeRemaining / 1000f) };
///
/// 灵极魂
///
- public static BaseAction UmbralSoul { get; } = new(ActionID.UmbralSoul) { ActionCheck = b => JobGauge.InUmbralIce && Transpose.ActionCheck(b) };
+ public static IBaseAction UmbralSoul { get; } = new BaseAction(ActionID.UmbralSoul) { ActionCheck = b => JobGauge.InUmbralIce && Transpose.ActionCheck(b) };
///
/// 魔罩
///
- public static BaseAction Manaward { get; } = new(ActionID.Manaward, true, isTimeline: true);
+ public static IBaseAction Manaward { get; } = new BaseAction(ActionID.Manaward, true, isTimeline: true);
///
/// 魔泉
///
- public static BaseAction Manafont { get; } = new(ActionID.Manafont);
+ public static IBaseAction Manafont { get; } = new BaseAction(ActionID.Manafont);
///
/// 激情咏唱
///
- public static BaseAction Sharpcast { get; } = new(ActionID.Sharpcast)
+ public static IBaseAction Sharpcast { get; } = new BaseAction(ActionID.Sharpcast)
{
- BuffsProvide = new[] { StatusID.Sharpcast },
+ StatusProvide = new[] { StatusID.Sharpcast },
ActionCheck = b => HaveHostilesInRange,
};
///
/// 三连咏唱
///
- public static BaseAction Triplecast { get; } = new(ActionID.Triplecast)
+ public static IBaseAction Triplecast { get; } = new BaseAction(ActionID.Triplecast)
{
- BuffsProvide = Swiftcast.BuffsProvide,
+ StatusProvide = Swiftcast.StatusProvide,
};
///
/// 黑魔纹
///
- public static BaseAction Leylines { get; } = new(ActionID.Leylines, true, shouldEndSpecial: true)
+ public static IBaseAction Leylines { get; } = new BaseAction(ActionID.Leylines, true, shouldEndSpecial: true)
{
- BuffsProvide = new[] { StatusID.LeyLines, },
+ StatusProvide = new[] { StatusID.LeyLines, },
};
///
/// 魔纹步
///
- public static BaseAction BetweenTheLines { get; } = new(ActionID.BetweenTheLines, true, shouldEndSpecial: true)
+ public static IBaseAction BetweenTheLines { get; } = new BaseAction(ActionID.BetweenTheLines, true, shouldEndSpecial: true)
{
- BuffsNeed = Leylines.BuffsProvide,
+ StatusNeed = Leylines.StatusProvide,
};
///
/// 以太步
///
- public static BaseAction AetherialManipulation { get; } = new(ActionID.AetherialManipulation, true)
+ public static IBaseAction AetherialManipulation { get; } = new BaseAction(ActionID.AetherialManipulation, true)
{
ChoiceTarget = TargetFilter.FindTargetForMoving,
};
@@ -224,37 +224,37 @@ public override bool ShouldUse(out IAction act, bool mustUse = false, bool empty
///
/// 详述
///
- public static BaseAction Amplifier { get; } = new(ActionID.Amplifier) { ActionCheck = b => JobGauge.EnochianTimer > 10000 && JobGauge.PolyglotStacks < 2 };
+ public static IBaseAction Amplifier { get; } = new BaseAction(ActionID.Amplifier) { ActionCheck = b => JobGauge.EnochianTimer > 10000 && JobGauge.PolyglotStacks < 2 };
///
/// 核爆
///
- public static BaseAction Flare { get; } = new ElementAction(ActionID.Flare) { ActionCheck = b => JobGauge.InAstralFire };
+ public static IBaseAction Flare { get; } = new ElementAction(ActionID.Flare) { ActionCheck = b => JobGauge.InAstralFire };
///
/// 绝望
///
- public static BaseAction Despair { get; } = new ElementAction(ActionID.Despair) { ActionCheck = b => JobGauge.InAstralFire };
+ public static IBaseAction Despair { get; } = new ElementAction(ActionID.Despair) { ActionCheck = b => JobGauge.InAstralFire };
///
/// 秽浊
///
- public static BaseAction Foul { get; } = new(ActionID.Foul) { ActionCheck = b => JobGauge.PolyglotStacks != 0 };
+ public static IBaseAction Foul { get; } = new BaseAction(ActionID.Foul) { ActionCheck = b => JobGauge.PolyglotStacks != 0 };
///
/// 异言
///
- public static BaseAction Xenoglossy { get; } = new(ActionID.Xenoglossy) { ActionCheck = b => JobGauge.PolyglotStacks != 0 };
+ public static IBaseAction Xenoglossy { get; } = new BaseAction(ActionID.Xenoglossy) { ActionCheck = b => JobGauge.PolyglotStacks != 0 };
///
/// 崩溃
///
- public static BaseAction Scathe { get; } = new(ActionID.Scathe);
+ public static IBaseAction Scathe { get; } = new BaseAction(ActionID.Scathe);
///
/// 悖论
///
- public static BaseAction Paradox { get; } = new(ActionID.Paradox)
+ public static IBaseAction Paradox { get; } = new BaseAction(ActionID.Paradox)
{
ActionCheck = b => JobGauge.IsParadoxActive,
};
@@ -262,22 +262,22 @@ public override bool ShouldUse(out IAction act, bool mustUse = false, bool empty
///
/// 火1
///
- public static BaseAction Fire { get; } = new(ActionID.Fire);
+ public static IBaseAction Fire { get; } = new BaseAction(ActionID.Fire);
///
/// 火2
///
- public static BaseAction Fire2 { get; } = new(ActionID.Fire2);
+ public static IBaseAction Fire2 { get; } = new BaseAction(ActionID.Fire2);
///
/// 火3
///
- public static BaseAction Fire3 { get; } = new Fire3Action(ActionID.Fire3);
+ public static IBaseAction Fire3 { get; } = new Fire3Action(ActionID.Fire3);
///
/// 火4
///
- public static BaseAction Fire4 { get; } = new ElementAction(ActionID.Fire4)
+ public static IBaseAction Fire4 { get; } = new ElementAction(ActionID.Fire4)
{
ActionCheck = b => JobGauge.InAstralFire,
};
@@ -285,22 +285,22 @@ public override bool ShouldUse(out IAction act, bool mustUse = false, bool empty
///
/// 冰1
///
- public static BaseAction Blizzard { get; } = new(ActionID.Blizzard);
+ public static IBaseAction Blizzard { get; } = new BaseAction(ActionID.Blizzard);
///
/// 冰2
///
- public static BaseAction Blizzard2 { get; } = new(ActionID.Blizzard2);
+ public static IBaseAction Blizzard2 { get; } = new BaseAction(ActionID.Blizzard2);
///
/// 冰3
///
- public static BaseAction Blizzard3 { get; } = new(ActionID.Blizzard3);
+ public static IBaseAction Blizzard3 { get; } = new BaseAction(ActionID.Blizzard3);
///
/// 冰4
///
- public static BaseAction Blizzard4 { get; } = new ElementAction(ActionID.Blizzard4)
+ public static IBaseAction Blizzard4 { get; } = new ElementAction(ActionID.Blizzard4)
{
ActionCheck = b =>
{
@@ -315,7 +315,7 @@ public override bool ShouldUse(out IAction act, bool mustUse = false, bool empty
///
/// 冻结
///
- public static BaseAction Freeze { get; } = new ElementAction(ActionID.Freeze)
+ public static IBaseAction Freeze { get; } = new ElementAction(ActionID.Freeze)
{
ActionCheck = b => JobGauge.InUmbralIce,
};
diff --git a/RotationSolver/Rotations/Basic/BLURotation_Base.cs b/RotationSolver/Rotations/Basic/BLURotation_Base.cs
deleted file mode 100644
index 573b8fa3b..000000000
--- a/RotationSolver/Rotations/Basic/BLURotation_Base.cs
+++ /dev/null
@@ -1,741 +0,0 @@
-using System;
-using System.Linq;
-using RotationSolver.Updaters;
-using RotationSolver.Actions.BaseAction;
-using RotationSolver.Actions;
-using RotationSolver.Helpers;
-using RotationSolver.Data;
-
-namespace RotationSolver.Rotations.Basic;
-
-
-internal abstract class BLURotation_Base : CustomRotation.CustomRotation
-{
- internal enum BLUID : byte
- {
- Tank,
- Healer,
- DPS,
- }
-
-
- internal enum BLUAttackType : byte
- {
- Magical,
- Physical,
- Both,
- }
-
- internal enum BLUActionType : byte
- {
- None,
- Magical,
- Physical,
- }
-
- public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.BlueMage };
-
- protected static BLUAttackType AttackType { get; set; } = BLUAttackType.Both;
-
- protected static BLUID BlueId { get; set; } = BLUID.DPS;
-
- private protected sealed override BaseAction Raise => AngelWhisper;
-
- public class BLUAction : BaseAction
- {
- private BLUActionType Type;
-
- public unsafe bool OnSlot => ActionUpdater.BluSlots.Any(i => AdjustedID == Service.IconReplacer.OriginalHook(i));
-
- internal BLUAction(ActionID actionID, BLUActionType type, bool isFriendly = false, bool shouldEndSpecial = false, bool isEot = false, bool isTimeline = false)
- : base(actionID, isFriendly, shouldEndSpecial, isEot, isTimeline)
- {
- Type = type;
- }
-
- public override bool ShouldUse(out IAction act, bool mustUse = false, bool emptyOrSkipCombo = false, bool skipDisable = false)
- {
- act = null;
-
- if (!OnSlot) return false;
-
- //排除其他类型的魔法。
- if (AttackType == BLUAttackType.Physical && Type == BLUActionType.Magical) return false;
- if (AttackType == BLUAttackType.Magical && Type == BLUActionType.Physical) return false;
-
- return base.ShouldUse(out act, mustUse, emptyOrSkipCombo, skipDisable);
- }
- }
-
- #region 魔法单体
-
- ///
- /// 水炮
- ///
- public static BLUAction WaterCannon { get; } = new(ActionID.WaterCannon, BLUActionType.Magical);
-
- ///
- /// 苦闷之歌
- ///
- public static BLUAction SongofTorment { get; } = new(ActionID.SongofTorment, BLUActionType.Magical, isEot: true)
- {
- TargetStatus = new[] { StatusID.Bleeding }
- };
-
- ///
- /// 吸血
- ///
- public static BLUAction BloodDrain { get; } = new(ActionID.BloodDrain, BLUActionType.Magical)
- {
- ActionCheck = b => Player.CurrentMp <= 9500,
- };
-
- ///
- /// 音爆
- ///
- public static BLUAction SonicBoom { get; } = new(ActionID.SonicBoom, BLUActionType.Magical);
-
- ///
- /// 永恒射线
- ///
- public static BLUAction PerpetualRay { get; } = new(ActionID.PerpetualRay, BLUActionType.Magical);
-
-
- ///
- /// 逆流
- ///
- public static BLUAction Reflux { get; } = new(ActionID.Reflux, BLUActionType.Magical);
-
- ///
- /// 捕食
- ///
- public static BLUAction Devour { get; } = new(ActionID.Devour, BLUActionType.Magical, isTimeline: true);
-
- ///
- /// 斗灵弹
- ///
- public static BLUAction TheRoseofDestruction { get; } = new(ActionID.TheRoseofDestruction, BLUActionType.Magical);
-
- ///
- /// 马特拉魔术
- ///
- public static BLUAction MatraMagic { get; } = new(ActionID.MatraMagic, BLUActionType.Magical);
-
- ///
- /// 冰雾
- ///
- public static BLUAction WhiteDeath { get; } = new(ActionID.WhiteDeath, BLUActionType.Magical)
- {
- ActionCheck = b => Player.HasStatus(true, StatusID.TouchofFrost)
- };
- #endregion
-
- #region 魔法群体
-
- ///
- /// 火炎放射
- ///
- public static BLUAction FlameThrower { get; } = new(ActionID.FlameThrower, BLUActionType.Magical);
-
- ///
- /// 水流吐息
- ///
- public static BLUAction AquaBreath { get; } = new(ActionID.AquaBreath, BLUActionType.Magical, isEot: true);
-
- ///
- /// 高压电流
- ///
- public static BLUAction HighVoltage { get; } = new(ActionID.HighVoltage, BLUActionType.Magical);
-
- ///
- /// 怒视
- ///
- public static BLUAction Glower { get; } = new(ActionID.Glower, BLUActionType.Magical);
-
- ///
- /// 平原震裂
- ///
- public static BLUAction Plaincracker { get; } = new(ActionID.Plaincracker, BLUActionType.Magical);
-
- ///
- /// 诡异视线
- ///
- public static BLUAction TheLook { get; } = new(ActionID.TheLook, BLUActionType.Magical);
-
- ///
- /// 寒冰咆哮
- ///
- public static BLUAction TheRamVoice { get; } = new(ActionID.TheRamVoice, BLUActionType.Magical);
-
- ///
- /// 雷电咆哮
- ///
- public static BLUAction TheDragonVoice { get; } = new(ActionID.TheDragonVoice, BLUActionType.Magical);
-
- ///
- /// 喷墨
- ///
- public static BLUAction InkJet { get; } = new(ActionID.InkJet, BLUActionType.Magical);
-
- ///
- /// 火投枪
- ///
- public static BLUAction FireAngon { get; } = new(ActionID.FireAngon, BLUActionType.Magical);
-
- ///
- /// 精神冲击
- ///
- public static BLUAction MindBlast { get; } = new(ActionID.MindBlast, BLUActionType.Magical);
-
- ///
- /// 飞翎雨
- ///
- public static BLUAction FeatherRain { get; } = new(ActionID.FeatherRain, BLUActionType.Magical);
-
- ///
- /// 地火喷发
- ///
- public static BLUAction Eruption { get; } = new(ActionID.Eruption, BLUActionType.Magical);
-
- ///
- /// 山崩
- ///
- public static BLUAction MountainBuster { get; } = new(ActionID.MountainBusterBLU, BLUActionType.Magical);
-
- ///
- /// 轰雷
- ///
- public static BLUAction ShockStrike { get; } = new(ActionID.ShockStrike, BLUActionType.Magical);
-
- ///
- /// 冰雪乱舞
- ///
- public static BLUAction GlassDance { get; } = new(ActionID.GlassDance, BLUActionType.Magical);
-
- ///
- /// 高山气流
- ///
- public static BLUAction AlpineDraft { get; } = new(ActionID.AlpineDraft, BLUActionType.Magical);
-
- ///
- /// 万变水波
- ///
- public static BLUAction ProteanWave { get; } = new(ActionID.ProteanWave, BLUActionType.Magical);
-
- ///
- /// 狂风暴雪
- ///
- public static BLUAction Northerlies { get; } = new(ActionID.Northerlies, BLUActionType.Magical);
-
- ///
- /// 生物电
- ///
- public static BLUAction Electrogenesis { get; } = new(ActionID.Electrogenesis, BLUActionType.Magical);
-
- ///
- /// 魔法锤
- ///
- public static BLUAction MagicHammer { get; } = new(ActionID.MagicHammer, BLUActionType.Magical, isTimeline: true);
-
- ///
- /// 白骑士之旅
- ///
- public static BLUAction WhiteKnightsTour { get; } = new(ActionID.WhiteKnightsTour, BLUActionType.Magical);
-
- ///
- /// 黑骑士之旅
- ///
- public static BLUAction BlackKnightsTour { get; } = new(ActionID.BlackKnightsTour, BLUActionType.Magical);
-
- ///
- /// 穿甲散弹
- ///
- public static BLUAction Surpanakha { get; } = new(ActionID.Surpanakha, BLUActionType.Magical);
-
- ///
- /// 类星体
- ///
- public static BLUAction Quasar { get; } = new(ActionID.Quasar, BLUActionType.Magical);
-
- ///
- /// 哔哩哔哩
- ///
- public static BLUAction Tingle { get; } = new(ActionID.Tingle, BLUActionType.Magical);
-
- ///
- /// 掀地板之术
- ///
- public static BLUAction Tatamigaeshi { get; } = new(ActionID.Tatamigaeshi, BLUActionType.Magical);
-
- ///
- /// 圣光射线
- ///
- public static BLUAction SaintlyBeam { get; } = new(ActionID.SaintlyBeam, BLUActionType.Magical);
-
- ///
- /// 污泥泼洒
- ///
- public static BLUAction FeculentFlood { get; } = new(ActionID.FeculentFlood, BLUActionType.Magical);
-
- ///
- /// 冰焰
- ///
- public static BLUAction Blaze { get; } = new(ActionID.Blaze, BLUActionType.Magical);
-
- ///
- /// 芥末爆弹
- ///
- public static BLUAction MustardBomb { get; } = new(ActionID.MustardBomb, BLUActionType.Magical);
-
- ///
- /// 以太火花
- ///
- public static BLUAction AetherialSpark { get; } = new(ActionID.AetherialSpark, BLUActionType.Magical, isEot: true);
-
- ///
- /// 水力吸引
- ///
- public static BLUAction HydroPull { get; } = new(ActionID.HydroPull, BLUActionType.Magical);
-
- ///
- /// 水脉诅咒
- ///
- public static BLUAction MaledictionofWater { get; } = new(ActionID.MaledictionofWater, BLUActionType.Magical);
-
- ///
- /// 陆行鸟陨石
- ///
- public static BLUAction ChocoMeteor { get; } = new(ActionID.ChocoMeteor, BLUActionType.Magical);
-
- ///
- /// 月下彼岸花
- ///
- public static BLUAction Nightbloom { get; } = new(ActionID.Nightbloom, BLUActionType.Magical);
-
- ///
- /// 玄天武水壁
- ///
- public static BLUAction DivineCataract { get; } = new(ActionID.DivineCataract, BLUActionType.Magical)
- {
- ActionCheck = b => Player.HasStatus(true, StatusID.AuspiciousTrance)
- };
-
- ///
- /// 鬼宿脚(需要buff版本)
- ///
- public static BLUAction PhantomFlurry2 { get; } = new(ActionID.PhantomFlurry2, BLUActionType.Magical)
- {
- ActionCheck = b => Player.HasStatus(true, StatusID.PhantomFlurry)
- };
- #endregion
-
- #region 物理单体
-
- ///
- /// 终极针
- ///
- public static BLUAction FinalSting { get; } = new(ActionID.FinalSting, BLUActionType.Physical)
- {
- ActionCheck = b => !Player.HasStatus(true, StatusID.BrushwithDeath),
- };
-
- ///
- /// 锋利菜刀
- ///
- public static BLUAction SharpenedKnife { get; } = new(ActionID.SharpenedKnife, BLUActionType.Physical);
-
- ///
- /// 投掷沙丁鱼
- ///
- public static BLUAction FlyingSardine { get; } = new(ActionID.FlyingSardine, BLUActionType.Physical);
-
- ///
- /// 深渊贯穿
- ///
- public static BLUAction AbyssalTransfixion { get; } = new(ActionID.AbyssalTransfixion, BLUActionType.Physical);
-
- ///
- /// 渔叉三段
- ///
- public static BLUAction TripleTrident { get; } = new(ActionID.TripleTrident, BLUActionType.Physical);
-
- ///
- /// 复仇冲击
- ///
- public static BLUAction RevengeBlast { get; } = new(ActionID.RevengeBlast, BLUActionType.Physical)
- {
- ActionCheck = b => b.GetHealthRatio() < 0.2f,
- };
-
- #endregion
-
- #region 物理群体
-
- ///
- /// 狂乱
- ///
- public static BLUAction FlyingFrenzy { get; } = new(ActionID.FlyingFrenzy, BLUActionType.Physical);
-
- ///
- /// 钻头炮
- ///
- public static BLUAction DrillCannons { get; } = new(ActionID.DrillCannons, BLUActionType.Physical);
-
- ///
- /// 4星吨
- ///
- public static BLUAction Weight4tonze { get; } = new(ActionID.Weight4tonze, BLUActionType.Physical);
-
- ///
- /// 千针刺
- ///
- public static BLUAction Needles1000 { get; } = new(ActionID.Needles1000, BLUActionType.Physical);
-
- ///
- /// 寒光
- ///
- public static BLUAction Kaltstrahl { get; } = new(ActionID.Kaltstrahl, BLUActionType.Physical);
-
- ///
- /// 正义飞踢
- ///
- public static BLUAction JKick { get; } = new(ActionID.JKick, BLUActionType.Physical);
-
- ///
- /// 生成外设
- ///
- public static BLUAction PeripheralSynthesis { get; } = new(ActionID.PeripheralSynthesis, BLUActionType.Physical);
-
- ///
- /// 如意大旋风
- ///
- public static BLUAction BothEnds { get; } = new(ActionID.BothEnds, BLUActionType.Physical);
- #endregion
-
- #region 其他单体
- ///
- /// 滑舌
- ///
- public static BLUAction StickyTongue { get; } = new(ActionID.StickyTongue, BLUActionType.None);
-
- ///
- /// 导弹
- ///
- public static BLUAction Missile { get; } = new(ActionID.Missile, BLUActionType.None);
-
- ///
- /// 螺旋尾
- ///
- public static BLUAction TailScrew { get; } = new(ActionID.TailScrew, BLUActionType.None);
-
- ///
- /// 死亡宣告
- ///
- public static BLUAction Doom { get; } = new(ActionID.Doom, BLUActionType.None);
-
- ///
- /// 怪音波
- ///
- public static BLUAction EerieSoundwave { get; } = new(ActionID.EerieSoundwave, BLUActionType.None);
-
- ///
- /// 小侦测
- ///
- public static BLUAction CondensedLibra { get; } = new(ActionID.CondensedLibra, BLUActionType.None);
- #endregion
-
- #region 其他群体
-
- ///
- /// 5级石化
- ///
- public static BLUAction Level5Petrify { get; } = new(ActionID.Level5Petrify, BLUActionType.None);
-
- ///
- /// 橡果炸弹
- ///
- public static BLUAction AcornBomb { get; } = new(ActionID.AcornBomb, BLUActionType.None);
-
- ///
- /// 投弹
- ///
- public static BLUAction BombToss { get; } = new(ActionID.BombToss, BLUActionType.None);
-
- ///
- /// 自爆
- ///
- public static BLUAction Selfdestruct { get; } = new(ActionID.Selfdestruct, BLUActionType.None)
- {
- ActionCheck = b => !Player.HasStatus(true, StatusID.BrushwithDeath),
- };
-
- ///
- /// 拍掌
- ///
- public static BLUAction Faze { get; } = new(ActionID.Faze, BLUActionType.None);
-
- ///
- /// 鼻息
- ///
- public static BLUAction Snort { get; } = new(ActionID.Snort, BLUActionType.None);
-
- ///
- /// 臭气
- ///
- public static BLUAction BadBreath { get; } = new(ActionID.BadBreath, BLUActionType.None, isTimeline: true);
-
- ///
- /// 唧唧咋咋
- ///
- public static BLUAction Chirp { get; } = new(ActionID.Chirp, BLUActionType.None);
-
- ///
- /// 蛙腿
- ///
- public static BLUAction FrogLegs { get; } = new(ActionID.FrogLegs, BLUActionType.None);
-
- ///
- /// 5级即死
- ///
- public static BLUAction Level5Death { get; } = new(ActionID.Level5Death, BLUActionType.None);
-
- ///
- /// 火箭炮
- ///
- public static BLUAction Launcher { get; } = new(ActionID.Launcher, BLUActionType.None);
-
- ///
- /// 超振动
- ///
- public static BLUAction Ultravibration { get; } = new(ActionID.Ultravibration, BLUActionType.None);
-
- ///
- /// 鬼宿脚
- ///
- public static BLUAction PhantomFlurry { get; } = new(ActionID.PhantomFlurry, BLUActionType.None);
- #endregion
-
- #region 防御
-
- ///
- /// 冰棘屏障
- ///
- public static BLUAction IceSpikes { get; } = new(ActionID.IceSpikes, BLUActionType.None, true);
-
- ///
- /// 水神的面纱
- ///
- public static BLUAction VeiloftheWhorl { get; } = new(ActionID.VeiloftheWhorl, BLUActionType.None, true);
-
- ///
- /// 超硬化
- ///
- public static BLUAction Diamondback { get; } = new(ActionID.Diamondback, BLUActionType.None, true, isTimeline: true)
- {
- BuffsProvide = Rampart.BuffsProvide,
- ActionCheck = BaseAction.TankDefenseSelf,
- };
-
- ///
- /// 哥布防御
- ///
- public static BLUAction Gobskin { get; } = new(ActionID.Gobskin, BLUActionType.None, true, isTimeline: true)
- {
- BuffsProvide = Rampart.BuffsProvide,
- ActionCheck = BaseAction.TankDefenseSelf,
- };
-
- ///
- /// 仙人盾
- ///
- public static BLUAction Cactguard { get; } = new(ActionID.Cactguard, BLUActionType.None, true, isTimeline: true)
- {
- BuffsProvide = Rampart.BuffsProvide,
- ActionCheck = BaseAction.TankDefenseSelf,
- };
-
- ///
- /// 玄结界
- ///
- public static BLUAction ChelonianGate { get; } = new(ActionID.ChelonianGate, BLUActionType.None, true, isTimeline: true)
- {
- BuffsProvide = Rampart.BuffsProvide,
- ActionCheck = BaseAction.TankDefenseSelf,
- };
-
- ///
- /// 龙之力
- ///
- public static BLUAction DragonForce { get; } = new(ActionID.DragonForce, BLUActionType.None, true, isTimeline: true)
- {
- BuffsProvide = Rampart.BuffsProvide,
- ActionCheck = BaseAction.TankDefenseSelf,
- };
- #endregion
-
-
- #region 辅助
- ///
- /// 油性分泌物
- ///
- public static BLUAction ToadOil { get; } = new(ActionID.ToadOil, BLUActionType.None, true);
-
- ///
- /// 怒发冲冠
- ///
- public static BLUAction Bristle { get; } = new(ActionID.Bristle, BLUActionType.Magical, true)
- {
- BuffsProvide = new StatusID[] { StatusID.Boost, StatusID.Harmonized },
- };
-
- ///
- /// 破防
- ///
- public static BLUAction Offguard { get; } = new(ActionID.Offguard, BLUActionType.None, true);
-
- ///
- /// 强力守护
- ///
- public static BLUAction MightyGuard { get; } = new(ActionID.MightyGuard, BLUActionType.None, true);
-
- ///
- /// 月之笛
- ///
- public static BLUAction MoonFlute { get; } = new(ActionID.MoonFlute, BLUActionType.None, true)
- {
- BuffsProvide = new StatusID[] { StatusID.WaxingNocturne },
- };
-
- ///
- /// 惊奇光
- ///
- public static BLUAction PeculiarLight { get; } = new(ActionID.PeculiarLight, BLUActionType.Magical);
-
- ///
- /// 防御指示
- ///
- public static BLUAction Avail { get; } = new(ActionID.Avail, BLUActionType.Magical);
-
- ///
- /// 口笛
- ///
- public static BLUAction Whistle { get; } = new(ActionID.Whistle, BLUActionType.Physical, true)
- {
- BuffsProvide = new StatusID[] { StatusID.Boost, StatusID.Harmonized },
- };
-
-
- ///
- /// 彻骨雾寒
- ///
- public static BLUAction ColdFog { get; } = new(ActionID.ColdFog, BLUActionType.Magical, true);
- #endregion
-
- #region 治疗
- ///
- /// 白风
- ///
- public static BLUAction WhiteWind { get; } = new(ActionID.WhiteWind, BLUActionType.None, true)
- {
- ActionCheck = b => Player.GetHealthRatio() is > 0.3f and < 0.5f,
- };
-
- ///
- /// 赞歌
- ///
- public static BLUAction Stotram { get; } = new(ActionID.Stotram, BLUActionType.Magical, true);
-
-
- ///
- /// 绒绒治疗
- ///
- public static BLUAction PomCure { get; } = new(ActionID.PomCure, BLUActionType.None, true);
-
- ///
- /// 天使低语
- ///
- public static BLUAction AngelWhisper { get; } = new(ActionID.AngelWhisper, BLUActionType.None, true);
-
- ///
- /// 蜕皮
- ///
- public static BLUAction Exuviation { get; } = new(ActionID.Exuviation, BLUActionType.None, true);
-
- ///
- /// 天使的点心
- ///
- public static BLUAction AngelsSnack { get; } = new(ActionID.AngelsSnack, BLUActionType.None, true);
- #endregion
-
- #region 其他
- ///
- /// 若隐若现
- ///
- private static BLUAction Loom { get; } = new(ActionID.Loom, BLUActionType.None);
-
- ///
- /// 斗争本能
- ///
- public static BLUAction BasicInstinct { get; } = new(ActionID.BasicInstinct, BLUActionType.None)
- {
- BuffsProvide = new StatusID[] { StatusID.BasicInstinct },
- ActionCheck = b =>
- {
- //TODO: 还需要判断是否为多人本
- return Service.Conditions[Dalamud.Game.ClientState.Conditions.ConditionFlag.BoundByDuty56]
- && TargetUpdater.PartyMembers.Count(p => p.GetHealthRatio() > 0) == 1;
- },
- };
-
- ///
- /// 以太复制
- ///
- private static BLUAction AetherialMimicry { get; } = new(ActionID.AetherialMimicry, BLUActionType.None, true)
- {
- ChoiceTarget = (charas, mustUse) =>
- {
- switch (BlueId)
- {
- case BLUID.DPS:
- if (!Player.HasStatus(true, StatusID.AethericMimicryDPS))
- {
- return charas.GetJobCategory(JobRole.Melee, JobRole.RangedMagicial, JobRole.RangedPhysical).FirstOrDefault();
- }
- break;
-
- case BLUID.Tank:
- if (!Player.HasStatus(true, StatusID.AethericMimicryTank))
- {
- return charas.GetJobCategory(JobRole.Tank).FirstOrDefault();
- }
- break;
-
- case BLUID.Healer:
- if (!Player.HasStatus(true, StatusID.AethericMimicryHealer))
- {
- return charas.GetJobCategory(JobRole.Healer).FirstOrDefault();
- }
- break;
- }
- return null;
- },
- };
-
- #endregion
-
- private protected override bool MoveGCD(out IAction act)
- {
- if (Loom.ShouldUse(out act)) return true;
- return base.MoveGCD(out act);
- }
-
-
- private protected override bool EmergencyGCD(out IAction act)
- {
- if (AetherialMimicry.ShouldUse(out act)) return true;
- if (BasicInstinct.ShouldUse(out act)) return true;
- return base.EmergencyGCD(out act);
- }
-
- protected static bool AllOnSlot(params BLUAction[] actions) => actions.All(a => a.OnSlot);
-}
diff --git a/RotationSolver/Rotations/Basic/BLU_Base.cs b/RotationSolver/Rotations/Basic/BLU_Base.cs
new file mode 100644
index 000000000..68eaf7e49
--- /dev/null
+++ b/RotationSolver/Rotations/Basic/BLU_Base.cs
@@ -0,0 +1,746 @@
+using System;
+using System.Linq;
+using RotationSolver.Updaters;
+using RotationSolver.Actions.BaseAction;
+using RotationSolver.Actions;
+using RotationSolver.Helpers;
+using RotationSolver.Data;
+
+namespace RotationSolver.Rotations.Basic;
+
+
+internal abstract class BLURotation_Base : CustomRotation.CustomRotation
+{
+ internal enum BLUID : byte
+ {
+ Tank,
+ Healer,
+ DPS,
+ }
+
+
+ internal enum BLUAttackType : byte
+ {
+ Magical,
+ Physical,
+ Both,
+ }
+
+ internal enum BLUActionType : byte
+ {
+ None,
+ Magical,
+ Physical,
+ }
+
+ public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.BlueMage };
+
+ protected static BLUAttackType AttackType { get; set; } = BLUAttackType.Both;
+
+ protected static BLUID BlueId { get; set; } = BLUID.DPS;
+
+ private protected sealed override IBaseAction Raise => AngelWhisper;
+
+ public interface IBLUAction : IBaseAction
+ {
+ bool OnSlot { get; }
+ }
+
+ public class BLUAction : BaseAction, IBLUAction
+ {
+ private BLUActionType Type;
+
+ public unsafe bool OnSlot => ActionUpdater.BluSlots.Any(i => AdjustedID == Service.IconReplacer.OriginalHook(i));
+
+ internal BLUAction(ActionID actionID, BLUActionType type, bool isFriendly = false, bool shouldEndSpecial = false, bool isEot = false, bool isTimeline = false)
+ : base(actionID, isFriendly, shouldEndSpecial, isEot, isTimeline)
+ {
+ Type = type;
+ }
+
+ public override bool ShouldUse(out IAction act, bool mustUse = false, bool emptyOrSkipCombo = false, bool skipDisable = false)
+ {
+ act = null;
+
+ if (!OnSlot) return false;
+
+ //排除其他类型的魔法。
+ if (AttackType == BLUAttackType.Physical && Type == BLUActionType.Magical) return false;
+ if (AttackType == BLUAttackType.Magical && Type == BLUActionType.Physical) return false;
+
+ return base.ShouldUse(out act, mustUse, emptyOrSkipCombo, skipDisable);
+ }
+ }
+
+ #region 魔法单体
+
+ ///
+ /// 水炮
+ ///
+ public static IBLUAction WaterCannon { get; } = new BLUAction(ActionID.WaterCannon, BLUActionType.Magical);
+
+ ///
+ /// 苦闷之歌
+ ///
+ public static IBLUAction SongofTorment { get; } = new BLUAction(ActionID.SongofTorment, BLUActionType.Magical, isEot: true)
+ {
+ TargetStatus = new[] { StatusID.Bleeding }
+ };
+
+ ///
+ /// 吸血
+ ///
+ public static IBLUAction BloodDrain { get; } = new BLUAction(ActionID.BloodDrain, BLUActionType.Magical)
+ {
+ ActionCheck = b => Player.CurrentMp <= 9500,
+ };
+
+ ///
+ /// 音爆
+ ///
+ public static IBLUAction SonicBoom { get; } = new BLUAction(ActionID.SonicBoom, BLUActionType.Magical);
+
+ ///
+ /// 永恒射线
+ ///
+ public static IBLUAction PerpetualRay { get; } = new BLUAction(ActionID.PerpetualRay, BLUActionType.Magical);
+
+
+ ///
+ /// 逆流
+ ///
+ public static IBLUAction Reflux { get; } = new BLUAction(ActionID.Reflux, BLUActionType.Magical);
+
+ ///
+ /// 捕食
+ ///
+ public static IBLUAction Devour { get; } = new BLUAction(ActionID.Devour, BLUActionType.Magical, isTimeline: true);
+
+ ///
+ /// 斗灵弹
+ ///
+ public static IBLUAction TheRoseofDestruction { get; } = new BLUAction(ActionID.TheRoseofDestruction, BLUActionType.Magical);
+
+ ///
+ /// 马特拉魔术
+ ///
+ public static IBLUAction MatraMagic { get; } = new BLUAction(ActionID.MatraMagic, BLUActionType.Magical);
+
+ ///
+ /// 冰雾
+ ///
+ public static IBLUAction WhiteDeath { get; } = new BLUAction(ActionID.WhiteDeath, BLUActionType.Magical)
+ {
+ ActionCheck = b => Player.HasStatus(true, StatusID.TouchofFrost)
+ };
+ #endregion
+
+ #region 魔法群体
+
+ ///
+ /// 火炎放射
+ ///
+ public static IBLUAction FlameThrower { get; } = new BLUAction(ActionID.FlameThrower, BLUActionType.Magical);
+
+ ///
+ /// 水流吐息
+ ///
+ public static IBLUAction AquaBreath { get; } = new BLUAction(ActionID.AquaBreath, BLUActionType.Magical, isEot: true);
+
+ ///
+ /// 高压电流
+ ///
+ public static IBLUAction HighVoltage { get; } = new BLUAction(ActionID.HighVoltage, BLUActionType.Magical);
+
+ ///
+ /// 怒视
+ ///
+ public static IBLUAction Glower { get; } = new BLUAction(ActionID.Glower, BLUActionType.Magical);
+
+ ///
+ /// 平原震裂
+ ///
+ public static IBLUAction Plaincracker { get; } = new BLUAction(ActionID.Plaincracker, BLUActionType.Magical);
+
+ ///
+ /// 诡异视线
+ ///
+ public static IBLUAction TheLook { get; } = new BLUAction(ActionID.TheLook, BLUActionType.Magical);
+
+ ///
+ /// 寒冰咆哮
+ ///
+ public static IBLUAction TheRamVoice { get; } = new BLUAction(ActionID.TheRamVoice, BLUActionType.Magical);
+
+ ///
+ /// 雷电咆哮
+ ///
+ public static IBLUAction TheDragonVoice { get; } = new BLUAction(ActionID.TheDragonVoice, BLUActionType.Magical);
+
+ ///
+ /// 喷墨
+ ///
+ public static IBLUAction InkJet { get; } = new BLUAction(ActionID.InkJet, BLUActionType.Magical);
+
+ ///
+ /// 火投枪
+ ///
+ public static IBLUAction FireAngon { get; } = new BLUAction(ActionID.FireAngon, BLUActionType.Magical);
+
+ ///
+ /// 精神冲击
+ ///
+ public static IBLUAction MindBlast { get; } = new BLUAction(ActionID.MindBlast, BLUActionType.Magical);
+
+ ///
+ /// 飞翎雨
+ ///
+ public static IBLUAction FeatherRain { get; } = new BLUAction(ActionID.FeatherRain, BLUActionType.Magical);
+
+ ///
+ /// 地火喷发
+ ///
+ public static IBLUAction Eruption { get; } = new BLUAction(ActionID.Eruption, BLUActionType.Magical);
+
+ ///
+ /// 山崩
+ ///
+ public static IBLUAction MountainBuster { get; } = new BLUAction(ActionID.MountainBusterBLU, BLUActionType.Magical);
+
+ ///
+ /// 轰雷
+ ///
+ public static IBLUAction ShockStrike { get; } = new BLUAction(ActionID.ShockStrike, BLUActionType.Magical);
+
+ ///
+ /// 冰雪乱舞
+ ///
+ public static IBLUAction GlassDance { get; } = new BLUAction(ActionID.GlassDance, BLUActionType.Magical);
+
+ ///
+ /// 高山气流
+ ///
+ public static IBLUAction AlpineDraft { get; } = new BLUAction(ActionID.AlpineDraft, BLUActionType.Magical);
+
+ ///
+ /// 万变水波
+ ///
+ public static IBLUAction ProteanWave { get; } = new BLUAction(ActionID.ProteanWave, BLUActionType.Magical);
+
+ ///
+ /// 狂风暴雪
+ ///
+ public static IBLUAction Northerlies { get; } = new BLUAction(ActionID.Northerlies, BLUActionType.Magical);
+
+ ///
+ /// 生物电
+ ///
+ public static IBLUAction Electrogenesis { get; } = new BLUAction(ActionID.Electrogenesis, BLUActionType.Magical);
+
+ ///
+ /// 魔法锤
+ ///
+ public static IBLUAction MagicHammer { get; } = new BLUAction(ActionID.MagicHammer, BLUActionType.Magical, isTimeline: true);
+
+ ///
+ /// 白骑士之旅
+ ///
+ public static IBLUAction WhiteKnightsTour { get; } = new BLUAction(ActionID.WhiteKnightsTour, BLUActionType.Magical);
+
+ ///
+ /// 黑骑士之旅
+ ///
+ public static IBLUAction BlackKnightsTour { get; } = new BLUAction(ActionID.BlackKnightsTour, BLUActionType.Magical);
+
+ ///
+ /// 穿甲散弹
+ ///
+ public static IBLUAction Surpanakha { get; } = new BLUAction(ActionID.Surpanakha, BLUActionType.Magical);
+
+ ///
+ /// 类星体
+ ///
+ public static IBLUAction Quasar { get; } = new BLUAction(ActionID.Quasar, BLUActionType.Magical);
+
+ ///
+ /// 哔哩哔哩
+ ///
+ public static IBLUAction Tingle { get; } = new BLUAction(ActionID.Tingle, BLUActionType.Magical);
+
+ ///
+ /// 掀地板之术
+ ///
+ public static IBLUAction Tatamigaeshi { get; } = new BLUAction(ActionID.Tatamigaeshi, BLUActionType.Magical);
+
+ ///
+ /// 圣光射线
+ ///
+ public static IBLUAction SaintlyBeam { get; } = new BLUAction(ActionID.SaintlyBeam, BLUActionType.Magical);
+
+ ///
+ /// 污泥泼洒
+ ///
+ public static IBLUAction FeculentFlood { get; } = new BLUAction(ActionID.FeculentFlood, BLUActionType.Magical);
+
+ ///
+ /// 冰焰
+ ///
+ public static IBLUAction Blaze { get; } = new BLUAction(ActionID.Blaze, BLUActionType.Magical);
+
+ ///
+ /// 芥末爆弹
+ ///
+ public static IBLUAction MustardBomb { get; } = new BLUAction(ActionID.MustardBomb, BLUActionType.Magical);
+
+ ///
+ /// 以太火花
+ ///
+ public static IBLUAction AetherialSpark { get; } = new BLUAction(ActionID.AetherialSpark, BLUActionType.Magical, isEot: true);
+
+ ///
+ /// 水力吸引
+ ///
+ public static IBLUAction HydroPull { get; } = new BLUAction(ActionID.HydroPull, BLUActionType.Magical);
+
+ ///
+ /// 水脉诅咒
+ ///
+ public static IBLUAction MaledictionofWater { get; } = new BLUAction(ActionID.MaledictionofWater, BLUActionType.Magical);
+
+ ///
+ /// 陆行鸟陨石
+ ///
+ public static IBLUAction ChocoMeteor { get; } = new BLUAction(ActionID.ChocoMeteor, BLUActionType.Magical);
+
+ ///
+ /// 月下彼岸花
+ ///
+ public static IBLUAction Nightbloom { get; } = new BLUAction(ActionID.Nightbloom, BLUActionType.Magical);
+
+ ///
+ /// 玄天武水壁
+ ///
+ public static IBLUAction DivineCataract { get; } = new BLUAction(ActionID.DivineCataract, BLUActionType.Magical)
+ {
+ ActionCheck = b => Player.HasStatus(true, StatusID.AuspiciousTrance)
+ };
+
+ ///
+ /// 鬼宿脚(需要buff版本)
+ ///
+ public static IBLUAction PhantomFlurry2 { get; } = new BLUAction(ActionID.PhantomFlurry2, BLUActionType.Magical)
+ {
+ ActionCheck = b => Player.HasStatus(true, StatusID.PhantomFlurry)
+ };
+ #endregion
+
+ #region 物理单体
+
+ ///
+ /// 终极针
+ ///
+ public static IBLUAction FinalSting { get; } = new BLUAction(ActionID.FinalSting, BLUActionType.Physical)
+ {
+ ActionCheck = b => !Player.HasStatus(true, StatusID.BrushwithDeath),
+ };
+
+ ///
+ /// 锋利菜刀
+ ///
+ public static IBLUAction SharpenedKnife { get; } = new BLUAction(ActionID.SharpenedKnife, BLUActionType.Physical);
+
+ ///
+ /// 投掷沙丁鱼
+ ///
+ public static IBLUAction FlyingSardine { get; } = new BLUAction(ActionID.FlyingSardine, BLUActionType.Physical);
+
+ ///
+ /// 深渊贯穿
+ ///
+ public static IBLUAction AbyssalTransfixion { get; } = new BLUAction(ActionID.AbyssalTransfixion, BLUActionType.Physical);
+
+ ///
+ /// 渔叉三段
+ ///
+ public static IBLUAction TripleTrident { get; } = new BLUAction(ActionID.TripleTrident, BLUActionType.Physical);
+
+ ///
+ /// 复仇冲击
+ ///
+ public static IBLUAction RevengeBlast { get; } = new BLUAction(ActionID.RevengeBlast, BLUActionType.Physical)
+ {
+ ActionCheck = b => b.GetHealthRatio() < 0.2f,
+ };
+
+ #endregion
+
+ #region 物理群体
+
+ ///
+ /// 狂乱
+ ///
+ public static IBLUAction FlyingFrenzy { get; } = new BLUAction(ActionID.FlyingFrenzy, BLUActionType.Physical);
+
+ ///
+ /// 钻头炮
+ ///
+ public static IBLUAction DrillCannons { get; } = new BLUAction(ActionID.DrillCannons, BLUActionType.Physical);
+
+ ///
+ /// 4星吨
+ ///
+ public static IBLUAction Weight4tonze { get; } = new BLUAction(ActionID.Weight4tonze, BLUActionType.Physical);
+
+ ///
+ /// 千针刺
+ ///
+ public static IBLUAction Needles1000 { get; } = new BLUAction(ActionID.Needles1000, BLUActionType.Physical);
+
+ ///
+ /// 寒光
+ ///
+ public static IBLUAction Kaltstrahl { get; } = new BLUAction(ActionID.Kaltstrahl, BLUActionType.Physical);
+
+ ///
+ /// 正义飞踢
+ ///
+ public static IBLUAction JKick { get; } = new BLUAction(ActionID.JKick, BLUActionType.Physical);
+
+ ///
+ /// 生成外设
+ ///
+ public static IBLUAction PeripheralSynthesis { get; } = new BLUAction(ActionID.PeripheralSynthesis, BLUActionType.Physical);
+
+ ///
+ /// 如意大旋风
+ ///
+ public static IBLUAction BothEnds { get; } = new BLUAction(ActionID.BothEnds, BLUActionType.Physical);
+ #endregion
+
+ #region 其他单体
+ ///
+ /// 滑舌
+ ///
+ public static IBLUAction StickyTongue { get; } = new BLUAction(ActionID.StickyTongue, BLUActionType.None);
+
+ ///
+ /// 导弹
+ ///
+ public static IBLUAction Missile { get; } = new BLUAction(ActionID.Missile, BLUActionType.None);
+
+ ///
+ /// 螺旋尾
+ ///
+ public static IBLUAction TailScrew { get; } = new BLUAction(ActionID.TailScrew, BLUActionType.None);
+
+ ///
+ /// 死亡宣告
+ ///
+ public static IBLUAction Doom { get; } = new BLUAction(ActionID.Doom, BLUActionType.None);
+
+ ///
+ /// 怪音波
+ ///
+ public static IBLUAction EerieSoundwave { get; } = new BLUAction(ActionID.EerieSoundwave, BLUActionType.None);
+
+ ///
+ /// 小侦测
+ ///
+ public static IBLUAction CondensedLibra { get; } = new BLUAction(ActionID.CondensedLibra, BLUActionType.None);
+ #endregion
+
+ #region 其他群体
+
+ ///
+ /// 5级石化
+ ///
+ public static IBLUAction Level5Petrify { get; } = new BLUAction(ActionID.Level5Petrify, BLUActionType.None);
+
+ ///
+ /// 橡果炸弹
+ ///
+ public static IBLUAction AcornBomb { get; } = new BLUAction(ActionID.AcornBomb, BLUActionType.None);
+
+ ///
+ /// 投弹
+ ///
+ public static IBLUAction BombToss { get; } = new BLUAction(ActionID.BombToss, BLUActionType.None);
+
+ ///
+ /// 自爆
+ ///
+ public static IBLUAction Selfdestruct { get; } = new BLUAction(ActionID.Selfdestruct, BLUActionType.None)
+ {
+ ActionCheck = b => !Player.HasStatus(true, StatusID.BrushwithDeath),
+ };
+
+ ///
+ /// 拍掌
+ ///
+ public static IBLUAction Faze { get; } = new BLUAction(ActionID.Faze, BLUActionType.None);
+
+ ///
+ /// 鼻息
+ ///
+ public static IBLUAction Snort { get; } = new BLUAction(ActionID.Snort, BLUActionType.None);
+
+ ///
+ /// 臭气
+ ///
+ public static IBLUAction BadBreath { get; } = new BLUAction(ActionID.BadBreath, BLUActionType.None, isTimeline: true);
+
+ ///
+ /// 唧唧咋咋
+ ///
+ public static IBLUAction Chirp { get; } = new BLUAction(ActionID.Chirp, BLUActionType.None);
+
+ ///
+ /// 蛙腿
+ ///
+ public static IBLUAction FrogLegs { get; } = new BLUAction(ActionID.FrogLegs, BLUActionType.None);
+
+ ///
+ /// 5级即死
+ ///
+ public static IBLUAction Level5Death { get; } = new BLUAction(ActionID.Level5Death, BLUActionType.None);
+
+ ///
+ /// 火箭炮
+ ///
+ public static IBLUAction Launcher { get; } = new BLUAction(ActionID.Launcher, BLUActionType.None);
+
+ ///
+ /// 超振动
+ ///
+ public static IBLUAction Ultravibration { get; } = new BLUAction(ActionID.Ultravibration, BLUActionType.None);
+
+ ///
+ /// 鬼宿脚
+ ///
+ public static IBLUAction PhantomFlurry { get; } = new BLUAction(ActionID.PhantomFlurry, BLUActionType.None);
+ #endregion
+
+ #region 防御
+
+ ///
+ /// 冰棘屏障
+ ///
+ public static IBLUAction IceSpikes { get; } = new BLUAction(ActionID.IceSpikes, BLUActionType.None, true);
+
+ ///
+ /// 水神的面纱
+ ///
+ public static IBLUAction VeiloftheWhorl { get; } = new BLUAction(ActionID.VeiloftheWhorl, BLUActionType.None, true);
+
+ ///
+ /// 超硬化
+ ///
+ public static IBLUAction Diamondback { get; } = new BLUAction(ActionID.Diamondback, BLUActionType.None, true, isTimeline: true)
+ {
+ StatusProvide = Rampart.StatusProvide,
+ ActionCheck = BaseAction.TankDefenseSelf,
+ };
+
+ ///
+ /// 哥布防御
+ ///
+ public static IBLUAction Gobskin { get; } = new BLUAction(ActionID.Gobskin, BLUActionType.None, true, isTimeline: true)
+ {
+ StatusProvide = Rampart.StatusProvide,
+ ActionCheck = BaseAction.TankDefenseSelf,
+ };
+
+ ///
+ /// 仙人盾
+ ///
+ public static IBLUAction Cactguard { get; } = new BLUAction(ActionID.Cactguard, BLUActionType.None, true, isTimeline: true)
+ {
+ StatusProvide = Rampart.StatusProvide,
+ ActionCheck = BaseAction.TankDefenseSelf,
+ };
+
+ ///
+ /// 玄结界
+ ///
+ public static IBLUAction ChelonianGate { get; } = new BLUAction(ActionID.ChelonianGate, BLUActionType.None, true, isTimeline: true)
+ {
+ StatusProvide = Rampart.StatusProvide,
+ ActionCheck = BaseAction.TankDefenseSelf,
+ };
+
+ ///
+ /// 龙之力
+ ///
+ public static IBLUAction DragonForce { get; } = new BLUAction(ActionID.DragonForce, BLUActionType.None, true, isTimeline: true)
+ {
+ StatusProvide = Rampart.StatusProvide,
+ ActionCheck = BaseAction.TankDefenseSelf,
+ };
+ #endregion
+
+
+ #region 辅助
+ ///
+ /// 油性分泌物
+ ///
+ public static IBLUAction ToadOil { get; } = new BLUAction(ActionID.ToadOil, BLUActionType.None, true);
+
+ ///
+ /// 怒发冲冠
+ ///
+ public static IBLUAction Bristle { get; } = new BLUAction(ActionID.Bristle, BLUActionType.Magical, true)
+ {
+ StatusProvide = new StatusID[] { StatusID.Boost, StatusID.Harmonized },
+ };
+
+ ///
+ /// 破防
+ ///
+ public static IBLUAction Offguard { get; } = new BLUAction(ActionID.Offguard, BLUActionType.None, true);
+
+ ///
+ /// 强力守护
+ ///
+ public static IBLUAction MightyGuard { get; } = new BLUAction(ActionID.MightyGuard, BLUActionType.None, true);
+
+ ///
+ /// 月之笛
+ ///
+ public static IBLUAction MoonFlute { get; } = new BLUAction(ActionID.MoonFlute, BLUActionType.None, true)
+ {
+ StatusProvide = new StatusID[] { StatusID.WaxingNocturne },
+ };
+
+ ///
+ /// 惊奇光
+ ///
+ public static IBLUAction PeculiarLight { get; } = new BLUAction(ActionID.PeculiarLight, BLUActionType.Magical);
+
+ ///
+ /// 防御指示
+ ///
+ public static IBLUAction Avail { get; } = new BLUAction(ActionID.Avail, BLUActionType.Magical);
+
+ ///
+ /// 口笛
+ ///
+ public static IBLUAction Whistle { get; } = new BLUAction(ActionID.Whistle, BLUActionType.Physical, true)
+ {
+ StatusProvide = new StatusID[] { StatusID.Boost, StatusID.Harmonized },
+ };
+
+
+ ///
+ /// 彻骨雾寒
+ ///
+ public static IBLUAction ColdFog { get; } = new BLUAction(ActionID.ColdFog, BLUActionType.Magical, true);
+ #endregion
+
+ #region 治疗
+ ///
+ /// 白风
+ ///
+ public static IBLUAction WhiteWind { get; } = new BLUAction(ActionID.WhiteWind, BLUActionType.None, true)
+ {
+ ActionCheck = b => Player.GetHealthRatio() is > 0.3f and < 0.5f,
+ };
+
+ ///
+ /// 赞歌
+ ///
+ public static IBLUAction Stotram { get; } = new BLUAction(ActionID.Stotram, BLUActionType.Magical, true);
+
+
+ ///
+ /// 绒绒治疗
+ ///
+ public static IBLUAction PomCure { get; } = new BLUAction(ActionID.PomCure, BLUActionType.None, true);
+
+ ///
+ /// 天使低语
+ ///
+ public static IBLUAction AngelWhisper { get; } = new BLUAction(ActionID.AngelWhisper, BLUActionType.None, true);
+
+ ///
+ /// 蜕皮
+ ///
+ public static IBLUAction Exuviation { get; } = new BLUAction(ActionID.Exuviation, BLUActionType.None, true);
+
+ ///
+ /// 天使的点心
+ ///
+ public static IBLUAction AngelsSnack { get; } = new BLUAction(ActionID.AngelsSnack, BLUActionType.None, true);
+ #endregion
+
+ #region 其他
+ ///
+ /// 若隐若现
+ ///
+ private static IBLUAction Loom { get; } = new BLUAction(ActionID.Loom, BLUActionType.None);
+
+ ///
+ /// 斗争本能
+ ///
+ public static IBLUAction BasicInstinct { get; } = new BLUAction(ActionID.BasicInstinct, BLUActionType.None)
+ {
+ StatusProvide = new StatusID[] { StatusID.BasicInstinct },
+ ActionCheck = b =>
+ {
+ //TODO: 还需要判断是否为多人本
+ return Service.Conditions[Dalamud.Game.ClientState.Conditions.ConditionFlag.BoundByDuty56]
+ && TargetUpdater.PartyMembers.Count(p => p.GetHealthRatio() > 0) == 1;
+ },
+ };
+
+ ///
+ /// 以太复制
+ ///
+ private static IBLUAction AetherialMimicry { get; } = new BLUAction(ActionID.AetherialMimicry, BLUActionType.None, true)
+ {
+ ChoiceTarget = (charas, mustUse) =>
+ {
+ switch (BlueId)
+ {
+ case BLUID.DPS:
+ if (!Player.HasStatus(true, StatusID.AethericMimicryDPS))
+ {
+ return charas.GetJobCategory(JobRole.Melee, JobRole.RangedMagicial, JobRole.RangedPhysical).FirstOrDefault();
+ }
+ break;
+
+ case BLUID.Tank:
+ if (!Player.HasStatus(true, StatusID.AethericMimicryTank))
+ {
+ return charas.GetJobCategory(JobRole.Tank).FirstOrDefault();
+ }
+ break;
+
+ case BLUID.Healer:
+ if (!Player.HasStatus(true, StatusID.AethericMimicryHealer))
+ {
+ return charas.GetJobCategory(JobRole.Healer).FirstOrDefault();
+ }
+ break;
+ }
+ return null;
+ },
+ };
+
+ #endregion
+
+ private protected override bool MoveGCD(out IAction act)
+ {
+ if (Loom.ShouldUse(out act)) return true;
+ return base.MoveGCD(out act);
+ }
+
+
+ private protected override bool EmergencyGCD(out IAction act)
+ {
+ if (AetherialMimicry.ShouldUse(out act)) return true;
+ if (BasicInstinct.ShouldUse(out act)) return true;
+ return base.EmergencyGCD(out act);
+ }
+
+ protected static bool AllOnSlot(params IBLUAction[] actions) => actions.All(a => a.OnSlot);
+}
diff --git a/RotationSolver/Rotations/Basic/BRDRotation_Base.cs b/RotationSolver/Rotations/Basic/BRD_Base.cs
similarity index 64%
rename from RotationSolver/Rotations/Basic/BRDRotation_Base.cs
rename to RotationSolver/Rotations/Basic/BRD_Base.cs
index 20758540b..d85743139 100644
--- a/RotationSolver/Rotations/Basic/BRDRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/BRD_Base.cs
@@ -62,17 +62,17 @@ protected static bool SongEndAfterGCD(uint gctCount = 0, uint abilityCount = 0)
///
/// ǿ�����
///
- public static BaseAction HeavyShoot { get; } = new(ActionID.HeavyShoot) { BuffsProvide = new[] { StatusID.StraightShotReady } };
+ public static IBaseAction HeavyShoot { get; } = new BaseAction(ActionID.HeavyShoot) { StatusProvide = new[] { StatusID.StraightShotReady } };
///
/// ֱ�����
///
- public static BaseAction StraitShoot { get; } = new(ActionID.StraitShoot) { BuffsNeed = new[] { StatusID.StraightShotReady } };
+ public static IBaseAction StraitShoot { get; } = new BaseAction(ActionID.StraitShoot) { StatusNeed = new[] { StatusID.StraightShotReady } };
///
/// ��ҧ��
///
- public static BaseAction VenomousBite { get; } = new(ActionID.VenomousBite, isEot: true)
+ public static IBaseAction VenomousBite { get; } = new BaseAction(ActionID.VenomousBite, isEot: true)
{
TargetStatus = new[] { StatusID.VenomousBite, StatusID.CausticBite }
};
@@ -80,7 +80,7 @@ protected static bool SongEndAfterGCD(uint gctCount = 0, uint abilityCount = 0)
///
/// ��ʴ��
///
- public static BaseAction Windbite { get; } = new(ActionID.Windbite, isEot: true)
+ public static IBaseAction Windbite { get; } = new BaseAction(ActionID.Windbite, isEot: true)
{
TargetStatus = new[] { StatusID.Windbite, StatusID.Stormbite }
};
@@ -88,7 +88,7 @@ protected static bool SongEndAfterGCD(uint gctCount = 0, uint abilityCount = 0)
///
/// ��������
///
- public static BaseAction IronJaws { get; } = new(ActionID.IronJaws, isEot: true)
+ public static IBaseAction IronJaws { get; } = new BaseAction(ActionID.IronJaws, isEot: true)
{
TargetStatus = VenomousBite.TargetStatus.Union(Windbite.TargetStatus).ToArray(),
ActionCheck = b => b.HasStatus(true, VenomousBite.TargetStatus) & b.HasStatus(true, Windbite.TargetStatus),
@@ -97,32 +97,32 @@ protected static bool SongEndAfterGCD(uint gctCount = 0, uint abilityCount = 0)
///
/// �������������
///
- public static BaseAction WanderersMinuet { get; } = new(ActionID.WanderersMinuet);
+ public static IBaseAction WanderersMinuet { get; } = new BaseAction(ActionID.WanderersMinuet);
///
/// ���ߵ�����ҥ
///
- public static BaseAction MagesBallad { get; } = new(ActionID.MagesBallad);
+ public static IBaseAction MagesBallad { get; } = new BaseAction(ActionID.MagesBallad);
///
/// �����������
///
- public static BaseAction ArmysPaeon { get; } = new(ActionID.ArmysPaeon);
+ public static IBaseAction ArmysPaeon { get; } = new BaseAction(ActionID.ArmysPaeon);
///
/// ս��֮��
///
- public static BaseAction BattleVoice { get; } = new(ActionID.BattleVoice, true);
+ public static IBaseAction BattleVoice { get; } = new BaseAction(ActionID.BattleVoice, true);
///
/// ����ǿ��
///
- public static BaseAction RagingStrikes { get; } = new(ActionID.RagingStrikes, true);
+ public static IBaseAction RagingStrikes { get; } = new BaseAction(ActionID.RagingStrikes, true);
///
/// ���������������
///
- public static BaseAction RadiantFinale { get; } = new(ActionID.RadiantFinale, true)
+ public static IBaseAction RadiantFinale { get; } = new BaseAction(ActionID.RadiantFinale, true)
{
ActionCheck = b => JobGauge.Coda.Any(s => s != Song.NONE),
};
@@ -130,17 +130,17 @@ protected static bool SongEndAfterGCD(uint gctCount = 0, uint abilityCount = 0)
///
/// ���Ҽ�
///
- public static BaseAction Barrage { get; } = new(ActionID.Barrage);
+ public static IBaseAction Barrage { get; } = new BaseAction(ActionID.Barrage);
///
/// ��������
///
- public static BaseAction EmpyrealArrow { get; } = new(ActionID.EmpyrealArrow);
+ public static IBaseAction EmpyrealArrow { get; } = new BaseAction(ActionID.EmpyrealArrow);
///
/// ��������
///
- public static BaseAction PitchPerfect { get; } = new(ActionID.PitchPerfect)
+ public static IBaseAction PitchPerfect { get; } = new BaseAction(ActionID.PitchPerfect)
{
ActionCheck = b => JobGauge.Song == Song.WANDERER,
};
@@ -148,48 +148,48 @@ protected static bool SongEndAfterGCD(uint gctCount = 0, uint abilityCount = 0)
///
/// ʧѪ��
///
- public static BaseAction Bloodletter { get; } = new(ActionID.Bloodletter);
+ public static IBaseAction Bloodletter { get; } = new BaseAction(ActionID.Bloodletter);
///
/// ��������
///
- public static BaseAction RainofDeath { get; } = new(ActionID.RainofDeath);
+ public static IBaseAction RainofDeath { get; } = new BaseAction(ActionID.RainofDeath);
///
/// �����
///
- public static BaseAction QuickNock { get; } = new(ActionID.QuickNock)
+ public static IBaseAction QuickNock { get; } = new BaseAction(ActionID.QuickNock)
{
- BuffsProvide = new[] { StatusID.ShadowbiteReady }
+ StatusProvide = new[] { StatusID.ShadowbiteReady }
};
///
/// Ӱ�ɼ�
///
- public static BaseAction Shadowbite { get; } = new(ActionID.Shadowbite)
+ public static IBaseAction Shadowbite { get; } = new BaseAction(ActionID.Shadowbite)
{
- BuffsNeed = new[] { StatusID.ShadowbiteReady }
+ StatusNeed = new[] { StatusID.ShadowbiteReady }
};
///
/// �������������
///
- public static BaseAction WardensPaean { get; } = new(ActionID.WardensPaean, true, isTimeline: true);
+ public static IBaseAction WardensPaean { get; } = new BaseAction(ActionID.WardensPaean, true, isTimeline: true);
///
/// ��������������
///
- public static BaseAction NaturesMinne { get; } = new(ActionID.NaturesMinne, true, isTimeline: true);
+ public static IBaseAction NaturesMinne { get; } = new BaseAction(ActionID.NaturesMinne, true, isTimeline: true);
///
/// ����յ���
///
- public static BaseAction Sidewinder { get; } = new(ActionID.Sidewinder);
+ public static IBaseAction Sidewinder { get; } = new BaseAction(ActionID.Sidewinder);
///
/// �����
///
- public static BaseAction ApexArrow { get; } = new(ActionID.ApexArrow)
+ public static IBaseAction ApexArrow { get; } = new BaseAction(ActionID.ApexArrow)
{
ActionCheck = b => JobGauge.SoulVoice >= 20 && !Player.HasStatus(true, StatusID.BlastArrowReady),
};
@@ -197,7 +197,7 @@ protected static bool SongEndAfterGCD(uint gctCount = 0, uint abilityCount = 0)
///
/// ���Ƽ�
///
- public static BaseAction BlastArrow { get; } = new(ActionID.BlastArrow)
+ public static IBaseAction BlastArrow { get; } = new BaseAction(ActionID.BlastArrow)
{
ActionCheck = b => Player.HasStatus(true, StatusID.BlastArrowReady),
};
@@ -205,7 +205,7 @@ protected static bool SongEndAfterGCD(uint gctCount = 0, uint abilityCount = 0)
///
/// ����
///
- public static BaseAction Troubadour { get; } = new(ActionID.Troubadour, true, isTimeline: true)
+ public static IBaseAction Troubadour { get; } = new BaseAction(ActionID.Troubadour, true, isTimeline: true)
{
ActionCheck = b => !Player.HasStatus(false, StatusID.Troubadour,
StatusID.Tactician1,
diff --git a/RotationSolver/Rotations/Basic/DNCRotation_Base.cs b/RotationSolver/Rotations/Basic/DNC_Base.cs
similarity index 60%
rename from RotationSolver/Rotations/Basic/DNCRotation_Base.cs
rename to RotationSolver/Rotations/Basic/DNC_Base.cs
index 7e22b630d..44a91b91b 100644
--- a/RotationSolver/Rotations/Basic/DNCRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/DNC_Base.cs
@@ -33,107 +33,107 @@ internal abstract class DNCRotation_Base : CustomRotation.CustomRotation
///
/// ��к
///
- public static BaseAction Cascade { get; } = new(ActionID.Cascade)
+ public static IBaseAction Cascade { get; } = new BaseAction(ActionID.Cascade)
{
- BuffsProvide = new[] { StatusID.SilkenSymmetry }
+ StatusProvide = new[] { StatusID.SilkenSymmetry }
};
///
/// ��Ȫ
///
- public static BaseAction Fountain { get; } = new(ActionID.Fountain)
+ public static IBaseAction Fountain { get; } = new BaseAction(ActionID.Fountain)
{
- BuffsProvide = new[] { StatusID.SilkenFlow }
+ StatusProvide = new[] { StatusID.SilkenFlow }
};
///
/// ����к
///
- public static BaseAction ReverseCascade { get; } = new(ActionID.ReverseCascade)
+ public static IBaseAction ReverseCascade { get; } = new BaseAction(ActionID.ReverseCascade)
{
- BuffsNeed = new[] { StatusID.SilkenSymmetry, StatusID.SilkenSymmetry2 },
+ StatusNeed = new[] { StatusID.SilkenSymmetry, StatusID.SilkenSymmetry2 },
};
///
/// ��Ȫ
///
- public static BaseAction Fountainfall { get; } = new(ActionID.Fountainfall)
+ public static IBaseAction Fountainfall { get; } = new BaseAction(ActionID.Fountainfall)
{
- BuffsNeed = new[] { StatusID.SilkenFlow, StatusID.SilkenFlow2 }
+ StatusNeed = new[] { StatusID.SilkenFlow, StatusID.SilkenFlow2 }
};
///
/// ���衤��
///
- public static BaseAction FanDance { get; } = new(ActionID.FanDance)
+ public static IBaseAction FanDance { get; } = new BaseAction(ActionID.FanDance)
{
ActionCheck = b => JobGauge.Feathers > 0,
- BuffsProvide = new[] { StatusID.ThreefoldFanDance },
+ StatusProvide = new[] { StatusID.ThreefoldFanDance },
};
///
/// �糵
///
- public static BaseAction Windmill { get; } = new(ActionID.Windmill)
+ public static IBaseAction Windmill { get; } = new BaseAction(ActionID.Windmill)
{
- BuffsProvide = Cascade.BuffsProvide,
+ StatusProvide = Cascade.StatusProvide,
};
///
/// ������
///
- public static BaseAction Bladeshower { get; } = new(ActionID.Bladeshower)
+ public static IBaseAction Bladeshower { get; } = new BaseAction(ActionID.Bladeshower)
{
- BuffsProvide = Fountain.BuffsProvide,
+ StatusProvide = Fountain.StatusProvide,
};
///
/// ���糵
///
- public static BaseAction RisingWindmill { get; } = new(ActionID.RisingWindmill)
+ public static IBaseAction RisingWindmill { get; } = new BaseAction(ActionID.RisingWindmill)
{
- BuffsNeed = ReverseCascade.BuffsNeed,
+ StatusNeed = ReverseCascade.StatusNeed,
};
///
/// ��Ѫ��
///
- public static BaseAction Bloodshower { get; } = new(ActionID.Bloodshower)
+ public static IBaseAction Bloodshower { get; } = new BaseAction(ActionID.Bloodshower)
{
AOECount = 2,
- BuffsNeed = Fountainfall.BuffsNeed,
+ StatusNeed = Fountainfall.StatusNeed,
};
///
/// ���衤��
///
- public static BaseAction FanDance2 { get; } = new(ActionID.FanDance2)
+ public static IBaseAction FanDance2 { get; } = new BaseAction(ActionID.FanDance2)
{
ActionCheck = b => Feathers > 0,
AOECount = 2,
- BuffsProvide = new[] { StatusID.ThreefoldFanDance },
+ StatusProvide = new[] { StatusID.ThreefoldFanDance },
};
///
/// ���衤��
///
- public static BaseAction FanDance3 { get; } = new(ActionID.FanDance3)
+ public static IBaseAction FanDance3 { get; } = new BaseAction(ActionID.FanDance3)
{
- BuffsNeed = FanDance2.BuffsProvide,
+ StatusNeed = FanDance2.StatusProvide,
};
///
/// ���衤��
///
- public static BaseAction FanDance4 { get; } = new(ActionID.FanDance4)
+ public static IBaseAction FanDance4 { get; } = new BaseAction(ActionID.FanDance4)
{
- BuffsNeed = new[] { StatusID.FourfoldFanDance },
+ StatusNeed = new[] { StatusID.FourfoldFanDance },
};
///
/// ����
///
- public static BaseAction SaberDance { get; } = new(ActionID.SaberDance)
+ public static IBaseAction SaberDance { get; } = new BaseAction(ActionID.SaberDance)
{
ActionCheck = b => Esprit >= 50,
};
@@ -141,20 +141,20 @@ internal abstract class DNCRotation_Base : CustomRotation.CustomRotation
///
/// ������
///
- public static BaseAction StarfallDance { get; } = new(ActionID.StarfallDance)
+ public static IBaseAction StarfallDance { get; } = new BaseAction(ActionID.StarfallDance)
{
- BuffsNeed = new[] { StatusID.FlourishingStarfall },
+ StatusNeed = new[] { StatusID.FlourishingStarfall },
};
///
/// ǰ�岽
///
- public static BaseAction EnAvant { get; } = new(ActionID.EnAvant, true, shouldEndSpecial: true);
+ public static IBaseAction EnAvant { get; } = new BaseAction(ActionID.EnAvant, true, shouldEndSpecial: true);
///
/// Ǿޱ���Ų�
///
- private static BaseAction Emboite { get; } = new(ActionID.Emboite, true)
+ private static IBaseAction Emboite { get; } = new BaseAction(ActionID.Emboite, true)
{
ActionCheck = b => (ActionID)JobGauge.NextStep == ActionID.Emboite,
};
@@ -162,7 +162,7 @@ internal abstract class DNCRotation_Base : CustomRotation.CustomRotation
///
/// ����
///
- private static BaseAction Entrechat { get; } = new(ActionID.Entrechat, true)
+ private static IBaseAction Entrechat { get; } = new BaseAction(ActionID.Entrechat, true)
{
ActionCheck = b => (ActionID)JobGauge.NextStep == ActionID.Entrechat,
};
@@ -170,7 +170,7 @@ internal abstract class DNCRotation_Base : CustomRotation.CustomRotation
///
/// ��ҶС����
///
- private static BaseAction Jete { get; } = new(ActionID.Jete, true)
+ private static IBaseAction Jete { get; } = new BaseAction(ActionID.Jete, true)
{
ActionCheck = b => (ActionID)JobGauge.NextStep == ActionID.Jete,
};
@@ -178,7 +178,7 @@ internal abstract class DNCRotation_Base : CustomRotation.CustomRotation
///
/// ���ֺ��ת
///
- private static BaseAction Pirouette { get; } = new(ActionID.Pirouette, true)
+ private static IBaseAction Pirouette { get; } = new BaseAction(ActionID.Pirouette, true)
{
ActionCheck = b => (ActionID)JobGauge.NextStep == ActionID.Pirouette,
};
@@ -186,9 +186,9 @@ internal abstract class DNCRotation_Base : CustomRotation.CustomRotation
///
/// ���貽
///
- public static BaseAction StandardStep { get; } = new(ActionID.StandardStep)
+ public static IBaseAction StandardStep { get; } = new BaseAction(ActionID.StandardStep)
{
- BuffsProvide = new[]
+ StatusProvide = new[]
{
StatusID.StandardStep,
StatusID.TechnicalStep,
@@ -198,37 +198,37 @@ internal abstract class DNCRotation_Base : CustomRotation.CustomRotation
///
/// �����貽
///
- public static BaseAction TechnicalStep { get; } = new(ActionID.TechnicalStep)
+ public static IBaseAction TechnicalStep { get; } = new BaseAction(ActionID.TechnicalStep)
{
- BuffsNeed = new[]
+ StatusNeed = new[]
{
StatusID.StandardFinish,
},
- BuffsProvide = StandardStep.BuffsProvide,
+ StatusProvide = StandardStep.StatusProvide,
};
///
/// ���貽����
///
- private static BaseAction StandardFinish { get; } = new(ActionID.StandardFinish)
+ private static IBaseAction StandardFinish { get; } = new BaseAction(ActionID.StandardFinish)
{
- BuffsNeed = new[] { StatusID.StandardStep },
+ StatusNeed = new[] { StatusID.StandardStep },
ActionCheck = b => IsDancing && JobGauge.CompletedSteps == 2,
};
///
/// �����貽����
///
- private static BaseAction TechnicalFinish { get; } = new(ActionID.TechnicalFinish)
+ private static IBaseAction TechnicalFinish { get; } = new BaseAction(ActionID.TechnicalFinish)
{
- BuffsNeed = new[] { StatusID.TechnicalStep },
+ StatusNeed = new[] { StatusID.TechnicalStep },
ActionCheck = b => IsDancing && JobGauge.CompletedSteps == 4,
};
///
/// ����֮ɣ��
///
- public static BaseAction ShieldSamba { get; } = new(ActionID.ShieldSamba, true, isTimeline: true)
+ public static IBaseAction ShieldSamba { get; } = new BaseAction(ActionID.ShieldSamba, true, isTimeline: true)
{
ActionCheck = b => !Player.HasStatus(false, StatusID.Troubadour,
StatusID.Tactician1,
@@ -239,12 +239,12 @@ internal abstract class DNCRotation_Base : CustomRotation.CustomRotation
///
/// ����֮������
///
- public static BaseAction CuringWaltz { get; } = new(ActionID.CuringWaltz, true, isTimeline: true);
+ public static IBaseAction CuringWaltz { get; } = new BaseAction(ActionID.CuringWaltz, true, isTimeline: true);
///
/// ��ʽ����
///
- public static BaseAction ClosedPosition { get; } = new(ActionID.ClosedPosition, true)
+ public static IBaseAction ClosedPosition { get; } = new BaseAction(ActionID.ClosedPosition, true)
{
ChoiceTarget = (Targets, mustUse) =>
{
@@ -262,15 +262,15 @@ internal abstract class DNCRotation_Base : CustomRotation.CustomRotation
///
/// ����֮̽��
///
- public static BaseAction Devilment { get; } = new(ActionID.Devilment, true);
+ public static IBaseAction Devilment { get; } = new BaseAction(ActionID.Devilment, true);
///
/// �ٻ�����
///
- public static BaseAction Flourish { get; } = new(ActionID.Flourish, true)
+ public static IBaseAction Flourish { get; } = new BaseAction(ActionID.Flourish, true)
{
- BuffsNeed = new[] { StatusID.StandardFinish },
- BuffsProvide = new[]
+ StatusNeed = new[] { StatusID.StandardFinish },
+ StatusProvide = new[]
{
StatusID.ThreefoldFanDance,
StatusID.FourfoldFanDance,
@@ -281,14 +281,14 @@ internal abstract class DNCRotation_Base : CustomRotation.CustomRotation
///
/// ���˱���
///
- public static BaseAction Improvisation { get; } = new(ActionID.Improvisation, true);
+ public static IBaseAction Improvisation { get; } = new BaseAction(ActionID.Improvisation, true);
///
/// ������
///
- public static BaseAction Tillana { get; } = new(ActionID.Tillana)
+ public static IBaseAction Tillana { get; } = new BaseAction(ActionID.Tillana)
{
- BuffsNeed = new[] { StatusID.FlourishingFinish },
+ StatusNeed = new[] { StatusID.FlourishingFinish },
};
///
diff --git a/RotationSolver/Rotations/Basic/DRGRotation_Base.cs b/RotationSolver/Rotations/Basic/DRG_Base.cs
similarity index 51%
rename from RotationSolver/Rotations/Basic/DRGRotation_Base.cs
rename to RotationSolver/Rotations/Basic/DRG_Base.cs
index 213276305..b11828957 100644
--- a/RotationSolver/Rotations/Basic/DRGRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/DRG_Base.cs
@@ -4,6 +4,7 @@
using RotationSolver.Actions.BaseAction;
using RotationSolver.Helpers;
using RotationSolver.Data;
+using RotationSolver.Actions;
namespace RotationSolver.Rotations.Basic;
@@ -17,12 +18,12 @@ internal abstract class DRGRotation_Base : CustomRotation.CustomRotation
///
/// ����
///
- public static BaseAction TrueThrust { get; } = new(ActionID.TrueThrust);
+ public static IBaseAction TrueThrust { get; } = new BaseAction(ActionID.TrueThrust);
///
/// ��ͨ��
///
- public static BaseAction VorpalThrust { get; } = new(ActionID.VorpalThrust)
+ public static IBaseAction VorpalThrust { get; } = new BaseAction(ActionID.VorpalThrust)
{
OtherIDsCombo = new[] { ActionID.RaidenThrust }
};
@@ -30,12 +31,12 @@ internal abstract class DRGRotation_Base : CustomRotation.CustomRotation
///
/// ֱ��
///
- public static BaseAction FullThrust { get; } = new(ActionID.FullThrust);
+ public static IBaseAction FullThrust { get; } = new BaseAction(ActionID.FullThrust);
///
/// ����ǹ
///
- public static BaseAction Disembowel { get; } = new(ActionID.Disembowel)
+ public static IBaseAction Disembowel { get; } = new BaseAction(ActionID.Disembowel)
{
OtherIDsCombo = new[] { ActionID.RaidenThrust }
};
@@ -43,38 +44,38 @@ internal abstract class DRGRotation_Base : CustomRotation.CustomRotation
///
/// ӣ��ŭ��
///
- public static BaseAction ChaosThrust { get; } = new(ActionID.ChaosThrust);
+ public static IBaseAction ChaosThrust { get; } = new BaseAction(ActionID.ChaosThrust);
///
/// ������צ
///
- public static BaseAction FangandClaw { get; } = new(ActionID.FangandClaw)
+ public static IBaseAction FangandClaw { get; } = new BaseAction(ActionID.FangandClaw)
{
- BuffsNeed = new StatusID[] { StatusID.SharperFangandClaw },
+ StatusNeed = new StatusID[] { StatusID.SharperFangandClaw },
};
///
/// ������
///
- public static BaseAction WheelingThrust { get; } = new(ActionID.WheelingThrust)
+ public static IBaseAction WheelingThrust { get; } = new BaseAction(ActionID.WheelingThrust)
{
- BuffsNeed = new StatusID[] { StatusID.EnhancedWheelingThrust },
+ StatusNeed = new StatusID[] { StatusID.EnhancedWheelingThrust },
};
///
/// �ᴩ��
///
- public static BaseAction PiercingTalon { get; } = new(ActionID.PiercingTalon);
+ public static IBaseAction PiercingTalon { get; } = new BaseAction(ActionID.PiercingTalon);
///
/// ����ǹ
///
- public static BaseAction DoomSpike { get; } = new(ActionID.DoomSpike);
+ public static IBaseAction DoomSpike { get; } = new BaseAction(ActionID.DoomSpike);
///
/// ���ٴ�
///
- public static BaseAction SonicThrust { get; } = new(ActionID.SonicThrust)
+ public static IBaseAction SonicThrust { get; } = new BaseAction(ActionID.SonicThrust)
{
OtherIDsCombo = new[] { ActionID.DraconianFury }
};
@@ -82,51 +83,51 @@ internal abstract class DRGRotation_Base : CustomRotation.CustomRotation
///
/// ɽ������
///
- public static BaseAction CoerthanTorment { get; } = new(ActionID.CoerthanTorment);
+ public static IBaseAction CoerthanTorment { get; } = new BaseAction(ActionID.CoerthanTorment);
///
/// �����
///
- public static BaseAction SpineshatterDive { get; } = new(ActionID.SpineshatterDive);
+ public static IBaseAction SpineshatterDive { get; } = new BaseAction(ActionID.SpineshatterDive);
///
/// ���׳�
///
- public static BaseAction DragonfireDive { get; } = new(ActionID.DragonfireDive);
+ public static IBaseAction DragonfireDive { get; } = new BaseAction(ActionID.DragonfireDive);
///
/// ��Ծ
///
- public static BaseAction Jump { get; } = new(ActionID.Jump)
+ public static IBaseAction Jump { get; } = new BaseAction(ActionID.Jump)
{
- BuffsProvide = new StatusID[] { StatusID.DiveReady },
+ StatusProvide = new StatusID[] { StatusID.DiveReady },
};
///
/// ����
///
- public static BaseAction HighJump { get; } = new(ActionID.HighJump)
+ public static IBaseAction HighJump { get; } = new BaseAction(ActionID.HighJump)
{
- BuffsProvide = Jump.BuffsProvide,
+ StatusProvide = Jump.StatusProvide,
};
///
/// �����
///
- public static BaseAction MirageDive { get; } = new(ActionID.MirageDive)
+ public static IBaseAction MirageDive { get; } = new BaseAction(ActionID.MirageDive)
{
- BuffsNeed = Jump.BuffsProvide,
+ StatusNeed = Jump.StatusProvide,
};
///
/// ����ǹ
///
- public static BaseAction Geirskogul { get; } = new(ActionID.Geirskogul);
+ public static IBaseAction Geirskogul { get; } = new BaseAction(ActionID.Geirskogul);
///
/// ����֮��
///
- public static BaseAction Nastrond { get; } = new(ActionID.Nastrond)
+ public static IBaseAction Nastrond { get; } = new BaseAction(ActionID.Nastrond)
{
ActionCheck = b => JobGauge.IsLOTDActive,
};
@@ -134,7 +135,7 @@ internal abstract class DRGRotation_Base : CustomRotation.CustomRotation
///
/// �dz�
///
- public static BaseAction Stardiver { get; } = new(ActionID.Stardiver)
+ public static IBaseAction Stardiver { get; } = new BaseAction(ActionID.Stardiver)
{
ActionCheck = b => JobGauge.IsLOTDActive,
};
@@ -142,7 +143,7 @@ internal abstract class DRGRotation_Base : CustomRotation.CustomRotation
///
/// �����㾦
///
- public static BaseAction WyrmwindThrust { get; } = new(ActionID.WyrmwindThrust)
+ public static IBaseAction WyrmwindThrust { get; } = new BaseAction(ActionID.WyrmwindThrust)
{
ActionCheck = b => JobGauge.FirstmindsFocusCount == 2,
};
@@ -150,9 +151,9 @@ internal abstract class DRGRotation_Base : CustomRotation.CustomRotation
///
/// ����
///
- public static BaseAction LifeSurge { get; } = new(ActionID.LifeSurge, true)
+ public static IBaseAction LifeSurge { get; } = new BaseAction(ActionID.LifeSurge, true)
{
- BuffsProvide = new[] { StatusID.LifeSurge },
+ StatusProvide = new[] { StatusID.LifeSurge },
ActionCheck = b => !IsLastAbility(true, LifeSurge),
};
@@ -160,12 +161,12 @@ internal abstract class DRGRotation_Base : CustomRotation.CustomRotation
///
/// ��ǹ
///
- public static BaseAction LanceCharge { get; } = new(ActionID.LanceCharge, true);
+ public static IBaseAction LanceCharge { get; } = new BaseAction(ActionID.LanceCharge, true);
///
/// ��������
///
- public static BaseAction DragonSight { get; } = new(ActionID.DragonSight, true)
+ public static IBaseAction DragonSight { get; } = new BaseAction(ActionID.DragonSight, true)
{
ChoiceTarget = (Targets, mustUse) =>
{
@@ -181,8 +182,8 @@ internal abstract class DRGRotation_Base : CustomRotation.CustomRotation
///
/// ս������
///
- public static BaseAction BattleLitany { get; } = new(ActionID.BattleLitany, true)
+ public static IBaseAction BattleLitany { get; } = new BaseAction(ActionID.BattleLitany, true)
{
- BuffsNeed = new[] { StatusID.PowerSurge },
+ StatusNeed = new[] { StatusID.PowerSurge },
};
}
diff --git a/RotationSolver/Rotations/Basic/DRKRotation_Base.cs b/RotationSolver/Rotations/Basic/DRK_Base.cs
similarity index 60%
rename from RotationSolver/Rotations/Basic/DRKRotation_Base.cs
rename to RotationSolver/Rotations/Basic/DRK_Base.cs
index f5c21a417..3bcfb7a24 100644
--- a/RotationSolver/Rotations/Basic/DRKRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/DRK_Base.cs
@@ -41,32 +41,32 @@ protected static bool DarkSideEndAfterGCD(uint gctCount = 0, uint abilityCount =
}
public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.DarkKnight };
- private sealed protected override BaseAction Shield => Grit;
+ private sealed protected override IBaseAction Shield => Grit;
///
/// 重斩
///
- public static BaseAction HardSlash { get; } = new(ActionID.HardSlash);
+ public static IBaseAction HardSlash { get; } = new BaseAction(ActionID.HardSlash);
///
/// 吸收斩
///
- public static BaseAction SyphonStrike { get; } = new(ActionID.SyphonStrike);
+ public static IBaseAction SyphonStrike { get; } = new BaseAction(ActionID.SyphonStrike);
///
/// 释放
///
- public static BaseAction Unleash { get; } = new(ActionID.Unleash);
+ public static IBaseAction Unleash { get; } = new BaseAction(ActionID.Unleash);
///
/// 深恶痛绝
///
- public static BaseAction Grit { get; } = new(ActionID.Grit, shouldEndSpecial: true);
+ public static IBaseAction Grit { get; } = new BaseAction(ActionID.Grit, shouldEndSpecial: true);
///
/// 伤残
///
- public static BaseAction Unmend { get; } = new(ActionID.Unmend)
+ public static IBaseAction Unmend { get; } = new BaseAction(ActionID.Unmend)
{
FilterForTarget = b => TargetFilter.ProvokeTarget(b),
};
@@ -74,36 +74,36 @@ protected static bool DarkSideEndAfterGCD(uint gctCount = 0, uint abilityCount =
///
/// 噬魂斩
///
- public static BaseAction Souleater { get; } = new(ActionID.Souleater);
+ public static IBaseAction Souleater { get; } = new BaseAction(ActionID.Souleater);
///
/// 暗黑波动
///
- public static BaseAction FloodofDarkness { get; } = new(ActionID.FloodofDarkness);
+ public static IBaseAction FloodofDarkness { get; } = new BaseAction(ActionID.FloodofDarkness);
///
/// 暗黑锋
///
- public static BaseAction EdgeofDarkness { get; } = new(ActionID.EdgeofDarkness);
+ public static IBaseAction EdgeofDarkness { get; } = new BaseAction(ActionID.EdgeofDarkness);
///
/// 嗜血
///
- public static BaseAction BloodWeapon { get; } = new(ActionID.BloodWeapon);
+ public static IBaseAction BloodWeapon { get; } = new BaseAction(ActionID.BloodWeapon);
///
/// 暗影墙
///
- public static BaseAction ShadowWall { get; } = new(ActionID.ShadowWall, true, isTimeline: true)
+ public static IBaseAction ShadowWall { get; } = new BaseAction(ActionID.ShadowWall, true, isTimeline: true)
{
- BuffsProvide = Rampart.BuffsProvide,
+ StatusProvide = Rampart.StatusProvide,
ActionCheck = BaseAction.TankDefenseSelf,
};
///
/// 弃明投暗
///
- public static BaseAction DarkMind { get; } = new(ActionID.DarkMind, true, isTimeline: true)
+ public static IBaseAction DarkMind { get; } = new BaseAction(ActionID.DarkMind, true, isTimeline: true)
{
ActionCheck = BaseAction.TankDefenseSelf,
};
@@ -111,17 +111,17 @@ protected static bool DarkSideEndAfterGCD(uint gctCount = 0, uint abilityCount =
///
/// 行尸走肉
///
- public static BaseAction LivingDead { get; } = new(ActionID.LivingDead, true, isTimeline: true);
+ public static IBaseAction LivingDead { get; } = new BaseAction(ActionID.LivingDead, true, isTimeline: true);
///
/// 腐秽大地
///
- public static BaseAction SaltedEarth { get; } = new(ActionID.SaltedEarth);
+ public static IBaseAction SaltedEarth { get; } = new BaseAction(ActionID.SaltedEarth);
///
/// 跳斩
///
- public static BaseAction Plunge { get; } = new(ActionID.Plunge, shouldEndSpecial: true)
+ public static IBaseAction Plunge { get; } = new BaseAction(ActionID.Plunge, shouldEndSpecial: true)
{
ChoiceTarget = TargetFilter.FindTargetForMoving
};
@@ -129,17 +129,17 @@ protected static bool DarkSideEndAfterGCD(uint gctCount = 0, uint abilityCount =
///
/// 吸血深渊
///
- public static BaseAction AbyssalDrain { get; } = new(ActionID.AbyssalDrain);
+ public static IBaseAction AbyssalDrain { get; } = new BaseAction(ActionID.AbyssalDrain);
///
/// 精雕怒斩
///
- public static BaseAction CarveandSpit { get; } = new(ActionID.CarveandSpit);
+ public static IBaseAction CarveandSpit { get; } = new BaseAction(ActionID.CarveandSpit);
///
/// 血溅
///
- public static BaseAction Bloodspiller { get; } = new(ActionID.Bloodspiller)
+ public static IBaseAction Bloodspiller { get; } = new BaseAction(ActionID.Bloodspiller)
{
ActionCheck = b => JobGauge.Blood >= 50 || Player.HasStatus(true, StatusID.Delirium),
};
@@ -147,7 +147,7 @@ protected static bool DarkSideEndAfterGCD(uint gctCount = 0, uint abilityCount =
///
/// 寂灭
///
- public static BaseAction Quietus { get; } = new(ActionID.Quietus)
+ public static IBaseAction Quietus { get; } = new BaseAction(ActionID.Quietus)
{
ActionCheck = Bloodspiller.ActionCheck,
};
@@ -155,12 +155,12 @@ protected static bool DarkSideEndAfterGCD(uint gctCount = 0, uint abilityCount =
///
/// 血乱
///
- public static BaseAction Delirium { get; } = new(ActionID.Delirium);
+ public static IBaseAction Delirium { get; } = new BaseAction(ActionID.Delirium);
///
/// 至黑之夜
///
- public static BaseAction TheBlackestNight { get; } = new(ActionID.TheBlackestNight, isTimeline: true)
+ public static IBaseAction TheBlackestNight { get; } = new BaseAction(ActionID.TheBlackestNight, isTimeline: true)
{
ChoiceTarget = TargetFilter.FindAttackedTarget,
};
@@ -168,17 +168,17 @@ protected static bool DarkSideEndAfterGCD(uint gctCount = 0, uint abilityCount =
///
/// 刚魂
///
- public static BaseAction StalwartSoul { get; } = new(ActionID.StalwartSoul);
+ public static IBaseAction StalwartSoul { get; } = new BaseAction(ActionID.StalwartSoul);
///
/// 暗黑布道
///
- public static BaseAction DarkMissionary { get; } = new(ActionID.DarkMissionary, true, isTimeline: true);
+ public static IBaseAction DarkMissionary { get; } = new BaseAction(ActionID.DarkMissionary, true, isTimeline: true);
///
/// 掠影示现
///
- public static BaseAction LivingShadow { get; } = new(ActionID.LivingShadow)
+ public static IBaseAction LivingShadow { get; } = new BaseAction(ActionID.LivingShadow)
{
ActionCheck = b => JobGauge.Blood >= 50,
};
@@ -186,7 +186,7 @@ protected static bool DarkSideEndAfterGCD(uint gctCount = 0, uint abilityCount =
///
/// 献奉
///
- public static BaseAction Oblation { get; } = new(ActionID.Oblation, true, isTimeline: true)
+ public static IBaseAction Oblation { get; } = new BaseAction(ActionID.Oblation, true, isTimeline: true)
{
ChoiceTarget = TargetFilter.FindAttackedTarget,
};
@@ -194,7 +194,7 @@ protected static bool DarkSideEndAfterGCD(uint gctCount = 0, uint abilityCount =
///
/// 暗影使者
///
- public static BaseAction Shadowbringer { get; } = new(ActionID.Shadowbringer)
+ public static IBaseAction Shadowbringer { get; } = new BaseAction(ActionID.Shadowbringer)
{
ActionCheck = b => JobGauge.DarksideTimeRemaining > 0,
};
@@ -202,9 +202,9 @@ protected static bool DarkSideEndAfterGCD(uint gctCount = 0, uint abilityCount =
///
/// 腐秽黑暗
///
- public static BaseAction SaltandDarkness { get; } = new(ActionID.SaltandDarkness)
+ public static IBaseAction SaltandDarkness { get; } = new BaseAction(ActionID.SaltandDarkness)
{
- BuffsNeed = new[] { StatusID.SaltedEarth },
+ StatusNeed = new[] { StatusID.SaltedEarth },
};
private protected override bool EmergencyAbility(byte abilityRemain, IAction nextGCD, out IAction act)
diff --git a/RotationSolver/Rotations/Basic/GNBRotation_Base.cs b/RotationSolver/Rotations/Basic/GNB_Base.cs
similarity index 59%
rename from RotationSolver/Rotations/Basic/GNBRotation_Base.cs
rename to RotationSolver/Rotations/Basic/GNB_Base.cs
index 23c61268c..bc3f9445b 100644
--- a/RotationSolver/Rotations/Basic/GNBRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/GNB_Base.cs
@@ -23,7 +23,7 @@ internal abstract class GNBRotation_Base : CustomRotation.CustomRotation
protected static byte AmmoComboStep => JobGauge.AmmoComboStep;
public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Gunbreaker };
- private sealed protected override BaseAction Shield => RoyalGuard;
+ private sealed protected override IBaseAction Shield => RoyalGuard;
protected override bool CanHealSingleSpell => false;
protected override bool CanHealAreaSpell => false;
@@ -33,27 +33,27 @@ internal abstract class GNBRotation_Base : CustomRotation.CustomRotation
///
/// ��������
///
- public static BaseAction RoyalGuard { get; } = new(ActionID.RoyalGuard, shouldEndSpecial: true);
+ public static IBaseAction RoyalGuard { get; } = new BaseAction(ActionID.RoyalGuard, shouldEndSpecial: true);
///
/// ����ն
///
- public static BaseAction KeenEdge { get; } = new(ActionID.KeenEdge);
+ public static IBaseAction KeenEdge { get; } = new BaseAction(ActionID.KeenEdge);
///
/// ����
///
- public static BaseAction NoMercy { get; } = new(ActionID.NoMercy);
+ public static IBaseAction NoMercy { get; } = new BaseAction(ActionID.NoMercy);
///
/// ���
///
- public static BaseAction BrutalShell { get; } = new(ActionID.BrutalShell);
+ public static IBaseAction BrutalShell { get; } = new BaseAction(ActionID.BrutalShell);
///
/// αװ
///
- public static BaseAction Camouflage { get; } = new(ActionID.Camouflage, true, isTimeline: true)
+ public static IBaseAction Camouflage { get; } = new BaseAction(ActionID.Camouflage, true, isTimeline: true)
{
ActionCheck = BaseAction.TankDefenseSelf,
};
@@ -61,27 +61,27 @@ internal abstract class GNBRotation_Base : CustomRotation.CustomRotation
///
/// ��ħ��
///
- public static BaseAction DemonSlice { get; } = new(ActionID.DemonSlice);
+ public static IBaseAction DemonSlice { get; } = new BaseAction(ActionID.DemonSlice);
///
/// ����
///
- public static BaseAction LightningShot { get; } = new(ActionID.LightningShot);
+ public static IBaseAction LightningShot { get; } = new BaseAction(ActionID.LightningShot);
///
/// ������
///
- public static BaseAction DangerZone { get; } = new(ActionID.DangerZone);
+ public static IBaseAction DangerZone { get; } = new BaseAction(ActionID.DangerZone);
///
/// Ѹ��ն
///
- public static BaseAction SolidBarrel { get; } = new(ActionID.SolidBarrel);
+ public static IBaseAction SolidBarrel { get; } = new BaseAction(ActionID.SolidBarrel);
///
/// ������
///
- public static BaseAction BurstStrike { get; } = new(ActionID.BurstStrike)
+ public static IBaseAction BurstStrike { get; } = new BaseAction(ActionID.BurstStrike)
{
ActionCheck = b => JobGauge.Ammo > 0,
};
@@ -89,36 +89,36 @@ internal abstract class GNBRotation_Base : CustomRotation.CustomRotation
///
/// ����
///
- public static BaseAction Nebula { get; } = new(ActionID.Nebula, true, isTimeline: true)
+ public static IBaseAction Nebula { get; } = new BaseAction(ActionID.Nebula, true, isTimeline: true)
{
- BuffsProvide = Rampart.BuffsProvide,
+ StatusProvide = Rampart.StatusProvide,
ActionCheck = BaseAction.TankDefenseSelf,
};
///
/// ��ħɱ
///
- public static BaseAction DemonSlaughter { get; } = new(ActionID.DemonSlaughter);
+ public static IBaseAction DemonSlaughter { get; } = new BaseAction(ActionID.DemonSlaughter);
///
/// ����
///
- public static BaseAction Aurora { get; } = new BaseAction(ActionID.Aurora, true, isTimeline: true);
+ public static IBaseAction Aurora { get; } = new BaseAction(ActionID.Aurora, true, isTimeline: true);
///
/// ��������
///
- public static BaseAction Superbolide { get; } = new(ActionID.Superbolide, true, isTimeline: true);
+ public static IBaseAction Superbolide { get; } = new BaseAction(ActionID.Superbolide, true, isTimeline: true);
///
/// ������
///
- public static BaseAction SonicBreak { get; } = new(ActionID.SonicBreak);
+ public static IBaseAction SonicBreak { get; } = new BaseAction(ActionID.SonicBreak);
///
/// �ַ�ն
///
- public static BaseAction RoughDivide { get; } = new(ActionID.RoughDivide, shouldEndSpecial: true)
+ public static IBaseAction RoughDivide { get; } = new BaseAction(ActionID.RoughDivide, shouldEndSpecial: true)
{
ChoiceTarget = TargetFilter.FindTargetForMoving,
};
@@ -126,7 +126,7 @@ internal abstract class GNBRotation_Base : CustomRotation.CustomRotation
///
/// ����
///
- public static BaseAction GnashingFang { get; } = new(ActionID.GnashingFang)
+ public static IBaseAction GnashingFang { get; } = new BaseAction(ActionID.GnashingFang)
{
ActionCheck = b => JobGauge.AmmoComboStep == 0 && JobGauge.Ammo > 0,
};
@@ -134,17 +134,17 @@ internal abstract class GNBRotation_Base : CustomRotation.CustomRotation
///
/// ���γ岨
///
- public static BaseAction BowShock { get; } = new(ActionID.BowShock);
+ public static IBaseAction BowShock { get; } = new BaseAction(ActionID.BowShock);
///
/// ��֮��
///
- public static BaseAction HeartofLight { get; } = new(ActionID.HeartofLight, true, isTimeline: true);
+ public static IBaseAction HeartofLight { get; } = new BaseAction(ActionID.HeartofLight, true, isTimeline: true);
///
/// ʯ֮��
///
- public static BaseAction HeartofStone { get; } = new(ActionID.HeartofStone, true, isTimeline: true)
+ public static IBaseAction HeartofStone { get; } = new BaseAction(ActionID.HeartofStone, true, isTimeline: true)
{
ChoiceTarget = TargetFilter.FindAttackedTarget,
};
@@ -152,7 +152,7 @@ internal abstract class GNBRotation_Base : CustomRotation.CustomRotation
///
/// ����֮��
///
- public static BaseAction FatedCircle { get; } = new(ActionID.FatedCircle)
+ public static IBaseAction FatedCircle { get; } = new BaseAction(ActionID.FatedCircle)
{
ActionCheck = b => JobGauge.Ammo > 0,
};
@@ -160,7 +160,7 @@ internal abstract class GNBRotation_Base : CustomRotation.CustomRotation
///
/// Ѫ��
///
- public static BaseAction Bloodfest { get; } = new(ActionID.Bloodfest, true)
+ public static IBaseAction Bloodfest { get; } = new BaseAction(ActionID.Bloodfest, true)
{
ActionCheck = b => MaxAmmo - JobGauge.Ammo > 1,
};
@@ -168,7 +168,7 @@ internal abstract class GNBRotation_Base : CustomRotation.CustomRotation
///
/// ����
///
- public static BaseAction DoubleDown { get; } = new(ActionID.DoubleDown)
+ public static IBaseAction DoubleDown { get; } = new BaseAction(ActionID.DoubleDown)
{
ActionCheck = b => JobGauge.Ammo > 1,
};
@@ -176,7 +176,7 @@ internal abstract class GNBRotation_Base : CustomRotation.CustomRotation
///
/// ����צ
///
- public static BaseAction SavageClaw { get; } = new(ActionID.SavageClaw)
+ public static IBaseAction SavageClaw { get; } = new BaseAction(ActionID.SavageClaw)
{
ActionCheck = b => Service.IconReplacer.OriginalHook(ActionID.GnashingFang) == ActionID.SavageClaw,
};
@@ -184,7 +184,7 @@ internal abstract class GNBRotation_Base : CustomRotation.CustomRotation
///
/// ����צ
///
- public static BaseAction WickedTalon { get; } = new(ActionID.WickedTalon)
+ public static IBaseAction WickedTalon { get; } = new BaseAction(ActionID.WickedTalon)
{
ActionCheck = b => Service.IconReplacer.OriginalHook(ActionID.GnashingFang) == ActionID.WickedTalon,
};
@@ -192,7 +192,7 @@ internal abstract class GNBRotation_Base : CustomRotation.CustomRotation
///
/// ˺��
///
- public static BaseAction JugularRip { get; } = new(ActionID.JugularRip)
+ public static IBaseAction JugularRip { get; } = new BaseAction(ActionID.JugularRip)
{
ActionCheck = b => Service.IconReplacer.OriginalHook(ActionID.Continuation) == ActionID.JugularRip,
};
@@ -200,7 +200,7 @@ internal abstract class GNBRotation_Base : CustomRotation.CustomRotation
///
/// ����
///
- public static BaseAction AbdomenTear { get; } = new(ActionID.AbdomenTear)
+ public static IBaseAction AbdomenTear { get; } = new BaseAction(ActionID.AbdomenTear)
{
ActionCheck = b => Service.IconReplacer.OriginalHook(ActionID.Continuation) == ActionID.AbdomenTear,
};
@@ -208,7 +208,7 @@ internal abstract class GNBRotation_Base : CustomRotation.CustomRotation
///
/// ��Ŀ
///
- public static BaseAction EyeGouge { get; } = new(ActionID.EyeGouge)
+ public static IBaseAction EyeGouge { get; } = new BaseAction(ActionID.EyeGouge)
{
ActionCheck = b => Service.IconReplacer.OriginalHook(ActionID.Continuation) == ActionID.EyeGouge,
};
@@ -216,7 +216,7 @@ internal abstract class GNBRotation_Base : CustomRotation.CustomRotation
///
/// ������
///
- public static BaseAction Hypervelocity { get; } = new(ActionID.Hypervelocity)
+ public static IBaseAction Hypervelocity { get; } = new BaseAction(ActionID.Hypervelocity)
{
ActionCheck = b => Service.IconReplacer.OriginalHook(ActionID.Continuation)
== ActionID.Hypervelocity,
diff --git a/RotationSolver/Rotations/Basic/MCHRotation_Base.cs b/RotationSolver/Rotations/Basic/MCH_Base.cs
similarity index 65%
rename from RotationSolver/Rotations/Basic/MCHRotation_Base.cs
rename to RotationSolver/Rotations/Basic/MCH_Base.cs
index 9adb54cc9..2bf69e57a 100644
--- a/RotationSolver/Rotations/Basic/MCHRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/MCH_Base.cs
@@ -3,6 +3,7 @@
using RotationSolver.Actions.BaseAction;
using RotationSolver.Helpers;
using RotationSolver.Data;
+using RotationSolver.Actions;
namespace RotationSolver.Rotations.Basic;
@@ -51,12 +52,12 @@ protected static bool OverheatedEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// 分裂弹
///
- public static BaseAction SplitShot { get; } = new(ActionID.SplitShot);
+ public static IBaseAction SplitShot { get; } = new BaseAction(ActionID.SplitShot);
///
/// 独头弹
///
- public static BaseAction SlugShot { get; } = new(ActionID.SlugShot)
+ public static IBaseAction SlugShot { get; } = new BaseAction(ActionID.SlugShot)
{
OtherIDsCombo = new[] { ActionID.HeatedSplitShot },
};
@@ -64,7 +65,7 @@ protected static bool OverheatedEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// 狙击弹
///
- public static BaseAction CleanShot { get; } = new(ActionID.CleanShot)
+ public static IBaseAction CleanShot { get; } = new BaseAction(ActionID.CleanShot)
{
OtherIDsCombo = new[] { ActionID.HeatedSlugShot },
};
@@ -72,7 +73,7 @@ protected static bool OverheatedEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// 热冲击
///
- public static BaseAction HeatBlast { get; } = new(ActionID.HeatBlast)
+ public static IBaseAction HeatBlast { get; } = new BaseAction(ActionID.HeatBlast)
{
ActionCheck = b => JobGauge.IsOverheated
&& !OverheatedEndAfterGCD(),
@@ -81,12 +82,12 @@ protected static bool OverheatedEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// 散射
///
- public static BaseAction SpreadShot { get; } = new(ActionID.SpreadShot);
+ public static IBaseAction SpreadShot { get; } = new BaseAction(ActionID.SpreadShot);
///
/// 自动弩
///
- public static BaseAction AutoCrossbow { get; } = new(ActionID.AutoCrossbow)
+ public static IBaseAction AutoCrossbow { get; } = new BaseAction(ActionID.AutoCrossbow)
{
ActionCheck = HeatBlast.ActionCheck,
};
@@ -94,41 +95,41 @@ protected static bool OverheatedEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// 热弹
///
- public static BaseAction HotShot { get; } = new(ActionID.HotShot);
+ public static IBaseAction HotShot { get; } = new BaseAction(ActionID.HotShot);
///
/// 空气锚
///
- public static BaseAction AirAnchor { get; } = new(ActionID.AirAnchor);
+ public static IBaseAction AirAnchor { get; } = new BaseAction(ActionID.AirAnchor);
///
/// 钻头
///
- public static BaseAction Drill { get; } = new(ActionID.Drill);
+ public static IBaseAction Drill { get; } = new BaseAction(ActionID.Drill);
///
/// 回转飞锯
///
- public static BaseAction ChainSaw { get; } = new(ActionID.ChainSaw);
+ public static IBaseAction ChainSaw { get; } = new BaseAction(ActionID.ChainSaw);
///
/// 毒菌冲击
///
- public static BaseAction Bioblaster { get; } = new(ActionID.Bioblaster, isEot: true);
+ public static IBaseAction Bioblaster { get; } = new BaseAction(ActionID.Bioblaster, isEot: true);
///
/// 整备
///
- public static BaseAction Reassemble { get; } = new(ActionID.Reassemble)
+ public static IBaseAction Reassemble { get; } = new BaseAction(ActionID.Reassemble)
{
- BuffsProvide = new StatusID[] { StatusID.Reassemble },
+ StatusProvide = new StatusID[] { StatusID.Reassemble },
ActionCheck = b => HaveHostilesInRange,
};
///
/// 超荷
///
- public static BaseAction Hypercharge { get; } = new(ActionID.Hypercharge)
+ public static IBaseAction Hypercharge { get; } = new BaseAction(ActionID.Hypercharge)
{
ActionCheck = b => !JobGauge.IsOverheated && JobGauge.Heat >= 50,
};
@@ -136,22 +137,22 @@ protected static bool OverheatedEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// 野火
///
- public static BaseAction Wildfire { get; } = new(ActionID.Wildfire);
+ public static IBaseAction Wildfire { get; } = new BaseAction(ActionID.Wildfire);
///
/// 虹吸弹
///
- public static BaseAction GaussRound { get; } = new(ActionID.GaussRound);
+ public static IBaseAction GaussRound { get; } = new BaseAction(ActionID.GaussRound);
///
/// 弹射
///
- public static BaseAction Ricochet { get; } = new(ActionID.Ricochet);
+ public static IBaseAction Ricochet { get; } = new BaseAction(ActionID.Ricochet);
///
/// 枪管加热
///
- public static BaseAction BarrelStabilizer { get; } = new(ActionID.BarrelStabilizer)
+ public static IBaseAction BarrelStabilizer { get; } = new BaseAction(ActionID.BarrelStabilizer)
{
ActionCheck = b => JobGauge.Heat <= 50 && InCombat,
};
@@ -159,7 +160,7 @@ protected static bool OverheatedEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// 车式浮空炮塔
///
- public static BaseAction RookAutoturret { get; } = new(ActionID.RookAutoturret)
+ public static IBaseAction RookAutoturret { get; } = new BaseAction(ActionID.RookAutoturret)
{
ActionCheck = b => JobGauge.Battery >= 50 && !JobGauge.IsRobotActive,
};
@@ -167,7 +168,7 @@ protected static bool OverheatedEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// 策动
///
- public static BaseAction Tactician { get; } = new(ActionID.Tactician, true, isTimeline: true)
+ public static IBaseAction Tactician { get; } = new BaseAction(ActionID.Tactician, true, isTimeline: true)
{
ActionCheck = b => !Player.HasStatus(false, StatusID.Troubadour,
StatusID.Tactician1,
diff --git a/RotationSolver/Rotations/Basic/MNKRotation_Base.cs b/RotationSolver/Rotations/Basic/MNK_Base.cs
similarity index 50%
rename from RotationSolver/Rotations/Basic/MNKRotation_Base.cs
rename to RotationSolver/Rotations/Basic/MNK_Base.cs
index a8c96a4cf..85ddf8ea9 100644
--- a/RotationSolver/Rotations/Basic/MNKRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/MNK_Base.cs
@@ -32,45 +32,45 @@ internal abstract class MNKRotation_Base : CustomRotation.CustomRotation
///
/// 双龙脚
///
- public static BaseAction DragonKick { get; } = new(ActionID.DragonKick)
+ public static IBaseAction DragonKick { get; } = new BaseAction(ActionID.DragonKick)
{
- BuffsProvide = new[] { StatusID.LeadenFist },
+ StatusProvide = new[] { StatusID.LeadenFist },
};
///
/// 连击
///
- public static BaseAction Bootshine { get; } = new(ActionID.Bootshine);
+ public static IBaseAction Bootshine { get; } = new BaseAction(ActionID.Bootshine);
///
/// 破坏神冲 aoe
///
- public static BaseAction ArmoftheDestroyer { get; } = new(ActionID.ArmoftheDestroyer);
+ public static IBaseAction ArmoftheDestroyer { get; } = new BaseAction(ActionID.ArmoftheDestroyer);
///
/// 破坏神脚 aoe
///
- public static BaseAction ShadowoftheDestroyer { get; } = new(ActionID.ShadowoftheDestroyer);
+ public static IBaseAction ShadowoftheDestroyer { get; } = new BaseAction(ActionID.ShadowoftheDestroyer);
///
/// 双掌打 伤害提高
///
- public static BaseAction TwinSnakes { get; } = new(ActionID.TwinSnakes, isEot: true);
+ public static IBaseAction TwinSnakes { get; } = new BaseAction(ActionID.TwinSnakes, isEot: true);
///
/// 正拳
///
- public static BaseAction TrueStrike { get; } = new(ActionID.TrueStrike);
+ public static IBaseAction TrueStrike { get; } = new BaseAction(ActionID.TrueStrike);
///
/// 四面脚 aoe
///
- public static BaseAction FourpointFury { get; } = new(ActionID.FourpointFury);
+ public static IBaseAction FourpointFury { get; } = new BaseAction(ActionID.FourpointFury);
///
/// 破碎拳
///
- public static BaseAction Demolish { get; } = new(ActionID.Demolish, isEot: true)
+ public static IBaseAction Demolish { get; } = new BaseAction(ActionID.Demolish, isEot: true)
{
TargetStatus = new StatusID[] { StatusID.Demolish },
};
@@ -78,22 +78,22 @@ internal abstract class MNKRotation_Base : CustomRotation.CustomRotation
///
/// 崩拳
///
- public static BaseAction SnapPunch { get; } = new(ActionID.SnapPunch);
+ public static IBaseAction SnapPunch { get; } = new BaseAction(ActionID.SnapPunch);
///
/// 地烈劲 aoe
///
- public static BaseAction Rockbreaker { get; } = new(ActionID.Rockbreaker);
+ public static IBaseAction Rockbreaker { get; } = new BaseAction(ActionID.Rockbreaker);
///
/// 斗气
///
- public static BaseAction Meditation { get; } = new(ActionID.Meditation, true);
+ public static IBaseAction Meditation { get; } = new BaseAction(ActionID.Meditation, true);
///
/// 铁山靠
///
- public static BaseAction SteelPeak { get; } = new(ActionID.SteelPeak)
+ public static IBaseAction SteelPeak { get; } = new BaseAction(ActionID.SteelPeak)
{
ActionCheck = b => InCombat && Chakra == 5,
};
@@ -101,7 +101,7 @@ internal abstract class MNKRotation_Base : CustomRotation.CustomRotation
///
/// 空鸣拳
///
- public static BaseAction HowlingFist { get; } = new(ActionID.HowlingFist)
+ public static IBaseAction HowlingFist { get; } = new BaseAction(ActionID.HowlingFist)
{
ActionCheck = SteelPeak.ActionCheck,
};
@@ -109,17 +109,17 @@ internal abstract class MNKRotation_Base : CustomRotation.CustomRotation
///
/// 义结金兰
///
- public static BaseAction Brotherhood { get; } = new(ActionID.Brotherhood, true);
+ public static IBaseAction Brotherhood { get; } = new BaseAction(ActionID.Brotherhood, true);
///
/// 红莲极意 提高dps
///
- public static BaseAction RiddleofFire { get; } = new(ActionID.RiddleofFire, true);
+ public static IBaseAction RiddleofFire { get; } = new BaseAction(ActionID.RiddleofFire, true);
///
/// 突进技能
///
- public static BaseAction Thunderclap { get; } = new(ActionID.Thunderclap, shouldEndSpecial: true)
+ public static IBaseAction Thunderclap { get; } = new BaseAction(ActionID.Thunderclap, shouldEndSpecial: true)
{
ChoiceTarget = TargetFilter.FindTargetForMoving,
};
@@ -127,63 +127,63 @@ internal abstract class MNKRotation_Base : CustomRotation.CustomRotation
///
/// 真言
///
- public static BaseAction Mantra { get; } = new(ActionID.Mantra, true, isTimeline: true);
+ public static IBaseAction Mantra { get; } = new BaseAction(ActionID.Mantra, true, isTimeline: true);
///
/// 震脚
///
- public static BaseAction PerfectBalance { get; } = new(ActionID.PerfectBalance)
+ public static IBaseAction PerfectBalance { get; } = new BaseAction(ActionID.PerfectBalance)
{
- BuffsNeed = new StatusID[] { StatusID.RaptorForm },
+ StatusNeed = new StatusID[] { StatusID.RaptorForm },
ActionCheck = b => InCombat,
};
///
/// 苍气炮 阴
///
- public static BaseAction ElixirField { get; } = new(ActionID.ElixirField);
+ public static IBaseAction ElixirField { get; } = new BaseAction(ActionID.ElixirField);
///
/// 爆裂脚 阳
///
- public static BaseAction FlintStrike { get; } = new(ActionID.FlintStrike);
+ public static IBaseAction FlintStrike { get; } = new BaseAction(ActionID.FlintStrike);
///
/// 翻天脚 兔
///
- public static BaseAction CelestialRevolution { get; } = new(ActionID.CelestialRevolution);
+ public static IBaseAction CelestialRevolution { get; } = new BaseAction(ActionID.CelestialRevolution);
///
/// 凤凰舞
///
- public static BaseAction RisingPhoenix { get; } = new(ActionID.RisingPhoenix);
+ public static IBaseAction RisingPhoenix { get; } = new BaseAction(ActionID.RisingPhoenix);
///
/// 斗魂旋风脚 阴阳
///
- public static BaseAction TornadoKick { get; } = new(ActionID.TornadoKick);
- public static BaseAction PhantomRush { get; } = new(ActionID.PhantomRush);
+ public static IBaseAction TornadoKick { get; } = new BaseAction(ActionID.TornadoKick);
+ public static IBaseAction PhantomRush { get; } = new BaseAction(ActionID.PhantomRush);
///
/// 演武
///
- public static BaseAction FormShift { get; } = new(ActionID.FormShift, true)
+ public static IBaseAction FormShift { get; } = new BaseAction(ActionID.FormShift, true)
{
- BuffsProvide = new[] { StatusID.FormlessFist, StatusID.PerfectBalance },
+ StatusProvide = new[] { StatusID.FormlessFist, StatusID.PerfectBalance },
};
///
/// 金刚极意 盾
///
- public static BaseAction RiddleofEarth { get; } = new(ActionID.RiddleofEarth, true, shouldEndSpecial: true, isTimeline: true)
+ public static IBaseAction RiddleofEarth { get; } = new BaseAction(ActionID.RiddleofEarth, true, shouldEndSpecial: true, isTimeline: true)
{
- BuffsProvide = new[] { StatusID.RiddleofEarth },
+ StatusProvide = new[] { StatusID.RiddleofEarth },
};
///
/// 疾风极意
///
- public static BaseAction RiddleofWind { get; } = new(ActionID.RiddleofWind, true);
+ public static IBaseAction RiddleofWind { get; } = new BaseAction(ActionID.RiddleofWind, true);
private protected override bool MoveForwardAbility(byte abilityRemain, out IAction act)
{
diff --git a/RotationSolver/Rotations/Basic/NINRotation_Base.cs b/RotationSolver/Rotations/Basic/NINRotation_Base.cs
deleted file mode 100644
index 5fbca529c..000000000
--- a/RotationSolver/Rotations/Basic/NINRotation_Base.cs
+++ /dev/null
@@ -1,312 +0,0 @@
-using Dalamud.Game.ClientState.JobGauge.Types;
-using RotationSolver.Actions.BaseAction;
-using RotationSolver.Actions;
-using RotationSolver.Helpers;
-using RotationSolver.Data;
-
-namespace RotationSolver.Rotations.Basic;
-
-internal abstract class NINRotation_Base : CustomRotation.CustomRotation
-{
- private static NINGauge JobGauge => Service.JobGauges.Get();
-
- ///
- /// 在风buff中
- ///
- protected static bool InHuton => JobGauge.HutonTimer > 0;
-
- ///
- /// 忍术点数
- ///
- protected static byte Ninki => JobGauge.Ninki;
-
- public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Ninja, ClassJobID.Rogue };
- public class NinAction : BaseAction
- {
- internal BaseAction[] Ninjutsus { get; }
- internal NinAction(ActionID actionID, params BaseAction[] ninjutsus)
- : base(actionID, false, false)
- {
- Ninjutsus = ninjutsus;
- }
- }
-
- ///
- /// 隐遁
- ///
- public static BaseAction Hide { get; } = new(ActionID.Hide, true);
-
- ///
- /// 双刃旋
- ///
- public static BaseAction SpinningEdge { get; } = new(ActionID.SpinningEdge);
-
- ///
- /// 残影
- ///
- public static BaseAction ShadeShift { get; } = new(ActionID.ShadeShift, true);
-
- ///
- /// 绝风
- ///
- public static BaseAction GustSlash { get; } = new(ActionID.GustSlash);
-
- ///
- /// 飞刀
- ///
- public static BaseAction ThrowingDagger { get; } = new(ActionID.ThrowingDagger);
-
- ///
- /// 夺取
- ///
- public static BaseAction Mug { get; } = new(ActionID.Mug)
- {
- ActionCheck = b => JobGauge.Ninki <= 50,
- };
-
- ///
- /// 攻其不备
- ///
- public static BaseAction TrickAttack { get; } = new(ActionID.TrickAttack)
- {
- BuffsNeed = new StatusID[] { StatusID.Suiton, StatusID.Hidden },
- };
-
- ///
- /// 旋风刃
- ///
- public static BaseAction AeolianEdge { get; } = new(ActionID.AeolianEdge);
-
- ///
- /// 血雨飞花
- ///
- public static BaseAction DeathBlossom { get; } = new(ActionID.DeathBlossom);
-
- ///
- /// 天之印
- ///
- public static BaseAction Ten { get; } = new(ActionID.Ten, true);
-
- ///
- /// 地之印
- ///
- public static BaseAction Chi { get; } = new(ActionID.Chi, true);
-
- ///
- /// 人之印
- ///
- public static BaseAction Jin { get; } = new(ActionID.Jin, true);
-
- ///
- /// 天地人
- ///
- public static BaseAction TenChiJin { get; } = new(ActionID.TenChiJin, true)
- {
- BuffsProvide = new[] { StatusID.Kassatsu, StatusID.TenChiJin },
- ActionCheck = b => JobGauge.HutonTimer > 0,
- };
-
- ///
- /// 缩地
- ///
- public static BaseAction Shukuchi { get; } = new(ActionID.Shukuchi, true)
- {
- ChoiceTarget = TargetFilter.FindTargetForMoving,
- };
-
- ///
- /// 断绝
- ///
- public static BaseAction Assassinate { get; } = new(ActionID.Assassinate);
-
- ///
- /// 命水
- ///
- public static BaseAction Meisui { get; } = new(ActionID.Meisui, true)
- {
- BuffsNeed = new[] { StatusID.Suiton },
- ActionCheck = b => JobGauge.Ninki <= 50,
- };
-
- ///
- /// 生杀予夺
- ///
- public static BaseAction Kassatsu { get; } = new(ActionID.Kassatsu, true)
- {
- BuffsProvide = TenChiJin.BuffsProvide,
- };
-
- ///
- /// 八卦无刃杀
- ///
- public static BaseAction HakkeMujinsatsu { get; } = new(ActionID.HakkeMujinsatsu);
-
- ///
- /// 强甲破点突
- ///
- public static BaseAction ArmorCrush { get; } = new(ActionID.ArmorCrush)
- {
- ActionCheck = b => EndAfter(JobGauge.HutonTimer / 1000f, 29) && JobGauge.HutonTimer > 0,
- };
-
- ///
- /// 分身之术
- ///
- public static BaseAction Bunshin { get; } = new(ActionID.Bunshin, true)
- {
- ActionCheck = b => Ninki >= 50,
- };
-
- ///
- /// 通灵之术·大虾蟆
- ///
- public static BaseAction HellfrogMedium { get; } = new(ActionID.HellfrogMedium)
- {
- ActionCheck = Bunshin.ActionCheck,
- };
-
- ///
- /// 六道轮回
- ///
- public static BaseAction Bhavacakra { get; } = new(ActionID.Bhavacakra)
- {
- ActionCheck = Bunshin.ActionCheck,
- };
-
-
-
- ///
- /// 残影镰鼬
- ///
- public static BaseAction PhantomKamaitachi { get; } = new(ActionID.PhantomKamaitachi)
- {
- BuffsNeed = new[] { StatusID.PhantomKamaitachiReady },
- };
-
- ///
- /// 月影雷兽牙
- ///
- public static BaseAction FleetingRaiju { get; } = new(ActionID.FleetingRaiju)
- {
- BuffsNeed = new[] { StatusID.RaijuReady },
- };
-
- ///
- /// 月影雷兽爪
- ///
- public static BaseAction ForkedRaiju { get; } = new(ActionID.ForkedRaiju)
- {
- BuffsNeed = FleetingRaiju.BuffsNeed,
- };
-
- ///
- /// 风来刃
- ///
- public static BaseAction Huraijin { get; } = new(ActionID.Huraijin)
- {
- ActionCheck = b => JobGauge.HutonTimer == 0,
- };
-
- ///
- /// 梦幻三段
- ///
- public static BaseAction DreamWithinaDream { get; } = new(ActionID.DreamWithinaDream);
-
- ///
- /// 风魔手里剑天
- ///
- public static BaseAction FumaShurikenTen { get; } = new(ActionID.FumaShurikenTen);
-
- ///
- /// 风魔手里剑人
- ///
- public static BaseAction FumaShurikenJin { get; } = new(ActionID.FumaShurikenJin);
-
- ///
- /// 火遁之术天
- ///
- public static BaseAction KatonTen { get; } = new(ActionID.KatonTen);
-
- ///
- /// 雷遁之术地
- ///
- public static BaseAction RaitonChi { get; } = new(ActionID.RaitonChi);
-
- ///
- /// 土遁之术地
- ///
- public static BaseAction DotonChi { get; } = new(ActionID.DotonChi);
-
- ///
- /// 水遁之术人
- ///
- public static BaseAction SuitonJin { get; } = new(ActionID.SuitonJin);
-
-
- ///
- /// 通灵之术
- ///
- public static NinAction RabbitMedium { get; } = new(ActionID.RabbitMedium);
-
- ///
- /// 风魔手里剑
- ///
- public static NinAction FumaShuriken { get; } = new(ActionID.FumaShuriken, Ten);
-
- ///
- /// 火遁之术
- ///
- public static NinAction Katon { get; } = new(ActionID.Katon, Chi, Ten);
-
- ///
- /// 雷遁之术
- ///
- public static NinAction Raiton { get; } = new(ActionID.Raiton, Ten, Chi);
-
- ///
- /// 冰遁之术
- ///
- public static NinAction Hyoton { get; } = new(ActionID.Hyoton, Ten, Jin);
-
- ///
- /// 风遁之术
- ///
- public static NinAction Huton { get; } = new(ActionID.Huton, Jin, Chi, Ten)
- {
- ActionCheck = b => JobGauge.HutonTimer == 0,
- };
-
- ///
- /// 土遁之术
- ///
- public static NinAction Doton { get; } = new(ActionID.Doton, Jin, Ten, Chi)
- {
- BuffsProvide = new[] { StatusID.Doton },
- };
-
- ///
- /// 水遁之术
- ///
- public static NinAction Suiton { get; } = new(ActionID.Suiton, Ten, Chi, Jin)
- {
- BuffsProvide = new[] { StatusID.Suiton },
- ActionCheck = b => TrickAttack.WillHaveOneChargeGCD(1, 1),
- };
-
- ///
- /// 劫火灭却之术
- ///
- public static NinAction GokaMekkyaku { get; } = new(ActionID.GokaMekkyaku, Chi, Ten);
-
- ///
- /// 冰晶乱流之术
- ///
- public static NinAction HyoshoRanryu { get; } = new(ActionID.HyoshoRanryu, Ten, Jin);
-
- private protected override bool MoveForwardAbility(byte abilityRemain, out IAction act)
- {
- if (Shukuchi.ShouldUse(out act, emptyOrSkipCombo: true)) return true;
-
- return false;
- }
-}
diff --git a/RotationSolver/Rotations/Basic/NIN_Base.cs b/RotationSolver/Rotations/Basic/NIN_Base.cs
new file mode 100644
index 000000000..760d82e30
--- /dev/null
+++ b/RotationSolver/Rotations/Basic/NIN_Base.cs
@@ -0,0 +1,316 @@
+using Dalamud.Game.ClientState.JobGauge.Types;
+using RotationSolver.Actions.BaseAction;
+using RotationSolver.Actions;
+using RotationSolver.Helpers;
+using RotationSolver.Data;
+
+namespace RotationSolver.Rotations.Basic;
+
+internal abstract class NINRotation_Base : CustomRotation.CustomRotation
+{
+ private static NINGauge JobGauge => Service.JobGauges.Get();
+
+ ///
+ /// 在风buff中
+ ///
+ protected static bool InHuton => JobGauge.HutonTimer > 0;
+
+ ///
+ /// 忍术点数
+ ///
+ protected static byte Ninki => JobGauge.Ninki;
+
+ public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Ninja, ClassJobID.Rogue };
+
+ public interface INinAction : IBaseAction
+ {
+ IBaseAction[] Ninjutsus { get; }
+ }
+
+ public class NinAction : BaseAction, INinAction
+ {
+ public IBaseAction[] Ninjutsus { get; }
+ internal NinAction(ActionID actionID, params IBaseAction[] ninjutsus)
+ : base(actionID, false, false)
+ {
+ Ninjutsus = ninjutsus;
+ }
+ }
+
+ ///
+ /// 隐遁
+ ///
+ public static IBaseAction Hide { get; } = new BaseAction(ActionID.Hide, true);
+
+ ///
+ /// 双刃旋
+ ///
+ public static IBaseAction SpinningEdge { get; } = new BaseAction(ActionID.SpinningEdge);
+
+ ///
+ /// 残影
+ ///
+ public static IBaseAction ShadeShift { get; } = new BaseAction(ActionID.ShadeShift, true);
+
+ ///
+ /// 绝风
+ ///
+ public static IBaseAction GustSlash { get; } = new BaseAction(ActionID.GustSlash);
+
+ ///
+ /// 飞刀
+ ///
+ public static IBaseAction ThrowingDagger { get; } = new BaseAction(ActionID.ThrowingDagger);
+
+ ///
+ /// 夺取
+ ///
+ public static IBaseAction Mug { get; } = new BaseAction(ActionID.Mug)
+ {
+ ActionCheck = b => JobGauge.Ninki <= 50,
+ };
+
+ ///
+ /// 攻其不备
+ ///
+ public static IBaseAction TrickAttack { get; } = new BaseAction(ActionID.TrickAttack)
+ {
+ StatusNeed = new StatusID[] { StatusID.Suiton, StatusID.Hidden },
+ };
+
+ ///
+ /// 旋风刃
+ ///
+ public static IBaseAction AeolianEdge { get; } = new BaseAction(ActionID.AeolianEdge);
+
+ ///
+ /// 血雨飞花
+ ///
+ public static IBaseAction DeathBlossom { get; } = new BaseAction(ActionID.DeathBlossom);
+
+ ///
+ /// 天之印
+ ///
+ public static IBaseAction Ten { get; } = new BaseAction(ActionID.Ten, true);
+
+ ///
+ /// 地之印
+ ///
+ public static IBaseAction Chi { get; } = new BaseAction(ActionID.Chi, true);
+
+ ///
+ /// 人之印
+ ///
+ public static IBaseAction Jin { get; } = new BaseAction(ActionID.Jin, true);
+
+ ///
+ /// 天地人
+ ///
+ public static IBaseAction TenChiJin { get; } = new BaseAction(ActionID.TenChiJin, true)
+ {
+ StatusProvide = new[] { StatusID.Kassatsu, StatusID.TenChiJin },
+ ActionCheck = b => JobGauge.HutonTimer > 0,
+ };
+
+ ///
+ /// 缩地
+ ///
+ public static IBaseAction Shukuchi { get; } = new BaseAction(ActionID.Shukuchi, true)
+ {
+ ChoiceTarget = TargetFilter.FindTargetForMoving,
+ };
+
+ ///
+ /// 断绝
+ ///
+ public static IBaseAction Assassinate { get; } = new BaseAction(ActionID.Assassinate);
+
+ ///
+ /// 命水
+ ///
+ public static IBaseAction Meisui { get; } = new BaseAction(ActionID.Meisui, true)
+ {
+ StatusNeed = new[] { StatusID.Suiton },
+ ActionCheck = b => JobGauge.Ninki <= 50,
+ };
+
+ ///
+ /// 生杀予夺
+ ///
+ public static IBaseAction Kassatsu { get; } = new BaseAction(ActionID.Kassatsu, true)
+ {
+ StatusProvide = TenChiJin.StatusProvide,
+ };
+
+ ///
+ /// 八卦无刃杀
+ ///
+ public static IBaseAction HakkeMujinsatsu { get; } = new BaseAction(ActionID.HakkeMujinsatsu);
+
+ ///
+ /// 强甲破点突
+ ///
+ public static IBaseAction ArmorCrush { get; } = new BaseAction(ActionID.ArmorCrush)
+ {
+ ActionCheck = b => EndAfter(JobGauge.HutonTimer / 1000f, 29) && JobGauge.HutonTimer > 0,
+ };
+
+ ///
+ /// 分身之术
+ ///
+ public static IBaseAction Bunshin { get; } = new BaseAction(ActionID.Bunshin, true)
+ {
+ ActionCheck = b => Ninki >= 50,
+ };
+
+ ///
+ /// 通灵之术·大虾蟆
+ ///
+ public static IBaseAction HellfrogMedium { get; } = new BaseAction(ActionID.HellfrogMedium)
+ {
+ ActionCheck = Bunshin.ActionCheck,
+ };
+
+ ///
+ /// 六道轮回
+ ///
+ public static IBaseAction Bhavacakra { get; } = new BaseAction(ActionID.Bhavacakra)
+ {
+ ActionCheck = Bunshin.ActionCheck,
+ };
+
+ ///
+ /// 残影镰鼬
+ ///
+ public static IBaseAction PhantomKamaitachi { get; } = new BaseAction(ActionID.PhantomKamaitachi)
+ {
+ StatusNeed = new[] { StatusID.PhantomKamaitachiReady },
+ };
+
+ ///
+ /// 月影雷兽牙
+ ///
+ public static IBaseAction FleetingRaiju { get; } = new BaseAction(ActionID.FleetingRaiju)
+ {
+ StatusNeed = new[] { StatusID.RaijuReady },
+ };
+
+ ///
+ /// 月影雷兽爪
+ ///
+ public static IBaseAction ForkedRaiju { get; } = new BaseAction(ActionID.ForkedRaiju)
+ {
+ StatusNeed = FleetingRaiju.StatusNeed,
+ };
+
+ ///
+ /// 风来刃
+ ///
+ public static IBaseAction Huraijin { get; } = new BaseAction(ActionID.Huraijin)
+ {
+ ActionCheck = b => JobGauge.HutonTimer == 0,
+ };
+
+ ///
+ /// 梦幻三段
+ ///
+ public static IBaseAction DreamWithinaDream { get; } = new BaseAction(ActionID.DreamWithinaDream);
+
+ ///
+ /// 风魔手里剑天
+ ///
+ public static IBaseAction FumaShurikenTen { get; } = new BaseAction(ActionID.FumaShurikenTen);
+
+ ///
+ /// 风魔手里剑人
+ ///
+ public static IBaseAction FumaShurikenJin { get; } = new BaseAction(ActionID.FumaShurikenJin);
+
+ ///
+ /// 火遁之术天
+ ///
+ public static IBaseAction KatonTen { get; } = new BaseAction(ActionID.KatonTen);
+
+ ///
+ /// 雷遁之术地
+ ///
+ public static IBaseAction RaitonChi { get; } = new BaseAction(ActionID.RaitonChi);
+
+ ///
+ /// 土遁之术地
+ ///
+ public static IBaseAction DotonChi { get; } = new BaseAction(ActionID.DotonChi);
+
+ ///
+ /// 水遁之术人
+ ///
+ public static IBaseAction SuitonJin { get; } = new BaseAction(ActionID.SuitonJin);
+
+
+ ///
+ /// 通灵之术
+ ///
+ public static INinAction RabbitMedium { get; } = new NinAction(ActionID.RabbitMedium);
+
+ ///
+ /// 风魔手里剑
+ ///
+ public static INinAction FumaShuriken { get; } = new NinAction(ActionID.FumaShuriken, Ten);
+
+ ///
+ /// 火遁之术
+ ///
+ public static INinAction Katon { get; } = new NinAction(ActionID.Katon, Chi, Ten);
+
+ ///
+ /// 雷遁之术
+ ///
+ public static INinAction Raiton { get; } = new NinAction(ActionID.Raiton, Ten, Chi);
+
+ ///
+ /// 冰遁之术
+ ///
+ public static INinAction Hyoton { get; } = new NinAction(ActionID.Hyoton, Ten, Jin);
+
+ ///
+ /// 风遁之术
+ ///
+ public static INinAction Huton { get; } = new NinAction(ActionID.Huton, Jin, Chi, Ten)
+ {
+ ActionCheck = b => JobGauge.HutonTimer == 0,
+ };
+
+ ///
+ /// 土遁之术
+ ///
+ public static INinAction Doton { get; } = new NinAction(ActionID.Doton, Jin, Ten, Chi)
+ {
+ StatusProvide = new[] { StatusID.Doton },
+ };
+
+ ///
+ /// 水遁之术
+ ///
+ public static INinAction Suiton { get; } = new NinAction(ActionID.Suiton, Ten, Chi, Jin)
+ {
+ StatusProvide = new[] { StatusID.Suiton },
+ ActionCheck = b => TrickAttack.WillHaveOneChargeGCD(1, 1),
+ };
+
+ ///
+ /// 劫火灭却之术
+ ///
+ public static INinAction GokaMekkyaku { get; } = new NinAction(ActionID.GokaMekkyaku, Chi, Ten);
+
+ ///
+ /// 冰晶乱流之术
+ ///
+ public static INinAction HyoshoRanryu { get; } = new NinAction(ActionID.HyoshoRanryu, Ten, Jin);
+
+ private protected override bool MoveForwardAbility(byte abilityRemain, out IAction act)
+ {
+ if (Shukuchi.ShouldUse(out act, emptyOrSkipCombo: true)) return true;
+
+ return false;
+ }
+}
diff --git a/RotationSolver/Rotations/Basic/PLDRotation_Base.cs b/RotationSolver/Rotations/Basic/PLD_Base.cs
similarity index 54%
rename from RotationSolver/Rotations/Basic/PLDRotation_Base.cs
rename to RotationSolver/Rotations/Basic/PLD_Base.cs
index 763a05eb4..84890d2bc 100644
--- a/RotationSolver/Rotations/Basic/PLDRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/PLD_Base.cs
@@ -20,29 +20,29 @@ internal abstract class PLDRotation_Base : CustomRotation.CustomRotation
public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Paladin, ClassJobID.Gladiator };
- private sealed protected override BaseAction Shield => IronWill;
+ private sealed protected override IBaseAction Shield => IronWill;
protected override bool CanHealSingleSpell => TargetUpdater.PartyMembers.Count() == 1 && base.CanHealSingleSpell;
///
/// ��������
///
- public static BaseAction IronWill { get; } = new(ActionID.IronWill, shouldEndSpecial: true);
+ public static IBaseAction IronWill { get; } = new BaseAction(ActionID.IronWill, shouldEndSpecial: true);
///
/// �ȷ潣
///
- public static BaseAction FastBlade { get; } = new(ActionID.FastBlade);
+ public static IBaseAction FastBlade { get; } = new BaseAction(ActionID.FastBlade);
///
/// ���ҽ�
///
- public static BaseAction RiotBlade { get; } = new(ActionID.RiotBlade);
+ public static IBaseAction RiotBlade { get; } = new BaseAction(ActionID.RiotBlade);
///
/// ��Ѫ��
///
- public static BaseAction GoringBlade { get; } = new(ActionID.GoringBlade, isEot: true)
+ public static IBaseAction GoringBlade { get; } = new BaseAction(ActionID.GoringBlade, isEot: true)
{
TargetStatus = new[]
{
@@ -54,12 +54,12 @@ internal abstract class PLDRotation_Base : CustomRotation.CustomRotation
///
/// սŮ��֮ŭ(��Ȩ��)
///
- public static BaseAction RageofHalone { get; } = new(ActionID.RageofHalone);
+ public static IBaseAction RageofHalone { get; } = new BaseAction(ActionID.RageofHalone);
///
/// Ͷ��
///
- public static BaseAction ShieldLob { get; } = new(ActionID.ShieldLob)
+ public static IBaseAction ShieldLob { get; } = new BaseAction(ActionID.ShieldLob)
{
FilterForTarget = b => TargetFilter.ProvokeTarget(b),
};
@@ -67,56 +67,56 @@ internal abstract class PLDRotation_Base : CustomRotation.CustomRotation
///
/// ս�ӷ�Ӧ
///
- public static BaseAction FightorFlight { get; } = new(ActionID.FightorFlight, true);
+ public static IBaseAction FightorFlight { get; } = new BaseAction(ActionID.FightorFlight, true);
///
/// ȫʴն
///
- public static BaseAction TotalEclipse { get; } = new(ActionID.TotalEclipse);
+ public static IBaseAction TotalEclipse { get; } = new BaseAction(ActionID.TotalEclipse);
///
/// ����ն
///
- public static BaseAction Prominence { get; } = new(ActionID.Prominence);
+ public static IBaseAction Prominence { get; } = new BaseAction(ActionID.Prominence);
///
/// Ԥ��
///
- public static BaseAction Sentinel { get; } = new(ActionID.Sentinel, isTimeline: true, isFriendly: true)
+ public static IBaseAction Sentinel { get; } = new BaseAction(ActionID.Sentinel, isTimeline: true, isFriendly: true)
{
- BuffsProvide = Rampart.BuffsProvide,
+ StatusProvide = Rampart.StatusProvide,
ActionCheck = BaseAction.TankDefenseSelf,
};
///
/// ������ת
///
- public static BaseAction CircleofScorn { get; } = new(ActionID.CircleofScorn);
+ public static IBaseAction CircleofScorn { get; } = new BaseAction(ActionID.CircleofScorn);
///
/// ���֮��
///
- public static BaseAction SpiritsWithin { get; } = new(ActionID.SpiritsWithin);
+ public static IBaseAction SpiritsWithin { get; } = new BaseAction(ActionID.SpiritsWithin);
///
/// ��ʥ����
///
- public static BaseAction HallowedGround { get; } = new(ActionID.HallowedGround, isTimeline: true);
+ public static IBaseAction HallowedGround { get; } = new BaseAction(ActionID.HallowedGround, isTimeline: true);
///
/// ʥ��Ļ��
///
- public static BaseAction DivineVeil { get; } = new(ActionID.DivineVeil, true, isTimeline: true);
+ public static IBaseAction DivineVeil { get; } = new BaseAction(ActionID.DivineVeil, true, isTimeline: true);
///
/// ���ʺ���
///
- public static BaseAction Clemency { get; } = new(ActionID.Clemency, true, true, isTimeline: true);
+ public static IBaseAction Clemency { get; } = new BaseAction(ActionID.Clemency, true, true, isTimeline: true);
///
/// ��Ԥ
///
- public static BaseAction Intervention { get; } = new(ActionID.Intervention, true, isTimeline: true)
+ public static IBaseAction Intervention { get; } = new BaseAction(ActionID.Intervention, true, isTimeline: true)
{
ChoiceTarget = TargetFilter.FindAttackedTarget,
};
@@ -124,7 +124,7 @@ internal abstract class PLDRotation_Base : CustomRotation.CustomRotation
///
/// ��ͣ
///
- public static BaseAction Intervene { get; } = new(ActionID.Intervene, shouldEndSpecial: true)
+ public static IBaseAction Intervene { get; } = new BaseAction(ActionID.Intervene, shouldEndSpecial: true)
{
ChoiceTarget = TargetFilter.FindTargetForMoving,
};
@@ -132,63 +132,63 @@ internal abstract class PLDRotation_Base : CustomRotation.CustomRotation
///
/// ���」
///
- public static BaseAction Atonement { get; } = new(ActionID.Atonement)
+ public static IBaseAction Atonement { get; } = new BaseAction(ActionID.Atonement)
{
- BuffsNeed = new[] { StatusID.SwordOath },
+ StatusNeed = new[] { StatusID.SwordOath },
};
///
/// ���꽣
///
- public static BaseAction Expiacion { get; } = new(ActionID.Expiacion);
+ public static IBaseAction Expiacion { get; } = new BaseAction(ActionID.Expiacion);
///
/// Ӣ��֮��
///
- public static BaseAction BladeofValor { get; } = new(ActionID.BladeofValor);
+ public static IBaseAction BladeofValor { get; } = new BaseAction(ActionID.BladeofValor);
///
/// ����֮��
///
- public static BaseAction BladeofTruth { get; } = new(ActionID.BladeofTruth);
+ public static IBaseAction BladeofTruth { get; } = new BaseAction(ActionID.BladeofTruth);
///
/// ����֮��
///
- public static BaseAction BladeofFaith { get; } = new(ActionID.BladeofFaith)
+ public static IBaseAction BladeofFaith { get; } = new BaseAction(ActionID.BladeofFaith)
{
- BuffsNeed = new[] { StatusID.ReadyForBladeofFaith },
+ StatusNeed = new[] { StatusID.ReadyForBladeofFaith },
};
///
/// ��������
///
- public static BaseAction Requiescat { get; } = new(ActionID.Requiescat, true);
+ public static IBaseAction Requiescat { get; } = new BaseAction(ActionID.Requiescat, true);
///
/// ����
///
- public static BaseAction Confiteor { get; } = new(ActionID.Confiteor);
+ public static IBaseAction Confiteor { get; } = new BaseAction(ActionID.Confiteor);
///
/// ʥ��
///
- public static BaseAction HolyCircle { get; } = new(ActionID.HolyCircle);
+ public static IBaseAction HolyCircle { get; } = new BaseAction(ActionID.HolyCircle);
///
/// ʥ��
///
- public static BaseAction HolySpirit { get; } = new(ActionID.HolySpirit);
+ public static IBaseAction HolySpirit { get; } = new BaseAction(ActionID.HolySpirit);
///
/// ��װ����
///
- public static BaseAction PassageofArms { get; } = new(ActionID.PassageofArms, true, isTimeline: true);
+ public static IBaseAction PassageofArms { get; } = new BaseAction(ActionID.PassageofArms, true, isTimeline: true);
///
/// ����
///
- public static BaseAction Cover { get; } = new(ActionID.Cover, true, isTimeline: true)
+ public static IBaseAction Cover { get; } = new BaseAction(ActionID.Cover, true, isTimeline: true)
{
ChoiceTarget = TargetFilter.FindAttackedTarget,
ActionCheck = b => OathGauge >= 50,
@@ -197,7 +197,7 @@ internal abstract class PLDRotation_Base : CustomRotation.CustomRotation
///
/// ����
///
- public static BaseAction Sheltron { get; } = new(ActionID.Sheltron, isTimeline: true)
+ public static IBaseAction Sheltron { get; } = new BaseAction(ActionID.Sheltron, isTimeline: true)
{
ActionCheck = Cover.ActionCheck,
};
diff --git a/RotationSolver/Rotations/Basic/RDMRotation_Base.cs b/RotationSolver/Rotations/Basic/RDM_Base.cs
similarity index 53%
rename from RotationSolver/Rotations/Basic/RDMRotation_Base.cs
rename to RotationSolver/Rotations/Basic/RDM_Base.cs
index 2e776be9c..6b488ce24 100644
--- a/RotationSolver/Rotations/Basic/RDMRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/RDM_Base.cs
@@ -32,25 +32,25 @@ internal abstract class RDMRotation_Base : CustomRotation.CustomRotation
public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.RedMage };
protected override bool CanHealSingleSpell => TargetUpdater.PartyMembers.Count() == 1 && base.CanHealSingleSpell;
- private sealed protected override BaseAction Raise => Verraise;
+ private sealed protected override IBaseAction Raise => Verraise;
///
/// �ิ��
///
- public static BaseAction Verraise { get; } = new(ActionID.Verraise, true);
+ public static IBaseAction Verraise { get; } = new BaseAction(ActionID.Verraise, true);
///
/// ��
///
- public static BaseAction Jolt { get; } = new(ActionID.Jolt)
+ public static IBaseAction Jolt { get; } = new BaseAction(ActionID.Jolt)
{
- BuffsProvide = Swiftcast.BuffsProvide.Union(new[] { StatusID.Acceleration }).ToArray(),
+ StatusProvide = Swiftcast.StatusProvide.Union(new[] { StatusID.Acceleration }).ToArray(),
};
///
/// �ش�
///
- public static BaseAction Riposte { get; } = new(ActionID.Riposte)
+ public static IBaseAction Riposte { get; } = new BaseAction(ActionID.Riposte)
{
ActionCheck = b => JobGauge.BlackMana >= 20 && JobGauge.WhiteMana >= 20,
};
@@ -58,15 +58,15 @@ internal abstract class RDMRotation_Base : CustomRotation.CustomRotation
///
/// ������
///
- public static BaseAction Verthunder { get; } = new(ActionID.Verthunder)
+ public static IBaseAction Verthunder { get; } = new BaseAction(ActionID.Verthunder)
{
- BuffsNeed = Jolt.BuffsProvide,
+ StatusNeed = Jolt.StatusProvide,
};
///
/// �̱����
///
- public static BaseAction CorpsAcorps { get; } = new(ActionID.CorpsAcorps, shouldEndSpecial: true)
+ public static IBaseAction CorpsAcorps { get; } = new BaseAction(ActionID.CorpsAcorps, shouldEndSpecial: true)
{
ChoiceTarget = TargetFilter.FindTargetForMoving,
};
@@ -74,57 +74,57 @@ internal abstract class RDMRotation_Base : CustomRotation.CustomRotation
///
/// �༲��
///
- public static BaseAction Veraero { get; } = new(ActionID.Veraero)
+ public static IBaseAction Veraero { get; } = new BaseAction(ActionID.Veraero)
{
- BuffsNeed = Jolt.BuffsProvide,
+ StatusNeed = Jolt.StatusProvide,
};
///
/// ɢ��
///
- public static BaseAction Scatter { get; } = new(ActionID.Scatter)
+ public static IBaseAction Scatter { get; } = new BaseAction(ActionID.Scatter)
{
- BuffsNeed = Jolt.BuffsProvide,
+ StatusNeed = Jolt.StatusProvide,
};
///
/// ������
///
- public static BaseAction Verthunder2 { get; } = new(ActionID.Verthunder2)
+ public static IBaseAction Verthunder2 { get; } = new BaseAction(ActionID.Verthunder2)
{
- BuffsProvide = Jolt.BuffsProvide,
+ StatusProvide = Jolt.StatusProvide,
};
///
/// ���ҷ�
///
- public static BaseAction Veraero2 { get; } = new(ActionID.Veraero2)
+ public static IBaseAction Veraero2 { get; } = new BaseAction(ActionID.Veraero2)
{
- BuffsProvide = Jolt.BuffsProvide,
+ StatusProvide = Jolt.StatusProvide,
};
///
/// �����
///
- public static BaseAction Verfire { get; } = new(ActionID.Verfire)
+ public static IBaseAction Verfire { get; } = new BaseAction(ActionID.Verfire)
{
- BuffsNeed = new[] { StatusID.VerfireReady },
- BuffsProvide = Jolt.BuffsProvide,
+ StatusNeed = new[] { StatusID.VerfireReady },
+ StatusProvide = Jolt.StatusProvide,
};
///
/// ���ʯ
///
- public static BaseAction Verstone { get; } = new(ActionID.Verstone)
+ public static IBaseAction Verstone { get; } = new BaseAction(ActionID.Verstone)
{
- BuffsNeed = new[] { StatusID.VerstoneReady },
- BuffsProvide = Jolt.BuffsProvide,
+ StatusNeed = new[] { StatusID.VerstoneReady },
+ StatusProvide = Jolt.StatusProvide,
};
///
/// ����ն
///
- public static BaseAction Zwerchhau { get; } = new(ActionID.Zwerchhau)
+ public static IBaseAction Zwerchhau { get; } = new BaseAction(ActionID.Zwerchhau)
{
ActionCheck = b => BlackMana >= 15 && WhiteMana >= 15,
};
@@ -132,17 +132,17 @@ internal abstract class RDMRotation_Base : CustomRotation.CustomRotation
///
/// ����
///
- public static BaseAction Engagement { get; } = new(ActionID.Engagement);
+ public static IBaseAction Engagement { get; } = new BaseAction(ActionID.Engagement);
///
/// �ɽ�
///
- public static BaseAction Fleche { get; } = new(ActionID.Fleche);
+ public static IBaseAction Fleche { get; } = new BaseAction(ActionID.Fleche);
///
/// ����
///
- public static BaseAction Redoublement { get; } = new(ActionID.Redoublement)
+ public static IBaseAction Redoublement { get; } = new BaseAction(ActionID.Redoublement)
{
ActionCheck = b => BlackMana >= 15 && WhiteMana >= 15,
};
@@ -151,15 +151,15 @@ internal abstract class RDMRotation_Base : CustomRotation.CustomRotation
///
/// �ٽ�
///
- public static BaseAction Acceleration { get; } = new(ActionID.Acceleration, true)
+ public static IBaseAction Acceleration { get; } = new BaseAction(ActionID.Acceleration, true)
{
- BuffsProvide = new[] { StatusID.Acceleration },
+ StatusProvide = new[] { StatusID.Acceleration },
};
///
/// ��Բն
///
- public static BaseAction Moulinet { get; } = new(ActionID.Moulinet)
+ public static IBaseAction Moulinet { get; } = new BaseAction(ActionID.Moulinet)
{
ActionCheck = b => BlackMana >= 20 && WhiteMana >= 20,
};
@@ -167,45 +167,40 @@ internal abstract class RDMRotation_Base : CustomRotation.CustomRotation
///
/// ������
///
- public static BaseAction Vercure { get; } = new(ActionID.Vercure, true)
+ public static IBaseAction Vercure { get; } = new BaseAction(ActionID.Vercure, true)
{
- BuffsProvide = Swiftcast.BuffsProvide.Union(Acceleration.BuffsProvide).ToArray(),
+ StatusProvide = Swiftcast.StatusProvide.Union(Acceleration.StatusProvide).ToArray(),
};
///
/// ���ַ���
///
- public static BaseAction ContreSixte { get; } = new(ActionID.ContreSixte);
+ public static IBaseAction ContreSixte { get; } = new BaseAction(ActionID.ContreSixte);
///
/// ����
///
- public static BaseAction Embolden { get; } = new(ActionID.Embolden, true);
-
- /////
- ///// ��ն
- /////
- //public static BaseAction Reprise { get; } = new(ActionID.Reprise);
+ public static IBaseAction Embolden { get; } = new BaseAction(ActionID.Embolden, true);
///
/// ����
///
- public static BaseAction MagickBarrier { get; } = new(ActionID.MagickBarrier, true, isTimeline: true);
+ public static IBaseAction MagickBarrier { get; } = new BaseAction(ActionID.MagickBarrier, true, isTimeline: true);
///
/// ��˱�
///
- public static BaseAction Verflare { get; } = new(ActionID.Verflare);
+ public static IBaseAction Verflare { get; } = new BaseAction(ActionID.Verflare);
///
/// ����ʥ
///
- public static BaseAction Verholy { get; } = new(ActionID.Verholy);
+ public static IBaseAction Verholy { get; } = new BaseAction(ActionID.Verholy);
///
/// ����
///
- public static BaseAction Scorch { get; } = new(ActionID.Scorch)
+ public static IBaseAction Scorch { get; } = new BaseAction(ActionID.Scorch)
{
OtherIDsCombo = new[] { ActionID.Verholy },
};
@@ -213,12 +208,12 @@ internal abstract class RDMRotation_Base : CustomRotation.CustomRotation
///
/// ����
///
- public static BaseAction Resolution { get; } = new(ActionID.Resolution);
+ public static IBaseAction Resolution { get; } = new BaseAction(ActionID.Resolution);
///
/// ħԪ��
///
- public static BaseAction Manafication { get; } = new(ActionID.Manafication)
+ public static IBaseAction Manafication { get; } = new BaseAction(ActionID.Manafication)
{
ActionCheck = b => WhiteMana <= 50 && BlackMana <= 50 && InCombat && ManaStacks == 0,
OtherIDsNot = new[] { ActionID.Riposte, ActionID.Zwerchhau, ActionID.Scorch, ActionID.Verflare, ActionID.Verholy },
diff --git a/RotationSolver/Rotations/Basic/RPRRotation_Base.cs b/RotationSolver/Rotations/Basic/RPR_Base.cs
similarity index 58%
rename from RotationSolver/Rotations/Basic/RPRRotation_Base.cs
rename to RotationSolver/Rotations/Basic/RPR_Base.cs
index 5f53b4c5d..8b8d05099 100644
--- a/RotationSolver/Rotations/Basic/RPRRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/RPR_Base.cs
@@ -52,7 +52,7 @@ internal PRPAction(ActionID actionID, bool isFriendly = false, bool shouldEndSpe
///
/// 切割
///
- public static BaseAction Slice { get; } = new(ActionID.Slice)
+ public static IBaseAction Slice { get; } = new BaseAction(ActionID.Slice)
{
ActionCheck = b => !Enshrouded && !SoulReaver,
};
@@ -60,7 +60,7 @@ internal PRPAction(ActionID actionID, bool isFriendly = false, bool shouldEndSpe
///
/// 增盈切割
///
- public static BaseAction WaxingSlice { get; } = new(ActionID.WaxingSlice)
+ public static IBaseAction WaxingSlice { get; } = new BaseAction(ActionID.WaxingSlice)
{
ActionCheck = Slice.ActionCheck,
};
@@ -68,7 +68,7 @@ internal PRPAction(ActionID actionID, bool isFriendly = false, bool shouldEndSpe
///
/// 地狱切割
///
- public static BaseAction InfernalSlice { get; } = new(ActionID.InfernalSlice)
+ public static IBaseAction InfernalSlice { get; } = new BaseAction(ActionID.InfernalSlice)
{
ActionCheck = Slice.ActionCheck,
};
@@ -76,7 +76,7 @@ internal PRPAction(ActionID actionID, bool isFriendly = false, bool shouldEndSpe
///
/// 死亡之影
///
- public static BaseAction ShadowofDeath { get; } = new(ActionID.ShadowofDeath, isEot: true)
+ public static IBaseAction ShadowofDeath { get; } = new BaseAction(ActionID.ShadowofDeath, isEot: true)
{
TargetStatus = new[] { StatusID.DeathsDesign },
ActionCheck = b => !SoulReaver,
@@ -85,7 +85,7 @@ internal PRPAction(ActionID actionID, bool isFriendly = false, bool shouldEndSpe
///
/// 灵魂切割
///
- public static BaseAction SoulSlice { get; } = new(ActionID.SoulSlice)
+ public static IBaseAction SoulSlice { get; } = new BaseAction(ActionID.SoulSlice)
{
ActionCheck = b => !Enshrouded && !SoulReaver && Soul <= 50,
};
@@ -94,7 +94,7 @@ internal PRPAction(ActionID actionID, bool isFriendly = false, bool shouldEndSpe
///
/// 旋转钐割
///
- public static BaseAction SpinningScythe { get; } = new(ActionID.SpinningScythe)
+ public static IBaseAction SpinningScythe { get; } = new BaseAction(ActionID.SpinningScythe)
{
ActionCheck = Slice.ActionCheck,
};
@@ -102,7 +102,7 @@ internal PRPAction(ActionID actionID, bool isFriendly = false, bool shouldEndSpe
///
/// 噩梦钐割
///
- public static BaseAction NightmareScythe { get; } = new(ActionID.NightmareScythe)
+ public static IBaseAction NightmareScythe { get; } = new BaseAction(ActionID.NightmareScythe)
{
ActionCheck = Slice.ActionCheck,
};
@@ -110,7 +110,7 @@ internal PRPAction(ActionID actionID, bool isFriendly = false, bool shouldEndSpe
///
/// 死亡之涡
///
- public static BaseAction WhorlofDeath { get; } = new(ActionID.WhorlofDeath, isEot: true)
+ public static IBaseAction WhorlofDeath { get; } = new BaseAction(ActionID.WhorlofDeath, isEot: true)
{
TargetStatus = new[] { StatusID.DeathsDesign },
ActionCheck = ShadowofDeath.ActionCheck,
@@ -119,7 +119,7 @@ internal PRPAction(ActionID actionID, bool isFriendly = false, bool shouldEndSpe
///
/// 灵魂钐割
///
- public static BaseAction SoulScythe { get; } = new(ActionID.SoulScythe)
+ public static IBaseAction SoulScythe { get; } = new BaseAction(ActionID.SoulScythe)
{
ActionCheck = SoulSlice.ActionCheck,
};
@@ -128,52 +128,52 @@ internal PRPAction(ActionID actionID, bool isFriendly = false, bool shouldEndSpe
///
/// 绞决
///
- public static BaseAction Gibbet { get; } = new(ActionID.Gibbet)
+ public static IBaseAction Gibbet { get; } = new BaseAction(ActionID.Gibbet)
{
- BuffsNeed = new[] { StatusID.SoulReaver }
+ StatusNeed = new[] { StatusID.SoulReaver }
};
///
/// 缢杀
///
- public static BaseAction Gallows { get; } = new(ActionID.Gallows)
+ public static IBaseAction Gallows { get; } = new BaseAction(ActionID.Gallows)
{
- BuffsNeed = new[] { StatusID.SoulReaver }
+ StatusNeed = new[] { StatusID.SoulReaver }
};
///
/// 断首
///
- public static BaseAction Guillotine { get; } = new(ActionID.Guillotine)
+ public static IBaseAction Guillotine { get; } = new BaseAction(ActionID.Guillotine)
{
- BuffsNeed = new[] { StatusID.SoulReaver }
+ StatusNeed = new[] { StatusID.SoulReaver }
};
#endregion
#region 红条50灵魂
///
/// 隐匿挥割
///
- public static BaseAction BloodStalk { get; } = new(ActionID.BloodStalk)
+ public static IBaseAction BloodStalk { get; } = new BaseAction(ActionID.BloodStalk)
{
- BuffsProvide = new[] { StatusID.SoulReaver },
+ StatusProvide = new[] { StatusID.SoulReaver },
ActionCheck = b => !SoulReaver && !Enshrouded && Soul >= 50
};
///
/// 束缚挥割
///
- public static BaseAction GrimSwathe { get; } = new(ActionID.GrimSwathe)
+ public static IBaseAction GrimSwathe { get; } = new BaseAction(ActionID.GrimSwathe)
{
- BuffsProvide = new[] { StatusID.SoulReaver },
+ StatusProvide = new[] { StatusID.SoulReaver },
ActionCheck = BloodStalk.ActionCheck,
};
///
/// 暴食
///
- public static BaseAction Gluttony { get; } = new(ActionID.Gluttony)
+ public static IBaseAction Gluttony { get; } = new BaseAction(ActionID.Gluttony)
{
- BuffsProvide = new[] { StatusID.SoulReaver },
+ StatusProvide = new[] { StatusID.SoulReaver },
ActionCheck = BloodStalk.ActionCheck,
};
#endregion
@@ -181,17 +181,17 @@ internal PRPAction(ActionID actionID, bool isFriendly = false, bool shouldEndSpe
///
/// 神秘环
///
- public static BaseAction ArcaneCircle { get; } = new(ActionID.ArcaneCircle, true)
+ public static IBaseAction ArcaneCircle { get; } = new BaseAction(ActionID.ArcaneCircle, true)
{
- BuffsProvide = new[] { StatusID.CircleofSacrifice, StatusID.BloodsownCircle }
+ StatusProvide = new[] { StatusID.CircleofSacrifice, StatusID.BloodsownCircle }
};
///
/// 大丰收
///
- public static BaseAction PlentifulHarvest { get; } = new(ActionID.PlentifulHarvest)
+ public static IBaseAction PlentifulHarvest { get; } = new BaseAction(ActionID.PlentifulHarvest)
{
- BuffsNeed = new[] { StatusID.ImmortalSacrifice },
+ StatusNeed = new[] { StatusID.ImmortalSacrifice },
ActionCheck = b => !Player.HasStatus(true, StatusID.BloodsownCircle)
};
#endregion
@@ -199,68 +199,68 @@ internal PRPAction(ActionID actionID, bool isFriendly = false, bool shouldEndSpe
///
/// 夜游魂衣
///
- public static BaseAction Enshroud { get; } = new(ActionID.Enshroud)
+ public static IBaseAction Enshroud { get; } = new BaseAction(ActionID.Enshroud)
{
- BuffsProvide = new[] { StatusID.Enshrouded },
+ StatusProvide = new[] { StatusID.Enshrouded },
ActionCheck = b => Shroud >= 50 && !SoulReaver && !Enshrouded
};
///
/// 团契
///
- public static BaseAction Communio { get; } = new(ActionID.Communio)
+ public static IBaseAction Communio { get; } = new BaseAction(ActionID.Communio)
{
- BuffsNeed = new[] { StatusID.Enshrouded },
+ StatusNeed = new[] { StatusID.Enshrouded },
ActionCheck = b => LemureShroud == 1
};
///
/// 夜游魂切割
///
- public static BaseAction LemuresSlice { get; } = new(ActionID.LemuresSlice)
+ public static IBaseAction LemuresSlice { get; } = new BaseAction(ActionID.LemuresSlice)
{
- BuffsNeed = new[] { StatusID.Enshrouded },
+ StatusNeed = new[] { StatusID.Enshrouded },
ActionCheck = b => VoidShroud >= 2,
};
///
/// 夜游魂钐割
///
- public static BaseAction LemuresScythe { get; } = new(ActionID.LemuresScythe)
+ public static IBaseAction LemuresScythe { get; } = new BaseAction(ActionID.LemuresScythe)
{
- BuffsNeed = new[] { StatusID.Enshrouded },
+ StatusNeed = new[] { StatusID.Enshrouded },
ActionCheck = b => VoidShroud >= 2,
};
///
/// 虚无收割
///
- public static BaseAction VoidReaping { get; } = new(ActionID.VoidReaping)
+ public static IBaseAction VoidReaping { get; } = new BaseAction(ActionID.VoidReaping)
{
- BuffsNeed = new[] { StatusID.Enshrouded },
+ StatusNeed = new[] { StatusID.Enshrouded },
};
///
/// 交错收割
///
- public static BaseAction CrossReaping { get; } = new(ActionID.CrossReaping)
+ public static IBaseAction CrossReaping { get; } = new BaseAction(ActionID.CrossReaping)
{
- BuffsNeed = new[] { StatusID.Enshrouded },
+ StatusNeed = new[] { StatusID.Enshrouded },
};
///
/// 阴冷收割
///
- public static BaseAction GrimReaping { get; } = new(ActionID.GrimReaping)
+ public static IBaseAction GrimReaping { get; } = new BaseAction(ActionID.GrimReaping)
{
- BuffsNeed = new[] { StatusID.Enshrouded },
+ StatusNeed = new[] { StatusID.Enshrouded },
};
#endregion
#region 杂项
///
/// 勾刃
///
- public static BaseAction Harpe { get; } = new(ActionID.Harpe)
+ public static IBaseAction Harpe { get; } = new BaseAction(ActionID.Harpe)
{
ActionCheck = b => !SoulReaver
};
@@ -268,42 +268,42 @@ internal PRPAction(ActionID actionID, bool isFriendly = false, bool shouldEndSpe
///
/// 地狱入境
///
- public static BaseAction HellsIngress { get; } = new(ActionID.HellsIngress)
+ public static IBaseAction HellsIngress { get; } = new BaseAction(ActionID.HellsIngress)
{
- BuffsProvide = new[] { StatusID.EnhancedHarpe },
+ StatusProvide = new[] { StatusID.EnhancedHarpe },
ActionCheck = b => !Player.HasStatus(true, StatusID.Bind1, StatusID.Bind2)
};
///
/// 地狱出境
///
- public static BaseAction HellsEgress { get; } = new(ActionID.HellsEgress)
+ public static IBaseAction HellsEgress { get; } = new BaseAction(ActionID.HellsEgress)
{
- BuffsProvide = HellsIngress.BuffsProvide,
+ StatusProvide = HellsIngress.StatusProvide,
ActionCheck = HellsIngress.ActionCheck
};
///
/// 播魂种
///
- public static BaseAction Soulsow { get; } = new(ActionID.Soulsow)
+ public static IBaseAction Soulsow { get; } = new BaseAction(ActionID.Soulsow)
{
- BuffsProvide = new[] { StatusID.Soulsow },
+ StatusProvide = new[] { StatusID.Soulsow },
ActionCheck = b => !InCombat,
};
///
/// 收获月
///
- public static BaseAction HarvestMoon { get; } = new(ActionID.HarvestMoon)
+ public static IBaseAction HarvestMoon { get; } = new BaseAction(ActionID.HarvestMoon)
{
- BuffsNeed = new[] { StatusID.Soulsow },
+ StatusNeed = new[] { StatusID.Soulsow },
};
///
/// 神秘纹 加盾
///
- public static BaseAction ArcaneCrest { get; } = new(ActionID.ArcaneCrest, true, isTimeline: true);
+ public static IBaseAction ArcaneCrest { get; } = new BaseAction(ActionID.ArcaneCrest, true, isTimeline: true);
#endregion
diff --git a/RotationSolver/Rotations/Basic/SAMRotation_Base.cs b/RotationSolver/Rotations/Basic/SAM_Base.cs
similarity index 63%
rename from RotationSolver/Rotations/Basic/SAMRotation_Base.cs
rename to RotationSolver/Rotations/Basic/SAM_Base.cs
index 89c3616b8..0087844ac 100644
--- a/RotationSolver/Rotations/Basic/SAMRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/SAM_Base.cs
@@ -52,37 +52,37 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// �з�
///
- public static BaseAction Hakaze { get; } = new(ActionID.Hakaze);
+ public static IBaseAction Hakaze { get; } = new BaseAction(ActionID.Hakaze);
///
/// ���
///
- public static BaseAction Jinpu { get; } = new(ActionID.Jinpu);
+ public static IBaseAction Jinpu { get; } = new BaseAction(ActionID.Jinpu);
///
/// �¹�
///
- public static BaseAction Gekko { get; } = new(ActionID.Gekko);
+ public static IBaseAction Gekko { get; } = new BaseAction(ActionID.Gekko);
///
/// ʿ��
///
- public static BaseAction Shifu { get; } = new(ActionID.Shifu);
+ public static IBaseAction Shifu { get; } = new BaseAction(ActionID.Shifu);
///
/// ����
///
- public static BaseAction Kasha { get; } = new(ActionID.Kasha);
+ public static IBaseAction Kasha { get; } = new BaseAction(ActionID.Kasha);
///
/// ѩ��
///
- public static BaseAction Yukikaze { get; } = new(ActionID.Yukikaze);
+ public static IBaseAction Yukikaze { get; } = new BaseAction(ActionID.Yukikaze);
///
/// ����
///
- public static BaseAction Shoha { get; } = new(ActionID.Shoha)
+ public static IBaseAction Shoha { get; } = new BaseAction(ActionID.Shoha)
{
ActionCheck = b => MeditationStacks == 3
};
@@ -93,17 +93,17 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// ����
///
- public static BaseAction Fuga { get; } = new(ActionID.Fuga);
+ public static IBaseAction Fuga { get; } = new BaseAction(ActionID.Fuga);
///
/// ���
///
- public static BaseAction Fuko { get; } = new(ActionID.Fuko);
+ public static IBaseAction Fuko { get; } = new BaseAction(ActionID.Fuko);
///
/// ����
///
- public static BaseAction Mangetsu { get; } = new(ActionID.Mangetsu)
+ public static IBaseAction Mangetsu { get; } = new BaseAction(ActionID.Mangetsu)
{
OtherIDsCombo = new[]
{
@@ -113,7 +113,7 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// ӣ��
///
- public static BaseAction Oka { get; } = new(ActionID.Oka)
+ public static IBaseAction Oka { get; } = new BaseAction(ActionID.Oka)
{
OtherIDsCombo = new[]
{
@@ -124,7 +124,7 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// ��������
///
- public static BaseAction Shoha2 { get; } = new(ActionID.Shoha2)
+ public static IBaseAction Shoha2 { get; } = new BaseAction(ActionID.Shoha2)
{
ActionCheck = b => MeditationStacks == 3
};
@@ -132,16 +132,16 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// ����ն��
///
- public static BaseAction OgiNamikiri { get; } = new(ActionID.OgiNamikiri)
+ public static IBaseAction OgiNamikiri { get; } = new BaseAction(ActionID.OgiNamikiri)
{
- BuffsNeed = new[] { StatusID.OgiNamikiriReady },
+ StatusNeed = new[] { StatusID.OgiNamikiriReady },
ActionCheck = b => !IsMoving
};
///
/// �ط�ն��
///
- public static BaseAction KaeshiNamikiri { get; } = new(ActionID.KaeshiNamikiri)
+ public static IBaseAction KaeshiNamikiri { get; } = new BaseAction(ActionID.KaeshiNamikiri)
{
ActionCheck = b => JobGauge.Kaeshi == Dalamud.Game.ClientState.JobGauge.Enums.Kaeshi.NAMIKIRI
};
@@ -151,7 +151,7 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// �˰���
///
- public static BaseAction Higanbana { get; } = new(ActionID.Higanbana, isEot: true)
+ public static IBaseAction Higanbana { get; } = new BaseAction(ActionID.Higanbana, isEot: true)
{
ActionCheck = b => !IsMoving && SenCount == 1,
TargetStatus = new[] { StatusID.Higanbana },
@@ -160,7 +160,7 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// �����彣
///
- public static BaseAction TenkaGoken { get; } = new(ActionID.TenkaGoken)
+ public static IBaseAction TenkaGoken { get; } = new BaseAction(ActionID.TenkaGoken)
{
ActionCheck = b => !IsMoving && SenCount == 2,
};
@@ -168,7 +168,7 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// ����ѩ�»�
///
- public static BaseAction MidareSetsugekka { get; } = new(ActionID.MidareSetsugekka)
+ public static IBaseAction MidareSetsugekka { get; } = new BaseAction(ActionID.MidareSetsugekka)
{
ActionCheck = b => !IsMoving && SenCount == 3,
};
@@ -176,12 +176,12 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// ��ط�
///
- public static BaseAction TsubameGaeshi { get; } = new(ActionID.TsubameGaeshi);
+ public static IBaseAction TsubameGaeshi { get; } = new BaseAction(ActionID.TsubameGaeshi);
///
/// �ط��彣
///
- public static BaseAction KaeshiGoken { get; } = new(ActionID.KaeshiGoken)
+ public static IBaseAction KaeshiGoken { get; } = new BaseAction(ActionID.KaeshiGoken)
{
ActionCheck = b => JobGauge.Kaeshi == Dalamud.Game.ClientState.JobGauge.Enums.Kaeshi.GOKEN
};
@@ -189,7 +189,7 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// �ط�ѩ�»�
///
- public static BaseAction KaeshiSetsugekka { get; } = new(ActionID.KaeshiSetsugekka)
+ public static IBaseAction KaeshiSetsugekka { get; } = new BaseAction(ActionID.KaeshiSetsugekka)
{
ActionCheck = b => JobGauge.Kaeshi == Dalamud.Game.ClientState.JobGauge.Enums.Kaeshi.SETSUGEKKA
};
@@ -199,25 +199,25 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// ����
///
- public static BaseAction ThirdEye { get; } = new(ActionID.ThirdEye, true, isTimeline: true);
+ public static IBaseAction ThirdEye { get; } = new BaseAction(ActionID.ThirdEye, true, isTimeline: true);
///
/// ���
///
- public static BaseAction Enpi { get; } = new(ActionID.Enpi);
+ public static IBaseAction Enpi { get; } = new BaseAction(ActionID.Enpi);
///
/// ����ֹˮ
///
- public static BaseAction MeikyoShisui { get; } = new(ActionID.MeikyoShisui)
+ public static IBaseAction MeikyoShisui { get; } = new BaseAction(ActionID.MeikyoShisui)
{
- BuffsProvide = new[] { StatusID.MeikyoShisui },
+ StatusProvide = new[] { StatusID.MeikyoShisui },
};
///
/// Ҷ��
///
- public static BaseAction Hagakure { get; } = new(ActionID.Hagakure)
+ public static IBaseAction Hagakure { get; } = new BaseAction(ActionID.Hagakure)
{
ActionCheck = b => SenCount > 0
};
@@ -225,9 +225,9 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// ��������
///
- public static BaseAction Ikishoten { get; } = new(ActionID.Ikishoten)
+ public static IBaseAction Ikishoten { get; } = new BaseAction(ActionID.Ikishoten)
{
- BuffsProvide = new[] { StatusID.OgiNamikiriReady },
+ StatusProvide = new[] { StatusID.OgiNamikiriReady },
ActionCheck = b => InCombat
};
#endregion
@@ -236,7 +236,7 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// ��ɱ��������
///
- public static BaseAction HissatsuShinten { get; } = new(ActionID.HissatsuShinten)
+ public static IBaseAction HissatsuShinten { get; } = new BaseAction(ActionID.HissatsuShinten)
{
ActionCheck = b => Kenki >= 25
};
@@ -244,7 +244,7 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// ��ɱ��������
///
- public static BaseAction HissatsuGyoten { get; } = new(ActionID.HissatsuGyoten)
+ public static IBaseAction HissatsuGyoten { get; } = new BaseAction(ActionID.HissatsuGyoten)
{
ActionCheck = b => Kenki >= 10 && !Player.HasStatus(true, StatusID.Bind1, StatusID.Bind2)
};
@@ -252,7 +252,7 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// ��ɱ����ҹ��
///
- public static BaseAction HissatsuYaten { get; } = new(ActionID.HissatsuYaten)
+ public static IBaseAction HissatsuYaten { get; } = new BaseAction(ActionID.HissatsuYaten)
{
ActionCheck = HissatsuGyoten.ActionCheck
};
@@ -260,7 +260,7 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// ��ɱ��������
///
- public static BaseAction HissatsuKyuten { get; } = new(ActionID.HissatsuKyuten)
+ public static IBaseAction HissatsuKyuten { get; } = new BaseAction(ActionID.HissatsuKyuten)
{
ActionCheck = b => Kenki >= 25
};
@@ -268,7 +268,7 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// ��ɱ��������
///
- public static BaseAction HissatsuGuren { get; } = new(ActionID.HissatsuGuren)
+ public static IBaseAction HissatsuGuren { get; } = new BaseAction(ActionID.HissatsuGuren)
{
ActionCheck = b => Kenki >= 25
};
@@ -276,7 +276,7 @@ internal abstract class SAMRotation_Base : CustomRotation.CustomRotation
///
/// ��ɱ������Ӱ
///
- public static BaseAction HissatsuSenei { get; } = new(ActionID.HissatsuSenei)
+ public static IBaseAction HissatsuSenei { get; } = new BaseAction(ActionID.HissatsuSenei)
{
ActionCheck = b => Kenki >= 25
};
diff --git a/RotationSolver/Rotations/Basic/SCHRotation_Base.cs b/RotationSolver/Rotations/Basic/SCH_Base.cs
similarity index 58%
rename from RotationSolver/Rotations/Basic/SCHRotation_Base.cs
rename to RotationSolver/Rotations/Basic/SCH_Base.cs
index 62f23432d..80da82da9 100644
--- a/RotationSolver/Rotations/Basic/SCHRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/SCH_Base.cs
@@ -4,6 +4,7 @@
using RotationSolver.Updaters;
using RotationSolver.Data;
using RotationSolver.Helpers;
+using RotationSolver.Actions;
namespace RotationSolver.Rotations.Basic;
@@ -18,7 +19,7 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Scholar };
- private sealed protected override BaseAction Raise => Resurrection;
+ private sealed protected override IBaseAction Raise => Resurrection;
///
/// 有豆子
///
@@ -32,12 +33,12 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 医术
///
- public static BaseAction Physick { get; } = new(ActionID.Physick, true, isTimeline: true);
+ public static IBaseAction Physick { get; } = new BaseAction(ActionID.Physick, true, isTimeline: true);
///
/// 鼓舞激励之策
///
- public static BaseAction Adloquium { get; } = new(ActionID.Adloquium, true, isTimeline: true)
+ public static IBaseAction Adloquium { get; } = new BaseAction(ActionID.Adloquium, true, isTimeline: true)
{
ActionCheck = b => !b.HasStatus(false, StatusID.EukrasianDiagnosis,
StatusID.EukrasianPrognosis,
@@ -48,20 +49,20 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 复生
///
- public static BaseAction Resurrection { get; } = new(ActionID.Resurrection, true);
+ public static IBaseAction Resurrection { get; } = new BaseAction(ActionID.Resurrection, true);
///
/// 士气高扬之策
///
- public static BaseAction Succor { get; } = new(ActionID.Succor, true, isTimeline: true)
+ public static IBaseAction Succor { get; } = new BaseAction(ActionID.Succor, true, isTimeline: true)
{
- BuffsProvide = new[] { StatusID.Galvanize },
+ StatusProvide = new[] { StatusID.Galvanize },
};
///
/// 生命活性法
///
- public static BaseAction Lustrate { get; } = new(ActionID.Lustrate, true, isTimeline: true)
+ public static IBaseAction Lustrate { get; } = new BaseAction(ActionID.Lustrate, true, isTimeline: true)
{
ActionCheck = b => HasAetherflow
};
@@ -69,7 +70,7 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 野战治疗阵
///
- public static BaseAction SacredSoil { get; } = new(ActionID.SacredSoil, true, isTimeline: true)
+ public static IBaseAction SacredSoil { get; } = new BaseAction(ActionID.SacredSoil, true, isTimeline: true)
{
ActionCheck = b => HasAetherflow && !IsMoving,
};
@@ -77,7 +78,7 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 不屈不挠之策
///
- public static BaseAction Indomitability { get; } = new(ActionID.Indomitability, true, isTimeline: true)
+ public static IBaseAction Indomitability { get; } = new BaseAction(ActionID.Indomitability, true, isTimeline: true)
{
ActionCheck = b => HasAetherflow
};
@@ -85,7 +86,7 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 深谋远虑之策
///
- public static BaseAction Excogitation { get; } = new(ActionID.Excogitation, true, isTimeline: true)
+ public static IBaseAction Excogitation { get; } = new BaseAction(ActionID.Excogitation, true, isTimeline: true)
{
ActionCheck = b => HasAetherflow
};
@@ -93,7 +94,7 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 慰藉
///
- public static BaseAction Consolation { get; } = new(ActionID.Consolation, true, isTimeline: true)
+ public static IBaseAction Consolation { get; } = new BaseAction(ActionID.Consolation, true, isTimeline: true)
{
ActionCheck = b => HasSeraph,
};
@@ -101,13 +102,13 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 生命回生法
///
- public static BaseAction Protraction { get; } = new(ActionID.Protraction, true, isTimeline: true);
+ public static IBaseAction Protraction { get; } = new BaseAction(ActionID.Protraction, true, isTimeline: true);
#endregion
#region 进攻
///
/// 毒菌 猛毒菌 蛊毒法
///
- public static BaseAction Bio { get; } = new(ActionID.Bio, isEot: true)
+ public static IBaseAction Bio { get; } = new BaseAction(ActionID.Bio, isEot: true)
{
TargetStatus = new StatusID[] { StatusID.Bio, StatusID.Bio2, StatusID.Biolysis },
};
@@ -115,17 +116,17 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 毁灭 气炎法 魔炎法 死炎法 极炎法
///
- public static BaseAction Ruin { get; } = new(ActionID.Ruin);
+ public static IBaseAction Ruin { get; } = new BaseAction(ActionID.Ruin);
///
/// 毁坏
///
- public static BaseAction Ruin2 { get; } = new(ActionID.Ruin2);
+ public static IBaseAction Ruin2 { get; } = new BaseAction(ActionID.Ruin2);
///
/// 能量吸收
///
- public static BaseAction EnergyDrain { get; } = new(ActionID.EnergyDrain)
+ public static IBaseAction EnergyDrain { get; } = new BaseAction(ActionID.EnergyDrain)
{
ActionCheck = b => HasAetherflow
};
@@ -133,13 +134,13 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 破阵法
///
- public static BaseAction ArtofWar { get; } = new(ActionID.ArtofWar);//裂阵法 25866
+ public static IBaseAction ArtofWar { get; } = new BaseAction(ActionID.ArtofWar);//裂阵法 25866
#endregion
#region 仙女
///
/// 炽天召唤
///
- public static BaseAction SummonSeraph { get; } = new(ActionID.SummonSeraph, true, isTimeline: true)
+ public static IBaseAction SummonSeraph { get; } = new BaseAction(ActionID.SummonSeraph, true, isTimeline: true)
{
ActionCheck = b => TargetUpdater.HavePet,
};
@@ -147,7 +148,7 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 朝日召唤
///
- public static BaseAction SummonEos { get; } = new(ActionID.SummonEos)//夕月召唤 17216
+ public static IBaseAction SummonEos { get; } = new BaseAction(ActionID.SummonEos)//夕月召唤 17216
{
ActionCheck = b => !TargetUpdater.HavePet && (!Player.HasStatus(true, StatusID.Dissipation) || Dissipation.WillHaveOneCharge(30) && Dissipation.EnoughLevel),
};
@@ -155,7 +156,7 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 仙光的低语/天使的低语
///
- public static BaseAction WhisperingDawn { get; } = new(ActionID.WhisperingDawn, isTimeline: true)
+ public static IBaseAction WhisperingDawn { get; } = new BaseAction(ActionID.WhisperingDawn, isTimeline: true)
{
ActionCheck = b => TargetUpdater.HavePet,
};
@@ -163,7 +164,7 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 异想的幻光/炽天的幻光
///
- public static BaseAction FeyIllumination { get; } = new(ActionID.FeyIllumination, isTimeline: true)
+ public static IBaseAction FeyIllumination { get; } = new BaseAction(ActionID.FeyIllumination, isTimeline: true)
{
ActionCheck = b => TargetUpdater.HavePet,
};
@@ -171,16 +172,16 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 转化
///
- public static BaseAction Dissipation { get; } = new(ActionID.Dissipation)
+ public static IBaseAction Dissipation { get; } = new BaseAction(ActionID.Dissipation)
{
- BuffsProvide = new[] { StatusID.Dissipation },
+ StatusProvide = new[] { StatusID.Dissipation },
ActionCheck = b => !HasAetherflow && !HasSeraph && InCombat && TargetUpdater.HavePet,
};
///
/// 以太契约-异想的融光
///
- public static BaseAction Aetherpact { get; } = new(ActionID.Aetherpact, true, isTimeline: true)
+ public static IBaseAction Aetherpact { get; } = new BaseAction(ActionID.Aetherpact, true, isTimeline: true)
{
ActionCheck = b => JobGauge.FairyGauge >= 10 && TargetUpdater.HavePet && !HasSeraph
};
@@ -188,7 +189,7 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 异想的祥光
///
- public static BaseAction FeyBlessing { get; } = new(ActionID.FeyBlessing, isTimeline: true)
+ public static IBaseAction FeyBlessing { get; } = new BaseAction(ActionID.FeyBlessing, isTimeline: true)
{
ActionCheck = b => !HasSeraph && TargetUpdater.HavePet,
};
@@ -197,7 +198,7 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 以太超流
///
- public static BaseAction Aetherflow { get; } = new(ActionID.Aetherflow)
+ public static IBaseAction Aetherflow { get; } = new BaseAction(ActionID.Aetherflow)
{
ActionCheck = b => InCombat && !HasAetherflow
};
@@ -205,12 +206,12 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 秘策
///
- public static BaseAction Recitation { get; } = new(ActionID.Recitation, isTimeline: true);
+ public static IBaseAction Recitation { get; } = new BaseAction(ActionID.Recitation, isTimeline: true);
///
/// 连环计
///
- public static BaseAction ChainStratagem { get; } = new(ActionID.ChainStratagem)
+ public static IBaseAction ChainStratagem { get; } = new BaseAction(ActionID.ChainStratagem)
{
ActionCheck = b => InCombat && IsTargetBoss
};
@@ -218,7 +219,7 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 展开战术
///
- public static BaseAction DeploymentTactics { get; } = new(ActionID.DeploymentTactics, true, isTimeline: true)
+ public static IBaseAction DeploymentTactics { get; } = new BaseAction(ActionID.DeploymentTactics, true, isTimeline: true)
{
ChoiceTarget = (friends, mustUse) =>
{
@@ -233,11 +234,11 @@ internal abstract class SCHRotation_Base : CustomRotation.CustomRotation
///
/// 应急战术
///
- public static BaseAction EmergencyTactics { get; } = new(ActionID.EmergencyTactics, isTimeline: true);
+ public static IBaseAction EmergencyTactics { get; } = new BaseAction(ActionID.EmergencyTactics, isTimeline: true);
///
/// 疾风怒涛之计
///
- public static BaseAction Expedient { get; } = new(ActionID.Expedient, isTimeline: true);
+ public static IBaseAction Expedient { get; } = new BaseAction(ActionID.Expedient, isTimeline: true);
#endregion
}
\ No newline at end of file
diff --git a/RotationSolver/Rotations/Basic/SGERotation_Base.cs b/RotationSolver/Rotations/Basic/SGE_Base.cs
similarity index 59%
rename from RotationSolver/Rotations/Basic/SGERotation_Base.cs
rename to RotationSolver/Rotations/Basic/SGE_Base.cs
index 50f031720..bbf79c681 100644
--- a/RotationSolver/Rotations/Basic/SGERotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/SGE_Base.cs
@@ -5,6 +5,7 @@
using RotationSolver.Updaters;
using RotationSolver.Helpers;
using RotationSolver.Data;
+using RotationSolver.Actions;
namespace RotationSolver.Rotations.Basic;
@@ -12,19 +13,9 @@ internal abstract class SGERotation_Base : CustomRotation.CustomRotation
{
private static SGEGauge JobGauge => Service.JobGauges.Get();
- ///
- /// �Ƿ��о��⣿
- ///
protected static bool HasEukrasia => JobGauge.Eukrasia;
-
- ///
- /// ��������������ɶ�����ˡ�
- ///
protected static byte Addersgall => JobGauge.Addersgall;
- ///
- /// �����ö�������������ɶ�����ˡ�
- ///
protected static byte Addersting => JobGauge.Addersting;
///
@@ -49,22 +40,22 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, uint abilityCount
}
public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Sage };
- private sealed protected override BaseAction Raise => Egeiro;
+ private sealed protected override IBaseAction Raise => Egeiro;
///
/// ����
///
- public static BaseAction Egeiro { get; } = new(ActionID.Egeiro, true);
+ public static IBaseAction Egeiro { get; } = new BaseAction(ActionID.Egeiro, true);
///
/// עҩ
///
- public static BaseAction Dosis { get; } = new(ActionID.Dosis);
+ public static IBaseAction Dosis { get; } = new BaseAction(ActionID.Dosis);
///
/// ����עҩ
///
- public static BaseAction EukrasianDosis { get; } = new(ActionID.EukrasianDosis, isEot: true)
+ public static IBaseAction EukrasianDosis { get; } = new BaseAction(ActionID.EukrasianDosis, isEot: true)
{
TargetStatus = new StatusID[]
{
@@ -77,29 +68,29 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// ����
///
- public static BaseAction Phlegma { get; } = new(ActionID.Phlegma);
+ public static IBaseAction Phlegma { get; } = new BaseAction(ActionID.Phlegma);
///
/// ����2
///
- public static BaseAction Phlegma2 { get; } = new(ActionID.Phlegma2);
+ public static IBaseAction Phlegma2 { get; } = new BaseAction(ActionID.Phlegma2);
///
/// ����3
///
- public static BaseAction Phlegma3 { get; } = new(ActionID.Phlegma3);
+ public static IBaseAction Phlegma3 { get; } = new BaseAction(ActionID.Phlegma3);
///
/// ���
///
- public static BaseAction Diagnosis { get; } = new(ActionID.Diagnosis, true);
+ public static IBaseAction Diagnosis { get; } = new BaseAction(ActionID.Diagnosis, true);
///
/// ��
///
- public static BaseAction Kardia { get; } = new(ActionID.Kardia, true)
+ public static IBaseAction Kardia { get; } = new BaseAction(ActionID.Kardia, true)
{
- BuffsProvide = new StatusID[] { StatusID.Kardia },
+ StatusProvide = new StatusID[] { StatusID.Kardia },
ChoiceTarget = (Targets, mustUse) =>
{
var targets = Targets.GetJobCategory(JobRole.Tank);
@@ -115,22 +106,17 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// Ԥ��
///
- public static BaseAction Prognosis { get; } = new(ActionID.Prognosis, true, shouldEndSpecial: true, isTimeline: true);
+ public static IBaseAction Prognosis { get; } = new BaseAction(ActionID.Prognosis, true, shouldEndSpecial: true, isTimeline: true);
///
/// ����
///
- public static BaseAction Physis { get; } = new(ActionID.Physis, true, isTimeline: true);
-
- /////
- ///// ����2
- /////
- //public static BaseAction Physis2 { get; } = new(ActionID.Physis2, true, isTimeline: true);
+ public static IBaseAction Physis { get; } = new BaseAction(ActionID.Physis, true, isTimeline: true);
///
/// ����
///
- public static BaseAction Eukrasia { get; } = new(ActionID.Eukrasia, true, isTimeline: true)
+ public static IBaseAction Eukrasia { get; } = new BaseAction(ActionID.Eukrasia, true, isTimeline: true)
{
ActionCheck = b => !JobGauge.Eukrasia,
};
@@ -138,12 +124,12 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// ����
///
- public static BaseAction Soteria { get; } = new(ActionID.Soteria, true, isTimeline: true);
+ public static IBaseAction Soteria { get; } = new BaseAction(ActionID.Soteria, true, isTimeline: true);
///
/// ����
///
- public static BaseAction Icarus { get; } = new(ActionID.Icarus, shouldEndSpecial: true)
+ public static IBaseAction Icarus { get; } = new BaseAction(ActionID.Icarus, shouldEndSpecial: true)
{
ChoiceTarget = TargetFilter.FindTargetForMoving,
};
@@ -151,7 +137,7 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// ������֭
///
- public static BaseAction Druochole { get; } = new(ActionID.Druochole, true, isTimeline: true)
+ public static IBaseAction Druochole { get; } = new BaseAction(ActionID.Druochole, true, isTimeline: true)
{
ActionCheck = b => JobGauge.Addersgall > 0,
};
@@ -159,12 +145,12 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// ʧ��
///
- public static BaseAction Dyskrasia { get; } = new(ActionID.Dyskrasia);
+ public static IBaseAction Dyskrasia { get; } = new BaseAction(ActionID.Dyskrasia);
///
/// �����֭
///
- public static BaseAction Kerachole { get; } = new(ActionID.Kerachole, true, isTimeline: true)
+ public static IBaseAction Kerachole { get; } = new BaseAction(ActionID.Kerachole, true, isTimeline: true)
{
ActionCheck = b => JobGauge.Addersgall > 0,
};
@@ -172,7 +158,7 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// ������֭
///
- public static BaseAction Ixochole { get; } = new(ActionID.Ixochole, true, isTimeline: true)
+ public static IBaseAction Ixochole { get; } = new BaseAction(ActionID.Ixochole, true, isTimeline: true)
{
ActionCheck = b => JobGauge.Addersgall > 0,
};
@@ -180,12 +166,12 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// �
///
- public static BaseAction Zoe { get; } = new(ActionID.Zoe, isTimeline: true);
+ public static IBaseAction Zoe { get; } = new BaseAction(ActionID.Zoe, isTimeline: true);
///
/// ��ţ��֭
///
- public static BaseAction Taurochole { get; } = new(ActionID.Taurochole, true, isTimeline: true)
+ public static IBaseAction Taurochole { get; } = new BaseAction(ActionID.Taurochole, true, isTimeline: true)
{
ChoiceTarget = TargetFilter.FindAttackedTarget,
ActionCheck = b => JobGauge.Addersgall > 0,
@@ -194,7 +180,7 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// ����
///
- public static BaseAction Toxikon { get; } = new(ActionID.Toxikon)
+ public static IBaseAction Toxikon { get; } = new BaseAction(ActionID.Toxikon)
{
ActionCheck = b => JobGauge.Addersting > 0,
};
@@ -202,7 +188,7 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// ��Ѫ
///
- public static BaseAction Haima { get; } = new(ActionID.Haima, true, isTimeline: true)
+ public static IBaseAction Haima { get; } = new BaseAction(ActionID.Haima, true, isTimeline: true)
{
ChoiceTarget = TargetFilter.FindAttackedTarget,
};
@@ -210,7 +196,7 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// �������
///
- public static BaseAction EukrasianDiagnosis { get; } = new(ActionID.EukrasianDiagnosis, true, isTimeline: true)
+ public static IBaseAction EukrasianDiagnosis { get; } = new BaseAction(ActionID.EukrasianDiagnosis, true, isTimeline: true)
{
ChoiceTarget = TargetFilter.FindAttackedTarget,
};
@@ -218,12 +204,12 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// ����Ԥ��
///
- public static BaseAction EukrasianPrognosis { get; } = new(ActionID.EukrasianPrognosis, true, isTimeline: true);
+ public static IBaseAction EukrasianPrognosis { get; } = new BaseAction(ActionID.EukrasianPrognosis, true, isTimeline: true);
///
/// ����
///
- public static BaseAction Rhizomata { get; } = new(ActionID.Rhizomata, isTimeline: true)
+ public static IBaseAction Rhizomata { get; } = new BaseAction(ActionID.Rhizomata, isTimeline: true)
{
ActionCheck = b => JobGauge.Addersgall < 3,
};
@@ -231,27 +217,27 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, uint abilityCount
///
/// ������
///
- public static BaseAction Holos { get; } = new(ActionID.Holos, true, isTimeline: true);
+ public static IBaseAction Holos { get; } = new BaseAction(ActionID.Holos, true, isTimeline: true);
///
/// ����Ѫ
///
- public static BaseAction Panhaima { get; } = new(ActionID.Panhaima, true, isTimeline: true);
+ public static IBaseAction Panhaima { get; } = new BaseAction(ActionID.Panhaima, true, isTimeline: true);
///
/// ���
///
- public static BaseAction Krasis { get; } = new(ActionID.Krasis, true, isTimeline: true);
+ public static IBaseAction Krasis { get; } = new BaseAction(ActionID.Krasis, true, isTimeline: true);
///
/// �����Ϣ
///
- public static BaseAction Pneuma { get; } = new(ActionID.Pneuma, isTimeline: true);
+ public static IBaseAction Pneuma { get; } = new BaseAction(ActionID.Pneuma, isTimeline: true);
///
/// ����
///
- public static BaseAction Pepsis { get; } = new(ActionID.Pepsis, true, isTimeline: true)
+ public static IBaseAction Pepsis { get; } = new BaseAction(ActionID.Pepsis, true, isTimeline: true)
{
ActionCheck = b =>
{
diff --git a/RotationSolver/Rotations/Basic/SMNRotation_Base.cs b/RotationSolver/Rotations/Basic/SMN_Base.cs
similarity index 64%
rename from RotationSolver/Rotations/Basic/SMNRotation_Base.cs
rename to RotationSolver/Rotations/Basic/SMN_Base.cs
index 72528233f..3ac9c9a33 100644
--- a/RotationSolver/Rotations/Basic/SMNRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/SMN_Base.cs
@@ -3,6 +3,7 @@
using RotationSolver.Actions.BaseAction;
using RotationSolver.Updaters;
using RotationSolver.Data;
+using RotationSolver.Actions;
namespace RotationSolver.Rotations.Basic;
@@ -42,7 +43,7 @@ protected static bool SummonTimeEndAfter(float time)
public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Summoner, ClassJobID.Arcanist };
protected override bool CanHealSingleSpell => false;
- private sealed protected override BaseAction Raise => Resurrection;
+ private sealed protected override IBaseAction Raise => Resurrection;
///
/// 宝石兽处于同行状态
@@ -93,16 +94,16 @@ protected static bool SummonTimeEndAfter(float time)
///
/// 红宝石召唤 火神召唤
///
- public static BaseAction SummonRuby { get; } = new(ActionID.SummonRuby)
+ public static IBaseAction SummonRuby { get; } = new BaseAction(ActionID.SummonRuby)
{
- BuffsProvide = new[] { StatusID.IfritsFavor },
+ StatusProvide = new[] { StatusID.IfritsFavor },
ActionCheck = b => HaveSummon && IsIfritReady
};
///
/// 黄宝石召唤 土神召唤
///
- public static BaseAction SummonTopaz { get; } = new(ActionID.SummonTopaz)
+ public static IBaseAction SummonTopaz { get; } = new BaseAction(ActionID.SummonTopaz)
{
ActionCheck = b => HaveSummon && IsTitanReady,
};
@@ -110,16 +111,16 @@ protected static bool SummonTimeEndAfter(float time)
///
/// 绿宝石召唤 风神召唤
///
- public static BaseAction SummonEmerald { get; } = new(ActionID.SummonEmerald)
+ public static IBaseAction SummonEmerald { get; } = new BaseAction(ActionID.SummonEmerald)
{
- BuffsProvide = new[] { StatusID.GarudasFavor },
+ StatusProvide = new[] { StatusID.GarudasFavor },
ActionCheck = b => HaveSummon && IsGarudaReady,
};
///
/// 宝石兽召唤
///
- public static BaseAction SummonCarbuncle { get; } = new(ActionID.SummonCarbuncle)
+ public static IBaseAction SummonCarbuncle { get; } = new BaseAction(ActionID.SummonCarbuncle)
{
ActionCheck = b => !TargetUpdater.HavePet,
};
@@ -128,7 +129,7 @@ protected static bool SummonTimeEndAfter(float time)
///
/// 宝石耀 单体
///
- public static BaseAction Gemshine { get; } = new(ActionID.Gemshine)
+ public static IBaseAction Gemshine { get; } = new BaseAction(ActionID.Gemshine)
{
ActionCheck = b => Attunement > 0,
};
@@ -136,7 +137,7 @@ protected static bool SummonTimeEndAfter(float time)
///
/// 宝石辉 AoE
///
- public static BaseAction PreciousBrilliance { get; } = new(ActionID.PreciousBrilliance)
+ public static IBaseAction PreciousBrilliance { get; } = new BaseAction(ActionID.PreciousBrilliance)
{
ActionCheck = b => Attunement > 0,
};
@@ -144,7 +145,7 @@ protected static bool SummonTimeEndAfter(float time)
///
/// 以太蓄能 龙神附体
///
- public static BaseAction Aethercharge { get; } = new(ActionID.Aethercharge)
+ public static IBaseAction Aethercharge { get; } = new BaseAction(ActionID.Aethercharge)
{
ActionCheck = b => InCombat && HaveSummon
};
@@ -152,14 +153,14 @@ protected static bool SummonTimeEndAfter(float time)
///
/// 龙神召唤 不死鸟召唤
///
- public static BaseAction SummonBahamut { get; } = new(ActionID.SummonBahamut)
+ public static IBaseAction SummonBahamut { get; } = new BaseAction(ActionID.SummonBahamut)
{
ActionCheck = b => InCombat && HaveSummon
};
///
/// 龙神迸发 不死鸟迸发
///
- public static BaseAction EnkindleBahamut { get; } = new(ActionID.EnkindleBahamut)
+ public static IBaseAction EnkindleBahamut { get; } = new BaseAction(ActionID.EnkindleBahamut)
{
ActionCheck = b => InBahamut || InPhoenix,
};
@@ -169,7 +170,7 @@ protected static bool SummonTimeEndAfter(float time)
///
/// 死星核爆
///
- public static BaseAction Deathflare { get; } = new(ActionID.Deathflare)
+ public static IBaseAction Deathflare { get; } = new BaseAction(ActionID.Deathflare)
{
ActionCheck = b => InBahamut,
};
@@ -177,7 +178,7 @@ protected static bool SummonTimeEndAfter(float time)
///
/// 苏生之炎
///
- public static BaseAction Rekindle { get; } = new(ActionID.Rekindle, true)
+ public static IBaseAction Rekindle { get; } = new BaseAction(ActionID.Rekindle, true)
{
ActionCheck = b => InPhoenix,
};
@@ -185,30 +186,30 @@ protected static bool SummonTimeEndAfter(float time)
///
/// 深红旋风
///
- public static BaseAction CrimsonCyclone { get; } = new(ActionID.CrimsonCyclone)
+ public static IBaseAction CrimsonCyclone { get; } = new BaseAction(ActionID.CrimsonCyclone)
{
- BuffsNeed = new[] { StatusID.IfritsFavor },
+ StatusNeed = new[] { StatusID.IfritsFavor },
};
///
/// 深红强袭
///
- public static BaseAction CrimsonStrike { get; } = new(ActionID.CrimsonStrike);
+ public static IBaseAction CrimsonStrike { get; } = new BaseAction(ActionID.CrimsonStrike);
///
/// 山崩
///
- public static BaseAction MountainBuster { get; } = new(ActionID.MountainBuster)
+ public static IBaseAction MountainBuster { get; } = new BaseAction(ActionID.MountainBuster)
{
- BuffsNeed = new[] { StatusID.TitansFavor },
+ StatusNeed = new[] { StatusID.TitansFavor },
};
///
/// 螺旋气流
///
- public static BaseAction Slipstream { get; } = new(ActionID.Slipstream)
+ public static IBaseAction Slipstream { get; } = new BaseAction(ActionID.Slipstream)
{
- BuffsNeed = new[] { StatusID.GarudasFavor },
+ StatusNeed = new[] { StatusID.GarudasFavor },
};
#endregion
@@ -216,36 +217,36 @@ protected static bool SummonTimeEndAfter(float time)
///
/// 毁灭 毁坏 毁荡
///
- public static BaseAction Ruin { get; } = new(ActionID.RuinSMN);
+ public static IBaseAction Ruin { get; } = new BaseAction(ActionID.RuinSMN);
///
/// 毁绝
///
- public static BaseAction RuinIV { get; } = new(ActionID.RuinIV)
+ public static IBaseAction RuinIV { get; } = new BaseAction(ActionID.RuinIV)
{
- BuffsNeed = new[] { StatusID.FurtherRuin },
+ StatusNeed = new[] { StatusID.FurtherRuin },
};
///
/// 迸裂 三重灾祸
///
- public static BaseAction Outburst { get; } = new(ActionID.Outburst);
+ public static IBaseAction Outburst { get; } = new BaseAction(ActionID.Outburst);
#endregion
#region 能力技
///
/// 灼热之光 团辅
///
- public static BaseAction SearingLight { get; } = new(ActionID.SearingLight, true)
+ public static IBaseAction SearingLight { get; } = new BaseAction(ActionID.SearingLight, true)
{
- BuffsProvide = new[] { StatusID.SearingLight },
+ StatusProvide = new[] { StatusID.SearingLight },
ActionCheck = b => InCombat,
};
///
/// 守护之光
///
- public static BaseAction RadiantAegis { get; } = new(ActionID.RadiantAegis, true, isTimeline: true)
+ public static IBaseAction RadiantAegis { get; } = new BaseAction(ActionID.RadiantAegis, true, isTimeline: true)
{
ActionCheck = b => HaveSummon
};
@@ -253,16 +254,16 @@ protected static bool SummonTimeEndAfter(float time)
///
/// 能量吸收
///
- public static BaseAction EnergyDrain { get; } = new(ActionID.EnergyDrainSMN)
+ public static IBaseAction EnergyDrain { get; } = new BaseAction(ActionID.EnergyDrainSMN)
{
- BuffsProvide = new[] { StatusID.FurtherRuin },
+ StatusProvide = new[] { StatusID.FurtherRuin },
ActionCheck = b => !HasAetherflowStacks
};
///
/// 溃烂爆发
///
- public static BaseAction Fester { get; } = new(ActionID.Fester)
+ public static IBaseAction Fester { get; } = new BaseAction(ActionID.Fester)
{
ActionCheck = b => HasAetherflowStacks
};
@@ -270,16 +271,16 @@ protected static bool SummonTimeEndAfter(float time)
///
/// 能量抽取
///
- public static BaseAction EnergySiphon { get; } = new(ActionID.EnergySiphon)
+ public static IBaseAction EnergySiphon { get; } = new BaseAction(ActionID.EnergySiphon)
{
- BuffsProvide = new[] { StatusID.FurtherRuin },
+ StatusProvide = new[] { StatusID.FurtherRuin },
ActionCheck = b => !HasAetherflowStacks
};
///
/// 痛苦核爆
///
- public static BaseAction Painflare { get; } = new(ActionID.Painflare)
+ public static IBaseAction Painflare { get; } = new BaseAction(ActionID.Painflare)
{
ActionCheck = b => HasAetherflowStacks
};
@@ -288,10 +289,10 @@ protected static bool SummonTimeEndAfter(float time)
///
/// 复生
///
- public static BaseAction Resurrection { get; } = new(ActionID.ResurrectionSMN, true);
+ public static IBaseAction Resurrection { get; } = new BaseAction(ActionID.ResurrectionSMN, true);
///
/// 医术
///
- public static BaseAction Physick { get; } = new(ActionID.Physick, true);
+ public static IBaseAction Physick { get; } = new BaseAction(ActionID.Physick, true);
}
\ No newline at end of file
diff --git a/RotationSolver/Rotations/Basic/WARRotation_Base.cs b/RotationSolver/Rotations/Basic/WAR_Base.cs
similarity index 55%
rename from RotationSolver/Rotations/Basic/WARRotation_Base.cs
rename to RotationSolver/Rotations/Basic/WAR_Base.cs
index 609b0d44c..789405428 100644
--- a/RotationSolver/Rotations/Basic/WARRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/WAR_Base.cs
@@ -11,32 +11,32 @@ internal abstract class WARRotation_Base : CustomRotation.CustomRotation
private static WARGauge JobGauge => Service.JobGauges.Get();
public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Warrior, ClassJobID.Marauder };
- private sealed protected override BaseAction Shield => Defiance;
+ private sealed protected override IBaseAction Shield => Defiance;
///
/// �ػ�
///
- public static BaseAction Defiance { get; } = new(ActionID.Defiance, shouldEndSpecial: true);
+ public static IBaseAction Defiance { get; } = new BaseAction(ActionID.Defiance, shouldEndSpecial: true);
///
/// ����
///
- public static BaseAction HeavySwing { get; } = new(ActionID.HeavySwing);
+ public static IBaseAction HeavySwing { get; } = new BaseAction(ActionID.HeavySwing);
///
/// �ײ���
///
- public static BaseAction Maim { get; } = new(ActionID.Maim);
+ public static IBaseAction Maim { get; } = new BaseAction(ActionID.Maim);
///
/// ����ն �̸�
///
- public static BaseAction StormsPath { get; } = new(ActionID.StormsPath);
+ public static IBaseAction StormsPath { get; } = new BaseAction(ActionID.StormsPath);
///
/// ������ �츫
///
- public static BaseAction StormsEye { get; } = new(ActionID.StormsEye)
+ public static IBaseAction StormsEye { get; } = new BaseAction(ActionID.StormsEye)
{
ActionCheck = b => Player.WillStatusEndGCD(3, 0, true, StatusID.SurgingTempest),
};
@@ -44,7 +44,7 @@ internal abstract class WARRotation_Base : CustomRotation.CustomRotation
///
/// �ɸ�
///
- public static BaseAction Tomahawk { get; } = new(ActionID.Tomahawk)
+ public static IBaseAction Tomahawk { get; } = new BaseAction(ActionID.Tomahawk)
{
FilterForTarget = b => TargetFilter.ProvokeTarget(b),
};
@@ -52,7 +52,7 @@ internal abstract class WARRotation_Base : CustomRotation.CustomRotation
///
/// ��
///
- public static BaseAction Onslaught { get; } = new(ActionID.Onslaught, shouldEndSpecial: true)
+ public static IBaseAction Onslaught { get; } = new BaseAction(ActionID.Onslaught, shouldEndSpecial: true)
{
ChoiceTarget = TargetFilter.FindTargetForMoving,
};
@@ -60,30 +60,30 @@ internal abstract class WARRotation_Base : CustomRotation.CustomRotation
///
/// ����
///
- public static BaseAction Upheaval { get; } = new(ActionID.Upheaval)
+ public static IBaseAction Upheaval { get; } = new BaseAction(ActionID.Upheaval)
{
- BuffsNeed = new StatusID[] { StatusID.SurgingTempest },
+ StatusNeed = new StatusID[] { StatusID.SurgingTempest },
};
///
/// ��ѹ��
///
- public static BaseAction Overpower { get; } = new(ActionID.Overpower);
+ public static IBaseAction Overpower { get; } = new BaseAction(ActionID.Overpower);
///
/// ��������
///
- public static BaseAction MythrilTempest { get; } = new(ActionID.MythrilTempest);
+ public static IBaseAction MythrilTempest { get; } = new BaseAction(ActionID.MythrilTempest);
///
/// Ⱥɽ¡��
///
- public static BaseAction Orogeny { get; } = new(ActionID.Orogeny);
+ public static IBaseAction Orogeny { get; } = new BaseAction(ActionID.Orogeny);
///
/// ԭ��֮��
///
- public static BaseAction InnerBeast { get; } = new(ActionID.InnerBeast)
+ public static IBaseAction InnerBeast { get; } = new BaseAction(ActionID.InnerBeast)
{
ActionCheck = b => JobGauge.BeastGauge >= 50 || Player.HasStatus(true, StatusID.InnerRelease),
};
@@ -91,7 +91,7 @@ internal abstract class WARRotation_Base : CustomRotation.CustomRotation
///
/// ԭ���Ľ��
///
- public static BaseAction InnerRelease { get; } = new(ActionID.InnerRelease)
+ public static IBaseAction InnerRelease { get; } = new BaseAction(ActionID.InnerRelease)
{
ActionCheck = InnerBeast.ActionCheck,
};
@@ -99,7 +99,7 @@ internal abstract class WARRotation_Base : CustomRotation.CustomRotation
///
/// ��������
///
- public static BaseAction SteelCyclone { get; } = new(ActionID.SteelCyclone)
+ public static IBaseAction SteelCyclone { get; } = new BaseAction(ActionID.SteelCyclone)
{
ActionCheck = InnerBeast.ActionCheck,
};
@@ -107,16 +107,16 @@ internal abstract class WARRotation_Base : CustomRotation.CustomRotation
///
/// ս��
///
- public static BaseAction Infuriate { get; } = new(ActionID.Infuriate)
+ public static IBaseAction Infuriate { get; } = new BaseAction(ActionID.Infuriate)
{
- BuffsProvide = new[] { StatusID.InnerRelease },
+ StatusProvide = new[] { StatusID.InnerRelease },
ActionCheck = b => HaveHostilesInRange && JobGauge.BeastGauge < 50 && InCombat,
};
///
/// ��
///
- public static BaseAction Berserk { get; } = new(ActionID.Berserk)
+ public static IBaseAction Berserk { get; } = new BaseAction(ActionID.Berserk)
{
ActionCheck = b => HaveHostilesInRange && !InnerRelease.IsCoolDown,
};
@@ -124,17 +124,17 @@ internal abstract class WARRotation_Base : CustomRotation.CustomRotation
///
/// ս��
///
- public static BaseAction ThrillofBattle { get; } = new(ActionID.ThrillofBattle, true, isTimeline: true);
+ public static IBaseAction ThrillofBattle { get; } = new BaseAction(ActionID.ThrillofBattle, true, isTimeline: true);
///
/// ̩Ȼ����
///
- public static BaseAction Equilibrium { get; } = new(ActionID.Equilibrium, true, isTimeline: true);
+ public static IBaseAction Equilibrium { get; } = new BaseAction(ActionID.Equilibrium, true, isTimeline: true);
///
/// ԭ��������
///
- public static BaseAction NascentFlash { get; } = new(ActionID.NascentFlash, isTimeline: true)
+ public static IBaseAction NascentFlash { get; } = new BaseAction(ActionID.NascentFlash, isTimeline: true)
{
ChoiceTarget = TargetFilter.FindAttackedTarget,
};
@@ -142,16 +142,16 @@ internal abstract class WARRotation_Base : CustomRotation.CustomRotation
///
/// ����
///
- public static BaseAction Vengeance { get; } = new(ActionID.Vengeance, isTimeline: true)
+ public static IBaseAction Vengeance { get; } = new BaseAction(ActionID.Vengeance, isTimeline: true)
{
- BuffsProvide = Rampart.BuffsProvide,
+ StatusProvide = Rampart.StatusProvide,
ActionCheck = BaseAction.TankDefenseSelf,
};
///
/// ԭ����ֱ��
///
- public static BaseAction RawIntuition { get; } = new(ActionID.RawIntuition, isTimeline: true)
+ public static IBaseAction RawIntuition { get; } = new BaseAction(ActionID.RawIntuition, isTimeline: true)
{
ActionCheck = BaseAction.TankDefenseSelf,
};
@@ -159,12 +159,12 @@ internal abstract class WARRotation_Base : CustomRotation.CustomRotation
///
/// ����
///
- public static BaseAction ShakeItOff { get; } = new(ActionID.ShakeItOff, true, isTimeline: true);
+ public static IBaseAction ShakeItOff { get; } = new BaseAction(ActionID.ShakeItOff, true, isTimeline: true);
///
/// ����
///
- public static BaseAction Holmgang { get; } = new(ActionID.Holmgang, isTimeline: true)
+ public static IBaseAction Holmgang { get; } = new BaseAction(ActionID.Holmgang, isTimeline: true)
{
ChoiceTarget = (tars, mustUse) => Player,
};
@@ -172,9 +172,9 @@ internal abstract class WARRotation_Base : CustomRotation.CustomRotation
///
/// ���ı���
///
- public static BaseAction PrimalRend { get; } = new(ActionID.PrimalRend)
+ public static IBaseAction PrimalRend { get; } = new BaseAction(ActionID.PrimalRend)
{
- BuffsNeed = new[] { StatusID.PrimalRendReady }
+ StatusNeed = new[] { StatusID.PrimalRendReady }
};
private protected override bool EmergencyAbility(byte abilityRemain, IAction nextGCD, out IAction act)
diff --git a/RotationSolver/Rotations/Basic/WHMRotation_Base.cs b/RotationSolver/Rotations/Basic/WHM_Base.cs
similarity index 55%
rename from RotationSolver/Rotations/Basic/WHMRotation_Base.cs
rename to RotationSolver/Rotations/Basic/WHM_Base.cs
index bf4e36f9c..dac5146b9 100644
--- a/RotationSolver/Rotations/Basic/WHMRotation_Base.cs
+++ b/RotationSolver/Rotations/Basic/WHM_Base.cs
@@ -3,6 +3,7 @@
using RotationSolver.Actions.BaseAction;
using RotationSolver.Helpers;
using RotationSolver.Data;
+using RotationSolver.Actions;
namespace RotationSolver.Rotations.Basic;
@@ -42,41 +43,41 @@ protected static bool LilyAfterGCD(uint gctCount = 0, uint abilityCount = 0)
}
public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.WhiteMage, ClassJobID.Conjurer };
- private sealed protected override BaseAction Raise => Raise1;
+ private sealed protected override IBaseAction Raise => Raise1;
#region 治疗
///
/// 治疗
///
- public static BaseAction Cure { get; } = new(ActionID.Cure, true, isTimeline: true);
+ public static IBaseAction Cure { get; } = new BaseAction(ActionID.Cure, true, isTimeline: true);
///
/// 医治
///
- public static BaseAction Medica { get; } = new(ActionID.Medica, true, isTimeline: true);
+ public static IBaseAction Medica { get; } = new BaseAction(ActionID.Medica, true, isTimeline: true);
///
/// 复活
///
- public static BaseAction Raise1 { get; } = new(ActionID.Raise1, true);
+ public static IBaseAction Raise1 { get; } = new BaseAction(ActionID.Raise1, true);
///
/// 救疗
///
- public static BaseAction Cure2 { get; } = new(ActionID.Cure2, true, isTimeline: true);
+ public static IBaseAction Cure2 { get; } = new BaseAction(ActionID.Cure2, true, isTimeline: true);
///
/// 医济
///
- public static BaseAction Medica2 { get; } = new(ActionID.Medica2, true, isEot: true, isTimeline: true)
+ public static IBaseAction Medica2 { get; } = new BaseAction(ActionID.Medica2, true, isEot: true, isTimeline: true)
{
- BuffsProvide = new[] { StatusID.Medica2, StatusID.TrueMedica2 },
+ StatusProvide = new[] { StatusID.Medica2, StatusID.TrueMedica2 },
};
///
/// 再生
///
- public static BaseAction Regen { get; } = new(ActionID.Regen, true, isEot: true, isTimeline: true)
+ public static IBaseAction Regen { get; } = new BaseAction(ActionID.Regen, true, isEot: true, isTimeline: true)
{
TargetStatus = new[]
{
@@ -89,22 +90,22 @@ protected static bool LilyAfterGCD(uint gctCount = 0, uint abilityCount = 0)
///
/// 愈疗
///
- public static BaseAction Cure3 { get; } = new(ActionID.Cure3, true, shouldEndSpecial: true, isTimeline: true);
+ public static IBaseAction Cure3 { get; } = new BaseAction(ActionID.Cure3, true, shouldEndSpecial: true, isTimeline: true);
///
/// 天赐祝福
///
- public static BaseAction Benediction { get; } = new(ActionID.Benediction, true, isTimeline: true);
+ public static IBaseAction Benediction { get; } = new BaseAction(ActionID.Benediction, true, isTimeline: true);
///
/// 庇护所
///
- public static BaseAction Asylum { get; } = new(ActionID.Asylum, true, isTimeline: true);
+ public static IBaseAction Asylum { get; } = new BaseAction(ActionID.Asylum, true, isTimeline: true);
///
/// 安慰之心
///
- public static BaseAction AfflatusSolace { get; } = new(ActionID.AfflatusSolace, true, isTimeline: true)
+ public static IBaseAction AfflatusSolace { get; } = new BaseAction(ActionID.AfflatusSolace, true, isTimeline: true)
{
ActionCheck = b => JobGauge.Lily > 0,
};
@@ -112,21 +113,21 @@ protected static bool LilyAfterGCD(uint gctCount = 0, uint abilityCount = 0)
///
/// 神名
///
- public static BaseAction Tetragrammaton { get; } = new(ActionID.Tetragrammaton, true, isTimeline: true);
+ public static IBaseAction Tetragrammaton { get; } = new BaseAction(ActionID.Tetragrammaton, true, isTimeline: true);
///
/// 神祝祷
///
- public static BaseAction DivineBenison { get; } = new(ActionID.DivineBenison, true, isTimeline: true)
+ public static IBaseAction DivineBenison { get; } = new BaseAction(ActionID.DivineBenison, true, isTimeline: true)
{
- BuffsProvide = new StatusID[] { StatusID.DivineBenison },
+ StatusProvide = new StatusID[] { StatusID.DivineBenison },
ChoiceTarget = TargetFilter.FindAttackedTarget,
};
///
/// 狂喜之心
///
- public static BaseAction AfflatusRapture { get; } = new(ActionID.AfflatusRapture, true, isTimeline: true)
+ public static IBaseAction AfflatusRapture { get; } = new BaseAction(ActionID.AfflatusRapture, true, isTimeline: true)
{
ActionCheck = b => JobGauge.Lily > 0,
};
@@ -134,23 +135,23 @@ protected static bool LilyAfterGCD(uint gctCount = 0, uint abilityCount = 0)
///
/// 水流幕
///
- public static BaseAction Aquaveil { get; } = new(ActionID.Aquaveil, true, isTimeline: true);
+ public static IBaseAction Aquaveil { get; } = new BaseAction(ActionID.Aquaveil, true, isTimeline: true);
///
/// 礼仪之铃
///
- public static BaseAction LiturgyoftheBell { get; } = new(ActionID.LiturgyoftheBell, true, isTimeline: true);
+ public static IBaseAction LiturgyoftheBell { get; } = new BaseAction(ActionID.LiturgyoftheBell, true, isTimeline: true);
#endregion
#region 输出
///
/// 飞石 坚石 垒石 崩石 闪耀 闪灼
///
- public static BaseAction Stone { get; } = new(ActionID.Stone);
+ public static IBaseAction Stone { get; } = new BaseAction(ActionID.Stone);
///
/// 疾风 烈风 天辉
///
- public static BaseAction Aero { get; } = new(ActionID.Aero, isEot: true)
+ public static IBaseAction Aero { get; } = new BaseAction(ActionID.Aero, isEot: true)
{
TargetStatus = new StatusID[]
{
@@ -163,17 +164,17 @@ protected static bool LilyAfterGCD(uint gctCount = 0, uint abilityCount = 0)
///
/// 神圣 豪圣
///
- public static BaseAction Holy { get; } = new(ActionID.Holy);
+ public static IBaseAction Holy { get; } = new BaseAction(ActionID.Holy);
///
/// 法令
///
- public static BaseAction Assize { get; } = new(ActionID.Assize);
+ public static IBaseAction Assize { get; } = new BaseAction(ActionID.Assize);
///
/// 苦难之心
///
- public static BaseAction AfflatusMisery { get; } = new(ActionID.AfflatusMisery)
+ public static IBaseAction AfflatusMisery { get; } = new BaseAction(ActionID.AfflatusMisery)
{
ActionCheck = b => JobGauge.BloodLily == 3,
};
@@ -182,7 +183,7 @@ protected static bool LilyAfterGCD(uint gctCount = 0, uint abilityCount = 0)
///
/// 神速咏唱
///
- public static BaseAction PresenseOfMind { get; } = new(ActionID.PresenseOfMind, true)
+ public static IBaseAction PresenseOfMind { get; } = new BaseAction(ActionID.PresenseOfMind, true)
{
ActionCheck = b => !IsMoving
};
@@ -190,17 +191,17 @@ protected static bool LilyAfterGCD(uint gctCount = 0, uint abilityCount = 0)
///
/// 无中生有
///
- public static BaseAction ThinAir { get; } = new(ActionID.ThinAir, true);
+ public static IBaseAction ThinAir { get; } = new BaseAction(ActionID.ThinAir, true);
///
/// 全大赦
///
- public static BaseAction PlenaryIndulgence { get; } = new(ActionID.PlenaryIndulgence, true, isTimeline: true);
+ public static IBaseAction PlenaryIndulgence { get; } = new BaseAction(ActionID.PlenaryIndulgence, true, isTimeline: true);
///
/// 节制
///
- public static BaseAction Temperance { get; } = new(ActionID.Temperance, true, isTimeline: true);
+ public static IBaseAction Temperance { get; } = new BaseAction(ActionID.Temperance, true, isTimeline: true);
#endregion
}
\ No newline at end of file
diff --git a/RotationSolver/Rotations/CustomRotation/CustomRotation_Actions.cs b/RotationSolver/Rotations/CustomRotation/CustomRotation_Actions.cs
index b415318a2..8129744e8 100644
--- a/RotationSolver/Rotations/CustomRotation/CustomRotation_Actions.cs
+++ b/RotationSolver/Rotations/CustomRotation/CustomRotation_Actions.cs
@@ -26,7 +26,7 @@ internal RoleAction(ActionID actionID, JobRole[] roles, bool isFriendly = false,
///
/// 昏乱
///
- public static RoleAction Addle { get; } = new(ActionID.Addle, new JobRole[] { JobRole.RangedMagicial }, isFriendly: true, isTimeline: true)
+ public static IBaseAction Addle { get; } = new RoleAction(ActionID.Addle, new JobRole[] { JobRole.RangedMagicial }, isFriendly: true, isTimeline: true)
{
ActionCheck = b => !b.HasStatus(false, StatusID.Addle),
};
@@ -34,9 +34,9 @@ internal RoleAction(ActionID actionID, JobRole[] roles, bool isFriendly = false,
///
/// 即刻咏唱
///
- public static RoleAction Swiftcast { get; } = new(ActionID.Swiftcast, new JobRole[] { JobRole.RangedMagicial, JobRole.Healer }, true)
+ public static IBaseAction Swiftcast { get; } = new RoleAction(ActionID.Swiftcast, new JobRole[] { JobRole.RangedMagicial, JobRole.Healer }, true)
{
- BuffsProvide = new StatusID[]
+ StatusProvide = new StatusID[]
{
StatusID.Swiftcast,
StatusID.Triplecast,
@@ -47,7 +47,7 @@ internal RoleAction(ActionID actionID, JobRole[] roles, bool isFriendly = false,
///
/// 康复
///
- public static RoleAction Esuna { get; } = new(ActionID.Esuna, new JobRole[] { JobRole.Healer }, true)
+ public static IBaseAction Esuna { get; } = new RoleAction(ActionID.Esuna, new JobRole[] { JobRole.Healer }, true)
{
ChoiceTarget = (tars, mustUse) =>
{
@@ -66,17 +66,17 @@ internal RoleAction(ActionID actionID, JobRole[] roles, bool isFriendly = false,
///
/// 营救
///
- public static RoleAction Rescue { get; } = new(ActionID.Rescue, new JobRole[] { JobRole.Healer }, true, isTimeline: true);
+ public static IBaseAction Rescue { get; } = new RoleAction(ActionID.Rescue, new JobRole[] { JobRole.Healer }, true, isTimeline: true);
///
/// 沉静
///
- public static RoleAction Repose { get; } = new(ActionID.Repose, new JobRole[] { JobRole.Healer });
+ public static IBaseAction Repose { get; } = new RoleAction(ActionID.Repose, new JobRole[] { JobRole.Healer });
///
/// 醒梦(如果MP低于6000那么使用)
///
- public static RoleAction LucidDreaming { get; } = new(ActionID.LucidDreaming,
+ public static IBaseAction LucidDreaming { get; } = new RoleAction(ActionID.LucidDreaming,
new JobRole[] { JobRole.Healer, JobRole.RangedMagicial }, true)
{
ActionCheck = b => Service.ClientState.LocalPlayer.CurrentMp < 6000 && InCombat,
@@ -85,7 +85,7 @@ internal RoleAction(ActionID actionID, JobRole[] roles, bool isFriendly = false,
///
/// 内丹
///
- public static RoleAction SecondWind { get; } = new(ActionID.SecondWind,
+ public static IBaseAction SecondWind { get; } = new RoleAction(ActionID.SecondWind,
new JobRole[] { JobRole.RangedPhysical, JobRole.Melee }, true, isTimeline: true)
{
ActionCheck = b => Service.ClientState.LocalPlayer?.GetHealthRatio() < Service.Configuration.HealthSingleAbility && InCombat,
@@ -94,14 +94,14 @@ internal RoleAction(ActionID actionID, JobRole[] roles, bool isFriendly = false,
///
/// 亲疏自行
///
- public static RoleAction ArmsLength { get; } = new(ActionID.ArmsLength, new JobRole[] { JobRole.Tank, JobRole.Melee, JobRole.RangedPhysical }, true, shouldEndSpecial: true);
+ public static IBaseAction ArmsLength { get; } = new RoleAction(ActionID.ArmsLength, new JobRole[] { JobRole.Tank, JobRole.Melee, JobRole.RangedPhysical }, true, shouldEndSpecial: true);
///
/// 铁壁
///
- public static RoleAction Rampart { get; } = new(ActionID.Rampart, new JobRole[] { JobRole.Tank }, true, isTimeline: true)
+ public static IBaseAction Rampart { get; } = new RoleAction(ActionID.Rampart, new JobRole[] { JobRole.Tank }, true, isTimeline: true)
{
- BuffsProvide = new StatusID[]
+ StatusProvide = new StatusID[]
{
StatusID.Superbolide, StatusID.HallowedGround,
StatusID.Rampart1, StatusID.Rampart2, StatusID.Rampart3,
@@ -124,7 +124,7 @@ internal RoleAction(ActionID actionID, JobRole[] roles, bool isFriendly = false,
///
/// 挑衅
///
- public static RoleAction Provoke { get; } = new(ActionID.Provoke, new JobRole[] { JobRole.Tank }, isTimeline: true)
+ public static IBaseAction Provoke { get; } = new RoleAction(ActionID.Provoke, new JobRole[] { JobRole.Tank }, isTimeline: true)
{
FilterForTarget = b => TargetFilter.ProvokeTarget(b),
};
@@ -132,12 +132,12 @@ internal RoleAction(ActionID actionID, JobRole[] roles, bool isFriendly = false,
///
/// 雪仇
///
- public static RoleAction Reprisal { get; } = new(ActionID.Reprisal, new JobRole[] { JobRole.Tank }, isTimeline: true);
+ public static IBaseAction Reprisal { get; } = new RoleAction(ActionID.Reprisal, new JobRole[] { JobRole.Tank }, isTimeline: true);
///
/// 退避
///
- public static RoleAction Shirk { get; } = new(ActionID.Shirk, new JobRole[] { JobRole.Tank }, true)
+ public static IBaseAction Shirk { get; } = new RoleAction(ActionID.Shirk, new JobRole[] { JobRole.Tank }, true)
{
ChoiceTarget = (friends, mustUse) => TargetFilter.GetJobCategory(friends, JobRole.Tank)?.FirstOrDefault(),
};
@@ -145,7 +145,7 @@ internal RoleAction(ActionID actionID, JobRole[] roles, bool isFriendly = false,
///
/// 浴血
///
- public static RoleAction Bloodbath { get; } = new(ActionID.Bloodbath, new JobRole[] { JobRole.Melee }, true, isTimeline: true)
+ public static IBaseAction Bloodbath { get; } = new RoleAction(ActionID.Bloodbath, new JobRole[] { JobRole.Melee }, true, isTimeline: true)
{
ActionCheck = SecondWind.ActionCheck,
};
@@ -153,7 +153,7 @@ internal RoleAction(ActionID actionID, JobRole[] roles, bool isFriendly = false,
///
/// 牵制
///
- public static RoleAction Feint { get; } = new(ActionID.Feint, new JobRole[] { JobRole.Melee }, isTimeline: true)
+ public static IBaseAction Feint { get; } = new RoleAction(ActionID.Feint, new JobRole[] { JobRole.Melee }, isTimeline: true)
{
ActionCheck = b => !b.HasStatus(false, StatusID.Feint),
};
@@ -161,12 +161,12 @@ internal RoleAction(ActionID actionID, JobRole[] roles, bool isFriendly = false,
///
/// 插言
///
- public static RoleAction Interject { get; } = new(ActionID.Interject, new JobRole[] { JobRole.Tank });
+ public static IBaseAction Interject { get; } = new RoleAction(ActionID.Interject, new JobRole[] { JobRole.Tank });
///
/// 下踢
///
- public static RoleAction LowBlow { get; } = new(ActionID.LowBlow, new JobRole[] { JobRole.Tank })
+ public static IBaseAction LowBlow { get; } = new RoleAction(ActionID.LowBlow, new JobRole[] { JobRole.Tank })
{
ActionCheck = b => !b.IsBoss() && !MovingUpdater.IsMoving,
};
@@ -174,39 +174,39 @@ internal RoleAction(ActionID actionID, JobRole[] roles, bool isFriendly = false,
///
/// 扫腿
///
- public static RoleAction LegSweep { get; } = new(ActionID.LegSweep, new JobRole[] { JobRole.Melee });
+ public static IBaseAction LegSweep { get; } = new RoleAction(ActionID.LegSweep, new JobRole[] { JobRole.Melee });
///
/// 伤头
///
- public static RoleAction HeadGraze { get; } = new(ActionID.HeadGraze, new JobRole[] { JobRole.RangedPhysical });
+ public static IBaseAction HeadGraze { get; } = new RoleAction(ActionID.HeadGraze, new JobRole[] { JobRole.RangedPhysical });
///
/// 沉稳咏唱
///
- public static RoleAction Surecast { get; } = new(ActionID.Surecast,
+ public static IBaseAction Surecast { get; } = new RoleAction(ActionID.Surecast,
new JobRole[] { JobRole.RangedMagicial, JobRole.Healer }, true, shouldEndSpecial: true);
///
/// 真北
///
- public static RoleAction TrueNorth { get; } = new(ActionID.TrueNorth,
+ public static IBaseAction TrueNorth { get; } = new RoleAction(ActionID.TrueNorth,
new JobRole[] { JobRole.Melee }, true, shouldEndSpecial: true)
{
- BuffsProvide = new StatusID[] { StatusID.TrueNorth },
+ StatusProvide = new StatusID[] { StatusID.TrueNorth },
};
///
/// 速行
///
- public static RoleAction Peloton { get; } = new(ActionID.Peloton, new JobRole[] { JobRole.RangedPhysical }, true)
+ public static IBaseAction Peloton { get; } = new RoleAction(ActionID.Peloton, new JobRole[] { JobRole.RangedPhysical }, true)
{
- BuffsProvide = new StatusID[] { StatusID.Peloton },
+ StatusProvide = new StatusID[] { StatusID.Peloton },
ActionCheck = b => !InCombat && !TargetUpdater.HostileTargets.Any(),
};
- private protected virtual BaseAction Raise => null;
- private protected virtual BaseAction Shield => null;
+ private protected virtual IBaseAction Raise => null;
+ private protected virtual IBaseAction Shield => null;
///
/// 当前这个类所有的BaseAction
diff --git a/RotationSolver/Rotations/CustomRotation/CustomRotation_BasicInfo.cs b/RotationSolver/Rotations/CustomRotation/CustomRotation_BasicInfo.cs
index abc5ededf..7fa5864a8 100644
--- a/RotationSolver/Rotations/CustomRotation/CustomRotation_BasicInfo.cs
+++ b/RotationSolver/Rotations/CustomRotation/CustomRotation_BasicInfo.cs
@@ -69,7 +69,7 @@ public bool IsEnabled
///
/// 有即刻相关Buff
///
- internal static bool HaveSwift => Player.HasStatus(true, Swiftcast.BuffsProvide);
+ internal static bool HaveSwift => Player.HasStatus(true, Swiftcast.StatusProvide);
///
/// 有盾姿,如果为非T那么始终为true
diff --git a/RotationSolver/Rotations/CustomRotation/CustomRotation_BreakItems.cs b/RotationSolver/Rotations/CustomRotation/CustomRotation_BreakItems.cs
index bf3b4c6e8..f24deb4c6 100644
--- a/RotationSolver/Rotations/CustomRotation/CustomRotation_BreakItems.cs
+++ b/RotationSolver/Rotations/CustomRotation/CustomRotation_BreakItems.cs
@@ -7,7 +7,7 @@
namespace RotationSolver.Rotations.CustomRotation;
internal abstract partial class CustomRotation
{
- private static readonly BaseItem
+ private static readonly IBaseItem
//刚力
TinctureofStrength6 = new BaseItem(36109, 196625),
//巧力
diff --git a/RotationSolver/Rotations/CustomRotation/ICustomRotation.cs b/RotationSolver/Rotations/CustomRotation/ICustomRotation.cs
index 7944c5d7a..50aedec82 100644
--- a/RotationSolver/Rotations/CustomRotation/ICustomRotation.cs
+++ b/RotationSolver/Rotations/CustomRotation/ICustomRotation.cs
@@ -8,7 +8,7 @@
namespace RotationSolver.Rotations.CustomRotation;
-internal interface ICustomRotation : IEnableTexture
+internal interface ICustomRotation : ITexture, IEnable
{
ClassJob Job { get; }
ClassJobID[] JobIDs { get; }
diff --git a/RotationSolver/Rotations/Healer/AST/AST_Default.cs b/RotationSolver/Rotations/Healer/AST/AST_Default.cs
index 215e4550c..c48841513 100644
--- a/RotationSolver/Rotations/Healer/AST/AST_Default.cs
+++ b/RotationSolver/Rotations/Healer/AST/AST_Default.cs
@@ -10,7 +10,7 @@
namespace RotationSolver.Rotations.Healer.ASTCombos;
-internal sealed class AST_Default : ASTRotation_Base
+internal sealed class AST_Default : AST_Base
{
public override string GameVersion => "6.28";
diff --git a/RotationSolver/Rotations/Healer/SCH/SCH_Default.cs b/RotationSolver/Rotations/Healer/SCH/SCH_Default.cs
index 206d90025..d68ead0f2 100644
--- a/RotationSolver/Rotations/Healer/SCH/SCH_Default.cs
+++ b/RotationSolver/Rotations/Healer/SCH/SCH_Default.cs
@@ -10,7 +10,7 @@
namespace RotationSolver.Rotations.Healer.SCHCombos;
-internal sealed class SCH_Default : SCHRotation_Base
+internal sealed class SCH_Default : SCH_Base
{
public override string GameVersion => "6.28";
diff --git a/RotationSolver/Rotations/Healer/SGE/SGE_Default.cs b/RotationSolver/Rotations/Healer/SGE/SGE_Default.cs
index 047c0c8db..0d4baffdb 100644
--- a/RotationSolver/Rotations/Healer/SGE/SGE_Default.cs
+++ b/RotationSolver/Rotations/Healer/SGE/SGE_Default.cs
@@ -11,7 +11,7 @@
namespace RotationSolver.Rotations.Healer.SGECombos;
-internal sealed class SGE_Default : SGERotation_Base
+internal sealed class SGE_Default : SGE_Base
{
public override string GameVersion => "6.18";
diff --git a/RotationSolver/Rotations/Healer/WHM/WHM_Default.cs b/RotationSolver/Rotations/Healer/WHM/WHM_Default.cs
index 49b176128..cc4d2faa1 100644
--- a/RotationSolver/Rotations/Healer/WHM/WHM_Default.cs
+++ b/RotationSolver/Rotations/Healer/WHM/WHM_Default.cs
@@ -10,7 +10,7 @@
using RotationSolver.Rotations.CustomRotation;
namespace RotationSolver.Rotations.Healer.WHMCombos;
-internal sealed class WHM_Default : WHMRotation_Base
+internal sealed class WHM_Default : WHM_Base
{
public override string GameVersion => "6.28";
diff --git a/RotationSolver/Rotations/Melee/DRG/DRG_Default.cs b/RotationSolver/Rotations/Melee/DRG/DRG_Default.cs
index f50e1a13d..e2eb2c9cc 100644
--- a/RotationSolver/Rotations/Melee/DRG/DRG_Default.cs
+++ b/RotationSolver/Rotations/Melee/DRG/DRG_Default.cs
@@ -9,7 +9,7 @@
namespace RotationSolver.Rotations.Melee.DRGCombos;
-internal sealed class DRG_Default : DRGRotation_Base
+internal sealed class DRG_Default : DRG_Base
{
public override string GameVersion => "6.18";
diff --git a/RotationSolver/Rotations/Melee/MNK/MNK_Default.cs b/RotationSolver/Rotations/Melee/MNK/MNK_Default.cs
index a83a74024..31f4944d8 100644
--- a/RotationSolver/Rotations/Melee/MNK/MNK_Default.cs
+++ b/RotationSolver/Rotations/Melee/MNK/MNK_Default.cs
@@ -11,7 +11,7 @@
using System.Linq;
namespace RotationSolver.Rotations.Melee.MNKCombos;
-internal sealed class MNK_Default : MNKRotation_Base
+internal sealed class MNK_Default : MNK_Base
{
public override string GameVersion => "6.0";
diff --git a/RotationSolver/Rotations/Melee/NIN/NIN_Default.cs b/RotationSolver/Rotations/Melee/NIN/NIN_Default.cs
index 9cb9f8e6d..d63c28d3f 100644
--- a/RotationSolver/Rotations/Melee/NIN/NIN_Default.cs
+++ b/RotationSolver/Rotations/Melee/NIN/NIN_Default.cs
@@ -16,7 +16,7 @@ internal sealed class NIN_Default : NINRotation_Base
public override string RotationName => "Default";
- private static NinAction _ninactionAim = null;
+ private static INinAction _ninactionAim = null;
private protected override IRotationConfigSet CreateConfiguration()
{
@@ -29,7 +29,7 @@ private protected override IRotationConfigSet CreateConfiguration()
{DescType.MoveAction, $"{Shukuchi},目标为面向夹角小于30°内最远目标。"},
};
- private static void SetNinjustus(NinAction act)
+ private static void SetNinjustus(INinAction act)
{
if (_ninactionAim != null && IsLastAction(false, Ten, Jin, Chi, FumaShurikenTen, FumaShurikenJin)) return;
_ninactionAim = act;
diff --git a/RotationSolver/Rotations/Melee/RPR/RPR_Default.cs b/RotationSolver/Rotations/Melee/RPR/RPR_Default.cs
index 8d53022cf..768be224d 100644
--- a/RotationSolver/Rotations/Melee/RPR/RPR_Default.cs
+++ b/RotationSolver/Rotations/Melee/RPR/RPR_Default.cs
@@ -8,7 +8,7 @@
namespace RotationSolver.Rotations.Melee.RPRCombos;
-internal sealed class RPR_Default : RPRRotation_Base
+internal sealed class RPR_Default : RPR_Base
{
public override string GameVersion => "6.28";
diff --git a/RotationSolver/Rotations/Melee/SAM/SAM_Default.cs b/RotationSolver/Rotations/Melee/SAM/SAM_Default.cs
index 8e2ae8c3e..5d1cc847e 100644
--- a/RotationSolver/Rotations/Melee/SAM/SAM_Default.cs
+++ b/RotationSolver/Rotations/Melee/SAM/SAM_Default.cs
@@ -8,7 +8,7 @@
namespace RotationSolver.Rotations.Melee.SAMCombos;
-internal sealed class SAM_Default : SAMRotation_Base
+internal sealed class SAM_Default : SAM_Base
{
public override string GameVersion => "6.28";
diff --git a/RotationSolver/Rotations/RangedMagicial/BLM/BLM_Default.cs b/RotationSolver/Rotations/RangedMagicial/BLM/BLM_Default.cs
index 3924a80c3..c857f6f45 100644
--- a/RotationSolver/Rotations/RangedMagicial/BLM/BLM_Default.cs
+++ b/RotationSolver/Rotations/RangedMagicial/BLM/BLM_Default.cs
@@ -10,7 +10,7 @@
using static RotationSolver.SigReplacers.Watcher;
namespace RotationSolver.Rotations.RangedMagicial.BLMCombos;
-internal sealed partial class BLM_Default : BLMRotation_Base
+internal sealed partial class BLM_Default : BLM_Base
{
public override string GameVersion => "6.18";
diff --git a/RotationSolver/Rotations/RangedMagicial/BLU/BLU_Default.cs b/RotationSolver/Rotations/RangedMagicial/BLU/BLU_Default.cs
index 8173dbb6b..9271131ea 100644
--- a/RotationSolver/Rotations/RangedMagicial/BLU/BLU_Default.cs
+++ b/RotationSolver/Rotations/RangedMagicial/BLU/BLU_Default.cs
@@ -9,7 +9,7 @@
namespace RotationSolver.Rotations.RangedMagicial.BLUCombos
{
- internal sealed class BLU_Default : BLURotation_Base
+ internal sealed class BLU_Default : BLU_Base
{
public override string GameVersion => "6.18";
diff --git a/RotationSolver/Rotations/RangedMagicial/RDM/RDM_Default.cs b/RotationSolver/Rotations/RangedMagicial/RDM/RDM_Default.cs
index 1f5cab989..cc79ddfb2 100644
--- a/RotationSolver/Rotations/RangedMagicial/RDM/RDM_Default.cs
+++ b/RotationSolver/Rotations/RangedMagicial/RDM/RDM_Default.cs
@@ -194,7 +194,7 @@ private protected override bool EmergencyGCD(out IAction act)
}
//������û�м�����صļ��ܡ�
- if (Player.HasStatus(true, Vercure.BuffsProvide))
+ if (Player.HasStatus(true, Vercure.StatusProvide))
{
return false;
}
diff --git a/RotationSolver/Rotations/RangedMagicial/SMN/SMN_Default.cs b/RotationSolver/Rotations/RangedMagicial/SMN/SMN_Default.cs
index 7d5e68eac..3925e3a6e 100644
--- a/RotationSolver/Rotations/RangedMagicial/SMN/SMN_Default.cs
+++ b/RotationSolver/Rotations/RangedMagicial/SMN/SMN_Default.cs
@@ -8,7 +8,7 @@
namespace RotationSolver.Rotations.RangedMagicial.SMNCombos;
-internal sealed class SMN_Default : SMNRotation_Base
+internal sealed class SMN_Default : SMN_Base
{
public override string GameVersion => "6.28";
diff --git a/RotationSolver/Rotations/RangedPhysicial/BRD/BRD_Default.cs b/RotationSolver/Rotations/RangedPhysicial/BRD/BRD_Default.cs
index 77daa90dd..da2bd6585 100644
--- a/RotationSolver/Rotations/RangedPhysicial/BRD/BRD_Default.cs
+++ b/RotationSolver/Rotations/RangedPhysicial/BRD/BRD_Default.cs
@@ -10,7 +10,7 @@
namespace RotationSolver.Rotations.RangedPhysicial.BRDCombos;
-internal sealed class BRD_Default : BRDRotation_Base
+internal sealed class BRD_Default : BRD_Base
{
public override string GameVersion => "6.28";
diff --git a/RotationSolver/Rotations/RangedPhysicial/DNC/DNC_Default.cs b/RotationSolver/Rotations/RangedPhysicial/DNC/DNC_Default.cs
index 57e0a5d35..9237cf86f 100644
--- a/RotationSolver/Rotations/RangedPhysicial/DNC/DNC_Default.cs
+++ b/RotationSolver/Rotations/RangedPhysicial/DNC/DNC_Default.cs
@@ -9,7 +9,7 @@
namespace RotationSolver.Rotations.RangedPhysicial.DNCCombos;
-internal sealed class DNC_Default : DNCRotation_Base
+internal sealed class DNC_Default : DNC_Base
{
public override string GameVersion => "6.28";
diff --git a/RotationSolver/Rotations/RangedPhysicial/MCH/MCH_Default.cs b/RotationSolver/Rotations/RangedPhysicial/MCH/MCH_Default.cs
index f80523844..d55331167 100644
--- a/RotationSolver/Rotations/RangedPhysicial/MCH/MCH_Default.cs
+++ b/RotationSolver/Rotations/RangedPhysicial/MCH/MCH_Default.cs
@@ -10,7 +10,7 @@
namespace RotationSolver.Rotations.RangedPhysicial.MCHCombos;
-internal sealed class MCH_Default : MCHRotation_Base
+internal sealed class MCH_Default : MCH_Base
{
public override string GameVersion => "6.28";
diff --git a/RotationSolver/Rotations/Tank/DRK/DRK_Default.cs b/RotationSolver/Rotations/Tank/DRK/DRK_Default.cs
index 29bda7a66..c88487467 100644
--- a/RotationSolver/Rotations/Tank/DRK/DRK_Default.cs
+++ b/RotationSolver/Rotations/Tank/DRK/DRK_Default.cs
@@ -11,7 +11,7 @@
namespace RotationSolver.Rotations.Tank.DRKCombos;
-internal sealed class DRK_Default : DRKRotation_Base
+internal sealed class DRK_Default : DRK_Base
{
public override string GameVersion => "6.18";
public override string RotationName => "Default";
diff --git a/RotationSolver/Rotations/Tank/GNB/GNB_Default.cs b/RotationSolver/Rotations/Tank/GNB/GNB_Default.cs
index 0ed2084d5..bf4b9fd69 100644
--- a/RotationSolver/Rotations/Tank/GNB/GNB_Default.cs
+++ b/RotationSolver/Rotations/Tank/GNB/GNB_Default.cs
@@ -8,7 +8,7 @@
namespace RotationSolver.Rotations.Tank.GNBCombos;
-internal sealed class GNB_Default : GNBRotation_Base
+internal sealed class GNB_Default : GNB_Base
{
public override string GameVersion => "6.18";
diff --git a/RotationSolver/Rotations/Tank/PLD/PLD_Default.cs b/RotationSolver/Rotations/Tank/PLD/PLD_Default.cs
index 0e26e05a1..11e9c2e81 100644
--- a/RotationSolver/Rotations/Tank/PLD/PLD_Default.cs
+++ b/RotationSolver/Rotations/Tank/PLD/PLD_Default.cs
@@ -8,7 +8,7 @@
namespace RotationSolver.Rotations.Tank.PLDCombos;
-internal sealed class PLD_Default : PLDRotation_Base
+internal sealed class PLD_Default : PLD_Base
{
public override string GameVersion => "6.18";
public override string RotationName => "Default";
diff --git a/RotationSolver/Rotations/Tank/WAR/WAR_Default.cs b/RotationSolver/Rotations/Tank/WAR/WAR_Default.cs
index da36ba27e..2d27bf85c 100644
--- a/RotationSolver/Rotations/Tank/WAR/WAR_Default.cs
+++ b/RotationSolver/Rotations/Tank/WAR/WAR_Default.cs
@@ -10,7 +10,7 @@
namespace RotationSolver.Rotations.Tank.WARCombos;
-internal sealed class WAR_Default : WARRotation_Base
+internal sealed class WAR_Default : WAR_Base
{
public override string GameVersion => "6.0";