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

MCH rework part 2 - the drillening #251

Merged
merged 2 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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