Skip to content

Commit 1e6425c

Browse files
authored
Merge pull request #851 from FFXIV-CombatReborn/reaperReborn
Added Reaper Rework rotation
2 parents dfe6e6e + 77f10b6 commit 1e6425c

File tree

3 files changed

+421
-29
lines changed

3 files changed

+421
-29
lines changed

BasicRotations/Melee/RPR_Reborn.cs

Lines changed: 385 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,385 @@
1+
namespace RebornRotations.Melee;
2+
3+
[Rotation("Rework", CombatType.PvE, GameVersion = "7.25")]
4+
[SourceCode(Path = "main/BasicRotations/Melee/RPR_Reborn.cs")]
5+
[Api(4)]
6+
public sealed class RPR_Reborn : ReaperRotation
7+
{
8+
#region Config Options
9+
[RotationConfig(CombatType.PvE, Name = "[Beta Option] Pool Shroud for Arcane Circle.")]
10+
public bool EnshroudPooling { get; set; } = false;
11+
12+
[RotationConfig(CombatType.PvE, Name = "Use custom timing to refresh Death's Design")]
13+
public bool UseCustomDDTiming { get; set; } = false;
14+
15+
[RotationConfig(CombatType.PvE, Name = "Refresh Death's Design with this many seconds remaining")]
16+
public int RefreshDDSecondsRemaining { get; set; } = 10;
17+
18+
#endregion
19+
20+
#region Countdown Logic
21+
protected override IAction? CountDownAction(float remainTime)
22+
{
23+
if (remainTime < HarpePvE.Info.CastTime + CountDownAhead
24+
&& HarpePvE.CanUse(out IAction? act))
25+
{
26+
return act;
27+
}
28+
if (SoulsowPvE.CanUse(out act))
29+
{
30+
return act;
31+
}
32+
return base.CountDownAction(remainTime);
33+
}
34+
#endregion
35+
36+
#region oGCD Logic
37+
[RotationDesc(ActionID.HellsIngressPvE)]
38+
protected override bool MoveForwardAbility(IAction nextGCD, out IAction? act)
39+
{
40+
if (HellsIngressPvE.CanUse(out act))
41+
{
42+
return true;
43+
}
44+
return base.MoveForwardAbility(nextGCD, out act);
45+
}
46+
47+
[RotationDesc(ActionID.HellsEgressPvE)]
48+
protected override bool MoveBackAbility(IAction nextGCD, out IAction? act)
49+
{
50+
if (HellsEgressPvE.CanUse(out act))
51+
{
52+
return true;
53+
}
54+
return base.MoveBackAbility(nextGCD, out act);
55+
}
56+
57+
[RotationDesc(ActionID.FeintPvE)]
58+
protected override bool DefenseAreaAbility(IAction nextGCD, out IAction? act)
59+
{
60+
if (!HasSoulReaver && !HasEnshrouded && !HasExecutioner && FeintPvE.CanUse(out act))
61+
{
62+
return true;
63+
}
64+
return base.DefenseAreaAbility(nextGCD, out act);
65+
}
66+
67+
[RotationDesc(ActionID.ArcaneCrestPvE)]
68+
protected override bool DefenseSingleAbility(IAction nextGCD, out IAction? act)
69+
{
70+
if (!HasSoulReaver && !HasEnshrouded && !HasExecutioner && ArcaneCrestPvE.CanUse(out act))
71+
{
72+
return true;
73+
}
74+
return base.DefenseSingleAbility(nextGCD, out act);
75+
}
76+
77+
protected override bool AttackAbility(IAction nextGCD, out IAction? act)
78+
{
79+
bool IsTargetBoss = CurrentTarget?.IsBossFromTTK() ?? false;
80+
bool IsTargetDying = CurrentTarget?.IsDying() ?? false;
81+
bool NoEnshroudPooling = !EnshroudPooling && Shroud >= 50;
82+
bool YesEnshroudPooling = EnshroudPooling && Shroud >= 50 && (!PlentifulHarvestPvE.EnoughLevel || HasArcaneCircle || ArcaneCirclePvE.Cooldown.WillHaveOneCharge(8) || (!HasArcaneCircle && ArcaneCirclePvE.Cooldown.WillHaveOneCharge(65) && !ArcaneCirclePvE.Cooldown.WillHaveOneCharge(50)) || (!HasArcaneCircle && Shroud >= 90));
83+
bool HasIdealHostBool = HasIdealHost;
84+
85+
if (IsBurst)
86+
{
87+
if ((CurrentTarget?.HasStatus(true, StatusID.DeathsDesign) ?? false)
88+
&& !CombatElapsedLess(3.5f) && ArcaneCirclePvE.CanUse(out act, skipAoeCheck: true))
89+
{
90+
return true;
91+
}
92+
}
93+
94+
if ((!HasExecutioner) && ((IsTargetBoss && IsTargetDying) || NoEnshroudPooling || YesEnshroudPooling || HasIdealHostBool))
95+
{
96+
if (EnshroudPvE.CanUse(out act))
97+
{
98+
return true;
99+
}
100+
}
101+
102+
if (SacrificiumPvE.CanUse(out act, skipAoeCheck: true, usedUp: true))
103+
{
104+
return true;
105+
}
106+
107+
if (HasEnshrouded && (HasArcaneCircle || LemureShroud < 3))
108+
{
109+
if (LemuresScythePvE.CanUse(out act, usedUp: true))
110+
{
111+
return true;
112+
}
113+
114+
if (LemuresSlicePvE.CanUse(out act, usedUp: true))
115+
{
116+
return true;
117+
}
118+
}
119+
120+
if ((PlentifulHarvestPvE.EnoughLevel && !HasPerfectioParata && !HasImmortalSacrifice) /*&& !Player.HasStatus(true, StatusID.BloodsownCircle_2972) */|| !PlentifulHarvestPvE.EnoughLevel)
121+
{
122+
if (GluttonyPvE.CanUse(out act, skipAoeCheck: true))
123+
{
124+
return true;
125+
}
126+
}
127+
128+
if (!HasBloodsownCircle && !HasPerfectioParata && !HasExecutioner && !HasImmortalSacrifice && ((GluttonyPvE.EnoughLevel && !GluttonyPvE.Cooldown.WillHaveOneChargeGCD(4)) || !GluttonyPvE.EnoughLevel || Soul == 100))
129+
{
130+
if (GrimSwathePvE.CanUse(out act))
131+
{
132+
return true;
133+
}
134+
135+
if (BloodStalkPvE.CanUse(out act))
136+
{
137+
return true;
138+
}
139+
}
140+
141+
return base.AttackAbility(nextGCD, out act);
142+
}
143+
#endregion
144+
145+
#region GCD Logic
146+
protected override bool GeneralGCD(out IAction? act)
147+
{
148+
if (EnhancedGluttonyTrait.EnoughLevel && (IsLastAction(true, GluttonyPvE, BloodStalkPvE) || HasExecutioner))
149+
{
150+
if (HasExecutioner)
151+
{
152+
if (ExecutionersGuillotinePvE.CanUse(out act))
153+
{
154+
return true;
155+
}
156+
157+
switch ((HasEnhancedGallows, HasEnhancedGibbet))
158+
{
159+
case (true, _):
160+
if (ExecutionersGallowsPvE.CanUse(out act, skipComboCheck: true))
161+
return true;
162+
break;
163+
case (_, true):
164+
if (ExecutionersGibbetPvE.CanUse(out act, skipComboCheck: true))
165+
return true;
166+
break;
167+
case (false, false):
168+
if (ExecutionersGallowsPvE.CanUse(out act, skipComboCheck: true) && ExecutionersGallowsPvE.Target.Target != null && CanHitPositional(EnemyPositional.Rear, ExecutionersGallowsPvE.Target.Target))
169+
return true;
170+
if (ExecutionersGibbetPvE.CanUse(out act, skipComboCheck: true) && ExecutionersGibbetPvE.Target.Target != null && CanHitPositional(EnemyPositional.Flank, ExecutionersGibbetPvE.Target.Target))
171+
return true;
172+
if (ExecutionersGallowsPvE.CanUse(out act, skipComboCheck: true))
173+
return true;
174+
if (ExecutionersGibbetPvE.CanUse(out act, skipComboCheck: true))
175+
return true;
176+
break;
177+
}
178+
}
179+
}
180+
181+
if (SoulsowPvE.CanUse(out act))
182+
{
183+
return true;
184+
}
185+
186+
if (!HasExecutioner && !HasSoulReaver)
187+
{
188+
if (PerfectioPvE.CanUse(out act, skipAoeCheck: true))
189+
{
190+
return true;
191+
}
192+
}
193+
194+
if (WhorlOfDeathPvE.CanUse(out act))
195+
{
196+
return true;
197+
}
198+
199+
if (UseCustomDDTiming && ((!CurrentTarget?.HasStatus(true, StatusID.DeathsDesign) ?? false) || (CurrentTarget?.WillStatusEnd(RefreshDDSecondsRemaining, true, StatusID.DeathsDesign) ?? false)))
200+
{
201+
if (ShadowOfDeathPvE.CanUse(out act, skipStatusProvideCheck: true))
202+
{
203+
return true;
204+
}
205+
}
206+
else
207+
{
208+
if (ShadowOfDeathPvE.CanUse(out act))
209+
{
210+
return true;
211+
}
212+
}
213+
214+
if (HasEnshrouded)
215+
{
216+
if (ShadowOfDeathPvE.CanUse(out act))
217+
{
218+
return true;
219+
}
220+
221+
if (LemureShroud > 1)
222+
{
223+
if (PlentifulHarvestPvE.EnoughLevel && ArcaneCirclePvE.Cooldown.WillHaveOneCharge(9) &&
224+
((LemureShroud == 4 && (CurrentTarget?.WillStatusEnd(30, true, StatusID.DeathsDesign) ?? false)) || (LemureShroud == 3 && (CurrentTarget?.WillStatusEnd(50, true, StatusID.DeathsDesign) ?? false))))
225+
{
226+
if (ShadowOfDeathPvE.CanUse(out act, skipStatusProvideCheck: true))
227+
{
228+
return true;
229+
}
230+
}
231+
232+
if (GrimReapingPvE.CanUse(out act))
233+
{
234+
return true;
235+
}
236+
237+
switch ((HasEnhancedCrossReaping, HasEnhancedVoidReaping))
238+
{
239+
case (true, _):
240+
if (CrossReapingPvE.CanUse(out act))
241+
return true;
242+
break;
243+
case (_, true):
244+
if (VoidReapingPvE.CanUse(out act))
245+
return true;
246+
break;
247+
case (false, false):
248+
if (CrossReapingPvE.CanUse(out act))
249+
return true;
250+
if (VoidReapingPvE.CanUse(out act))
251+
return true;
252+
break;
253+
}
254+
}
255+
if (LemureShroud == 1)
256+
{
257+
if (CommunioPvE.EnoughLevel)
258+
{
259+
if (!IsMoving && CommunioPvE.CanUse(out act, skipAoeCheck: true))
260+
{
261+
return true;
262+
}
263+
else
264+
{
265+
if (ShadowOfDeathPvE.CanUse(out act, skipAoeCheck: IsMoving))
266+
{
267+
return true;
268+
}
269+
}
270+
}
271+
else
272+
{
273+
if (GrimReapingPvE.CanUse(out act))
274+
{
275+
return true;
276+
}
277+
278+
switch ((HasEnhancedCrossReaping, HasEnhancedVoidReaping))
279+
{
280+
case (true, _):
281+
if (CrossReapingPvE.CanUse(out act))
282+
return true;
283+
break;
284+
case (_, true):
285+
if (VoidReapingPvE.CanUse(out act))
286+
return true;
287+
break;
288+
case (false, false):
289+
if (CrossReapingPvE.CanUse(out act))
290+
return true;
291+
if (VoidReapingPvE.CanUse(out act))
292+
return true;
293+
break;
294+
}
295+
}
296+
}
297+
}
298+
299+
if (HasSoulReaver)
300+
{
301+
if (GuillotinePvE.CanUse(out act))
302+
{
303+
return true;
304+
}
305+
306+
switch ((HasEnhancedGallows, HasEnhancedGibbet))
307+
{
308+
case (true, _):
309+
if (GallowsPvE.CanUse(out act))
310+
return true;
311+
break;
312+
case (_, true):
313+
if (GibbetPvE.CanUse(out act))
314+
return true;
315+
break;
316+
case (false, false):
317+
if (GallowsPvE.CanUse(out act, skipComboCheck: true) && GallowsPvE.Target.Target != null && CanHitPositional(EnemyPositional.Rear, GallowsPvE.Target.Target))
318+
return true;
319+
if (GibbetPvE.CanUse(out act, skipComboCheck: true) && GibbetPvE.Target.Target != null && CanHitPositional(EnemyPositional.Flank, GibbetPvE.Target.Target))
320+
return true;
321+
if (GallowsPvE.CanUse(out act, skipComboCheck: true))
322+
return true;
323+
if (GibbetPvE.CanUse(out act, skipComboCheck: true))
324+
return true;
325+
break;
326+
}
327+
}
328+
329+
if (!CombatElapsedLessGCD(2) && PlentifulHarvestPvE.CanUse(out act, skipAoeCheck: true))
330+
{
331+
return true;
332+
}
333+
334+
if (SoulScythePvE.CanUse(out act, usedUp: true))
335+
{
336+
return true;
337+
}
338+
339+
if (SoulSlicePvE.CanUse(out act, usedUp: true))
340+
{
341+
return true;
342+
}
343+
344+
if (NightmareScythePvE.CanUse(out act))
345+
{
346+
return true;
347+
}
348+
349+
if (SpinningScythePvE.CanUse(out act))
350+
{
351+
return true;
352+
}
353+
354+
if (!HasExecutioner)
355+
{
356+
if (InfernalSlicePvE.CanUse(out act))
357+
{
358+
return true;
359+
}
360+
361+
if (WaxingSlicePvE.CanUse(out act))
362+
{
363+
return true;
364+
}
365+
366+
if (SlicePvE.CanUse(out act))
367+
{
368+
return true;
369+
}
370+
}
371+
372+
if (InCombat && !HasSoulReaver && HarvestMoonPvE.CanUse(out act, skipAoeCheck: true))
373+
{
374+
return true;
375+
}
376+
377+
if (HarpePvE.CanUse(out act))
378+
{
379+
return true;
380+
}
381+
382+
return base.GeneralGCD(out act);
383+
}
384+
#endregion
385+
}

0 commit comments

Comments
 (0)