Skip to content

Commit

Permalink
Merge pull request #454 from FFXIV-CombatReborn/ttk+ability-timer-tes…
Browse files Browse the repository at this point in the history
…ting-stuff

TTK, Ability checks, Raise logic adjustments
  • Loading branch information
LTS-FFXIV authored Nov 30, 2024
2 parents 70a677c + 8f65d8f commit b8a9360
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 36 deletions.
3 changes: 2 additions & 1 deletion BasicRotations/Melee/MNK_Default.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ protected override bool AttackAbility(IAction nextGCD, out IAction? act)
if (HowlingFistPvE.CanUse(out act, skipAoeCheck: true)) return true; // Howling Fist
}
else
if (TheForbiddenChakraPvE.CanUse(out act)) return true;
if (SteelPeakPvE.CanUse(out act)) return true;
if (TheForbiddenChakraPvE.CanUse(out act)) return true;

// use bh when bh and rof are ready (opener) or ask bh to wait for rof's cd to be close and then use bh
if (!CombatElapsedLessGCD(2)
Expand Down
2 changes: 1 addition & 1 deletion ECommons
18 changes: 18 additions & 0 deletions RotationSolver.Basic/Actions/BaseAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,32 @@ public bool CanUse(out IAction act, bool isLastAbility = false, bool isFirstAbil

private bool IsLastAbilityUsable()
{
if (Service.Config.UseV2AbilityChecks)
{
return IsLastAbilityv2Usable();
}
return DataCenter.InCombat && (DataCenter.NextAbilityToNextGCD <= Math.Max(ActionManagerHelper.GetCurrentAnimationLock(), DataCenter.MinAnimationLock) + Service.Config.isLastAbilityTimer);
}

private bool IsFirstAbilityUsable()
{
if (Service.Config.UseV2AbilityChecks)
{
return IsFirstAbilityv2Usable();
}
return DataCenter.InCombat && (DataCenter.NextAbilityToNextGCD >= Math.Max(ActionManagerHelper.GetCurrentAnimationLock(), DataCenter.MinAnimationLock) + Service.Config.isFirstAbilityTimer);
}

private bool IsLastAbilityv2Usable()
{
return DataCenter.InCombat && (DataCenter.DefaultGCDElapsed >= DataCenter.DefaultGCDRemain);
}

private bool IsFirstAbilityv2Usable()
{
return DataCenter.InCombat && (DataCenter.DefaultGCDRemain >= DataCenter.DefaultGCDElapsed);
}

private bool IsTimeToKillValid()
{
return DataCenter.AverageTimeToKill >= Config.TimeToKill && DataCenter.AverageTimeToKill >= Config.TimeToUntargetable;
Expand Down
8 changes: 8 additions & 0 deletions RotationSolver.Basic/Configuration/Configs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,14 @@ public const string
Filter = Extra)]
private static readonly bool _autoOpenChest = true;

[ConditionBool, UI("Use experimental FirstAbility and LastAbility checks",
Filter = Extra)]
private static readonly bool _useV2AbilityChecks = false;

[ConditionBool, UI("Enable RSR click counter in main menu",
Filter = Extra)]
private static readonly bool _enableClickingCount = true;

[ConditionBool, UI("Auto close the loot window when auto opened the chest.",
Parent = nameof(AutoOpenChest))]
private static readonly bool _autoCloseChestWindow = true;
Expand Down
10 changes: 5 additions & 5 deletions RotationSolver.Basic/Data/ObjectListDelay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ public class ObjectListDelay<T> : IEnumerable<T> where T : IGameObject
{
private IEnumerable<T> _list = new List<T>();
private readonly Func<(float min, float max)> _getRange;
private SortedList<ulong, DateTime> _revealTime = new();
private readonly Random _ran = new(DateTime.Now.Millisecond);
private Dictionary<ulong, DateTime> _revealTime = new();
private readonly Random _ran = new();

/// <summary>
/// Initializes a new instance of the <see cref="ObjectListDelay{T}"/> class.
Expand Down Expand Up @@ -41,8 +41,8 @@ public ObjectListDelay(Func<Vector2> getRange)
/// <param name="originData">The original list of objects.</param>
public void Delay(IEnumerable<T> originData)
{
var outList = new List<T>(originData.Count());
var revealTime = new SortedList<ulong, DateTime>();
var outList = new List<T>();
var revealTime = new Dictionary<ulong, DateTime>();
var now = DateTime.Now;

foreach (var item in originData)
Expand All @@ -51,7 +51,7 @@ public void Delay(IEnumerable<T> originData)
{
var (min, max) = _getRange();
var delaySecond = min + (float)_ran.NextDouble() * (max - min);
time = now + new TimeSpan(0, 0, 0, 0, (int)(delaySecond * 1000));
time = now + TimeSpan.FromMilliseconds(delaySecond * 1000);
}
revealTime[item.GameObjectId] = time;

Expand Down
7 changes: 4 additions & 3 deletions RotationSolver.Basic/DataCenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
using RotationSolver.Basic.Configuration;
using RotationSolver.Basic.Configuration.Conditions;
using RotationSolver.Basic.Rotations.Duties;
using Svg.FilterEffects;
using System.Linq;
using Action = Lumina.Excel.Sheets.Action;
using CharacterManager = FFXIVClientStructs.FFXIV.Client.Game.Character.CharacterManager;

Expand Down Expand Up @@ -251,6 +249,9 @@ public static unsafe ushort FateId
public static float GCDTime(uint gcdCount = 0, float offset = 0)
=> ActionManagerHelper.GetDefaultRecastTime() * gcdCount + offset;

public static bool LastAbilityv2 => DataCenter.InCombat && !ActionHelper.CanUseGCD && (ActionManagerHelper.GetCurrentAnimationLock() == 0) && !Player.Object.IsCasting && (DataCenter.DefaultGCDElapsed >= DataCenter.DefaultGCDRemain);
public static bool FirstAbilityv2 => DataCenter.InCombat && !ActionHelper.CanUseGCD && (ActionManagerHelper.GetCurrentAnimationLock() == 0) && !Player.Object.IsCasting && (DataCenter.DefaultGCDRemain >= DataCenter.DefaultGCDElapsed);

public static bool LastAbilityorNot => DataCenter.InCombat && (DataCenter.NextAbilityToNextGCD <= Math.Max(ActionManagerHelper.GetCurrentAnimationLock(), DataCenter.MinAnimationLock) + Service.Config.isLastAbilityTimer);
public static bool FirstAbilityorNot => DataCenter.InCombat && (DataCenter.NextAbilityToNextGCD >= Math.Max(ActionManagerHelper.GetCurrentAnimationLock(), DataCenter.MinAnimationLock) + Service.Config.isFirstAbilityTimer);
#endregion
Expand Down Expand Up @@ -689,7 +690,7 @@ public static float PartyMembersDifferHP
#region Action Record
public const float MinAnimationLock = 0.6f;

const int QUEUECAPACITY = 16;
const int QUEUECAPACITY = 32;
private static readonly Queue<ActionRec> _actions = new(QUEUECAPACITY);
private static readonly Queue<DamageRec> _damages = new(QUEUECAPACITY);

Expand Down
22 changes: 11 additions & 11 deletions RotationSolver.Basic/Helpers/ObjectHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -460,31 +460,31 @@ internal static float GetTimeToKill(this IBattleChara b, bool wholeTime = false)
var objectId = b.GameObjectId;

DateTime startTime = DateTime.MinValue;
float thatTimeRatio = 0;
float initialHpRatio = 0;

// Create a copy of the RecordedHP collection to avoid modification during enumeration
var recordedHPCopy = DataCenter.RecordedHP.ToList();
// Use a snapshot of the RecordedHP collection to avoid modification during enumeration
var recordedHPCopy = DataCenter.RecordedHP.ToArray();

foreach (var (time, hpRatios) in recordedHPCopy)
{
if (hpRatios.TryGetValue(objectId, out var ratio) && ratio != 1)
{
startTime = time;
thatTimeRatio = ratio;
initialHpRatio = ratio;
break;
}
}

var timespan = DateTime.Now - startTime;
if (startTime == DateTime.MinValue || timespan < CheckSpan) return float.NaN;
if (startTime == DateTime.MinValue || (DateTime.Now - startTime) < CheckSpan) return float.NaN;

var ratioNow = b.GetHealthRatio();
if (float.IsNaN(ratioNow)) return float.NaN;
var currentHpRatio = b.GetHealthRatio();
if (float.IsNaN(currentHpRatio)) return float.NaN;

var ratioReduce = thatTimeRatio - ratioNow;
if (ratioReduce <= 0) return float.NaN;
var hpRatioDifference = initialHpRatio - currentHpRatio;
if (hpRatioDifference <= 0) return float.NaN;

return (float)timespan.TotalSeconds / ratioReduce * (wholeTime ? 1 : ratioNow);
var elapsedTime = (float)(DateTime.Now - startTime).TotalSeconds;
return elapsedTime / hpRatioDifference * (wholeTime ? 1 : currentHpRatio);
}

/// <summary>
Expand Down
16 changes: 8 additions & 8 deletions RotationSolver.Basic/Rotations/CustomRotation_GCD.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,6 @@ partial class CustomRotation

if (EmergencyGCD(out act)) return act;

IBaseAction.TargetOverride = TargetType.Death;

if (RaiseSpell(out act, false)) return act;

if (Service.Config.RaisePlayerByCasting && SwiftcastPvE.Cooldown.IsCoolingDown && RaiseSpell(out act, true)) return act;

IBaseAction.TargetOverride = null;

if (DataCenter.MergedStatus.HasFlag(AutoStatus.MoveForward)
&& MoveForwardGCD(out act))
{
Expand Down Expand Up @@ -78,6 +70,14 @@ partial class CustomRotation
if (DataCenter.MergedStatus.HasFlag(AutoStatus.Dispel)
&& DispelGCD(out act)) return act;

IBaseAction.TargetOverride = TargetType.Death;

if (RaiseSpell(out act, false)) return act;

if (Service.Config.RaisePlayerByCasting && SwiftcastPvE.Cooldown.IsCoolingDown && RaiseSpell(out act, true)) return act;

IBaseAction.TargetOverride = null;

IBaseAction.ShouldEndSpecial = false;
IBaseAction.TargetOverride = null;

Expand Down
6 changes: 5 additions & 1 deletion RotationSolver/Commands/RSCommands_Actions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@ public static void DoAction()

if (nextAction.Use())
{
OtherConfiguration.RotationSolverRecord.ClickingCount++;
// Check if the setting to enable clicking count increment is enabled
if (Service.Config.EnableClickingCount)
{
OtherConfiguration.RotationSolverRecord.ClickingCount++;
}

_lastActionID = nextAction.AdjustedID;
_lastUsedTime = DateTime.Now;
Expand Down
91 changes: 86 additions & 5 deletions RotationSolver/UI/RotationConfigWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Fate;
using FFXIVClientStructs.FFXIV.Client.System.Framework;
using FFXIVClientStructs.FFXIV.Client.System.Scheduler;
using FFXIVClientStructs.FFXIV.Common.Component.BGCollision;
using Lumina.Excel.Sheets;
using RotationSolver.Basic.Configuration;
Expand Down Expand Up @@ -2612,6 +2613,7 @@ private static void DrawDebug()
{() => "Next Action", DrawNextAction },
{() => "Last Action", DrawLastAction },
{() => "Others", DrawOthers },
{() => "GCD Cooldown Visualization", DrawGCDCooldownStuff },
{() => "Effect", () =>
{
ImGui.Text(Watcher.ShowStrSelf);
Expand Down Expand Up @@ -2645,11 +2647,11 @@ private static unsafe void DrawStatus()
}

// VFX info
ImGui.Text("VFX Data:");
foreach (var item in DataCenter.VfxDataQueue)
{
ImGui.Text(item.ToString());
}
//ImGui.Text("VFX Data:");
//foreach (var item in DataCenter.VfxDataQueue)
//{
// ImGui.Text(item.ToString());
//}

// Check and display VFX casting status
ImGui.Text($"Is Casting Tank VFX: {DataCenter.IsCastingTankVfx()}");
Expand Down Expand Up @@ -2826,6 +2828,8 @@ private static void DrawNextAction()
ImGui.Text(ActionUpdater.NextAction?.Name ?? "null");
ImGui.Text($"LastAbilityorNot: {DataCenter.LastAbilityorNot}");
ImGui.Text($"FirstAbilityorNot: {DataCenter.FirstAbilityorNot}");
ImGui.Text($"LastAbilityv2: {DataCenter.LastAbilityv2}");
ImGui.Text($"FirstAbilityv2: {DataCenter.FirstAbilityv2}");
ImGui.Text($"GCD Total: {DataCenter.DefaultGCDTotal}");
ImGui.Text($"GCD Remain: {DataCenter.DefaultGCDRemain}");
ImGui.Text($"GCD Elapsed: {DataCenter.DefaultGCDElapsed}");
Expand All @@ -2848,6 +2852,83 @@ private static void DrawOthers()
ImGui.Text($"Limit Break: {CustomRotation.LimitBreakLevel}");
}

private static float _maxAnimationLockTime = 0;

private static void DrawGCDCooldownStuff()
{
ImGui.Text("GCD Cooldown Visualization");

ImGui.Text($"GCD Elapsed: {DataCenter.DefaultGCDElapsed}");
ImGui.Text($"GCD Remain: {DataCenter.DefaultGCDRemain}");
ImGui.Text($"GCD Total: {DataCenter.DefaultGCDTotal}");

// Change text color based on LastAbilityv2
if (DataCenter.LastAbilityv2)
{
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.ParsedGreen);
ImGui.Text("LastAbilityv2: true");
}
else
{
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
ImGui.Text("LastAbilityv2: false");
}
ImGui.PopStyleColor();

// Change text color based on FirstAbilityv2
if (DataCenter.FirstAbilityv2)
{
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.ParsedGreen);
ImGui.Text("FirstAbilityv2: true");
}
else
{
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
ImGui.Text("FirstAbilityv2: false");
}
ImGui.PopStyleColor();

// Visualize the GCD and oGCD slots
float gcdTotal = DataCenter.DefaultGCDElapsed + DataCenter.DefaultGCDRemain;
float gcdProgress = DataCenter.DefaultGCDElapsed / gcdTotal;

// Draw the progress bar
ImGui.ProgressBar(gcdProgress, new Vector2(-1, 0), $"{DataCenter.DefaultGCDElapsed:F2}s / {gcdTotal:F2}s");

// Update the maximum Animation Lock Time if the current value is larger
float currentAnimationLockTime = ActionManagerHelper.GetCurrentAnimationLock(); // Assuming you have this value
if (currentAnimationLockTime > _maxAnimationLockTime)
{
_maxAnimationLockTime = currentAnimationLockTime;
}

// Calculate the position for the Animation Lock Delay marker
float markerPosition = _maxAnimationLockTime / gcdTotal;

// Draw the marker on the progress bar
Vector2 cursorPos = ImGui.GetCursorPos();
float progressBarWidth = ImGui.GetContentRegionAvail().X;
float markerXPos = cursorPos.X + (progressBarWidth * markerPosition);

// Draw the marker on the same line as the progress bar
ImGui.SetCursorPos(new Vector2(markerXPos, cursorPos.Y - ImGui.GetTextLineHeight() / 2));
ImGui.Text("|");

// Check if the marker is hovered and display a tooltip
if (ImGui.IsItemHovered())
{
ImGui.SetTooltip("Most recent recorded animation lock delay");
}

// Reset cursor position
ImGui.SetCursorPos(cursorPos);

// Add space below the progress bar
ImGui.Dummy(new Vector2(0, 20));

// Add any additional visualization for oGCD slots if needed
}

private static void DrawAction(ActionID id, string type)
{
ImGui.Text($"{type}: {id}");
Expand Down
1 change: 0 additions & 1 deletion RotationSolver/Watcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using Lumina.Excel.Sheets;
using RotationSolver.Basic.Configuration;
using System.Text.RegularExpressions;
using Action = Lumina.Excel.Sheets.Action;

namespace RotationSolver;

Expand Down

0 comments on commit b8a9360

Please sign in to comment.