Skip to content

Commit

Permalink
Add MBAbilities config, rename IsAlliance to IsAllianceMember
Browse files Browse the repository at this point in the history
Introduced a new enum `MasterfulBlitzUse` and a configuration
property `MBAbilities` to control Masterful Blitz usage logic.
Refactored related logic and updated `TheForbiddenChakraPvE`
usage. Renamed `IsAlliance` to `IsAllianceMember` for clarity
and updated relevant methods and properties. Corrected property
names for consistency and adjusted full party logic to consider
8 or 9 members.
  • Loading branch information
LTS-FFXIV committed Jan 12, 2025
1 parent 2d4b2ec commit c7981f9
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 29 deletions.
68 changes: 54 additions & 14 deletions BasicRotations/Melee/MNK_Default.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ public enum RiddleOfFireFirst : byte
[Description("Perfect Balance")] PerfectBalance,
}

public enum MasterfulBlitzUse : byte
{
[Description("Use Immediately")] UseAsAble,

[Description("With ROF burst logic")] RiddleOfFireUse,
}

[RotationConfig(CombatType.PvE, Name = "Use Form Shift")]
public bool AutoFormShift { get; set; } = true;

Expand All @@ -32,6 +39,9 @@ public enum RiddleOfFireFirst : byte
[RotationConfig(CombatType.PvE, Name = "Enable TEA Checker.")]
public bool EnableTEAChecker { get; set; } = false;

[RotationConfig(CombatType.PvE, Name = "Use Masterful Blitz abilites as soon as they are available.")]
public MasterfulBlitzUse MBAbilities { get; set; } = MasterfulBlitzUse.RiddleOfFireUse;

[RotationConfig(CombatType.PvE, Name = "Use Riddle of Fire after this ability")]
public RiddleOfFireFirst ROFFirst { get; set; } = RiddleOfFireFirst.Brotherhood;
#endregion
Expand Down Expand Up @@ -91,13 +101,18 @@ protected override bool EmergencyAbility(IAction nextGCD, out IAction? act)
// 'If you are in brotherhood and forbidden chakra is available, use it.'
if (TheForbiddenChakraPvE.CanUse(out act)) return true;
}
if (!InBrotherhood)
else
{
// 'If you are not in brotherhood and brotherhood is about to be available, hold for burst.'
if (BrotherhoodPvE.Cooldown.WillHaveOneChargeGCD(1) && TheForbiddenChakraPvE.CanUse(out act)) return false;
if (BrotherhoodPvE.Cooldown.WillHaveOneChargeGCD(1) && TheForbiddenChakraPvE.CanUse(out act)) return true;
// 'If you are not in brotherhood use it.'
if (TheForbiddenChakraPvE.CanUse(out act)) return true;
}
if (!BrotherhoodPvE.EnoughLevel)
{
// 'If you are not high enough level for brotherhood, use it.'
if (TheForbiddenChakraPvE.CanUse(out act)) return true;
}
if (!TheForbiddenChakraPvE.EnoughLevel)
{
// 'If you are not high enough level for TheForbiddenChakra, use immediately at 5 chakra.'
Expand Down Expand Up @@ -239,22 +254,47 @@ protected override bool GeneralGCD(out IAction? act)

// bullet proofed finisher - use when during burst
// or if burst was missed, and next burst is not arriving in time, use it better than waste it, otherwise, hold it for next rof
if (!BeastChakras.Contains(BeastChakra.NONE) && (Player.HasStatus(true, StatusID.RiddleOfFire) || RiddleOfFirePvE.Cooldown.JustUsedAfter(42)))
if (!BeastChakras.Contains(BeastChakra.NONE))
{
// Both Nadi and 3 beasts
if (PhantomRushPvE.CanUse(out act)) return true;
if (TornadoKickPvE.CanUse(out act)) return true;
switch (MBAbilities)
{
case MasterfulBlitzUse.UseAsAble:
default:
if (PhantomRushPvE.CanUse(out act)) return true;
if (TornadoKickPvE.CanUse(out act)) return true;

// Needing Solar Nadi and has 3 different beasts
if (RisingPhoenixPvE.CanUse(out act)) return true;
if (FlintStrikePvE.CanUse(out act)) return true;

// Needing Lunar Nadi and has 3 of the same beasts
if (ElixirBurstPvE.CanUse(out act)) return true;
if (ElixirFieldPvE.CanUse(out act)) return true;

// No Nadi and 3 beasts
if (CelestialRevolutionPvE.CanUse(out act)) return true;
break;

case MasterfulBlitzUse.RiddleOfFireUse:
if (Player.HasStatus(true, StatusID.RiddleOfFire) || RiddleOfFirePvE.Cooldown.JustUsedAfter(42))
{
// Both Nadi and 3 beasts
if (PhantomRushPvE.CanUse(out act)) return true;
if (TornadoKickPvE.CanUse(out act)) return true;

// Needing Solar Nadi and has 3 different beasts
if (RisingPhoenixPvE.CanUse(out act)) return true;
if (FlintStrikePvE.CanUse(out act)) return true;
// Needing Solar Nadi and has 3 different beasts
if (RisingPhoenixPvE.CanUse(out act)) return true;
if (FlintStrikePvE.CanUse(out act)) return true;

// Needing Lunar Nadi and has 3 of the same beasts
if (ElixirBurstPvE.CanUse(out act)) return true;
if (ElixirFieldPvE.CanUse(out act)) return true;
// Needing Lunar Nadi and has 3 of the same beasts
if (ElixirBurstPvE.CanUse(out act)) return true;
if (ElixirFieldPvE.CanUse(out act)) return true;

// No Nadi and 3 beasts
if (CelestialRevolutionPvE.CanUse(out act)) return true;
// No Nadi and 3 beasts
if (CelestialRevolutionPvE.CanUse(out act)) return true;
}
break;
}
}

// 'Because Fire¡¯s Reply grants formless, we have an imposed restriction that we prefer not to use it while under PB, or if we have a formless already.' + 'Cast Fire's Reply after an opo gcd'
Expand Down
2 changes: 1 addition & 1 deletion RotationSolver.Basic/Actions/ActionTargetInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ public bool GeneralCheck(IBattleChara gameObject, bool skipStatusProvideCheck)
{
if (!gameObject.IsTargetable) return false;

if (Service.Config.RaiseType == RaiseType.PartyOnly && gameObject.IsAlliance() && !gameObject.IsParty())
if (Service.Config.RaiseType == RaiseType.PartyOnly && !gameObject.IsParty())
{
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions RotationSolver.Basic/Actions/BaseAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ private bool IsLastAbilityUsable()
{
return IsLastAbilityv2Usable();
}
return DataCenter.InCombat && (DataCenter.NextAbilityToNextGCD <= Math.Max(ActionManagerHelper.GetCurrentAnimationLock(), DataCenter.MinAnimationLock) + Service.Config.isLastAbilityTimer);
return DataCenter.InCombat && (DataCenter.NextAbilityToNextGCD <= Math.Max(ActionManagerHelper.GetCurrentAnimationLock(), DataCenter.MinAnimationLock) + Service.Config.IsLastAbilityTimer);
}

private bool IsFirstAbilityUsable()
Expand All @@ -182,7 +182,7 @@ private bool IsFirstAbilityUsable()
{
return IsFirstAbilityv2Usable();
}
return DataCenter.InCombat && (DataCenter.NextAbilityToNextGCD >= Math.Max(ActionManagerHelper.GetCurrentAnimationLock(), DataCenter.MinAnimationLock) + Service.Config.isFirstAbilityTimer);
return DataCenter.InCombat && (DataCenter.NextAbilityToNextGCD >= Math.Max(ActionManagerHelper.GetCurrentAnimationLock(), DataCenter.MinAnimationLock) + Service.Config.IsFirstAbilityTimer);
}

private bool IsLastAbilityv2Usable()
Expand Down
6 changes: 3 additions & 3 deletions RotationSolver.Basic/Configuration/Configs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -382,12 +382,12 @@ public const string
[UI("isLastAbilityTimer", Description = "Don't fuck with this if you dont know what it does",
Filter = Extra)]
[Range(0.100f, 2.500f, ConfigUnitType.Seconds, 0.001f)]
public float isLastAbilityTimer { get; set; } = 0.800f;
public float IsLastAbilityTimer { get; set; } = 0.800f;

[UI("isFirstAbilityTimer", Description = "Don't fuck with this if you dont know what it does",
Filter = Extra)]
[Range(0.100f, 2.500f, ConfigUnitType.Seconds, 0.001f)]
public float isFirstAbilityTimer { get; set; } = 0.600f;
public float IsFirstAbilityTimer { get; set; } = 0.600f;

[UI("Auto turn off RSR when combat is over more for more then...",
Parent = nameof(AutoOffAfterCombat))]
Expand Down Expand Up @@ -478,7 +478,7 @@ public const string
Filter = HealingActionCondition, Section = 3)]
private static readonly bool _chocoboPartyMember = false;

[ConditionBool, UI("Treat focus targetted player as party member", Description = "Experimental.",
[ConditionBool, UI("Treat focus targeted player as party member in alliance raids", Description = "Experimental, includes Chaotic.",
Filter = HealingActionCondition, Section = 3)]
private static readonly bool _focusTargetIsParty = false;

Expand Down
4 changes: 2 additions & 2 deletions RotationSolver.Basic/DataCenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,8 @@ public static float GCDTime(uint gcdCount = 0, float offset = 0)
public static bool LastAbilityv2 => DataCenter.InCombat && !ActionHelper.CanUseGCD && (ActionManagerHelper.GetCurrentAnimationLock() == 0) && !Player.Object.IsCasting && (DataCenter.DefaultGCDElapsed >= DataCenter.DefaultGCDRemain);
public static bool FirstAbilityv2 => DataCenter.InCombat && !ActionHelper.CanUseGCD && (ActionManagerHelper.GetCurrentAnimationLock() == 0) && !Player.Object.IsCasting && (DataCenter.DefaultGCDRemain >= DataCenter.DefaultGCDElapsed);

public static bool LastAbilityorNot => DataCenter.InCombat && (DataCenter.NextAbilityToNextGCD <= Math.Max(ActionManagerHelper.GetCurrentAnimationLock(), DataCenter.MinAnimationLock) + Service.Config.isLastAbilityTimer);
public static bool FirstAbilityorNot => DataCenter.InCombat && (DataCenter.NextAbilityToNextGCD >= Math.Max(ActionManagerHelper.GetCurrentAnimationLock(), DataCenter.MinAnimationLock) + Service.Config.isFirstAbilityTimer);
public static bool LastAbilityorNot => DataCenter.InCombat && (DataCenter.NextAbilityToNextGCD <= Math.Max(ActionManagerHelper.GetCurrentAnimationLock(), DataCenter.MinAnimationLock) + Service.Config.IsLastAbilityTimer);
public static bool FirstAbilityorNot => DataCenter.InCombat && (DataCenter.NextAbilityToNextGCD >= Math.Max(ActionManagerHelper.GetCurrentAnimationLock(), DataCenter.MinAnimationLock) + Service.Config.IsFirstAbilityTimer);
#endregion

public static uint[] BluSlots { get; internal set; } = new uint[24];
Expand Down
8 changes: 4 additions & 4 deletions RotationSolver.Basic/Helpers/ObjectHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ internal static unsafe bool IsOthersPlayers(this IGameObject obj)

internal static bool IsAttackable(this IBattleChara battleChara)
{
if (battleChara.IsAlliance() == true) return false;
if (battleChara.IsAllianceMember() == true) return false;

// Dead.
if (Service.Config.FilterOneHpInvincible && battleChara.CurrentHp <= 1) return false;
Expand Down Expand Up @@ -245,7 +245,7 @@ internal static unsafe bool IsEnemy(this IGameObject obj)
=> obj != null
&& ActionManager.CanUseActionOnTarget((uint)ActionID.BlizzardPvE, obj.Struct());

internal static unsafe bool IsAlliance(this IGameObject obj)
internal static unsafe bool IsAllianceMember(this IGameObject obj)
=> obj.GameObjectId is not 0
&& (!DataCenter.IsPvP && DataCenter.IsInAllianceRaid && obj is IPlayerCharacter
|| DataCenter.IsInAllianceRaid && ActionManager.CanUseActionOnTarget((uint)ActionID.CurePvE, obj.Struct()));
Expand All @@ -268,7 +268,7 @@ internal static bool IsParty(this IGameObject gameObject)
if (Service.Config.FriendlyPartyNpcHealRaise2 && gameObject.GetBattleNPCSubKind() == BattleNpcSubKind.NpcPartyMember) return true;
if (Service.Config.ChocoboPartyMember && gameObject.GetNameplateKind() == NameplateKind.PlayerCharacterChocobo) return true;
if (Service.Config.FriendlyBattleNpcHeal && gameObject.GetNameplateKind() == NameplateKind.FriendlyBattleNPC) return true;
if (Service.Config.FocusTargetIsParty && gameObject.IsFocusTarget() == true && gameObject.IsAlliance() == true) return true;
if (Service.Config.FocusTargetIsParty && gameObject.IsFocusTarget() == true && gameObject.IsAllianceMember() == true) return true;
}
return false;
}
Expand Down Expand Up @@ -342,7 +342,7 @@ internal static bool IsTopPriorityNamedHostile(this IGameObject obj)
/// </returns>
internal static bool IsTopPriorityHostile(this IGameObject obj)
{
if (obj.IsAlliance() || obj.IsParty() || obj == null) return false;
if (obj.IsAllianceMember() || obj.IsParty() || obj == null) return false;

var fateId = DataCenter.FateId;

Expand Down
2 changes: 1 addition & 1 deletion RotationSolver.Basic/Rotations/CustomRotation_OtherInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ partial class CustomRotation
/// Whether the number of party members is 8.
/// </summary>
[Description("Is Full Party")]
public static bool IsFullParty => PartyMembers.Count() is 8;
public static bool IsFullParty => PartyMembers.Count() is 8 or 9;

/// <summary>
/// party members HP.
Expand Down
2 changes: 1 addition & 1 deletion RotationSolver/UI/RotationConfigWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2882,7 +2882,7 @@ private static unsafe void DrawTargetData()
ImGui.Text($"Is Alive: {battleChara.IsAlive()}");
ImGui.Text($"Is Party: {battleChara.IsParty()}");
ImGui.Text($"Is Healer: {battleChara.IsJobCategory(JobRole.Healer)}");
ImGui.Text($"Is Alliance: {battleChara.IsAlliance()}");
ImGui.Text($"Is Alliance: {battleChara.IsAllianceMember()}");
ImGui.Text($"Is Enemy: {battleChara.IsEnemy()}");
ImGui.Text($"Distance To Player: {battleChara.DistanceToPlayer()}");
ImGui.Text($"Is In EnemiesList: {battleChara.IsInEnemiesList()}");
Expand Down
2 changes: 1 addition & 1 deletion RotationSolver/Updaters/TargetUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ private static unsafe List<IBattleChara> GetAllianceMembers()
{
foreach (var target in DataCenter.AllTargets)
{
if (ObjectHelper.IsAlliance(target) && target.Character() != null &&
if (ObjectHelper.IsAllianceMember(target) && target.Character() != null &&
target.Character()->CharacterData.OnlineStatus != 15 &&
target.Character()->CharacterData.OnlineStatus != 5 && target.IsTargetable)
{
Expand Down

0 comments on commit c7981f9

Please sign in to comment.