Skip to content

Commit 0f187bf

Browse files
authored
Merge pull request #975 from FFXIV-CombatReborn/HardCastoption
UI cleanup in Action tab, Hard cast raise options cleaned up, melee class posititonal action fix
2 parents 114f768 + a3489ab commit 0f187bf

File tree

10 files changed

+219
-40
lines changed

10 files changed

+219
-40
lines changed

RotationSolver.Basic/Actions/ActionConfig.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,9 @@ public bool IsIntercepted
9393
/// Is this action in the cd window.
9494
/// </summary>
9595
public bool IsOnCooldownWindow { get; set; } = true;
96-
}
96+
97+
/// <summary>
98+
/// One-time flag to indicate the AOE-count reset has been applied.
99+
/// </summary>
100+
public bool AoeResetDone { get; set; } = false;
101+
}

RotationSolver.Basic/Actions/BaseAction.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,20 @@ public ActionConfig Config
117117
value.TimeToKill = 0;
118118
}
119119
}
120+
121+
// One-time AoE count reset: force AOE Count to rotation default (or global default),
122+
// without touching other user-configured fields.
123+
if (!value.AoeResetDone)
124+
{
125+
byte defaultAoe = (Setting.CreateConfig?.Invoke()?.AoeCount) ?? new ActionConfig().AoeCount;
126+
value.AoeCount = defaultAoe;
127+
value.AoeResetDone = true;
128+
129+
Service.Config.RotationActionConfig[ID] = value;
130+
// Optionally persist immediately:
131+
// Service.Config.Save();
132+
}
133+
120134
return value;
121135
}
122136
}
@@ -204,17 +218,17 @@ private bool IsTimeToKillValid()
204218
public unsafe bool Use()
205219
{
206220
if (Player.Object == null) return false;
207-
221+
208222
TargetResult target = Target;
209223
uint adjustId = AdjustedID;
210-
224+
211225
if (TargetInfo.IsTargetArea)
212226
{
213227
if (adjustId != ID || !target.Position.HasValue)
214228
return false;
215229

216230
Vector3 loc = target.Position.Value;
217-
231+
218232
// Use ActionManagerEx for enhanced timing if tweaks are enabled
219233
if (Service.Config.RemoveAnimationLockDelay || Service.Config.RemoveCooldownDelay)
220234
{
@@ -223,17 +237,17 @@ public unsafe bool Use()
223237
else
224238
{
225239
var actionManager = ActionManager.Instance();
226-
return actionManager != null &&
240+
return actionManager != null &&
227241
actionManager->UseActionLocation(ActionType.Action, ID, Player.Object.GameObjectId, &loc);
228242
}
229243
}
230244
else
231245
{
232246
ulong targetId = target.Target?.GameObjectId ?? Player.Object.GameObjectId;
233-
247+
234248
if (targetId == 0 || Svc.Objects.SearchById(targetId) == null)
235249
return false;
236-
250+
237251
// Use ActionManagerEx for enhanced timing if tweaks are enabled
238252
if (Service.Config.RemoveAnimationLockDelay || Service.Config.RemoveCooldownDelay)
239253
{
@@ -242,7 +256,7 @@ public unsafe bool Use()
242256
else
243257
{
244258
var actionManager = ActionManager.Instance();
245-
return actionManager != null &&
259+
return actionManager != null &&
246260
actionManager->UseAction(ActionType.Action, adjustId, targetId);
247261
}
248262
}

RotationSolver.Basic/Configuration/Configs.cs

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -488,29 +488,18 @@ public const string
488488
public float HealthSelfRatio { get; set; } = 0.4f;
489489

490490
#region
491-
[JobConfig, UI("Hard cast Raise while Swiftcast is on cooldown if Swiftcast cooldown is higher than Raise cast time (Experimental)",
492-
Filter = HealingActionCondition, Section = 2,
493-
PvEFilter = JobFilterType.Raise, PvPFilter = JobFilterType.NoJob)]
494-
private static readonly bool _raiseSwiftCooldown = false;
495-
496-
[JobConfig, UI("Hard cast Raise while Swiftcast is on cooldown if all other healers are dead (Experimental)",
497-
Filter = HealingActionCondition, Section = 2,
498-
PvEFilter = JobFilterType.Raise, PvPFilter = JobFilterType.NoJob)]
499-
private static readonly bool _raiseHealerByCasting = false;
500-
501-
[JobConfig, UI("Hard cast Raise while Swiftcast is on cooldown",
502-
Filter = HealingActionCondition, Section = 2,
503-
PvEFilter = JobFilterType.Raise, PvPFilter = JobFilterType.NoJob)]
504-
private static readonly bool _raisePlayerByCasting = true;
491+
[JobConfig, UI("Prioritize raising dead players over Healing/Defense.",
492+
Filter = HealingActionCondition, Section = 2)]
493+
private static readonly bool _raisePlayerFirst = false;
505494

506495
[JobConfig, UI("Raise player by using Swiftcast/Dualcast if available", Description = "If this is disabled, you will never use Swiftcast/Dualcast to raise players.",
507496
Filter = HealingActionCondition, Section = 2,
508497
PvEFilter = JobFilterType.Raise, PvPFilter = JobFilterType.NoJob)]
509498
private static readonly bool _raisePlayerBySwift = true;
510499

511-
[JobConfig, UI("Prioritize raising dead players over Healing/Defense.",
500+
[JobConfig, UI("Hard cast Raise logic",
512501
Filter = HealingActionCondition, Section = 2)]
513-
private static readonly bool _raisePlayerFirst = false;
502+
private readonly HardCastRaiseType _HardCastRaiseType = HardCastRaiseType.HardCastNormal;
514503

515504
[JobConfig, UI("Raise styles",
516505
Filter = HealingActionCondition, Section = 2)]
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
namespace RotationSolver.Basic.Data;
2+
3+
/// <summary>
4+
/// Hostile target.
5+
/// </summary>
6+
public enum HardCastRaiseType : byte
7+
{
8+
/// <summary>
9+
///
10+
/// </summary>
11+
[Description("Do not hard cast Raise ")]
12+
NoHardCast,
13+
14+
/// <summary>
15+
///
16+
/// </summary>
17+
[Description("Raise while Swiftcast is on cooldown")]
18+
HardCastNormal,
19+
20+
/// <summary>
21+
///
22+
/// </summary>
23+
[Description("Raise while Swiftcast is on cooldown and other healers are dead")]
24+
HardCastOnlyHealer,
25+
26+
/// <summary>
27+
///
28+
/// </summary>
29+
[Description("Raise while Swiftcast is on cooldown and cooldown is higher than raise cast time")]
30+
HardCastSwiftCooldown,
31+
32+
/// <summary>
33+
///
34+
/// </summary>
35+
[Description("Raise while Swiftcast is on cooldown and cooldown is higher than raise cast time and other healers are dead")]
36+
HardCastOnlyHealerSwiftCooldown,
37+
}

RotationSolver.Basic/Rotations/CustomRotation_GCD.cs

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,24 @@ public partial class CustomRotation
6363

6464
IBaseAction.TargetOverride = TargetType.Death;
6565

66+
HardCastRaiseType hardcastraisetype = Service.Config.HardCastRaiseType;
67+
6668
if (Service.Config.RaisePlayerFirst)
6769
{
6870
if (RaiseSpell(out act, false))
6971
{
7072
return act;
7173
}
7274

73-
if (Service.Config.RaisePlayerByCasting && SwiftcastPvE.Cooldown.IsCoolingDown)
75+
if (hardcastraisetype == HardCastRaiseType.HardCastNormal && SwiftcastPvE.Cooldown.IsCoolingDown)
7476
{
7577
if (RaiseSpell(out act, true))
7678
{
7779
return act;
7880
}
7981
}
8082

81-
if (Service.Config.RaiseSwiftCooldown)
83+
if (hardcastraisetype == HardCastRaiseType.HardCastSwiftCooldown)
8284
{
8385
if (SwiftcastPvE.Cooldown.IsCoolingDown && Raise != null && Raise.Info.CastTime < SwiftcastPvE.Cooldown.RecastTimeRemainOneCharge)
8486
{
@@ -89,7 +91,7 @@ public partial class CustomRotation
8991
}
9092
}
9193

92-
if (Service.Config.RaiseHealerByCasting)
94+
if (hardcastraisetype == HardCastRaiseType.HardCastOnlyHealer)
9395
{
9496
var deadhealers = new HashSet<IBattleChara>();
9597
if (DataCenter.PartyMembers != null)
@@ -119,6 +121,40 @@ public partial class CustomRotation
119121
return act;
120122
}
121123
}
124+
125+
if (hardcastraisetype == HardCastRaiseType.HardCastOnlyHealerSwiftCooldown)
126+
{
127+
if (SwiftcastPvE.Cooldown.IsCoolingDown && Raise != null && Raise.Info.CastTime < SwiftcastPvE.Cooldown.RecastTimeRemainOneCharge)
128+
{
129+
var deadhealers = new HashSet<IBattleChara>();
130+
if (DataCenter.PartyMembers != null)
131+
{
132+
foreach (var battleChara in DataCenter.PartyMembers.GetDeath())
133+
{
134+
if (TargetFilter.IsJobCategory(battleChara, JobRole.Healer) && !battleChara.IsPlayer())
135+
{
136+
deadhealers.Add(battleChara);
137+
}
138+
}
139+
}
140+
141+
var allhealers = new HashSet<IBattleChara>();
142+
if (DataCenter.PartyMembers != null)
143+
{
144+
foreach (var battleChara in DataCenter.PartyMembers)
145+
{
146+
if (TargetFilter.IsJobCategory(battleChara, JobRole.Healer) && !battleChara.IsPlayer())
147+
{
148+
allhealers.Add(battleChara);
149+
}
150+
}
151+
}
152+
if (RaiseSpell(out act, true) && deadhealers.Count == allhealers.Count && deadhealers.Count > 0)
153+
{
154+
return act;
155+
}
156+
}
157+
}
122158
}
123159

124160
IBaseAction.TargetOverride = null;
@@ -245,15 +281,15 @@ public partial class CustomRotation
245281
return act;
246282
}
247283

248-
if (Service.Config.RaisePlayerByCasting && SwiftcastPvE.Cooldown.IsCoolingDown)
284+
if (hardcastraisetype == HardCastRaiseType.HardCastNormal && SwiftcastPvE.Cooldown.IsCoolingDown)
249285
{
250286
if (RaiseSpell(out act, true))
251287
{
252288
return act;
253289
}
254290
}
255291

256-
if (Service.Config.RaiseSwiftCooldown)
292+
if (hardcastraisetype == HardCastRaiseType.HardCastSwiftCooldown)
257293
{
258294
if (SwiftcastPvE.Cooldown.IsCoolingDown && Raise != null && Raise.Info.CastTime < SwiftcastPvE.Cooldown.RecastTimeRemainOneCharge)
259295
{
@@ -264,7 +300,7 @@ public partial class CustomRotation
264300
}
265301
}
266302

267-
if (Service.Config.RaiseHealerByCasting)
303+
if (hardcastraisetype == HardCastRaiseType.HardCastOnlyHealer)
268304
{
269305
var deadhealers = new HashSet<IBattleChara>();
270306
if (DataCenter.PartyMembers != null)
@@ -289,11 +325,45 @@ public partial class CustomRotation
289325
}
290326
}
291327
}
292-
if (RaiseSpell(out act, true) && deadhealers.Count == allhealers.Count)
328+
if (RaiseSpell(out act, true) && deadhealers.Count == allhealers.Count && deadhealers.Count > 0)
293329
{
294330
return act;
295331
}
296332
}
333+
334+
if (hardcastraisetype == HardCastRaiseType.HardCastOnlyHealerSwiftCooldown)
335+
{
336+
if (SwiftcastPvE.Cooldown.IsCoolingDown && Raise != null && Raise.Info.CastTime < SwiftcastPvE.Cooldown.RecastTimeRemainOneCharge)
337+
{
338+
var deadhealers = new HashSet<IBattleChara>();
339+
if (DataCenter.PartyMembers != null)
340+
{
341+
foreach (var battleChara in DataCenter.PartyMembers.GetDeath())
342+
{
343+
if (TargetFilter.IsJobCategory(battleChara, JobRole.Healer) && !battleChara.IsPlayer())
344+
{
345+
deadhealers.Add(battleChara);
346+
}
347+
}
348+
}
349+
350+
var allhealers = new HashSet<IBattleChara>();
351+
if (DataCenter.PartyMembers != null)
352+
{
353+
foreach (var battleChara in DataCenter.PartyMembers)
354+
{
355+
if (TargetFilter.IsJobCategory(battleChara, JobRole.Healer) && !battleChara.IsPlayer())
356+
{
357+
allhealers.Add(battleChara);
358+
}
359+
}
360+
}
361+
if (RaiseSpell(out act, true) && deadhealers.Count == allhealers.Count && deadhealers.Count > 0)
362+
{
363+
return act;
364+
}
365+
}
366+
}
297367
}
298368

299369
IBaseAction.TargetOverride = null;

RotationSolver/RebornRotations/Melee/NIN_Reborn.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,10 @@ protected override bool GeneralGCD(out IAction? act)
10331033
{
10341034
return true;
10351035
}
1036+
else if (Kazematoi < 4 && ArmorCrushPvE.CanUse(out act))
1037+
{
1038+
return true;
1039+
}
10361040
}
10371041
}
10381042

RotationSolver/RebornRotations/Melee/RPR_Reborn.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ protected override bool GeneralGCD(out IAction? act)
161161
return true;
162162
if (ExecutionersGibbetPvE.CanUse(out act, skipComboCheck: true) && ExecutionersGibbetPvE.Target.Target != null && CanHitPositional(EnemyPositional.Flank, ExecutionersGibbetPvE.Target.Target))
163163
return true;
164+
if (ExecutionersGallowsPvE.CanUse(out act, skipComboCheck: true))
165+
return true;
166+
if (ExecutionersGibbetPvE.CanUse(out act, skipComboCheck: true))
167+
return true;
164168
break;
165169
case (true, false):
166170
if (ExecutionersGallowsPvE.CanUse(out act, skipComboCheck: true))
@@ -316,6 +320,10 @@ protected override bool GeneralGCD(out IAction? act)
316320
return true;
317321
if (GibbetPvE.CanUse(out act, skipComboCheck: true) && GibbetPvE.Target.Target != null && CanHitPositional(EnemyPositional.Flank, GibbetPvE.Target.Target))
318322
return true;
323+
if (GallowsPvE.CanUse(out act, skipComboCheck: true))
324+
return true;
325+
if (GibbetPvE.CanUse(out act, skipComboCheck: true))
326+
return true;
319327
break;
320328
case (true, _):
321329
if (GallowsPvE.CanUse(out act, skipComboCheck: true))

RotationSolver/RebornRotations/Melee/SAM_Reborn.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,16 @@ protected override bool GeneralGCD(out IAction? act)
405405
return true;
406406
}
407407

408+
if (!HasFugetsu && JinpuPvE.CanUse(out act))
409+
{
410+
return true;
411+
}
412+
413+
if (!HasFuka && ShifuPvE.CanUse(out act))
414+
{
415+
return true;
416+
}
417+
408418
if (!HasFugetsu)
409419
{
410420
if (JinpuPvE.CanUse(out act))

0 commit comments

Comments
 (0)