Files
HSUI/Interface/Party/PartyFramesRaiseTracker.cs

186 lines
5.6 KiB
C#

using Dalamud.Game.ClientState.Objects.Types;
using HSUI.Config;
using HSUI.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
namespace HSUI.Interface.Party
{
public class PartyFramesRaiseTracker : IDisposable
{
private PartyFramesRaiseTrackerConfig _config = null!;
public PartyFramesRaiseTracker()
{
ConfigurationManager.Instance.ResetEvent += OnConfigReset;
OnConfigReset(ConfigurationManager.Instance);
}
~PartyFramesRaiseTracker()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected void Dispose(bool disposing)
{
if (!disposing)
{
return;
}
ConfigurationManager.Instance.ResetEvent -= OnConfigReset;
}
public void OnConfigReset(ConfigurationManager sender)
{
_config = sender.GetConfigObject<PartyFramesTrackersConfig>().Raise;
}
public void Update(List<IPartyFramesMember> partyMembers)
{
if (!_config.Enabled)
{
return;
}
Dictionary<uint, IPartyFramesMember> deadAndNotRaised = new Dictionary<uint, IPartyFramesMember>();
float? limitBreakTime = null;
Dictionary<uint, float> raiseTimeMap = new Dictionary<uint, float>();
foreach (var member in partyMembers)
{
if (member.Character == null || member.ObjectId == 0)
{
member.RaiseTime = null;
continue;
}
if (member.HP > 0)
{
member.RaiseTime = null;
}
if (member.Character is not IBattleChara battleChara)
{
continue;
}
// check raise casts
if (Utils.IsActorCasting(battleChara))
{
var remaining = Math.Max(0, battleChara.TotalCastTime - battleChara.CurrentCastTime);
// check limit break
if (IsRaiseLimitBreakAction(battleChara.CastActionId) &&
(limitBreakTime.HasValue && limitBreakTime.Value > remaining))
{
limitBreakTime = remaining;
}
// check regular raise
else if (IsRaiseAction(battleChara.CastActionId))
{
if (raiseTimeMap.TryGetValue((uint)battleChara.CastTargetObjectId, out float raiseTime))
{
if (raiseTime > remaining)
{
raiseTimeMap[(uint)battleChara.CastTargetObjectId] = remaining;
}
}
else
{
raiseTimeMap.Add((uint)battleChara.CastTargetObjectId, remaining);
}
}
}
// check raise buff
if (member.HP <= 0)
{
bool hasBuff = false;
var statusList = Utils.StatusListForBattleChara(battleChara);
foreach (var status in statusList)
{
if (status == null || (status.StatusId != 148 && status.StatusId != 1140))
{
continue;
}
// apply raise data based on buff
member.RaiseTime = status.RemainingTime;
hasBuff = true;
break;
}
if (!hasBuff)
{
deadAndNotRaised.Add(member.ObjectId, member);
}
}
}
// apply raise data based on casts
foreach (var memberId in deadAndNotRaised.Keys)
{
var member = deadAndNotRaised[memberId];
if (raiseTimeMap.TryGetValue(memberId, out float raiseTime))
{
if (limitBreakTime.HasValue && limitBreakTime.Value < raiseTime)
{
member.RaiseTime = limitBreakTime;
}
else
{
member.RaiseTime = raiseTime;
}
}
else
{
member.RaiseTime = limitBreakTime; // its fine if this is null here
}
}
}
#region raise ids
private static bool IsRaiseLimitBreakAction(uint actionId)
{
return LimitBreakIds.Contains(actionId);
}
private static bool IsRaiseAction(uint actionId)
{
return RaiseIds.Contains(actionId);
}
private static List<uint> RaiseIds = new List<uint>()
{
173, // ACN, SMN, SCH
125, // CNH, WHM
3603, // AST
18317, // BLU
22345, // Lost Sacrifice, Bozja
20730, // Lost Arise, Bozja
12996, // Raise L, Eureka
24287 // SGE
};
private static List<uint> LimitBreakIds = new List<uint>()
{
208, // WHM
4247, // SCH
4248, // AST
24859 // SGE
};
#endregion
}
}