mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-29 20:03:41 +01:00
Create framework for YesHealMe (AU NoTankYou).
This commit is contained in:
parent
197abfeb0b
commit
4dbf27089a
5 changed files with 187 additions and 0 deletions
|
|
@ -135,6 +135,16 @@ internal class FoolsManager : IDisposable, IServiceType
|
||||||
RealAuthor = "Chirp",
|
RealAuthor = "Chirp",
|
||||||
Type = typeof(GoodVibesPlugin),
|
Type = typeof(GoodVibesPlugin),
|
||||||
},
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Name = "YesHealMe",
|
||||||
|
InternalName = "YesHealMePlugin",
|
||||||
|
Description = "The only warning you need.",
|
||||||
|
Author = "MidoriKami",
|
||||||
|
RealAuthor = "Berna",
|
||||||
|
Type = typeof(YesHealMePlugin),
|
||||||
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
41
Dalamud/Fools/Helper/YesHealMe/HudHelper.cs
Normal file
41
Dalamud/Fools/Helper/YesHealMe/HudHelper.cs
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
using Dalamud;
|
||||||
|
using Dalamud.Game.ClientState.Objects;
|
||||||
|
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
|
|
||||||
|
namespace NoTankYou.Utilities;
|
||||||
|
|
||||||
|
public static unsafe class HudHelper
|
||||||
|
{
|
||||||
|
private static AgentHUD* AgentHud => AgentModule.Instance()->GetAgentHUD();
|
||||||
|
|
||||||
|
public static PlayerCharacter? GetPlayerCharacter(int index)
|
||||||
|
{
|
||||||
|
// Sorta temporary, waiting for ClientStructs to merge a fixed size array for this element
|
||||||
|
var partyMemberList = AgentHud->PartyMemberList;
|
||||||
|
var targetOffset = index * sizeof(HudPartyMember);
|
||||||
|
var targetAddress = partyMemberList + targetOffset;
|
||||||
|
var hudData = (HudPartyMember*) targetAddress;
|
||||||
|
|
||||||
|
var targetPlayer = hudData->ObjectId;
|
||||||
|
|
||||||
|
return GetPlayer(targetPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlayerCharacter? GetAllianceMember(int index)
|
||||||
|
{
|
||||||
|
var targetPlayer = AgentHud->RaidMemberIds[index];
|
||||||
|
|
||||||
|
return GetPlayer(targetPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PlayerCharacter? GetPlayer(uint objectId)
|
||||||
|
{
|
||||||
|
var result = Service<ObjectTable>.Get().SearchById(objectId);
|
||||||
|
|
||||||
|
if (result?.GetType() == typeof(PlayerCharacter))
|
||||||
|
return result as PlayerCharacter;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
67
Dalamud/Fools/Helper/YesHealMe/PartyListAddon.cs
Normal file
67
Dalamud/Fools/Helper/YesHealMe/PartyListAddon.cs
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using Dalamud;
|
||||||
|
using Dalamud.Game;
|
||||||
|
using Dalamud.Game.Gui;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
|
using NoTankYou.DataModels;
|
||||||
|
using NoTankYou.Utilities;
|
||||||
|
|
||||||
|
namespace NoTankYou.System;
|
||||||
|
|
||||||
|
public unsafe class PartyListAddon : IEnumerable<PartyListAddonData>, IDisposable
|
||||||
|
{
|
||||||
|
public record PartyFramePositionInfo(Vector2 Position, Vector2 Size, Vector2 Scale);
|
||||||
|
public IEnumerator<PartyListAddonData> GetEnumerator() => addonData.GetEnumerator();
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
private static AddonPartyList* PartyList => (AddonPartyList*) Service<GameGui>.Get()?.GetAddonByName("_PartyList");
|
||||||
|
public static bool DataAvailable => PartyList != null && PartyList->AtkUnitBase.RootNode != null;
|
||||||
|
|
||||||
|
private readonly List<PartyListAddonData> addonData = new();
|
||||||
|
|
||||||
|
public PartyListAddon()
|
||||||
|
{
|
||||||
|
Service<Framework>.Get().Update += OnFrameworkUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Service<Framework>.Get().Update -= OnFrameworkUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnFrameworkUpdate(Framework framework)
|
||||||
|
{
|
||||||
|
addonData.Clear();
|
||||||
|
if (!DataAvailable) return;
|
||||||
|
if (PartyList->MemberCount <= 0) return;
|
||||||
|
|
||||||
|
foreach (var index in Enumerable.Range(0, PartyList->MemberCount))
|
||||||
|
{
|
||||||
|
var playerCharacter = HudHelper.GetPlayerCharacter(index);
|
||||||
|
var userInterface = PartyList->PartyMember[index];
|
||||||
|
|
||||||
|
addonData.Add(new PartyListAddonData
|
||||||
|
{
|
||||||
|
PlayerCharacter = playerCharacter,
|
||||||
|
UserInterface = userInterface,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PartyFramePositionInfo GetPositionInfo()
|
||||||
|
{
|
||||||
|
// Resource Node (id 9) contains a weird offset for the actual list elements
|
||||||
|
var rootNode = PartyList->AtkUnitBase.RootNode;
|
||||||
|
var addonBasePosition = new Vector2(rootNode->X, rootNode->Y);
|
||||||
|
var scale = new Vector2(rootNode->ScaleX, rootNode->ScaleY);
|
||||||
|
|
||||||
|
var partyListNode = PartyList->AtkUnitBase.GetNodeById(9);
|
||||||
|
var partyListPositionOffset = new Vector2(partyListNode->X, partyListNode->Y) * scale;
|
||||||
|
var partyListSize = new Vector2(partyListNode->Width, partyListNode->Height);
|
||||||
|
|
||||||
|
return new PartyFramePositionInfo(addonBasePosition + partyListPositionOffset, partyListSize * scale, scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
37
Dalamud/Fools/Helper/YesHealMe/PartyListAddonData.cs
Normal file
37
Dalamud/Fools/Helper/YesHealMe/PartyListAddonData.cs
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
|
|
||||||
|
namespace NoTankYou.DataModels;
|
||||||
|
|
||||||
|
public readonly unsafe struct PartyListAddonData
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<uint, Stopwatch> TimeSinceLastTargetable = new();
|
||||||
|
|
||||||
|
public AddonPartyList.PartyListMemberStruct UserInterface { get; init; }
|
||||||
|
public PlayerCharacter? PlayerCharacter { get; init; }
|
||||||
|
|
||||||
|
private bool Targetable => UserInterface.PartyMemberComponent->OwnerNode->AtkResNode.Color.A != 0x99;
|
||||||
|
|
||||||
|
public bool IsTargetable()
|
||||||
|
{
|
||||||
|
if (PlayerCharacter is null) return false;
|
||||||
|
|
||||||
|
TimeSinceLastTargetable.TryAdd(PlayerCharacter.ObjectId, Stopwatch.StartNew());
|
||||||
|
var stopwatch = TimeSinceLastTargetable[PlayerCharacter.ObjectId];
|
||||||
|
|
||||||
|
if (Targetable)
|
||||||
|
{
|
||||||
|
// Returns true if the party member has been targetable for 2second or more
|
||||||
|
return stopwatch.Elapsed >= TimeSpan.FromSeconds(2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Returns false, and continually resets the stopwatch
|
||||||
|
stopwatch.Restart();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
32
Dalamud/Fools/Plugins/YesHealMePlugin.cs
Normal file
32
Dalamud/Fools/Plugins/YesHealMePlugin.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
using System.Linq;
|
||||||
|
using Dalamud.Logging;
|
||||||
|
using NoTankYou.System;
|
||||||
|
|
||||||
|
namespace Dalamud.Fools.Plugins;
|
||||||
|
|
||||||
|
public class YesHealMePlugin: IFoolsPlugin
|
||||||
|
{
|
||||||
|
private PartyListAddon partyListAddon;
|
||||||
|
|
||||||
|
public YesHealMePlugin()
|
||||||
|
{
|
||||||
|
partyListAddon = new PartyListAddon();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawUi()
|
||||||
|
{
|
||||||
|
foreach (var partyMember in this.partyListAddon.Select(pla => pla.PlayerCharacter).Where(pc => pc is not null))
|
||||||
|
{
|
||||||
|
if (partyMember.CurrentHp < partyMember.MaxHp)
|
||||||
|
{
|
||||||
|
// Do things here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
this.partyListAddon.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue