Skip to content
This repository has been archived by the owner on Nov 23, 2024. It is now read-only.

Commit

Permalink
Merge pull request #251 from Karaha-Baruha/main
Browse files Browse the repository at this point in the history
MCH rework part 2 - the drillening
  • Loading branch information
LTS-FFXIV authored Sep 22, 2024
2 parents ab84ff5 + 7cc494e commit 75bd885
Show file tree
Hide file tree
Showing 2 changed files with 226 additions and 1 deletion.
225 changes: 225 additions & 0 deletions BasicRotations/Ranged/zMCH_Beta_2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
namespace DefaultRotations.Ranged;

[Rotation("zMCH Beta 2", CombatType.PvE, GameVersion = "7.05")]
[SourceCode(Path = "main/DefaultRotations/Ranged/zMCH_Beta_2.cs")]
[Api(4)]
public sealed class zMCH_Beta_2 : MachinistRotation
{
#region Config Options

#endregion

private const float HYPERCHARGE_DURATION = 8f;

#region Countdown logic
// Defines logic for actions to take during the countdown before combat starts.
protected override IAction? CountDownAction(float remainTime)
{
// ReassemblePvE's duration is 5s, need to fire the first GCD before it ends
if (remainTime < 5 && ReassemblePvE.CanUse(out var act)) return act;
// tincture needs to be used on -2s exactly
if (remainTime <= 2 && UseBurstMedicine(out act)) return act;
return base.CountDownAction(remainTime);
}
#endregion

#region oGCD Logic
// Determines emergency actions to take based on the next planned GCD action.
protected override bool EmergencyAbility(IAction nextGCD, out IAction? act)
{
if (IsBurst)
{

if (FullMetalFieldPvE.EnoughLevel)
{
// Use Wildfire before FMF in the second half of the GCD window to avoid wasting time in status
if (WeaponRemain < 1.25f && nextGCD.IsTheSameTo(true, FullMetalFieldPvE)
&& Player.HasStatus(true, StatusID.Hypercharged)
&& WildfirePvE.CanUse(out act, isLastAbility: true)) return true;
}
// Legacy logic for <100
else if ((IsLastAbility(false, HyperchargePvE)
|| Heat >= 50
|| Player.HasStatus(true, StatusID.Hypercharged))
&& ToolChargeSoon(out _)
&& !LowLevelHyperCheck
&& WildfirePvE.CanUse(out act)) return true;
}

// Reassemble Logic
// Check next GCD action and conditions for Reassemble.
bool isReassembleUsable =
//Reassemble current # of charges and double proc protection
ReassemblePvE.Cooldown.CurrentCharges > 0 && !Player.HasStatus(true, StatusID.Reassembled) &&
(nextGCD.IsTheSameTo(true, [ChainSawPvE, ExcavatorPvE]) || nextGCD.IsTheSameTo(false, [AirAnchorPvE]) ||
(!ChainSawPvE.EnoughLevel && nextGCD.IsTheSameTo(true, DrillPvE)) ||
(!DrillPvE.EnoughLevel && nextGCD.IsTheSameTo(true, CleanShotPvE)) ||
(!CleanShotPvE.EnoughLevel && nextGCD.IsTheSameTo(false, HotShotPvE)));
// Attempt to use Reassemble if it's ready
if (isReassembleUsable)
{
if (ReassemblePvE.CanUse(out act, skipComboCheck: true, usedUp: true)) return true;
}
return base.EmergencyAbility(nextGCD, out act);
}

// Logic for using attack abilities outside of GCD, focusing on burst windows and cooldown management.
protected override bool AttackAbility(IAction nextGCD, out IAction? act)
{
// If Wildfire is active, use Hypercharge.....Period
if (Player.HasStatus(true, StatusID.Wildfire_1946) && HyperchargePvE.CanUse(out act)) return true;

// don't do anything that might fuck with burst timings at 100
if (nextGCD.IsTheSameTo(true, FullMetalFieldPvE) || IsLastGCD(true, FullMetalFieldPvE))
{
act = null;
return false;
}

// Start Ricochet/Gauss cooldowns rolling
if (!RicochetPvE.Cooldown.IsCoolingDown && RicochetPvE.CanUse(out act, skipAoeCheck: true)) return true;
if (!GaussRoundPvE.Cooldown.IsCoolingDown && GaussRoundPvE.CanUse(out act, skipAoeCheck: true)) return true;

if (IsLastGCD(true, DrillPvE) && BarrelStabilizerPvE.CanUse(out act)) return true;

// Rook Autoturret/Queen Logic
if (CanUseQueenMeow(out act, nextGCD)) return true;

// Use Hypercharge if wildfire will not be up in 30 seconds or if you hit 100 heat and it will not break your combo
if (!LowLevelHyperCheck
&& !Player.HasStatus(true, StatusID.Reassembled)
&& (!WildfirePvE.Cooldown.WillHaveOneCharge(30) || Heat == 100)
&& !(LiveComboTime <= HYPERCHARGE_DURATION)
&& ToolChargeSoon(out act)) return true;

// Use Ricochet and Gauss if have pooled charges or is burst window
if (isRicochetMore)
{
if ((IsLastGCD(true, BlazingShotPvE, HeatBlastPvE)
|| RicochetPvE.Cooldown.RecastTimeElapsed >= 55
|| !WildfirePvE.Cooldown.ElapsedAfter(20))
&& RicochetPvE.CanUse(out act, skipAoeCheck: true, usedUp: true))
return true;
}

if ((IsLastGCD(true, BlazingShotPvE, HeatBlastPvE)
|| GaussRoundPvE.Cooldown.RecastTimeElapsed >= 55
|| !WildfirePvE.Cooldown.ElapsedAfter(20))
&& GaussRoundPvE.CanUse(out act, usedUp: true, skipAoeCheck: true))
return true;


if (IsBurst && !FullMetalFieldPvE.EnoughLevel)
{
if (BarrelStabilizerPvE.CanUse(out act)) return true;
}

return base.AttackAbility(nextGCD, out act);
}
#endregion

#region GCD Logic
protected override bool GeneralGCD(out IAction? act)
{
// use procs asap
if (ExcavatorPvE.CanUse(out act, skipAoeCheck: true)) return true;
if (!ChainSawPvE.Cooldown.WillHaveOneChargeGCD(2) && FullMetalFieldPvE.CanUse(out act)) return true;

// overheated aoe
if (AutoCrossbowPvE.CanUse(out act)) return true;
// overheated single
if (HeatBlastPvE.CanUse(out act)) return true;

// drill's aoe version
if (BioblasterPvE.CanUse(out act, usedUp: true)) return true;

// single target --- need to update this strange condition writing!!!
if (!SpreadShotPvE.CanUse(out _))
{
// use AirAnchor if possible
if (HotShotMasteryTrait.EnoughLevel && AirAnchorPvE.CanUse(out act)) return true;

// for burst: use Drill after AirAnchor
if (IsLastGCD(true, AirAnchorPvE) && EnhancedMultiweaponTrait.EnoughLevel && DrillPvE.CanUse(out act, usedUp: true)) return true;
if (!EnhancedMultiweaponTrait.EnoughLevel && DrillPvE.CanUse(out act, usedUp: true)) return true;

if (!AirAnchorPvE.EnoughLevel && HotShotPvE.CanUse(out act)) return true;
}

// ChainSaw is always used after Drill
if (ChainSawPvE.CanUse(out act, skipAoeCheck: true)) return true;

// save Drill for burst
if (EnhancedMultiweaponTrait.EnoughLevel
&& !ChainSawPvE.Cooldown.WillHaveOneCharge(6)
&& (!(LiveComboTime <= 6) || (!CleanShotPvE.CanUse(out _) && !SlugShotPvE.CanUse(out _)))
&& DrillPvE.CanUse(out act, usedUp: true)) return true;

// basic aoe
if (SpreadShotPvE.CanUse(out act)) return true;

// single target 123 combo
if (CleanShotPvE.CanUse(out act)) return true;
if (SlugShotPvE.CanUse(out act)) return true;
if (SplitShotPvE.CanUse(out act)) return true;

return base.GeneralGCD(out act);
}
#endregion

#region Extra Methods
// Extra private helper methods for determining the usability of specific abilities under certain conditions.
// These methods simplify the main logic by encapsulating specific checks related to abilities' cooldowns and prerequisites.
// Logic for Hypercharge
private bool ToolChargeSoon(out IAction? act)
{
if
//Cannot AOE
(!SpreadShotPvE.CanUse(out _)
&&
// AirAnchor Enough Level % AirAnchor
((AirAnchorPvE.EnoughLevel && AirAnchorPvE.Cooldown.WillHaveOneCharge(HYPERCHARGE_DURATION))
||
// HotShot Charge Detection
(!AirAnchorPvE.EnoughLevel && HotShotPvE.EnoughLevel && HotShotPvE.Cooldown.WillHaveOneCharge(HYPERCHARGE_DURATION))
||
// Drill Charge Detection
(DrillPvE.EnoughLevel && (!DrillPvE.Cooldown.IsCoolingDown))
||
// Chainsaw Charge Detection
(ChainSawPvE.EnoughLevel && ChainSawPvE.Cooldown.WillHaveOneCharge(HYPERCHARGE_DURATION))))
{
act = null;
return false;
}
else
{
return HyperchargePvE.CanUse(out act);
}
}

private bool CanUseQueenMeow(out IAction? act, IAction nextGCD)
{
if (
// ASAP in opener
(CombatElapsedLessGCD(10))
// In first 10 seconds of 2 minute window
|| (!AirAnchorPvE.Cooldown.ElapsedAfter(10) && (Player.HasStatus(true, StatusID.FullMetalMachinist) || BarrelStabilizerPvE.Cooldown.WillHaveOneChargeGCD(4)))
// or if about to overcap
|| nextGCD.IsTheSameTo(true, CleanShotPvE) && Battery == 100
|| (nextGCD.IsTheSameTo(true, AirAnchorPvE, ChainSawPvE, ExcavatorPvE) && (Battery == 90 || Battery == 100))
)
{
if (RookAutoturretPvE.CanUse(out act)) return true;
}
act = null;
return false;
}

// Check for not burning Hypercharge below level 52 on AOE
private bool LowLevelHyperCheck => !AutoCrossbowPvE.EnoughLevel && SpreadShotPvE.CanUse(out _);

// Keeps Ricochet and Gauss Cannon Even
private bool isRicochetMore => RicochetPvE.EnoughLevel && GaussRoundPvE.Cooldown.RecastTimeElapsed <= RicochetPvE.Cooldown.RecastTimeElapsed;
#endregion
}
2 changes: 1 addition & 1 deletion BasicRotations/RebornRotations.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<Compile Include="Duty\EmanationDefault" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="RotationSolverReborn.Basic" Version="7.0.5.115" />
<PackageReference Include="RotationSolverReborn.Basic" Version="7.0.5.117" />
</ItemGroup>
<ItemGroup>
<Reference Include="Dalamud">
Expand Down

0 comments on commit 75bd885

Please sign in to comment.