Skip to content

Commit

Permalink
Merge branch 'master' into pr/416
Browse files Browse the repository at this point in the history
  • Loading branch information
MKhayle committed Aug 12, 2024
2 parents 47b453d + 1afaa72 commit 1425c3d
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 93 deletions.
48 changes: 39 additions & 9 deletions XIVComboExpanded/Combos/GNB.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Data.Common;
using Dalamud.Game.ClientState.JobGauge.Types;
using System;

namespace XIVComboExpandedPlugin.Combos;

Expand Down Expand Up @@ -98,6 +100,12 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim
var gauge = GetJobGauge<GNBGauge>();
var maxAmmo = level >= GNB.Levels.CartridgeCharge2 ? 3 : 2;

if (IsEnabled(CustomComboPreset.GunbreakerDoubleDownFeatureST))
{
if (level >= GNB.Levels.DoubleDown && gauge.Ammo == maxAmmo && IsCooldownUsable(GNB.DoubleDown))
return GNB.DoubleDown;
}

if (IsEnabled(CustomComboPreset.GunbreakerBurstStrikeCont))
{
if (level >= GNB.Levels.EnhancedContinuation && HasEffect(GNB.Buffs.ReadyToBlast))
Expand Down Expand Up @@ -158,11 +166,33 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim
{
if (actionID == GNB.BurstStrike)
{
if (IsEnabled(CustomComboPreset.GunbreakerBurstStrikeDangerZone))
{
if (level >= GNB.Levels.DangerZone && IsCooldownUsable(GNB.DangerZone))
return OriginalHook(GNB.DangerZone);
}

if (IsEnabled(CustomComboPreset.GunbreakerBurstStrikeCont))
{
if (level >= GNB.Levels.EnhancedContinuation && HasEffect(GNB.Buffs.ReadyToBlast))
return GNB.Hypervelocity;
}

if (IsEnabled(CustomComboPreset.GunbreakerBurstStrikeGnashingFang))
{
if (level >= GNB.Levels.GnashingFang)
{
var gauge = GetJobGauge<GNBGauge>();
if (IsEnabled(CustomComboPreset.GunbreakerGnashingFangCont) &&
(HasEffect(GNB.Buffs.ReadyToRip) ||
HasEffect(GNB.Buffs.ReadyToTear) ||
HasEffect(GNB.Buffs.ReadyToGouge)))
return OriginalHook(GNB.Continuation);
if ((IsCooldownUsable(GNB.GnashingFang) && gauge.Ammo > 0) || !IsOriginal(GNB.GnashingFang))
return OriginalHook(GNB.GnashingFang);

}
}
}

if (actionID == GNB.FatedCircle)
Expand All @@ -178,12 +208,6 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim
{
var gauge = GetJobGauge<GNBGauge>();

if (IsEnabled(CustomComboPreset.GunbreakerDoubleDownFeature))
{
if (level >= GNB.Levels.DoubleDown && gauge.Ammo >= 2 && IsCooldownUsable(GNB.DoubleDown))
return GNB.DoubleDown;
}

if (IsEnabled(CustomComboPreset.GunbreakerEmptyBloodfestFeature))
{
if (level >= GNB.Levels.Bloodfest && gauge.Ammo == 0)
Expand Down Expand Up @@ -235,16 +259,22 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim

if (comboTime > 0 && lastComboMove == GNB.DemonSlice && level >= GNB.Levels.DemonSlaughter)
{
var gauge = GetJobGauge<GNBGauge>();
var maxAmmo = level >= GNB.Levels.CartridgeCharge2 ? 3 : 2;

if (IsEnabled(CustomComboPreset.GunbreakerDoubleDownFeatureAoE))
{
if (level >= GNB.Levels.DoubleDown && gauge.Ammo == maxAmmo && IsCooldownUsable(GNB.DoubleDown))
return GNB.DoubleDown;
}

if (IsEnabled(CustomComboPreset.GunbreakerFatedCircleFeature))
{
if (HasEffect(GNB.Buffs.ReadyToFated) && IsEnabled(CustomComboPreset.GunbreakerFatedCircleCont))
{
return GNB.FatedBrand;
}

var gauge = GetJobGauge<GNBGauge>();
var maxAmmo = level >= GNB.Levels.CartridgeCharge2 ? 3 : 2;

if (level >= GNB.Levels.FatedCircle && gauge.Ammo == maxAmmo)
return GNB.FatedCircle;
}
Expand Down
6 changes: 5 additions & 1 deletion XIVComboExpanded/Combos/NIN.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,11 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim
{
if (comboTime > 0)
{
if (IsEnabled(CustomComboPreset.NinjaKazematoiFeature) && lastComboMove == NIN.GustSlash && level >= NIN.Levels.ArmorCrush && gauge.Kazematoi == 0)
if (
((IsEnabled(CustomComboPreset.NinjaKazematoiFeature) && !IsEnabled(CustomComboPreset.NinjaOvercapKazematoiFeature) && gauge.Kazematoi == 0)
|| (IsEnabled(CustomComboPreset.NinjaOvercapKazematoiFeature) && gauge.Kazematoi + 2 <= 5))
&& lastComboMove == NIN.GustSlash
&& level >= NIN.Levels.ArmorCrush)
return NIN.ArmorCrush;

if (lastComboMove == NIN.GustSlash && level >= NIN.Levels.AeolianEdge)
Expand Down
63 changes: 49 additions & 14 deletions XIVComboExpanded/Combos/PLD.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,15 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim
// * Atonement, Royal Authority (460p).
// Notably, if we enter FoF with both Atonement and Holy Spirit available, using the full
// Atonement combo yields 40 more potency than using Holy Spirit + Atonement + Supplication.
// The absolute best combo is Supplication + Sepulchre + Holy Spirit, however (1540p).
// Optimal combos, in descending order, depending on when we enter FoF:
// * Holy Spirit -> Supplication -> Sepulchre (1540p)
// * Sepulchre -> Royal Authority -> Holy Spirit (1500p)
// * Atonement -> Supplication -> Sepulchre (1500p)
// * Supplication -> Sepulchre -> Royal Authority (1500p)
// * Royal Authority -> Holy Spirit -> Atonement (1460p)
// Note: Technically, this is only true after level 94's Melee Mastery II trait, as prior to
// that, Holy Spirit with Divine Might (450p) has 10 more potency than Sepulchre (440p),
// rather than the other way around. However, since optimizing gains or losses of only 10p
// rather than being equal. However, since optimizing gains or losses of only 10p
// doesn't really matter at all while leveling, we don't bother to adjust this logic for lower
// levels, except where Atonement isn't yet learned.
if (level >= PLD.Levels.Atonement &&
Expand Down Expand Up @@ -197,31 +202,61 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim
this.HasMp(PLD.HolySpirit) && HasEffect(PLD.Buffs.Requiescat))
return PLD.HolySpirit;

if (level >= PLD.Levels.Atonement &&
IsEnabled(CustomComboPreset.PaladinRoyalAuthorityAtonementComboFeature))
// Outside of FoF, we want to use Atonement immediately following Royal Authority, since it's in the lowest
// rung of potencies for FoF. We delay the rest of the Atonement combo AND using Divine Might until they'd
// be overwritten by a new Royal Authority combo. The specifically order we use them in prior to Royal
// Authority, assuming we're continuously in melee range, is Supplication -> Holy Spirit -> Sepulchre.
// This delays using the highest-potency Sepulchre until as late as possible, giving as many opportunities
// as possible for it to end up in FoF. Notably, this gives us an extra 40p if we enter FoF between the
// 2nd GCD prior to Royal Authority and the GCD immediately prior to it.
//
// Supplication is used before Divine Might for two reasons: it provides an extra GCD during the "standard"
// combo sequence (outside FoF) where we have it available for handling a disconnect, and it means that if
// we enter FoF between the 2nd and 3rd GCDs prior to Royal Authority, that Divine Might now protects TWO
// GCDs during FoF from disconnects where we otherwise wouldn't have any disconnect protection at all.
// Basically, Holy Spirit (w/ Divine Might) and Supplication have identical potencies, but Holy Spirit is
// the more flexible of the two, both because it is ranged and because it does not strictly need to be used
// prior to Sepulchre during FoF, so we prefer to have it available during FoF over Supplication.
if (IsEnabled(CustomComboPreset.PaladinRoyalAuthorityAtonementComboFeature) &&
level >= PLD.Levels.Atonement && inMeleeRange)
{
var sepulchre = FindEffect(PLD.Buffs.SepulchreReady);
if (sepulchre != null && inMeleeRange && (
lastComboMove == PLD.RiotBlade || sepulchre.RemainingTime < 4 ||
!IsEnabled(CustomComboPreset.PaladinFoFOptimizeFeature)))
return PLD.Sepulchre;

var supplication = FindEffect(PLD.Buffs.SupplicationReady);
if (supplication != null && inMeleeRange && (
lastComboMove == PLD.RiotBlade || supplication.RemainingTime < 4 ||
!IsEnabled(CustomComboPreset.PaladinFoFOptimizeFeature)))
return PLD.Supplication;

if (HasEffect(PLD.Buffs.AtonementReady) && inMeleeRange)
if (HasEffect(PLD.Buffs.AtonementReady))
return PLD.Atonement;
}

if (level >= PLD.Levels.HolySpirit && IsEnabled(CustomComboPreset.PaladinComboDivineMightFeature))
if (level >= PLD.Levels.HolySpirit &&
IsEnabled(CustomComboPreset.PaladinRoyalAuthorityDivineMightFeature) &&
IsEnabled(CustomComboPreset.PaladinFoFOptimizeFeature))
{
var divineMight = FindEffect(PLD.Buffs.DivineMight);
if (this.HasMp(PLD.HolySpirit) && divineMight != null &&
(!inMeleeRange || lastComboMove == PLD.RiotBlade || divineMight.RemainingTime < 4 ||
(!inMeleeRange || lastComboMove == PLD.RiotBlade || divineMight.RemainingTime < 4))
return PLD.HolySpirit;
}

if (IsEnabled(CustomComboPreset.PaladinRoyalAuthorityAtonementComboFeature) &&
level >= PLD.Levels.Atonement)
{
var sepulchre = FindEffect(PLD.Buffs.SepulchreReady);
if (sepulchre != null && inMeleeRange && (
lastComboMove == PLD.RiotBlade || sepulchre.RemainingTime < 4 ||
!IsEnabled(CustomComboPreset.PaladinFoFOptimizeFeature)))
return PLD.Sepulchre;
}

// Divine Might after Atonement combo if not doing optimization, just to handle potential melee disconnects
// during that time.
if (level >= PLD.Levels.HolySpirit &&
IsEnabled(CustomComboPreset.PaladinRoyalAuthorityDivineMightFeature) &&
!IsEnabled(CustomComboPreset.PaladinFoFOptimizeFeature))
{
if (this.HasMp(PLD.HolySpirit) && HasEffect(PLD.Buffs.DivineMight))
return PLD.HolySpirit;
}

Expand Down Expand Up @@ -282,7 +317,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim
(divineMight != null || HasEffect(PLD.Buffs.Requiescat)))
return PLD.HolyCircle;

if (IsEnabled(CustomComboPreset.PaladinComboDivineMightFeature) && divineMight != null &&
if (IsEnabled(CustomComboPreset.PaladinProminenceDivineMightFeature) && divineMight != null &&
(lastComboMove == PLD.TotalEclipse || divineMight.RemainingTime < 4 ||
!IsEnabled(CustomComboPreset.PaladinFoFOptimizeFeature)))
return PLD.HolyCircle;
Expand Down
36 changes: 34 additions & 2 deletions XIVComboExpanded/Combos/VPR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,27 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim
IsCooldownUsable(VPR.Vicewinder) && IsOriginal(VPR.SerpentsTail))
return VPR.Vicewinder;

if (IsEnabled(CustomComboPreset.ViperAutoSteelReavingFeature) && OriginalHook(VPR.SteelFangs) == VPR.SteelFangs)
if (IsEnabled(CustomComboPreset.ViperAutoFangBiteFeature))
{
if (OriginalHook(VPR.SteelFangs) == VPR.HindstingStrike)
{
if (HasEffect(VPR.Buffs.HindsbaneVenom))
return VPR.HindsbaneFang;
if (HasEffect(VPR.Buffs.HindstungVenom))
return VPR.HindstingStrike;
}

if (OriginalHook(VPR.SteelFangs) == VPR.FlankstingStrike)
{
if (HasEffect(VPR.Buffs.FlanksbaneVenom))
return VPR.FlanksbaneFang;
if (HasEffect(VPR.Buffs.FlankstungVenom))
return VPR.FlankstingStrike;
}
}

if (IsEnabled(CustomComboPreset.ViperAutoSteelReavingFeature) &&
OriginalHook(VPR.SteelFangs) == VPR.SteelFangs)
return HasEffect(VPR.Buffs.HonedReavers) ? VPR.ReavingFangs : VPR.SteelFangs;
}

Expand Down Expand Up @@ -266,7 +286,19 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim
IsCooldownUsable(VPR.VicePit) && IsOriginal(VPR.SerpentsTail))
return VPR.VicePit;

if (IsEnabled(CustomComboPreset.ViperAutoSteelReavingFeature) && OriginalHook(VPR.SteelMaw) == VPR.SteelMaw)
if (IsEnabled(CustomComboPreset.ViperAutoFangBiteFeature))
{
if (OriginalHook(VPR.SteelMaw) == VPR.JaggedMaw)
{
if (HasEffect(VPR.Buffs.GrimhuntersVenom))
return VPR.JaggedMaw;
if (HasEffect(VPR.Buffs.GrimskinsVenom))
return VPR.BloodiedMaw;
}
}

if (IsEnabled(CustomComboPreset.ViperAutoSteelReavingFeature) &&
OriginalHook(VPR.SteelMaw) == VPR.SteelMaw)
return HasEffect(VPR.Buffs.HonedReavers) ? VPR.ReavingMaw : VPR.SteelMaw;
}

Expand Down
Loading

0 comments on commit 1425c3d

Please sign in to comment.