From 8139b49a5d8b75b3bfec8e752db2456cd9992d9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E6=B0=B4?= <1123993881@qq.com> Date: Wed, 5 Apr 2023 11:09:27 +0800 Subject: [PATCH] fix: add burst ratio for party check. --- .../Actions/BaseAction_BasicInfo.cs | 3 +- RotationSolver.Basic/Actions/BaseItem.cs | 2 ++ RotationSolver.Basic/Actions/IAction.cs | 2 ++ RotationSolver.Basic/DataCenter.cs | 33 +++++++++++++++++++ RotationSolver.Basic/Helpers/StatusHelper.cs | 31 +++++++++-------- .../Rotations/CustomRotation_OtherInfo.cs | 11 ++----- .../UI/RotationConfigWindow_Debug.cs | 3 +- 7 files changed, 58 insertions(+), 27 deletions(-) diff --git a/RotationSolver.Basic/Actions/BaseAction_BasicInfo.cs b/RotationSolver.Basic/Actions/BaseAction_BasicInfo.cs index 580e6f5b5..3d6f0ac7f 100644 --- a/RotationSolver.Basic/Actions/BaseAction_BasicInfo.cs +++ b/RotationSolver.Basic/Actions/BaseAction_BasicInfo.cs @@ -18,7 +18,8 @@ public partial class BaseAction : IBaseAction /// /// EnoughLevel for using. /// - public bool EnoughLevel => Service.Player.Level >= _action.ClassJobLevel; + public bool EnoughLevel => Service.Player.Level >= Level; + public byte Level => _action.ClassJobLevel; public string Name => _action.Name; public string Description => string.Empty; diff --git a/RotationSolver.Basic/Actions/BaseItem.cs b/RotationSolver.Basic/Actions/BaseItem.cs index 2df7f91f4..8687109d1 100644 --- a/RotationSolver.Basic/Actions/BaseItem.cs +++ b/RotationSolver.Basic/Actions/BaseItem.cs @@ -43,6 +43,8 @@ public bool IsEnabled public bool EnoughLevel => true; + public byte Level => 0; + public unsafe bool IsCoolingDown => ActionManager.Instance()->IsRecastTimerActive(ActionType.Item, ID); public BaseItem(uint row, uint a4 = 65535) diff --git a/RotationSolver.Basic/Actions/IAction.cs b/RotationSolver.Basic/Actions/IAction.cs index 34831f84b..df920452e 100644 --- a/RotationSolver.Basic/Actions/IAction.cs +++ b/RotationSolver.Basic/Actions/IAction.cs @@ -19,4 +19,6 @@ public interface IAction : ITexture /// Player's level is enough for this action's usage. /// bool EnoughLevel { get; } + + internal byte Level { get; } } diff --git a/RotationSolver.Basic/DataCenter.cs b/RotationSolver.Basic/DataCenter.cs index 27c181b5c..1e5c156f6 100644 --- a/RotationSolver.Basic/DataCenter.cs +++ b/RotationSolver.Basic/DataCenter.cs @@ -196,9 +196,42 @@ public static void SetSpecialType(SpecialCommandType specialType) public static bool HasPet { get; set; } + public static unsafe bool HasCompanion => (IntPtr)Service.RawPlayer == IntPtr.Zero ? false : (IntPtr)CharacterManager.Instance()->LookupBuddyByOwnerObject(Service.RawPlayer) != IntPtr.Zero; + public static float RatioOfMembersIn2minsBurst + { + get + { + byte burst = 0, count = 0; + + foreach (var member in PartyMembers) + { + foreach (var burstInfo in StatusHelper.Burst2Mins) + { + if (burstInfo.jobs.Contains((ClassJobID)member.ClassJob.Id)) + { + if (member.Level >= burstInfo.level) + { + var tar = burstInfo.isOnHostile + && Service.TargetManager.Target is BattleChara b ? b + : Service.Player; + if (tar.HasStatus(false, burstInfo.status) + && !tar.WillStatusEndGCD(0, 0, false, burstInfo.status)) + { + burst++; + } + count++; + } + break; + } + } + } + return (float)burst / count; + } + } + #region HP public static IEnumerable PartyMembersHP { get; set; } public static float PartyMembersMinHP { get; set; } diff --git a/RotationSolver.Basic/Helpers/StatusHelper.cs b/RotationSolver.Basic/Helpers/StatusHelper.cs index 4a0e8666e..e6b6481ec 100644 --- a/RotationSolver.Basic/Helpers/StatusHelper.cs +++ b/RotationSolver.Basic/Helpers/StatusHelper.cs @@ -15,32 +15,31 @@ public static class StatusHelper StatusID.AspectedBenefic, StatusID.Regen1, StatusID.Regen2, StatusID.Regen3 }; - public static StatusID[] TankStanceStatus { get; } = new StatusID[] + internal static StatusID[] TankStanceStatus { get; } = new StatusID[] { StatusID.Grit, StatusID.RoyalGuard, StatusID.IronWill, StatusID.Defiance }; - public static StatusID[] NoNeedHealingStatus { get; } = new StatusID[] + internal static StatusID[] NoNeedHealingStatus { get; } = new StatusID[] { StatusID.Holmgang, StatusID.WillDead, StatusID.WalkingDead, }; - public static StatusID[] Burst2minsBuff { get; } = new StatusID[] - { - //StatusID.Divination, - StatusID.Brotherhood, - StatusID.BattleLitany, - StatusID.ArcaneCircle, - StatusID.BattleVoice, - //StatusID.TechnicalStepFinished, - StatusID.SearingLight, - StatusID.Embolden, - }; - public static StatusID[] Burst2minsDeBuff { get; } = new StatusID[] + internal record Burst2MinsInfo( StatusID status, bool isOnHostile, byte level, params ClassJobID[] jobs); + + internal static Burst2MinsInfo[] Burst2Mins { get; } = new Burst2MinsInfo[] { - StatusID.ChainStratagem, - //StatusID.Mug, + //new Burst2MinsInfo(StatusID.Divination, false, AST_Base.Divination.Level, ClassJobID.Astrologian), + new Burst2MinsInfo(StatusID.ChainStratagem, true, SCH_Base.ChainStratagem.Level, ClassJobID.Scholar), + new Burst2MinsInfo(StatusID.Brotherhood, false, MNK_Base.Brotherhood.Level, ClassJobID.Monk), + new Burst2MinsInfo(StatusID.BattleLitany, false, DRG_Base.BattleLitany.Level, ClassJobID.Dragoon), + new Burst2MinsInfo(StatusID.ArcaneCircle, false, RPR_Base.ArcaneCircle.Level, ClassJobID.Reaper), + new Burst2MinsInfo(StatusID.BattleVoice, false, BRD_Base.BattleVoice.Level, ClassJobID.Bard), + //new Burst2MinsInfo(StatusID.TechnicalStepFinished, false, DNC_Base.TechnicalStep.Level, ClassJobID.Dancer), + new Burst2MinsInfo(StatusID.SearingLight, false, SMN_Base.SearingLight.Level, ClassJobID.Summoner), + new Burst2MinsInfo(StatusID.Embolden, false, RDM_Base.Embolden.Level, ClassJobID.RedMage), + //new Burst2MinsInfo(StatusID.Mug, true, NIN_Base.Mug.Level, ClassJobID.Ninja, ClassJobID.Rogue), }; public static bool NeedHealing(this BattleChara p) => p.WillStatusEndGCD(2, 0, false, NoNeedHealingStatus); diff --git a/RotationSolver.Basic/Rotations/CustomRotation_OtherInfo.cs b/RotationSolver.Basic/Rotations/CustomRotation_OtherInfo.cs index 41569b9b6..ac2ab7f69 100644 --- a/RotationSolver.Basic/Rotations/CustomRotation_OtherInfo.cs +++ b/RotationSolver.Basic/Rotations/CustomRotation_OtherInfo.cs @@ -53,15 +53,8 @@ public abstract partial class CustomRotation protected static IEnumerable WeakenPeople => DataCenter.WeakenPeople; protected static IEnumerable DyingPeople => DataCenter.DyingPeople; - protected static byte CountOfMembersIn2minsBurst => (byte)(StatusHelper.Burst2minsBuff.Count(s => - { - if (!Player.HasStatus(false, s)) return false; - return !Player.WillStatusEndGCD(0, 0, false, s); - }) + StatusHelper.Burst2minsDeBuff.Count(s => - { - if (!Target.HasStatus(false, s)) return false; - return !Target.WillStatusEndGCD(0, 0, false, s); - })); + protected static float RatioOfMembersIn2minsBurst => DataCenter.RatioOfMembersIn2minsBurst; + /// /// Whether the number of party members is 8. diff --git a/RotationSolver/UI/RotationConfigWindow_Debug.cs b/RotationSolver/UI/RotationConfigWindow_Debug.cs index 446b5c207..9e08cfe26 100644 --- a/RotationSolver/UI/RotationConfigWindow_Debug.cs +++ b/RotationSolver/UI/RotationConfigWindow_Debug.cs @@ -46,7 +46,6 @@ private unsafe void DrawStatus() ImGui.Text("Have Companion: " + DataCenter.HasCompanion.ToString()); ImGui.Text("Targetable: " + Service.Player.IsTargetable().ToString()); - foreach (var status in Service.Player.StatusList) { var source = status.SourceId == Service.Player.ObjectId ? "You" : Service.ObjectTable.SearchById(status.SourceId) == null ? "None" : "Others"; @@ -69,6 +68,8 @@ private unsafe void DrawParty() // } //} + ImGui.Text("Party Burst Ratio: " + DataCenter.RatioOfMembersIn2minsBurst.ToString()); + ImGui.Text("Party: " + DataCenter.PartyMembers.Count().ToString()); ImGui.Text("CanHealSingleAbility: " + DataCenter.CanHealSingleAbility.ToString()); ImGui.Text("CanHealSingleSpell: " + DataCenter.CanHealSingleSpell.ToString());